diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5349dfe..e759a18 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,66 +6,83 @@ on: pull_request: branches: [main, master] +permissions: + contents: read + +env: + CMAKE_BUILD_TYPE: Release + jobs: - build: - runs-on: ${{ matrix.os }} - container: ${{ matrix.container }} - strategy: - matrix: - include: - - os: macos-latest - container: '' - install: | - brew update - brew upgrade - - os: ubuntu-latest - container: rockylinux:9 - install: | - dnf -y install gcc gcc-c++ make cmake git + build_macos: + name: Build (macOS) + runs-on: macos-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - name: Install dependencies - run: ${{ matrix.install }} + run: | + if ! command -v cmake >/dev/null 2>&1; then + brew install cmake + fi + cmake --version + c++ --version - - name: Configure and Build + - name: Configure + run: cmake -S . -B build -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DBUILD_TESTING=OFF + + - name: Build imalgs + run: cmake --build build --target imalgs --parallel + + build_rocky: + name: Build (Rocky Linux 9) + runs-on: ubuntu-latest + container: + image: rockylinux:9 + steps: + - name: Install dependencies run: | - cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF - cmake --build build --target imalgs -j - + dnf -y install gcc gcc-c++ make git tar gzip python3-pip + python3 -m pip install --upgrade "cmake>=3.26,<4.3" + cmake --version + c++ --version + + - uses: actions/checkout@v7 + + - name: Configure + run: cmake -S . -B build -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DBUILD_TESTING=OFF + + - name: Build imalgs + run: cmake --build build --target imalgs --parallel run_all_tests: + name: Test (Rocky Linux 9) runs-on: ubuntu-latest container: image: rockylinux:9 steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Install dependencies run: | - dnf -y install gcc gcc-c++ make cmake git + dnf -y install gcc gcc-c++ make git tar gzip python3-pip + python3 -m pip install --upgrade "cmake>=3.26,<4.3" + cmake --version + c++ --version - - name: Build project - run: | - cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON + - name: Checkout repository + uses: actions/checkout@v7 - - name: Run tests - run: | - cmake --build build --target run_imalgs_test -j + - name: Configure + run: cmake -S . -B build -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DIM_SAMPLE_ALGORITHM_BUILD_TESTING=ON + + - name: Build + run: cmake --build build --parallel + + - name: Run CTest + run: ctest --test-dir build --output-on-failure - name: Upload test results - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 + if: always() with: name: imalgs-test-results path: build/unittest/*results.xml if-no-files-found: error - - # - name: Publish JUnit test results - # uses: dorny/test-reporter@v2 - # if: always() - # with: - # name: IM Algorithms Tests - # path: build/unittest/*results.xml - # reporter: jest-junit - # fail-on-error: true diff --git a/CMakeLists.txt b/CMakeLists.txt index 1b4af5b..b00d7c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.26...4.2) -project(im_sample_algorithm VERSION 5.3.1.0 LANGUAGES CXX) # the nano value is a boolean. 1 == SNAPSHOT, 0 == release +project(im_sample_algorithm VERSION 5.3.2 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -20,6 +20,9 @@ if(NOT COMMAND CPMAddPackage) include(${CMAKE_CURRENT_LIST_DIR}/.cmake/get_cpm.cmake) endif() +include(CMakePackageConfigHelpers) +include(GNUInstallDirs) + if(${PROJECT_VERSION_TWEAK}) # Append -SNAPSHOT to the version name if this is a pre-release version set(msg_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}-SNAPSHOT) @@ -29,8 +32,11 @@ endif() message(STATUS "${PROJECT_NAME}: Generating build version ${msg_VERSION}") # Begin project dependencies ------------------------------------------------------ -option(IM_SAMPLE_ALGORITHM_FETCH_FMACM "Fetch FMACM when the pub target is not already available" ON) -set(IM_SAMPLE_ALGORITHM_FMACM_TAG "v5.3.1" CACHE STRING "FMACM tag used for standalone builds") +set( + IM_SAMPLE_ALGORITHM_AIRCRAFT_SIMULATION_CORE_TAG + "1.0.0" + CACHE STRING "aircraft_simulation_core tag used for im_sample_algorithm builds" +) set(IM_SAMPLE_ALGORITHM_FSLOADER_TAG "1.1.0" CACHE STRING "fsloader tag used for im_sample_algorithm builds") set(IM_SAMPLE_ALGORITHM_NLOHMANN_JSON_VERSION "3.11.3" CACHE STRING "nlohmann_json version used for standalone builds") set(IM_SAMPLE_ALGORITHM_LOG4CPLUS_TAG "REL_2_1_2" CACHE STRING "log4cplus tag used for standalone builds") @@ -88,25 +94,56 @@ if(NOT TARGET mitre::fsloader) ) endif() -if(NOT TARGET pub) - if(NOT IM_SAMPLE_ALGORITHM_FETCH_FMACM) - message(FATAL_ERROR "${PROJECT_NAME}: target pub is required. Add FMACM first or enable IM_SAMPLE_ALGORITHM_FETCH_FMACM.") - endif() - +if(NOT TARGET mitre::oss::simcore) CPMAddPackage( - NAME fmacm - GITHUB_REPOSITORY mitre/FMACM - GIT_TAG ${IM_SAMPLE_ALGORITHM_FMACM_TAG} - DOWNLOAD_ONLY TRUE + NAME aircraft_simulation_core + GIT_REPOSITORY https://github.com/mitre/aircraft_simulation_core.git + GIT_TAG ${IM_SAMPLE_ALGORITHM_AIRCRAFT_SIMULATION_CORE_TAG} + OPTIONS + "SIMCORE_BUILD_TESTING OFF" ) +endif() - # FMACM's Public CMake expects this variable from the FMACM root project. - set(aaesim_INCLUDE_DIRS ${fmacm_SOURCE_DIR}/include) - add_subdirectory(${fmacm_SOURCE_DIR}/Public ${CMAKE_BINARY_DIR}/_deps/fmacm-public-build) +if(NOT TARGET mitre::oss::simcore) + message(FATAL_ERROR "${PROJECT_NAME}: target mitre::oss::simcore is required.") endif() add_subdirectory(IntervalManagement) +set(IM_SAMPLE_ALGORITHM_INSTALL_CMAKEDIR + "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" + CACHE STRING "CMake package config install directory") + +install( + TARGETS imalgs + EXPORT im_sample_algorithm-targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install( + DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install( + EXPORT im_sample_algorithm-targets + FILE im_sample_algorithm-targets.cmake + NAMESPACE mitre::oss:: + DESTINATION ${IM_SAMPLE_ALGORITHM_INSTALL_CMAKEDIR}) + +configure_package_config_file( + ${CMAKE_CURRENT_LIST_DIR}/cmake/im_sample_algorithm-config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/im_sample_algorithm-config.cmake + INSTALL_DESTINATION ${IM_SAMPLE_ALGORITHM_INSTALL_CMAKEDIR}) +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/im_sample_algorithm-config-version.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion) +install( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/im_sample_algorithm-config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/im_sample_algorithm-config-version.cmake + DESTINATION ${IM_SAMPLE_ALGORITHM_INSTALL_CMAKEDIR}) + if(IM_SAMPLE_ALGORITHM_BUILD_TESTING) add_subdirectory(unittest) else() diff --git a/IntervalManagement/CMakeLists.txt b/IntervalManagement/CMakeLists.txt index 2892305..8f0941a 100644 --- a/IntervalManagement/CMakeLists.txt +++ b/IntervalManagement/CMakeLists.txt @@ -1,8 +1,8 @@ # This file causes creation of the IM algorithms library (libimalgs.a). cmake_minimum_required(VERSION 3.14) -if(NOT TARGET pub) - message(FATAL_ERROR "imalgs requires the FMACM pub target. Configure from the repository root or add FMACM before this directory.") +if(NOT TARGET mitre::oss::simcore) + message(FATAL_ERROR "imalgs requires the mitre::oss::simcore target. Configure from the repository root or add aircraft_simulation_core before this directory.") endif() if(NOT TARGET mitre::fsloader) message(FATAL_ERROR "imalgs requires the mitre::fsloader target. Configure from the repository root or add fsloader before this directory.") @@ -77,7 +77,11 @@ target_include_directories(imalgs $) target_link_libraries(imalgs PUBLIC - pub - mitre::fsloader - nlohmann_json::nlohmann_json - log4cplus::log4cplusS) + $ + $> + $ + $> + $ + $> + $ + $>) diff --git a/cmake/im_sample_algorithm-config.cmake.in b/cmake/im_sample_algorithm-config.cmake.in new file mode 100644 index 0000000..7b96e64 --- /dev/null +++ b/cmake/im_sample_algorithm-config.cmake.in @@ -0,0 +1,12 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +find_dependency(aircraft_simulation_core REQUIRED) +find_dependency(fsloader REQUIRED) +find_dependency(nlohmann_json REQUIRED) +find_dependency(log4cplus REQUIRED) + +include("${CMAKE_CURRENT_LIST_DIR}/im_sample_algorithm-targets.cmake") + +check_required_components(im_sample_algorithm) diff --git a/docs/README.md b/docs/README.md index cec7166..fbfd1d7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,7 +24,7 @@ This [repository](https://github.com/mitre/im_sample_algorithm) contains a C++ l _It is not an application._ GitHub [CI](../.github/workflows/ci.yml) is used to build & run tests. -You should be familiar with the [FAA's Flight-deck Interval Management](https://www.faa.gov/about/office_org/headquarters_offices/ang/offices/tc/library/storyboard/detailedwebpages/im.html) concept. To understand any of this content at a techincal level, you need to also have [RTCA's DO-361A, Appendix C](https://my.rtca.org/). +You should be familiar with the [FAA's Flight-deck Interval Management](https://www.faa.gov/about/office_org/headquarters_offices/ang/offices/tc/library/storyboard/detailedwebpages/im.html) concept. To understand any of this content at a technical level, you need to also have [RTCA's DO-361A, Appendix C](https://my.rtca.org/). For an application that can use this library, see the [FIM MOPS Aircraft & Control Model](https://mitre.github.io/FMACM/) (FMACM). @@ -80,16 +80,18 @@ Living, developer-level documentation is provided on this GitHub site. Here the - **Code Topics** + - Adding this library to a larger CMake simulation framework? Review the [short CPM integration recommendation](context.md#short-recommendation-cpm-integration) - Who you gonna call? :ghosts: Read [code entry points](entry_points.md) - How does an algorithm receive IM Clearance details? Read [code entry points](entry_points.md) - How does an algorithm receive a new aircraft state? Read [code entry points](entry_points.md) and the [traffic data discussion](traffic_data.md) - Find your own (shorter) path: [IM Turn Implementation](imturn.md) - - What are the ADS-B Data expectations? -- Reveiw the [traffic data discussion](traffic_data.md) + - What are the ADS-B Data expectations? -- Review the [traffic data discussion](traffic_data.md) - Where is the [IFPI defined](ifpi.md)? -- [Coming Soon](coming_soon.md) - Uh...Which algorithm is running? -- Review [the algorithm stages](which_algorithm.md) discussion - Are we missing some code? Review the [missing code table](missing_code.md) -Not seeing what you need to know about? [Post an issue](https://github.com/mitre/im_sample_algorithm/issues). We gladly prioritize specific requests. Thanks! +Not seeing what you need to know about? [Post an issue](https://github.com/mitre/im_sample_algorithm/issues). +Thanks! ## EUROCONTROL BADA Development -- Necessary? diff --git a/docs/context.md b/docs/context.md index 6610804..d72f6bc 100644 --- a/docs/context.md +++ b/docs/context.md @@ -38,4 +38,36 @@ The second simulation paradigm is MITRE's [Aviation IDEA Lab](https://www.mitre. ## How External Collaborators Can Use This Code -In order to use this Sample Algorithm code, you'll need to provide your own simulation environment that hosts the Sample Algorithm. This code base does not propagate aircraft state nor does it provide equations-of-motion, so your simulation will in the very least need a way to produce states for ownship and traffic aircraft and dynamically respond to the speed guidance coming from the Sample Algorithm. One possibility is to use MITRE's parametric simulation core, made available as [FMACM](https://github.com/mitre/FMACM). But use of FMACM is not required; you can use any simulation paradigm that is appropriate to your research needs. \ No newline at end of file +In order to use this Sample Algorithm code, you'll need to provide your own simulation environment that hosts the Sample Algorithm. This code base does not propagate aircraft state nor does it provide equations-of-motion, so your simulation will in the very least need a way to produce states for ownship and traffic aircraft and dynamically respond to the speed guidance coming from the Sample Algorithm. One possibility is to use MITRE's parametric simulation core, made available as [FMACM](https://github.com/mitre/FMACM). But use of FMACM is not required; you can use any simulation paradigm that is appropriate to your research needs. + +### Short Recommendation: CPM Integration + +For a CMake-based simulation framework, let the top-level simulation own dependency versions and bring this repository in as a library with [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake). Pin released tags or known-good commits, add `aircraft_simulation_core` first if your framework already uses it, disable child-project tests in the parent build, and link your simulation target to `mitre::oss::fim_sample_algorithm`. + +```cmake +include(cmake/CPM.cmake) + +CPMAddPackage( + NAME aircraft_simulation_core + GIT_REPOSITORY https://github.com/mitre/aircraft_simulation_core.git + GIT_TAG + OPTIONS + "SIMCORE_BUILD_TESTING OFF" +) + +CPMAddPackage( + NAME im_sample_algorithm + GIT_REPOSITORY https://github.com/mitre/im_sample_algorithm.git + GIT_TAG + OPTIONS + "IM_SAMPLE_ALGORITHM_BUILD_TESTING OFF" +) + +target_link_libraries(my_simulation_framework + PRIVATE + mitre::oss::fim_sample_algorithm) +``` + +The Sample Algorithm target carries its public dependency on `mitre::oss::simcore`. If your framework creates `mitre::oss::simcore` before adding this repository, this repository will reuse that target instead of fetching its own `aircraft_simulation_core` copy. If your framework does not provide it, this repository will fetch `aircraft_simulation_core` for standalone and CPM builds. + +Prefer the namespaced target `mitre::oss::fim_sample_algorithm` in new integration code. Older target names such as `mitre::im_sample_algorithm` should be treated as legacy references when updating an existing framework. diff --git a/unittest/src/IntervalManagement/interval_management.cmake b/unittest/src/IntervalManagement/interval_management.cmake index bc37d6e..a5d1e36 100644 --- a/unittest/src/IntervalManagement/interval_management.cmake +++ b/unittest/src/IntervalManagement/interval_management.cmake @@ -20,8 +20,7 @@ target_compile_options(imalgs_test $<$:-Wall -Wno-sign-compare -O1 -g3>) target_include_directories(imalgs_test PRIVATE ${CMAKE_CURRENT_LIST_DIR}/..) set_target_properties(imalgs_test PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin - EXCLUDE_FROM_ALL TRUE) + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) add_test( NAME imalgs_test