diff --git a/.github/actions/check-coverage/action.yml b/.github/actions/check-coverage/action.yml
new file mode 100644
index 000000000..59d8307c8
--- /dev/null
+++ b/.github/actions/check-coverage/action.yml
@@ -0,0 +1,34 @@
+name: Check Coverage Results
+description: 'Extracts a summary of the code coverage results'
+
+inputs:
+ binary-dir:
+ description: 'Directory containing binary files'
+ required: true
+ source-dir:
+ description: 'Directory containing source code files'
+ default: ./source
+
+runs:
+ using: 'composite'
+ steps:
+ - name: Capture Results
+ shell: bash
+ run: lcov
+ --capture --rc lcov_branch_coverage=1
+ --include '${{ github.workspace }}/*'
+ --directory '${{ inputs.binary-dir }}'
+ --output-file '${{ inputs.binary-dir }}/coverage.info'
+
+ - name: Generate HTML
+ shell: bash
+ run: genhtml
+ '${{ inputs.binary-dir }}/coverage.info'
+ --branch-coverage
+ --output-directory '${{ inputs.binary-dir }}/lcov-html'
+
+ - name: Extract Summary
+ shell: bash
+ run: xsltproc --html
+ '${{ inputs.source-dir }}/.github/scripts/lcov-output.xslt'
+ '${{ inputs.binary-dir }}/lcov-html/index.html' > '${{ inputs.binary-dir }}/lcov-summary.xml'
diff --git a/.github/scripts/lcov-output.xslt b/.github/scripts/lcov-output.xslt
new file mode 100644
index 000000000..77e2ea4dd
--- /dev/null
+++ b/.github/scripts/lcov-output.xslt
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ X
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LCOV Report
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.github/workflows/build-osal-documentation.yml b/.github/workflows/build-osal-documentation.yml
deleted file mode 100644
index 1f0417e59..000000000
--- a/.github/workflows/build-osal-documentation.yml
+++ /dev/null
@@ -1,68 +0,0 @@
-name: "Build OSAL Documentation (API Guide)"
-
-on:
- push:
- pull_request:
-
-jobs:
-
- #Check for duplicate actions. Skips push actions if there is a matching or duplicate pull-request action.
- check-for-duplicates:
- runs-on: ubuntu-latest
- # Map a step output to a job output
- outputs:
- should_skip: ${{ steps.skip_check.outputs.should_skip }}
- steps:
- - id: skip_check
- uses: fkirc/skip-duplicate-actions@master
- with:
- concurrent_skipping: 'same_content'
- skip_after_successful_duplicate: 'true'
- do_not_skip: '["pull_request", "workflow_dispatch", "schedule"]'
-
- build-osal-apiguide:
- #Continue if check-for-duplicates found no duplicates. Always runs for pull-requests.
- needs: check-for-duplicates
- if: ${{ needs.check-for-duplicates.outputs.should_skip != 'true' }}
- runs-on: ubuntu-20.04
- timeout-minutes: 15
-
- steps:
- - name: Install Dependencies
- run: sudo apt-get install doxygen graphviz -y
-
- - name: Checkout submodule
- uses: actions/checkout@v3
-
- - name: Set up for build
- run: |
- cp Makefile.sample Makefile
- make prep
-
- - name: Build OSAL API Guide
- run: |
- make osal-apiguide 2>&1 > make_osal-apiguide_stdout.txt | tee make_osal-apiguide_stderr.txt
- mv build/docs/osal-apiguide-warnings.log osal-apiguide-warnings.log
-
- - name: Archive Osal Guide Build Logs
- uses: actions/upload-artifact@v3
- with:
- name: OSAL Guide Artifacts
- path: |
- make_osal-apiguide_stdout.txt
- make_osal-apiguide_stderr.txt
- osal-apiguide-warnings.log
-
- - name: Error Check
- run: |
- if [[ -s make_osal-apiguide_stderr.txt ]]; then
- cat make_osal-apiguide_stderr.txt
- exit -1
- fi
-
- - name: Warning Check
- run: |
- if [[ -s osal-apiguide-warnings.log ]]; then
- cat osal-apiguide-warnings.log
- exit -1
- fi
diff --git a/.github/workflows/codeql-cfe-build.yml b/.github/workflows/codeql-cfe-build.yml
deleted file mode 100644
index 9a4a5099e..000000000
--- a/.github/workflows/codeql-cfe-build.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: "CodeQL cFE Build Analysis"
-
-on:
- push:
- pull_request:
-
-jobs:
- codeql:
- name: CodeQl Analysis
- uses: nasa/cFS/.github/workflows/codeql-reusable.yml@main
- with:
- component-path: osal
- make: 'make -C build/native/default_cpu1/osal'
diff --git a/.github/workflows/codeql-osal-default.yml b/.github/workflows/codeql-osal-default.yml
deleted file mode 100644
index 748faa93c..000000000
--- a/.github/workflows/codeql-osal-default.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-name: "CodeQL Analysis OSAL Default Build"
-
-on:
- push:
- pull_request:
-
-jobs:
- codeql:
- name: CodeQl Analysis
- uses: nasa/cFS/.github/workflows/codeql-reusable.yml@main
- with:
- component-path: cFS # Causes reusable workflow to not checkout bundle
- setup: 'cp Makefile.sample Makefile'
- prep: 'make prep'
- make: 'make'
diff --git a/.github/workflows/format-check.yml b/.github/workflows/format-check.yml
deleted file mode 100644
index bf12f09e2..000000000
--- a/.github/workflows/format-check.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-name: Format Check
-
-# Run on all push and pull requests
-on:
- push:
- pull_request:
-
-jobs:
- format-check:
- name: Run format check
- uses: nasa/cFS/.github/workflows/format-check.yml@main
\ No newline at end of file
diff --git a/.github/workflows/local_unit_test.yml b/.github/workflows/local_unit_test.yml
deleted file mode 100644
index a14a4f1c2..000000000
--- a/.github/workflows/local_unit_test.yml
+++ /dev/null
@@ -1,70 +0,0 @@
-name: "Local Unit Test"
-
-on:
- push:
- pull_request:
-
-jobs:
- #Checks for duplicate actions. Skips push actions if there is a matching or duplicate pull-request action.
- check-for-duplicates:
- runs-on: ubuntu-latest
- # Map a step output to a job output
- outputs:
- should_skip: ${{ steps.skip_check.outputs.should_skip }}
- steps:
- - id: skip_check
- uses: fkirc/skip-duplicate-actions@master
- with:
- concurrent_skipping: 'same_content'
- skip_after_successful_duplicate: 'true'
- do_not_skip: '["pull_request", "workflow_dispatch", "schedule"]'
-
- Local-Unit-Test:
- needs: check-for-duplicates
- if: ${{ needs.check-for-duplicates.outputs.should_skip != 'true' }}
- runs-on: ubuntu-20.04
- timeout-minutes: 15
-
- steps:
- - name: Install coverage tools
- run: sudo apt-get install lcov -y
-
- - name: Checkout submodule
- uses: actions/checkout@v3
-
- - name: Set up for build
- run: |
- cp Makefile.sample Makefile
- make ENABLE_UNIT_TESTS=true PERMISSIVE_MODE=true prep
-
- - name: Build the code
- run: make -j
-
- # Baseline lcov and run all tests
- - name: Test
- run: make test
-
- - name: Calculate coverage
- run: make lcov | tee lcov_out.txt
-
- - name: Confirm 100% line coverage
- run: |
- if [[ `grep -A 3 "Overall coverage rate" lcov_out.txt | grep lines` != *"100.0%"* ]]; then
- grep -A 3 "Overall coverage rate" lcov_out.txt
- echo "Lacks 100.0% line unit test coverage"
- exit -1
- fi
-
- - name: Confirm absolute line coverage
- run: |
- # Current best possible branch coverage is all but 4, with associated issues for each missing case
- missed_branches=4
- coverage_nums=$(grep -A 3 "Overall coverage rate" lcov_out.txt | grep branches | grep -oP "[0-9]+[0-9]*")
-
- diff=$(echo $coverage_nums | awk '{ print $4 - $3 }')
- if [ $diff -gt $missed_branches ]
- then
- grep -A 3 "Overall coverage rate" lcov_out.txt
- echo "More than $missed_branches branches missed"
- exit -1
- fi
diff --git a/.github/workflows/standalone-build.yml b/.github/workflows/standalone-build.yml
new file mode 100644
index 000000000..1f836bb7f
--- /dev/null
+++ b/.github/workflows/standalone-build.yml
@@ -0,0 +1,92 @@
+name: Build and Test Standalone OSAL package
+
+on:
+ workflow_dispatch:
+ pull_request:
+ push: # for now
+
+# Force bash to apply pipefail option so pipeline failures aren't masked
+defaults:
+ run:
+ shell: bash
+
+jobs:
+
+ build-and-test:
+ name: Build and Execute Tests
+
+ strategy:
+ fail-fast: false
+ matrix:
+ build-type: [Debug, Release]
+ base-os: [ubuntu-22.04, ubuntu-20.04]
+
+ runs-on: ${{ matrix.base-os }}
+
+ steps:
+
+ - name: Checkout OSAL
+ uses: actions/checkout@v3
+ with:
+ path: source
+
+ - name: Install Coverage Analysis Tools
+ if: ${{ matrix.build-type == 'Debug' && matrix.base-os == 'ubuntu-20.04' }}
+ run: sudo apt-get install -y lcov xsltproc && echo "run_lcov=TRUE" >> $GITHUB_ENV
+
+ - name: Set up debug environment
+ if: ${{ matrix.build-type == 'Debug' }}
+ run: |
+ echo "is_debug=TRUE" >> $GITHUB_ENV
+ echo "is_release=FALSE" >> $GITHUB_ENV
+ echo "build_tgt=all" >> $GITHUB_ENV
+ echo "DESTDIR=${{ github.workspace }}/staging-debug" >> $GITHUB_ENV
+
+ - name: Set up release environment
+ if: ${{ matrix.build-type == 'Release' }}
+ run: |
+ echo "is_debug=FALSE" >> $GITHUB_ENV
+ echo "is_release=TRUE" >> $GITHUB_ENV
+ echo "build_tgt=install osal_apicheck" >> $GITHUB_ENV
+ echo "DESTDIR=${{ github.workspace }}/staging-release" >> $GITHUB_ENV
+
+ - name: Set up build
+ run: cmake
+ -DCMAKE_BUILD_TYPE=${{ matrix.build-type }}
+ -DENABLE_UNIT_TESTS=${{ env.is_debug }}
+ -DOSAL_OMIT_DEPRECATED=${{ env.is_debug }}
+ -DOSAL_VALIDATE_API=${{ env.is_release }}
+ -DOSAL_INSTALL_LIBRARIES=${{ env.is_release }}
+ -DOSAL_CONFIG_DEBUG_PERMISSIVE_MODE=${{ env.is_debug }}
+ -DOSAL_SYSTEM_BSPTYPE=generic-linux
+ -DCMAKE_PREFIX_PATH=/usr/lib/cmake
+ -DCMAKE_INSTALL_PREFIX=/usr
+ -S source
+ -B build
+
+ - name: Build OSAL
+ working-directory: build
+ run: make ${{ env.build_tgt }} -j2 VERBOSE=1
+
+ - name: Run Tests
+ if: ${{ matrix.build-type == 'Debug' }}
+ working-directory: build
+ run: ctest --output-on-failure -j4 2>&1 | tee ../ctest.log
+
+ - name: Check Coverage
+ if: ${{ env.run_lcov == 'TRUE' }}
+ uses: ./source/.github/actions/check-coverage
+ with:
+ binary-dir: build
+
+ - name: Assemble Results
+ run: |
+ if [ -s ctest.log ]; then
+ echo '
CTest Execution
' >> $GITHUB_STEP_SUMMARY
+ echo '' >> $GITHUB_STEP_SUMMARY
+ cat ctest.log >> $GITHUB_STEP_SUMMARY
+ echo '
' >> $GITHUB_STEP_SUMMARY
+ fi
+ if [ -s 'build/lcov-summary.xml' ]; then
+ cat 'build/lcov-summary.xml' >> $GITHUB_STEP_SUMMARY
+ fi
diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml
deleted file mode 100644
index ea2250b04..000000000
--- a/.github/workflows/static-analysis.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-name: Static Analysis
-
-# Run on all push and pull requests
-on:
- push:
- pull_request:
- workflow_dispatch:
-
-jobs:
- static-analysis:
- name: Run Static Analysis
- uses: nasa/cFS/.github/workflows/static-analysis.yml@main
- with:
- strict-dir-list: './src/bsp ./src/os'
- cmake-project-options: -DENABLE_UNIT_TESTS=TRUE -DOSAL_OMIT_DEPRECATED=TRUE -DOSAL_SYSTEM_BSPTYPE=generic-linux
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 38a39952f..a7d44eba2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -97,7 +97,14 @@ if (CMAKE_VERSION VERSION_GREATER 3.13)
cmake_policy(SET CMP0079 NEW)
endif()
-project(OSAL C)
+option(OSAL_VALIDATE_API "Validate the OSAL API headers as part of the build" OFF)
+if (OSAL_VALIDATE_API)
+ set(OSAL_LANG C CXX)
+else()
+ set(OSAL_LANG C CXX)
+endif()
+
+project(OSAL ${OSAL_LANG})
# define a custom property to track relationship between BSP and OS
# this should be set on BSP "impl" targets to indicate the correct OS impl to go with it
@@ -178,7 +185,6 @@ if (OSAL_OMIT_DEPRECATED)
target_compile_definitions(osal_public_api INTERFACE OSAL_OMIT_DEPRECATED)
endif (OSAL_OMIT_DEPRECATED)
-
# OSAL_SYSTEM_BSPTYPE indicate which of the BSP packages
# to build. If not defined then no OSAL implementation will be built, however
# the api interface target (osal_public_api) is still usable. Therefore
@@ -478,3 +484,41 @@ if (OSAL_INSTALL_LIBRARIES)
)
endif()
+
+if (OSAL_VALIDATE_API)
+
+ # Validate the API header files individually
+ file(GLOB OSAL_API_HEADERS ${OSAL_SOURCE_DIR}/src/os/inc/*.h)
+ set(OSAL_APICHECK_SOURCES)
+ set(OSAL_APICHECK_DIR "${CMAKE_CURRENT_BINARY_DIR}/apicheck")
+
+ foreach(HDR_FILE ${OSAL_API_HEADERS})
+ get_filename_component(HDR "${HDR_FILE}" NAME)
+ string(MAKE_C_IDENTIFIER "${HDR}" HDR_ID)
+ configure_file(${OSAL_SOURCE_DIR}/check_header.c.in ${OSAL_APICHECK_DIR}/check_${HDR_ID}.c)
+ list(APPEND OSAL_APICHECK_SOURCES_C ${OSAL_APICHECK_DIR}/check_${HDR_ID}.c)
+ configure_file(${OSAL_SOURCE_DIR}/check_header.cpp.in ${OSAL_APICHECK_DIR}/check_${HDR_ID}.cpp)
+ list(APPEND OSAL_APICHECK_SOURCES_CXX ${OSAL_APICHECK_DIR}/check_${HDR_ID}.cpp)
+ endforeach(HDR_FILE ${OSAL_API_HEADERS})
+ add_library(osal_apicheck_C OBJECT ${OSAL_APICHECK_SOURCES_C})
+ add_library(osal_apicheck_CXX OBJECT ${OSAL_APICHECK_SOURCES_CXX})
+ if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
+ target_compile_options(osal_apicheck_C PUBLIC -std=c99 -pedantic -Wall -Werror)
+ endif()
+ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+ target_compile_options(osal_apicheck_CXX PUBLIC -std=c++03 -pedantic -Wall -Werror)
+ endif()
+
+ # This causes the check to compile with the same set of defines and include dirs as specified
+ # in the "INTERFACE" properties of the actual module
+ target_link_libraries(osal_apicheck_C PUBLIC
+ osal_public_api
+ )
+ target_link_libraries(osal_apicheck_CXX PUBLIC
+ osal_public_api
+ )
+
+ add_custom_target(osal_apicheck ALL)
+ add_dependencies(osal_apicheck osal_apicheck_C)
+ add_dependencies(osal_apicheck osal_apicheck_CXX)
+endif()
diff --git a/check_header.c.in b/check_header.c.in
new file mode 100644
index 000000000..e452d823f
--- /dev/null
+++ b/check_header.c.in
@@ -0,0 +1,4 @@
+#include "@HDR@"
+
+/* A no-op function so this compilation unit is not empty */
+void CheckHeader_@HDR_ID@(void) {}
diff --git a/check_header.cpp.in b/check_header.cpp.in
new file mode 100644
index 000000000..4be090c57
--- /dev/null
+++ b/check_header.cpp.in
@@ -0,0 +1,7 @@
+extern "C"
+{
+#include "@HDR@"
+}
+
+/* An empty class */
+class CheckHeader_@HDR_ID@ {};