diff --git a/.ci/.drone.yml b/.ci/.drone.yml index 4dab7ad31a..9c4fc444a9 100644 --- a/.ci/.drone.yml +++ b/.ci/.drone.yml @@ -37,7 +37,6 @@ # include: # - refs/heads/main # - refs/heads/develop -# - refs/heads/helics2 # - 'refs/pull/**' # - 'refs/tags/**' # @@ -80,6 +79,5 @@ trigger: include: - refs/heads/main - refs/heads/develop - - refs/heads/helics2 - "refs/pull/**" - "refs/tags/**" diff --git a/.ci/azure-pipelines-daily.yml b/.ci/azure-pipelines-daily.yml index 8ef8847545..4cab356f37 100644 --- a/.ci/azure-pipelines-daily.yml +++ b/.ci/azure-pipelines-daily.yml @@ -12,10 +12,10 @@ jobs: strategy: matrix: all-tests: - containerImage: "helics/buildenv:ubuntu20.04-default-builder" + containerImage: "helics/buildenv:ubuntu22.04-default-builder" test_config: "daily" zmq-subproject: - containerImage: "helics/buildenv:ubuntu20.04-default-builder" + containerImage: "helics/buildenv:ubuntu22.04-default-builder" test_config: "ci" zmq_subproject: true pool: diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index 53eda311aa..441dd3122c 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -12,22 +12,22 @@ jobs: strategy: matrix: ubuntuDefault: - containerImage: "helics/buildenv:ubuntu20.04-default-builder" + containerImage: "helics/buildenv:ubuntu22.04-default-builder" test_config: "ci" use_mpi: "true" encrypted: "true" - gcc8: - containerImage: "helics/buildenv:gcc8-builder" + gcc11: + containerImage: "helics/buildenv:gcc11-builder" test_config: "ci" use_mpi: "true" encrypted: "true" - clang13: - containerImage: "helics/buildenv:clang13-builder" + clang15: + containerImage: "helics/buildenv:clang15-builder" test_config: "ci" use_mpi: "" encrypted: "" - clang7: - containerImage: "helics/buildenv:clang7-builder" + clang18: + containerImage: "helics/buildenv:clang18-builder" test_config: "ci" use_mpi: "" encrypted: "" @@ -64,11 +64,11 @@ jobs: matrix: XCode-latest: test_config: "ci" - vmImage: "macOS-13" + vmImage: "macOS-14" XCode-oldest: test_config: "ci" - vmImage: "macOS-12" - xcode_path: "/Applications/Xcode_13.2.1.app" + vmImage: "macOS-13" + xcode_path: "/Applications/Xcode_14.1.app" pool: vmImage: $[ variables['vmImage'] ] timeoutInMinutes: 60 @@ -111,7 +111,7 @@ jobs: imageName: "windows-2019" langArch: "x64" vsArch: "x64" - extraFlags: "" + extraFlags: "-DHELICS_DISABLE_WEBSERVER=ON" VS2022-64bit: imageName: "windows-2022" langArch: "x64" @@ -169,7 +169,7 @@ jobs: # ----------------------- # Build HELICS # ----------------------- - - bash: cmake --build . --config Release + - bash: cmake --build . --parallel 4 --config Release displayName: "Build HELICS" workingDirectory: build diff --git a/.circleci/config.yml b/.circleci/config.yml index a79d8eacdd..57d9ed9fbb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,22 +18,6 @@ aliases: eval cmake .. ${CMAKE_FLAGS} make -j 2 - - &run_octave_tests - name: run_octave_tests - command: | - cd build - make install - cd ${OCTAVETEST} - # this return the write error code in RESULT - res=$(octave -W -V --eval "source('runTestsCIRCLECI.m');") - echo "$res" - if [[ "$res" == *"failed"* ]]; then - echo "*** Octave tests FAILED: " - exit -1 - fi - echo "*** Octave tests PASSED " - exit 0 - - &run_helics_tests name: run_helics_tests command: | @@ -64,20 +48,9 @@ aliases: make RUN_KEY_BENCHMARKS jobs: - helicsoctave: - docker: - - image: helics/buildenv:octave - environment: - OCTAVETEST: "/root/project/tests/octave" - CMAKE_FLAGS: "-DHELICS_BUILD_OCTAVE_INTERFACE=ON -DHELICS_BUILD_TESTS=ON" - steps: - - checkout - - run: *setup_helics - - run: *run_octave_tests - helicsgccTSan: docker: - - image: helics/buildenv:gcc13-builder + - image: helics/buildenv:gcc14-builder resource_class: large environment: CMAKE_FLAGS: '-DCMAKE_CXX_FLAGS="-fsanitize=thread -g -O1 " -DHELICS_BUILD_TESTS=ON -DHELICS_ZMQ_SUBPROJECT=ON -DHELICS_ZMQ_FORCE_SUBPROJECT=ON -DHELICS_ENABLE_EXTRA_COMPILER_WARNINGS=OFF -DHELICS_DISABLE_SYSTEM_CALL_TESTS=ON -DCMAKE_CXX_STANDARD=20' @@ -90,7 +63,7 @@ jobs: helicsgccASan: docker: - - image: helics/buildenv:gcc13-builder + - image: helics/buildenv:gcc14-builder resource_class: large environment: CMAKE_FLAGS: '-DCMAKE_CXX_FLAGS="-ggdb -fsanitize=address -fno-omit-frame-pointer -static-libstdc++ -static-libasan -lrt -g -O1 " -DHELICS_BUILD_TESTS=ON -DHELICS_ZMQ_SUBPROJECT=ON -DHELICS_ZMQ_FORCE_SUBPROJECT=ON -DHELICS_ENABLE_EXTRA_COMPILER_WARNINGS=OFF -DHELICS_DISABLE_SYSTEM_CALL_TESTS=ON -DCMAKE_CXX_STANDARD=20' @@ -116,7 +89,7 @@ jobs: helicsMSan: docker: - - image: helics/buildenv:sanitizers-14 + - image: helics/buildenv:sanitizers-18 environment: CMAKE_FLAGS: '-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_FLAGS="-fsanitize=memory -nostdinc++ -nostdlib++ -Wno-reserved-macro-identifier -L/root/develop/libcxx_msan/lib -lc++ -lc++abi -I/root/develop/libcxx_msan/include -I/root/develop/libcxx_msan/include/c++/v1 -Wno-unused-command-line-argument -fno-omit-frame-pointer -g -O1 -Wl,-rpath,/root/develop/libcxx_msan/lib" -DHELICS_ENABLE_EXTRA_COMPILER_WARNINGS=OFF -DHELICS_BUILD_TESTS=ON -DHELICS_ZMQ_SUBPROJECT=ON -DHELICS_ZMQ_FORCE_SUBPROJECT=ON' @@ -127,7 +100,7 @@ jobs: helicsTSan: docker: - - image: helics/buildenv:sanitizers-14 + - image: helics/buildenv:sanitizers-18 environment: CMAKE_FLAGS: '-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_FLAGS="-fsanitize=thread -nostdinc++ -nostdlib++ -L/root/develop/libcxx_tsan/lib -lc++ -lc++abi -I/root/develop/libcxx_tsan/include -I/root/develop/libcxx_tsan/include/c++/v1 -Wno-unused-command-line-argument -fno-omit-frame-pointer -g -O2 -Wl,-rpath,/root/develop/libcxx_tsan/lib" -DHELICS_ENABLE_EXTRA_COMPILER_WARNINGS=OFF -DHELICS_BUILD_TESTS=ON -DHELICS_ZMQ_SUBPROJECT=ON -DHELICS_ZMQ_FORCE_SUBPROJECT=ON' TSAN_OPTIONS: "suppressions=/root/project/.circleci/tsan_suppression.txt" @@ -138,7 +111,7 @@ jobs: helicsInstall1: docker: - - image: helics/buildenv:builder + - image: helics/buildenv:ubuntu24.04-default-builder environment: CMAKE_FLAGS: "-DHELICS_BUILD_CXX_SHARED_LIB=ON -DHELICS_BUILD_TESTS=ON -DHELICS_BUILD_BENCHMARKS=ON -DHELICS_INSTALL_PACKAGE_TESTS=ON" steps: @@ -148,9 +121,9 @@ jobs: helicsNoZmq: docker: - - image: helics/buildenv:gcc10-builder + - image: helics/buildenv:gcc13-builder environment: - CMAKE_FLAGS: "-DHELICS_BUILD_CXX_SHARED_LIB=ON -DHELICS_ENABLE_ZMQ_CORE=OFF -DHELICS_ENABLE_IPC_CORE=OFF -DHELICS_BUILD_TESTS=ON -DCMAKE_CXX_STANDARD=17" + CMAKE_FLAGS: "-DHELICS_BUILD_CXX_SHARED_LIB=ON -DHELICS_ENABLE_ZMQ_CORE=OFF -DHELICS_ENABLE_IPC_CORE=OFF -DHELICS_BUILD_TESTS=ON" steps: - checkout - run: *setup_helics @@ -167,7 +140,7 @@ jobs: helicsInstall2: docker: - - image: helics/buildenv:builder + - image: helics/buildenv:ubuntu24.04-default-builder environment: CMAKE_FLAGS: "-DHELICS_BUILD_TESTS=ON -DHELICS_INSTALL_PACKAGE_TESTS=ON" steps: @@ -175,9 +148,10 @@ jobs: - run: *setup_helics - run: *run_installer_tests - gcc13: + gcc14: docker: - - image: helics/buildenv:gcc13-builder + - image: helics/buildenv:gcc14-builder + resource_class: large environment: CMAKE_FLAGS: '-DHELICS_EXTRA_COMPILE_FLAGS=-Wredundant-tags -DCMAKE_CXX_FLAGS="-pedantic-errors" -DHELICS_BUILD_CXX_SHARED_LIB=ON -DHELICS_BUILD_TESTS=ON -DCMAKE_CXX_STANDARD=20' steps: @@ -185,9 +159,9 @@ jobs: - run: *setup_helics - run: *run_helics_tests - clang14: + clang18: docker: - - image: helics/buildenv:clang14-builder + - image: helics/buildenv:clang18-builder environment: CMAKE_FLAGS: '-DCMAKE_CXX_FLAGS="-pedantic-errors" -DHELICS_BUILD_CXX_SHARED_LIB=ON -DHELICS_BUILD_TESTS=ON -DCMAKE_CXX_STANDARD=20' steps: @@ -195,9 +169,9 @@ jobs: - run: *setup_helics - run: *run_helics_tests - clang14_cxx23: + clang18_cxx23: docker: - - image: helics/buildenv:clang14-builder + - image: helics/buildenv:clang18-builder environment: CMAKE_FLAGS: "-DHELICS_BUILD_CXX_SHARED_LIB=ON -DHELICS_BUILD_TESTS=ON -DHELICS_BUILD_EXAMPLES=ON -DCMAKE_CXX_STANDARD=23" steps: @@ -206,7 +180,7 @@ jobs: benchmarkjob: docker: - - image: helics/buildenv:builder + - image: helics/buildenv:ubuntu24.04-default-builder environment: CMAKE_FLAGS: "-DHELICS_BUILD_BENCHMARKS=ON -DBM_RESULT_DIR=/tmp/bm_results/ -DHELICS_DISABLE_C_SHARED_LIB=ON" steps: @@ -219,7 +193,7 @@ jobs: arm64: machine: - image: ubuntu-2004:current + image: ubuntu-2404:current resource_class: arm.medium environment: CMAKE_FLAGS: "-DHELICS_BUILD_CXX_SHARED_LIB=OFF -DHELICS_BUILD_TESTS=ON -DHELICS_ZMQ_SUBPROJECT=ON -DHELICS_ZMQ_FORCE_SUBPROJECT=ON -DHELICS_DISABLE_BOOST=ON" @@ -243,15 +217,15 @@ workflows: filters: branches: ignore: /pre-commit\/.*/ - - gcc13: + - gcc14: filters: branches: ignore: /pre-commit\/.*/ - - clang14: + - clang18: filters: branches: ignore: /pre-commit\/.*/ - - clang14_cxx23: + - clang18_cxx23: filters: branches: ignore: /pre-commit\/.*/ @@ -289,11 +263,6 @@ workflows: branches: only: - dailies_tests - - helicsoctave: - filters: - branches: - only: - - dailies_tests - helicsNoZmq: filters: branches: @@ -310,7 +279,6 @@ workflows: jobs: - helicsTumbleweed - helicsNoZmq - - helicsoctave - helicsTSan - helicsASan - helicsgccASan diff --git a/.circleci/config_old.yml b/.circleci/config_old.yml deleted file mode 100644 index 9fd0734da8..0000000000 --- a/.circleci/config_old.yml +++ /dev/null @@ -1,223 +0,0 @@ -version: 2 -aliases: - - &setup_helics - name: setup_helics - environment: - command: | - mkdir -p build - cd build - eval cmake .. ${CMAKE_FLAGS} - make -j 4 - - - &run_octave_tests - name: run_octave_tests - command: | - cd build - make install - cd ${OCTAVETEST} - # this return the write error code in RESULT - res=$(octave -W -V --eval "source('runTestsCIRCLECI.m');") - echo "$res" - if [[ "$res" == *"failed"* ]]; then - echo "*** Octave tests FAILED: " - exit -1 - fi - echo "*** Octave tests PASSED " - exit 0 - - - &run_helics_tests - name: run_helics_tests - command: | - /root/project/scripts/run-circleci-tests.sh - RESULT=$? - exit $RESULT - - - &run_installer_tests - name: run_installer_tests - command: | - cd build - make install - ctest -V -R find-package-tests - ctest -V -R package-config-tests - - - &run_benchmarks - name: run_benchmarks - command: | - mkdir /tmp/bm_results - cd build - make RUN_KEY_BENCHMARKS - -jobs: - helicsoctave: - docker: - - image: helics/buildenv:octave - environment: - OCTAVETEST: "/root/project/tests/octave" - CMAKE_FLAGS: "-DHELICS_BUILD_OCTAVE_INTERFACE=ON -DHELICS_BUILD_TESTS=ON" - steps: - - checkout - - run: *setup_helics - - run: *run_octave_tests - - helicsgccTSan: - docker: - - image: helics/buildenv:gcc12-builder - environment: - CMAKE_FLAGS: '-DCMAKE_CXX_FLAGS="-fsanitize=thread -g -O1 " -DHELICS_BUILD_TESTS=ON -DHELICS_ZMQ_SUBPROJECT=ON -DHELICS_ZMQ_FORCE_SUBPROJECT=ON -DHELICS_DISABLE_SYSTEM_CALL_TESTS=ON' - TSAN_OPTIONS: "second_deadlock_stack=1 suppressions=/root/project/.circleci/tsan_suppression.txt history_size=4" - - steps: - - checkout - - run: *setup_helics - - run: *run_helics_tests - - helicsgccASan: - docker: - - image: helics/buildenv:gcc12-builder - environment: - CMAKE_FLAGS: '-DCMAKE_CXX_FLAGS="-ggdb -fsanitize=address -fno-omit-frame-pointer -static-libstdc++ -static-libasan -lrt -g -O1 " -DHELICS_BUILD_TESTS=ON -DHELICS_ZMQ_SUBPROJECT=ON -DHELICS_ZMQ_FORCE_SUBPROJECT=ON -DHELICS_DISABLE_SYSTEM_CALL_TESTS=ON' - - steps: - - checkout - - run: *setup_helics - - run: *run_helics_tests - - helicsASan: - docker: - - image: helics/buildenv:sanitizers-14 - environment: - CMAKE_FLAGS: '-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_FLAGS="-fsanitize=undefined,address -fsanitize-address-use-after-scope -fsanitize-ignorelist=/root/project/.circleci/asan_suppression.txt -nostdinc++ -nostdlib++ -L/root/develop/libcxx_asan/lib -lc++ -lc++abi -isystem /root/develop/libcxx_asan/include/c++/v1 -Wno-unused-command-line-argument -fno-omit-frame-pointer -g -O1 -Wl,-rpath,/root/develop/libcxx_asan/lib -fsanitize-blacklist=/root/project/.circleci/asan_blacklist.txt" -DHELICS_BUILD_TESTS=ON -DHELICS_ZMQ_SUBPROJECT=ON -DHELICS_ZMQ_FORCE_SUBPROJECT=ON' - LSAN_OPTIONS: "suppressions=/root/project/.circleci/leak_suppression.txt" - UBSAN_OPTIONS: "print_stacktrace=1 suppressions=/root/project/.circleci/ubsan_suppression.txt" - steps: - - checkout - - run: *setup_helics - - run: *run_helics_tests - - helicsMSan: - docker: - - image: helics/buildenv:sanitizers-14 - environment: - CMAKE_FLAGS: '-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_FLAGS="-fsanitize=memory -nostdinc++ -nostdlib++ -L/root/develop/libcxx_msan/lib -lc++ -lc++abi -I/root/develop/libcxx_msan/include -I/root/develop/libcxx_msan/include/c++/v1 -Wno-unused-command-line-argument -fno-omit-frame-pointer -g -O1 -Wl,-rpath,/root/develop/libcxx_msan/lib" -DHELICS_BUILD_TESTS=ON -DHELICS_ZMQ_SUBPROJECT=ON -DHELICS_ZMQ_FORCE_SUBPROJECT=ON' - - steps: - - checkout - - run: *setup_helics - - run: *run_helics_tests - - helicsInstall1: - docker: - - image: helics/buildenv:builder - environment: - CMAKE_FLAGS: "-DHELICS_BUILD_CXX_SHARED_LIB=ON -DHELICS_BUILD_TESTS=ON -DHELICS_BUILD_BENCHMARKS=ON -DHELICS_INSTALL_PACKAGE_TESTS=ON" - steps: - - checkout - - run: *setup_helics - - run: *run_installer_tests - - helicsNoZmq: - docker: - - image: helics/buildenv:gcc8-builder - environment: - CMAKE_FLAGS: "-DHELICS_BUILD_CXX_SHARED_LIB=ON -DHELICS_ENABLE_ZMQ_CORE=OFF -DHELICS_ENABLE_IPC_CORE=OFF -DHELICS_BUILD_TESTS=ON -DCMAKE_CXX_STANDARD=17" - steps: - - checkout - - run: *setup_helics - - run: *run_helics_tests - - helicsTumbleweed: - docker: - - image: helics/buildenv:tumbleweed-builder - environment: - CMAKE_FLAGS: "-DHELICS_BUILD_CXX_SHARED_LIB=ON -DHELICS_ENABLE_ZMQ_CORE=OFF -DHELICS_ENABLE_IPC_CORE=OFF -DHELICS_ENABLE_UDP_CORE=OFF -DHELICS_BUILD_TESTS=ON -DCMAKE_CXX_STANDARD=17" - steps: - - checkout - - run: *setup_helics - - helicsInstall2: - docker: - - image: helics/buildenv:builder - environment: - CMAKE_FLAGS: "-DHELICS_BUILD_TESTS=ON -DHELICS_INSTALL_PACKAGE_TESTS=ON" - steps: - - checkout - - run: *setup_helics - - run: *run_installer_tests - - gcc12: - docker: - - image: helics/buildenv:gcc12-builder - environment: - CMAKE_FLAGS: "-DHELICS_EXTRA_COMPILE_FLAGS=-Wredundant-tags" - steps: - - checkout - - run: *setup_helics - - benchmarkjob: - docker: - - image: helics/buildenv:builder - environment: - CMAKE_FLAGS: "-DHELICS_BUILD_BENCHMARKS=ON -DBM_RESULT_DIR=/tmp/bm_results/ -DHELICS_DISABLE_C_SHARED_LIB=ON" - steps: - - checkout - - run: *setup_helics - - run: *run_benchmarks - - - store_artifacts: - path: /tmp/bm_results - -workflows: - version: 2 - helics_test: - jobs: - - helicsMSan: - filters: - branches: - ignore: /pre-commit\/.*/ - - helicsASan: - filters: - branches: - ignore: /pre-commit\/.*/ - - helicsInstall1: - filters: - branches: - ignore: /pre-commit\/.*/ - - helicsInstall2: - filters: - branches: - ignore: /pre-commit\/.*/ - - helicsgccTSan: - filters: - branches: - ignore: /pre-commit\/.*/ - - helicsgccASan: - filters: - branches: - ignore: /pre-commit\/.*/ - - helicsoctave: - filters: - branches: - ignore: /pre-commit\/.*/ - - nightly: - triggers: - - schedule: - cron: "0 8 * * *" - filters: - branches: - only: - - develop - jobs: - - helicsTumbleweed - - helicsNoZmq - - gcc12 - benchmark: - triggers: - - schedule: - cron: "17 9 * * 0,2,5" - filters: - branches: - only: - - develop - jobs: - - benchmarkjob diff --git a/.cirrus.yml b/.cirrus.yml index ba1d4682db..2a103eefe4 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -7,7 +7,7 @@ task: pkg install -y cmake libzmq4 ninja git build_script: | mkdir build && cd build - cmake -GNinja -DHELICS_BUILD_TESTS=ON -DHELICS_BUILD_EXAMPLES=ON .. + cmake -GNinja -DHELICS_BUILD_TESTS=ON -DHELICS_BUILD_EXAMPLES=ON -DCMAKE_CXX_STANDARD=17 .. cmake --build . test_script: | cd build diff --git a/.clang-tidy b/.clang-tidy index 4b02203eef..78f0597f4d 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -22,6 +22,7 @@ Checks: " -hicpp-avoid-c-arrays, -hicpp-no-array-decay, clang-analyzer-*, + clang-diagnostic*, bugprone-*, -bugprone-narrowing-conversions, -bugprone-easily-swappable-parameters, @@ -29,6 +30,7 @@ Checks: " -misc-non-private-member-variables-in-classes, -misc-no-recursion, -misc-use-anonymous-namespace, + -misc-include-cleaner, cert-*, -cert-err58-cpp, portability-*, @@ -61,6 +63,7 @@ WarningsAsErrors: " -hicpp-no-array-decay, clang-analyzer-*, -clang-analyzer-optin.cplusplus.VirtualCall, + clang-diagnostic*, bugprone-*, -bugprone-narrowing-conversions, -bugprone-easily-swappable-parameters, diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index ea4b2b05d5..9df966581e 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -6,7 +6,7 @@ In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, -education, socio-economic status, nationality, personal appearance, race, +education, socioeconomic status, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards diff --git a/.github/actions/benchmark-build/benchmark-Linux.sh b/.github/actions/benchmark-build/benchmark-Linux.sh index d46e05b7d9..39c6eead23 100755 --- a/.github/actions/benchmark-build/benchmark-Linux.sh +++ b/.github/actions/benchmark-build/benchmark-Linux.sh @@ -2,15 +2,11 @@ # This uses bash variable substitution in a few places # 1. getting the cmake directory for running cpack with an absolute path (chocolatey has an unfortunately named alias) -#wget --quiet -O cmake-install.sh https://github.com/Kitware/CMake/releases/download/v3.15.5/cmake-3.15.5-Linux-x86_64.sh && chmod +x cmake-install.sh -#sudo ./cmake-install.sh --prefix=/usr/local --exclude-subdir --skip-license -#rm cmake-install.sh - # Unset VCPKG_ROOT for GitHub actions environment unset VCPKG_ROOT mkdir build && cd build || exit -cmake -DCMAKE_BUILD_TYPE=Release -DHELICS_ZMQ_SUBPROJECT=ON -DHELICS_ENABLE_PACKAGE_BUILD=ON -DSTATIC_STANDARD_LIB=static -DHELICS_BUILD_EXAMPLES=OFF -DHELICS_BUILD_APP_EXECUTABLES=ON -DHELICS_BUILD_APP_LIBRARY=OFF -DHELICS_BUILD_BENCHMARKS=ON -DBUILD_TESTING=OFF .. +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=17 -DHELICS_ZMQ_SUBPROJECT=ON -DHELICS_ENABLE_PACKAGE_BUILD=ON -DSTATIC_STANDARD_LIB=static -DHELICS_BUILD_EXAMPLES=OFF -DHELICS_BUILD_APP_EXECUTABLES=ON -DHELICS_BUILD_APP_LIBRARY=OFF -DHELICS_BUILD_BENCHMARKS=ON -DBUILD_TESTING=OFF .. cmake --build . --config Release cpack_dir="$(command -v cmake)" cpack_dir="${cpack_dir%/cmake}" diff --git a/.github/actions/common/Windows/install-boost.sh b/.github/actions/common/Windows/install-boost.sh index f96928d2d8..8d37ae29ed 100755 --- a/.github/actions/common/Windows/install-boost.sh +++ b/.github/actions/common/Windows/install-boost.sh @@ -1,6 +1,6 @@ #!/bin/bash # Install Boost -BOOST_VERSION="1.74.0" +BOOST_VERSION="1.75.0" BOOST_ROOT="/c/boost" BOOST_URL="https://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION}/boost_${BOOST_VERSION//./_}.tar.bz2/download" ( diff --git a/.github/actions/linux-release-builder/Dockerfile b/.github/actions/linux-release-builder/Dockerfile index baf5cf1771..cf819dd703 100644 --- a/.github/actions/linux-release-builder/Dockerfile +++ b/.github/actions/linux-release-builder/Dockerfile @@ -2,12 +2,17 @@ FROM phusion/holy-build-box-64:2.1.0 # Install a copy of git and the Boost headers # curl -L follows redirects and -k ignores SSL certificate warnings -RUN curl -Lk -o boost.tar.gz https://sourceforge.net/projects/boost/files/boost/1.72.0/boost_1_72_0.tar.gz/download \ - && tar --strip-components=1 -xf boost.tar.gz boost_1_72_0/boost \ +RUN curl -Lk -o boost.tar.gz https://sourceforge.net/projects/boost/files/boost/1.75.0/boost_1_75_0.tar.gz/download \ + && tar --strip-components=1 -xf boost.tar.gz boost_1_75_0/boost \ && cp -R boost /usr/include/boost/ \ && rm -rf boost \ && rm boost.tar.gz +RUN curl -Lk -o cmake-install.sh https://github.com/Kitware/CMake/releases/download/v3.25.3/cmake-3.25.3-Linux-x86_64.sh \ + && chmod +x cmake-install.sh \ + && ./cmake-install.sh --prefix=/hbb --exclude-subdir --skip-license \ + && rm cmake-install.sh + # Make sure the install location for cmake is found ENV PATH="/hbb/bin:${PATH}" diff --git a/.github/actions/release-build/installer-Linux.sh b/.github/actions/release-build/installer-Linux.sh index fbf525b12d..a45cd80336 100755 --- a/.github/actions/release-build/installer-Linux.sh +++ b/.github/actions/release-build/installer-Linux.sh @@ -2,15 +2,11 @@ # This uses bash variable substitution in a few places # 1. getting the cmake directory for running cpack with an absolute path (chocolatey has an unfortunately named alias) -#wget --quiet -O cmake-install.sh https://github.com/Kitware/CMake/releases/download/v3.15.5/cmake-3.15.5-Linux-x86_64.sh && chmod +x cmake-install.sh -#sudo ./cmake-install.sh --prefix=/usr/local --exclude-subdir --skip-license -#rm cmake-install.sh - # Unset VCPKG_ROOT for GitHub actions environment unset VCPKG_ROOT mkdir build && cd build || exit -cmake -DCMAKE_BUILD_TYPE=Release -DHELICS_ZMQ_SUBPROJECT=ON -DHELICS_ENABLE_PACKAGE_BUILD=ON -DSTATIC_STANDARD_LIB=static -DHELICS_BUILD_EXAMPLES=OFF -DHELICS_BUILD_APP_EXECUTABLES=ON -DHELICS_BUILD_APP_LIBRARY=ON -DBUILD_TESTING=OFF .. +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=17 -DHELICS_ZMQ_SUBPROJECT=ON -DHELICS_ENABLE_PACKAGE_BUILD=ON -DSTATIC_STANDARD_LIB=static -DHELICS_BUILD_EXAMPLES=OFF -DHELICS_BUILD_APP_EXECUTABLES=ON -DHELICS_BUILD_APP_LIBRARY=ON -DBUILD_TESTING=OFF .. cmake --build . --config Release cpack_dir="$(command -v cmake)" cpack_dir="${cpack_dir%/cmake}" diff --git a/.github/actions/release-build/shared-library-Linux.sh b/.github/actions/release-build/shared-library-Linux.sh index 9e90b69817..9591ac26af 100755 --- a/.github/actions/release-build/shared-library-Linux.sh +++ b/.github/actions/release-build/shared-library-Linux.sh @@ -2,15 +2,11 @@ # This uses bash variable substitution in a few places # 1. getting the cmake directory for running cpack with an absolute path (chocolatey has an unfortunately named alias) -#wget --quiet -O cmake-install.sh https://github.com/Kitware/CMake/releases/download/v3.15.5/cmake-3.15.5-Linux-x86_64.sh && chmod +x cmake-install.sh -#sudo ./cmake-install.sh --prefix=/usr/local --exclude-subdir --skip-license -#rm cmake-install.sh - # Unset VCPKG_ROOT for GitHub actions environment unset VCPKG_ROOT mkdir build && cd build || exit -cmake -DCMAKE_BUILD_TYPE=Release -DHELICS_ZMQ_SUBPROJECT=ON -DHELICS_ENABLE_PACKAGE_BUILD=ON -DSTATIC_STANDARD_LIB=static -DHELICS_BUILD_APP_EXECUTABLES=OFF -DHELICS_BUILD_APP_LIBRARY=OFF -DHELICS_BUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF .. +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=17 -DHELICS_ZMQ_SUBPROJECT=ON -DHELICS_ENABLE_PACKAGE_BUILD=ON -DSTATIC_STANDARD_LIB=static -DHELICS_BUILD_APP_EXECUTABLES=OFF -DHELICS_BUILD_APP_LIBRARY=OFF -DHELICS_BUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF .. cmake --build . --config Release cpack_dir="$(command -v cmake)" cpack_dir="${cpack_dir%/cmake}" diff --git a/.github/workflows/static-analyzers.yml b/.github/workflows/static-analyzers.yml index 6db896862d..dac8a6e904 100644 --- a/.github/workflows/static-analyzers.yml +++ b/.github/workflows/static-analyzers.yml @@ -19,11 +19,12 @@ jobs: steps: - uses: actions/checkout@v4 - name: Run cpplint - run: cpplint --counting=detailed --recursive examples benchmarks src tests + run: cpplint --counting=detailed --recursive --extensions=cpp,cxx,h,hpp,hxx examples benchmarks src tests clang-tidy: if: github.event_name == 'pull_request' runs-on: ubuntu-latest + timeout-minutes: 45 container: helics/buildenv:clang-extra-tools steps: diff --git a/.github/workflows/swig-interface-gen.yml b/.github/workflows/swig-interface-gen.yml index 7d5e0603dd..c7639a191e 100644 --- a/.github/workflows/swig-interface-gen.yml +++ b/.github/workflows/swig-interface-gen.yml @@ -43,7 +43,7 @@ jobs: extra_args: clang-format --files src/helics/shared_api_library/backup/helics/helics.h src/helics/shared_api_library/backup/helics/helics_api.h - name: Create Pull Request - uses: peter-evans/create-pull-request@v6 + uses: peter-evans/create-pull-request@v7 with: commit-message: Automated update to generated interface files author: GitHub diff --git a/.gitmodules b/.gitmodules index 7ec6e689e9..3b0300bff7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,10 +20,6 @@ [submodule "ThirdParty/spdlog"] path = ThirdParty/spdlog url = ../../gabime/spdlog.git -[submodule "ThirdParty/json_cpp"] - path = ThirdParty/json_cpp - url = ../../open-source-parsers/jsoncpp.git - branch = master [submodule "ThirdParty/toml"] path = ThirdParty/toml url = ../../ToruNiina/toml11 @@ -31,3 +27,12 @@ path = ThirdParty/networking url = ../../GMLC-TDC/networking.git branch = main +[submodule "ThirdParty/libzmq"] + path = ThirdParty/libzmq + url = https://github.com/zeromq/libzmq.git +[submodule "ThirdParty/googletest"] + path = ThirdParty/googletest + url = https://github.com/google/googletest.git +[submodule "ThirdParty/benchmark"] + path = ThirdParty/benchmark + url = https://github.com/google/benchmark.git diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f12ba84788..cb8b2c8e23 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,12 +8,12 @@ repos: - id: dockerfile_lint args: [--rulefile, ./config/Docker/docker_rules.yml, --dockerfile] - repo: https://github.com/psf/black - rev: 24.4.2 + rev: 24.10.0 hooks: - id: black args: ["--line-length=100"] - repo: https://github.com/asottile/blacken-docs - rev: 1.16.0 + rev: 1.19.1 hooks: - id: blacken-docs additional_dependencies: [black==22.12] @@ -22,7 +22,7 @@ repos: hooks: - id: remove-tabs - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v5.0.0 hooks: - id: check-added-large-files - id: mixed-line-ending @@ -62,7 +62,7 @@ repos: - id: cmake-format exclude: "cmake_+" - repo: https://github.com/codespell-project/codespell - rev: v2.2.6 + rev: v2.3.0 hooks: - id: codespell exclude: ^(docs/user-guide/examples/user_guide_examples) @@ -74,7 +74,7 @@ repos: "--exclude-file=./config/spelling_ignorelines.txt", ] - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v18.1.5 + rev: v19.1.4 hooks: - id: clang-format types: diff --git a/CHANGELOG.md b/CHANGELOG.md index f4d17bfdf0..eddd345d8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,42 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm A note on future revisions. Everything within a major version number should be code compatible (with the exception of experimental interfaces). The most notable example of an experimental interface is the support for multiple source inputs. The APIs to deal with this will change in future minor releases. Everything within a single minor release should be network compatible with other federates on the same minor release number. Compatibility across minor release numbers may be possible in some situations but we are not going to guarantee this as those components are subject to performance improvements and may need to be modified at some point. Patch releases will be limited to bug fixes and other improvements not impacting the public API or network compatibility. Check the [Public API](./docs/Public_API.md) for details on what is included and excluded from the public API and version stability. +## [3.6.0][] - 2024-12-09 + +Major release including app support in the C library, bug fixes, and an update to the minimum build requirement for HELICS moving to a default of C++20. The 3.7 release will make C++20 the minimum compile standard. This release also changes out the json interpreter to use nlohmann::json instead of json_cpp. + +### Fixed + +- Fixed issue with maximum message size for the ZMQ and ZMQ_SS core types. Now block sizes up to 4 GB are supported on these core types (subject to memory limitations). This change is not backwards compatible in that previous versions will still not work with these sizes but it will still be recognized and perform equivalent or better then previously on older versions of HELICS. To support these sizes all federates must be updated to HELICS 3.6 and higher. +- Fixed release builder to use new minimum build standards +- Fixed issue where in certain cases the potential interfaces were not getting established and used by the connector +- Fixes for sanitizer builds and other clang-tidy and compiler warnings + +### Changed + +- Test with Boost 1.86 and CMake 3.31 +- Changed default C++ standard to C++20. Eventual 3.7 release will make this a minimum. +- Minimum build requirements changed to: + - GCC 11 + - Clang 15 + - CMake 3.22 + - MSVC 16.10 + - XCode 14 + - Boost 1.73 +- Updated third party libraries (toml, asio, fmt, spdlog, units) +- Replaced usage of json_cpp with nlohmann::json + +### Added + +- Added C shared library interface to the helics app library +- Added ability to send files directly to brokers and cores for configuration +- Added a global sync disconnect so all federates stay active until the federation is completed + +### Removed + +- Removed Octave interface build from the HELICS repo; Octave is now supported via matHELICS +- Removed dependency on Boost.ScopeExit in the MPI core + ## [3.5.3][] - 2024-07-08 Patch release with fixes for potential interface definitions and some compiler warnings diff --git a/CMakeLists.txt b/CMakeLists.txt index 6eb9de4eac..468869fb2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ # SPDX-License-Identifier: BSD-3-Clause # ~~~ -cmake_minimum_required(VERSION 3.11...3.28) +cmake_minimum_required(VERSION 3.22...3.31) # Install dependencies using vcpkg if VCPKG_ROOT is set and no CMake Toolchain file is given vcpkg # installation on a system doesn't set VCPKG_ROOT, so setting it should be like an opt-in for users @@ -17,14 +17,15 @@ if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE AND NOT HELICS_D set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "") endif() -project(HELICS VERSION 3.5.3) +message(STATUS "Generating with CMAKE version ${CMAKE_VERSION}") +project(HELICS VERSION 3.6.0) # ----------------------------------------------------------------------------- # HELICS Version number # ----------------------------------------------------------------------------- set(HELICS_VERSION_BUILD) # use ISO date YYYY-MM-DD -set(HELICS_DATE "2024-07-08") +set(HELICS_DATE "2024-12-09") set(HELICS_VERSION_UNDERSCORE "${HELICS_VERSION_MAJOR}_${HELICS_VERSION_MINOR}_${HELICS_VERSION_PATCH}" @@ -82,17 +83,15 @@ include(CMakeDependentOption) include(copy_key_files) include(CTest) -if(NOT CMAKE_VERSION VERSION_LESS 3.12) - option( - HELICS_ENABLE_PYTHON_BUILD_SCRIPTS - "HELICS build systems can use python to automatically generate some files. This is not required but may be useful if you are a developer and frequently modifying some files" - OFF - ) - mark_as_advanced(HELICS_ENABLE_PYTHON_BUILD_SCRIPTS) +option( + HELICS_ENABLE_PYTHON_BUILD_SCRIPTS + "HELICS build systems can use python to automatically generate some files. This is not required but may be useful if you are a developer and frequently modifying some files" + OFF +) +mark_as_advanced(HELICS_ENABLE_PYTHON_BUILD_SCRIPTS) - if(HELICS_ENABLE_PYTHON_BUILD_SCRIPTS) - find_package(Python COMPONENTS Interpreter) - endif() +if(HELICS_ENABLE_PYTHON_BUILD_SCRIPTS) + find_package(Python COMPONENTS Interpreter) endif() # allow BOOST library inclusion to be turned off completely; this option will disable the IPC core @@ -256,10 +255,6 @@ if(NOT HELICS_DISABLE_GIT_OPERATIONS) endif() endif() - if(NOT EXISTS "${PROJECT_SOURCE_DIR}/ThirdParty/json_cpp/CMakeLists.txt") - submod_update(ThirdParty/json_cpp) - endif() - if(NOT EXISTS "${PROJECT_SOURCE_DIR}/ThirdParty/containers/gmlc/containers/BlockingQueue.hpp") submod_update(ThirdParty/containers) endif() @@ -280,14 +275,32 @@ if(NOT HELICS_DISABLE_GIT_OPERATIONS) submod_update(ThirdParty/units) endif() - if(NOT EXISTS "${PROJECT_SOURCE_DIR}/ThirdParty/toml/toml/value.hpp") + if(NOT EXISTS "${PROJECT_SOURCE_DIR}/ThirdParty/toml/include/toml11/value.hpp") submod_update(ThirdParty/toml) endif() if(NOT EXISTS "${PROJECT_SOURCE_DIR}/ThirdParty/spdlog/CMakeLists.txt") submod_update(ThirdParty/spdlog) endif() - check_submodule_status() + + set(IGNORE_MODULES libzmq) + if(HELICS_BUILD_TESTS) + if(NOT EXISTS "${PROJECT_SOURCE_DIR}/ThirdParty/googletest/CMakeLists.txt") + submod_update(ThirdParty/googletest) + endif() + else() + list(APPEND IGNORE_MODULES googletest) + endif() + + if(HELICS_BUILD_BENCHMARKS) + if(NOT EXISTS "${PROJECT_SOURCE_DIR}/ThirdParty/benchmark/CMakeLists.txt") + submod_update(ThirdParty/benchmark) + endif() + else() + list(APPEND IGNORE_MODULES benchmark) + endif() + + check_submodule_status(IGNORE_MODULES) endif() # NOT HELICS_DISABLE_GIT_OPERATIONS include(GNUInstallDirs) @@ -308,8 +321,14 @@ if(NOT TARGET toml11::toml11) set(toml11_TEST_WITH_ASAN OFF CACHE INTERNAL "") set(toml11_TEST_WITH_UBSAN OFF CACHE INTERNAL "") set(toml11_INSTALL OFF CACHE INTERNAL "") - add_subdirectory(ThirdParty/toml EXCLUDE_FROM_ALL) + + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.25) + add_subdirectory(ThirdParty/toml EXCLUDE_FROM_ALL SYSTEM) + else() + add_subdirectory(ThirdParty/toml EXCLUDE_FROM_ALL) + endif() hide_variable(TOML11_USE_UNRELEASED_TOML_FEATURES) + hide_variable(TOML11_PRECOMPILE) endif() # ------------------------------------------------------------- @@ -409,10 +428,12 @@ if(MSYS OR CYGWIN) set(ENABLE_IPC_CORE FALSE) endif() # setting to windows 10 for all compilation - if(WIN32_WINNT) - add_compile_definitions("_WIN32_WINNT=${WIN32_WINNT}") - else() - add_compile_definitions(_WIN32_WINNT=0x0A00) + if(NOT HELICS_SKIP_WINNT_DEFINITION) + if(WIN32_WINNT) + add_compile_definitions("_WIN32_WINNT=${WIN32_WINNT}") + else() + add_compile_definitions(_WIN32_WINNT=0x0A00) + endif() endif() endif() @@ -468,15 +489,16 @@ target_include_directories( INTERFACE $ $ $/${CMAKE_INSTALL_INCLUDE_DIR}> - $ - $ - $ - $ ) # the utilities/gmlc is to account for the transfer of the header to a known location on install target_include_directories( - helics_base SYSTEM INTERFACE $ + helics_base SYSTEM + INTERFACE $ + $ + $ + $ + $ ) target_link_libraries(helics_base INTERFACE toml11::toml11) @@ -522,11 +544,6 @@ endif() # ----------------------------------------------------------------------------- include(addfmt) -# -------------------------------------------------------------- -# Create the target for jsoncpp -# ----------------------------------------------------------- -include(addJsoncpp) - # -------------------------------------------------------------- # Create the target for spdlog # ----------------------------------------------------------- @@ -690,8 +707,6 @@ set(LICENSE_LIST "${PROJECT_SOURCE_DIR}/ThirdParty/fmtlib/LICENSE" "units" "${PROJECT_SOURCE_DIR}/ThirdParty/units/LICENSE" - "JsonCpp" - "${PROJECT_SOURCE_DIR}/ThirdParty/json_cpp/LICENSE" "toml11" "${PROJECT_SOURCE_DIR}/ThirdParty/toml/LICENSE" "GMLC Utilities" @@ -701,17 +716,17 @@ set(LICENSE_LIST ) if(HELICS_BUILD_TESTS) - list(APPEND LICENSE_LIST "Google Test" "${PROJECT_BINARY_DIR}/_deps/googletest-src/LICENSE") + list(APPEND LICENSE_LIST "Google Test" "${PROJECT_SOURCE_DIR}/ThirdParty/googletest/LICENSE") endif() if(HELICS_BUILD_BENCHMARKS) list(APPEND LICENSE_LIST "Google Benchmark" - "${PROJECT_BINARY_DIR}/_deps/gbenchmark-src/LICENSE" + "${PROJECT_SOURCE_DIR}/ThirdParty/benchmark/LICENSE" ) endif() if(EXISTS ${PROJECT_BINARY_DIR}/_deps/libzmq-src AND HELICS_ENABLE_ZMQ_CORE) - list(APPEND LICENSE_LIST "ZeroMQ" "${PROJECT_BINARY_DIR}/_deps/libzmq-src/LICENSE") + list(APPEND LICENSE_LIST "ZeroMQ" "${PROJECT_SOURCE_DIR}/ThirdParty/libzmq/LICENSE") endif() if(NOT HELICS_DISABLE_ASIO) @@ -797,16 +812,6 @@ cmake_dependent_option( if(HELICS_ENABLE_PACKAGE_BUILD) - if(CMAKE_VERSION VERSION_LESS 3.13) - if(HELICS_ZMQ_SUBPROJECT OR HELICS_ZMQ_FORCE_SUBPROJECT) - if(ENABLE_ZMQ_CORE) - message( - FATAL_ERROR - "CMAKE 3.13 or higher is required to package a subproject of ZeroMQ with HELICS" - ) - endif() - endif() - endif() # cmake-format: off set(CPACK_PACKAGE_NAME "Helics") set(CPACK_PACKAGE_VENDOR "GMLC") @@ -827,7 +832,6 @@ if(HELICS_ENABLE_PACKAGE_BUILD) libs swig java - octave csharp benchmarks ) @@ -846,14 +850,12 @@ if(HELICS_ENABLE_PACKAGE_BUILD) set(CPACK_COMPONENT_BENCHMARKS_DISPLAY_NAME "Benchmarks") set(CPACK_COMPONENT_SWIG_DISPLAY_NAME "SWIG") set(CPACK_COMPONENT_JAVA_DISPLAY_NAME "Java") - set(CPACK_COMPONENT_OCTAVE_DISPLAY_NAME "Octave") set(CPACK_COMPONENT_CSHARP_DISPLAY_NAME "C#") set(CPACK_COMPONENT_GROUP_INTERFACES_DISPLAY_NAME "Interfaces") set(CPACK_COMPONENT_GROUP_INTERFACES_DESCRIPTION "Additional language interfaces for HELICS") set(CPACK_COMPONENT_SWIG_GROUP interfaces) set(CPACK_COMPONENT_JAVA_GROUP interfaces) - set(CPACK_COMPONENT_OCTAVE_GROUP interfaces) set(CPACK_COMPONENT_CSHARP_GROUP interfaces) set(CPACK_COMPONENT_GROUP_DEVELOPMENT_DISPLAY_NAME "Development") @@ -873,7 +875,6 @@ if(HELICS_ENABLE_PACKAGE_BUILD) "SWIG files needed for building 3rd party language interfaces (requires Development Headers)" ) set(CPACK_COMPONENT_JAVA_DESCRIPTION "Java language interface") - set(CPACK_COMPONENT_OCTAVE_DESCRIPTION "Octave language interface") set(CPACK_COMPONENT_CSHARP_DESCRIPTION "C# language interface") set(CPACK_COMPONENT_SWIG_DEPENDS headers) @@ -891,6 +892,8 @@ if(HELICS_ENABLE_PACKAGE_BUILD) "Helics Recorder" "helics_player" "Helics Player" + "helics_connector" + "Helics Connector" ) if(INSTALL_SYSTEM_LIBRARIES) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 4da2590bc3..bbba29219f 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -41,6 +41,7 @@ If you would like to contribute to the HELICS project see [CONTRIBUTING](CONTRIB - [Bryan Richardson](https://github.com/activeshadow) - [Matt Irish](https://github.com/mattirish) - [Slava Barsuk](https://github.com/vbarsuk) +- [Joseph McKinsey](https://github.com/josephmckinsey) ### Argonne National Lab @@ -54,6 +55,7 @@ If you would like to contribute to the HELICS project see [CONTRIBUTING](CONTRIB - [Nitin Barthwal](https://github.com/nitin-barthwal) - [Parth Bansal](https://github.com/parthb83) - [Gaurav Kumar](https://github.com/slashgk) +- [Mehdi Chinoune](https://github.com/MehdiChinoune) ## Used Libraries or Code @@ -65,9 +67,9 @@ Asio is used for TCP and UDP communication, as well as resolving IP addresses. T The header only bindings for the ZeroMQ library are used to interact with the ZeroMQ library. The header files are modified to include some string operations and are included in the HELICS source. cppzmq is licensed under the [MIT](https://github.com/zeromq/cppzmq/blob/master/LICENSE) license. -### [JsonCpp](https://github.com/open-source-parsers/jsoncpp) +### [JSON for Modern C++](https://github.com/nlohmann/json) -JsonCpp is used for parsing json files. It is included as a submodule JsonCpp is licensed under public domain or MIT in case public domain is not recognized [LICENSE](https://github.com/open-source-parsers/jsoncpp/blob/master/LICENSE). +JSON for Modern C++ is used for parsing json files. The single file header and forward declarations is included in this repo [LICENSE](https://github.com/nlohmann/json/blob/develop/LICENSE.MIT). ### [CLI11](https://github.com/CLIUtils/CLI11) @@ -122,7 +124,6 @@ A networking library with helper functions around Asio and other network interfa Several CMake scripts came from other sources and were either used or modified for use in HELICS. - Lars Bilke [CodeCoverage.cmake](https://github.com/bilke/cmake-modules/blob/master/CodeCoverage.cmake) -- NATIONAL HEART, LUNG, AND BLOOD INSTITUTE FindOctave.cmake - clang-format, clang-tidy scripts were created using tips from [Emmanuel Fleury](http://www.labri.fr/perso/fleury/posts/programming/using-clang-tidy-and-clang-format.html) - Viktor Kirilov, useful CMake macros [ucm](https://github.com/onqtam/ucm) particularly for the set_runtime macro to use static runtime libraries - scripts for cloning get repositories are included from [tschuchortdev/cmake_git_clone](https://github.com/tschuchortdev/cmake_git_clone) used with [MIT](https://github.com/tschuchortdev/cmake_git_clone/blob/master/LICENSE.TXT) License @@ -134,7 +135,7 @@ A list of optional component that are not included in HELICS but are optionally ### [BOOST](https://www.boost.org) -Boost is used in a few places in the code. The IPC core uses the Boost.Interprocess library. Some of the header-only Boost algorithms and other libraries are also used throughout the code. Some of the string parsing can optionally use boost spirit. The webserver that is part of the broker_server uses Boost::Beast from Boost 1.70 or higher. Boost is licensed under the Boost Software License. Boost can be removed entirely from the source code with the use of a [cmake](https://docs.helics.org/en/latest/user-guide/installation/helics_cmake_options.html) flag. +Boost is used in a few places in the code. The IPC core uses the Boost.Interprocess library. Some of the header-only Boost algorithms and other libraries are also used throughout the code. Some of the string parsing can optionally use boost spirit. The webserver that is part of the broker_server uses Boost::Beast. Boost is licensed under the Boost Software License. Boost can be removed entirely from the source code with the use of a [cmake](https://docs.helics.org/en/latest/user-guide/installation/helics_cmake_options.html) flag. #### [zmq](http://www.zeromq.org) diff --git a/CPPLINT.cfg b/CPPLINT.cfg index c543c09724..3ea8d97317 100644 --- a/CPPLINT.cfg +++ b/CPPLINT.cfg @@ -6,6 +6,7 @@ filter=-readability/multiline_comment,-readability/multiline_string # Errors du # Unused checks filter=-build/c++11 # Reports C++11 headers that aren't allowed for specific Google projects. +filter=-build/c++17 # Reports C++17 headers that aren't allowed for specific Google projects. filter=-build/include_order # Requires unusual include order that encourages creating not self-contained headers filter=-readability/nolint # Conflicts with clang-tidy filter=-runtime/references # Requires fundamental change of API, don't see need for this diff --git a/README.md b/README.md index d615039da0..ace51f9f1a 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ The HELICS team holds office hours [every-other Thursday](https://helics.org/HEL ### Language Bindings -HELICS provides a rich set of APIs for other languages including [Python](https://github.com/GMLC-TDC/pyhelics), C, Java, Octave, [Julia](https://github.com/GMLC-TDC/HELICS.jl), and [Matlab](https://github.com/GMLC-TDC/matHELICS). [nim](https://github.com/GMLC-TDC/helics.nim) and C# APIs are available on an experimental basis, and with an active open-source community, the set of supported languages is growing all the time. See [Language bindings](https://docs.helics.org/en/latest/user-guide/installation/language.html) for additional details. +HELICS provides a rich set of APIs for other languages including [Python](https://github.com/GMLC-TDC/pyhelics), C, Java, [Octave](https://github.com/GMLC-TDC/matHELICS), [Julia](https://github.com/GMLC-TDC/HELICS.jl), [Matlab](https://github.com/GMLC-TDC/matHELICS), and [Simulink](https://github.com/GMLC-TDC/simHELICS). [nim](https://github.com/GMLC-TDC/helics.nim) and C# APIs are available on an experimental basis, and with an active open-source community, the set of supported languages continues to grow. See [Language bindings](https://docs.helics.org/en/latest/user-guide/installation/language.html) for additional details. ## Documentation diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..bccc51c157 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,9 @@ +# Reporting Security Issues + +The HELICS team and community take security bugs in HELICS seriously. We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions. + +To report a security issue, please use the GitHub Security Advisory ["Report a Vulnerability"](https://github.com/GMLC-TDC/HELICS/security/advisories/new) tab. + +The HELICS team will send a response indicating the next steps in handling your report. After the initial reply to your report, the team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance. + +Report security bugs in third-party modules to the person or team maintaining the module. diff --git a/ThirdParty/asio b/ThirdParty/asio index 814f67e730..1f534288b4 160000 --- a/ThirdParty/asio +++ b/ThirdParty/asio @@ -1 +1 @@ -Subproject commit 814f67e730e154547aea3f4d99f709cbdf1ea4a0 +Subproject commit 1f534288b4be0be2dd664aab43882a0aa3106a1d diff --git a/ThirdParty/benchmark b/ThirdParty/benchmark new file mode 160000 index 0000000000..12235e2465 --- /dev/null +++ b/ThirdParty/benchmark @@ -0,0 +1 @@ +Subproject commit 12235e24652fc7f809373e7c11a5f73c5763fc4c diff --git a/ThirdParty/cmake/FindOctave.cmake b/ThirdParty/cmake/FindOctave.cmake deleted file mode 100644 index b141c1c261..0000000000 --- a/ThirdParty/cmake/FindOctave.cmake +++ /dev/null @@ -1,187 +0,0 @@ -#GADGETRON SOFTWARE LICENSE V1.0, NOVEMBER 2011 - -#PERMISSION IS HEREBY GRANTED, FREE OF CHARGE, TO ANY PERSON OBTAINING -#A COPY OF THIS SOFTWARE AND ASSOCIATED DOCUMENTATION FILES (THE -#"SOFTWARE"), TO DEAL IN THE SOFTWARE WITHOUT RESTRICTION, INCLUDING -#WITHOUT LIMITATION THE RIGHTS TO USE, COPY, MODIFY, MERGE, PUBLISH, -#DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THE SOFTWARE, AND TO -#PERMIT PERSONS TO WHOM THE SOFTWARE IS FURNISHED TO DO SO, SUBJECT TO -#THE FOLLOWING CONDITIONS: -# -#THE ABOVE COPYRIGHT NOTICE, THIS PERMISSION NOTICE, AND THE LIMITATION -#OF LIABILITY BELOW SHALL BE INCLUDED IN ALL COPIES OR REDISTRIBUTIONS -#OF SUBSTANTIAL PORTIONS OF THE SOFTWARE. -# -#SOFTWARE IS BEING DEVELOPED IN PART AT THE NATIONAL HEART, LUNG, AND BLOOD -#INSTITUTE, NATIONAL INSTITUTES OF HEALTH BY AN EMPLOYEE OF THE FEDERAL -#GOVERNMENT IN THE COURSE OF HIS OFFICIAL DUTIES. PURSUANT TO TITLE 17, -#SECTION 105 OF THE UNITED STATES CODE, THIS SOFTWARE IS NOT SUBJECT TO -#COPYRIGHT PROTECTION AND IS IN THE PUBLIC DOMAIN. EXCEPT AS CONTAINED IN -#THIS NOTICE, THE NAME OF THE AUTHORS, THE NATIONAL HEART, LUNG, AND BLOOD -#INSTITUTE (NHLBI), OR THE NATIONAL INSTITUTES OF HEALTH (NIH) MAY NOT -#BE USED TO ENDORSE OR PROMOTE PRODUCTS DERIVED FROM THIS SOFTWARE WITHOUT -#SPECIFIC PRIOR WRITTEN PERMISSION FROM THE NHLBI OR THE NIH.THE SOFTWARE IS -#PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -#INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -#FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -#AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -#IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -#IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -#modified Philip Top 2018 to add windows search paths and find octave executable itself - -# Try to find the build flags to compile octave shared objects (oct and mex files) -# Once done this will define -# -# OCTAVE_FOUND - if OCTAVE is found -# OCTAVE_CXXFLAGS - extra flags -# OCTAVE_INCLUDE_DIRS - include directories -# OCTAVE_LINK_DIRS - link directories -# OCTAVE_LIBRARY_RELEASE - the relase version -# OCTAVE_LIBRARY_DEBUG - the debug version -# OCTAVE_LIBRARY - a default library, with priority debug. - -if (WIN32) - -#message(STATUS "win32 octave search") -set (octave_versions -Octave-5.1.0.0 -Octave-4.4.0 -Octave-4.2.1 -Octave-4.2.0 -Octave-4.0.3 -Octave-4.0.2 -Octave-4.0.1 -Octave-4.0.0 -) - -set(poss_prefixes -C: -C:/Octave -"C:/Program Files" -C:/local -C:/local/Octave -D: -D:/Octave -"D:/Program Files" -D:/local -D:/local/Octave -) - -# create an empty list -list(APPEND octave_paths "") - -foreach( dir ${poss_prefixes}) - foreach( octver ${octave_versions}) - if (IS_DIRECTORY ${dir}/${octver}) - list(APPEND oct_paths ${dir}/${octver}) - message(STATUS "found oct path ${dir}/${octver}") - endif() - endforeach() -endforeach() - - -endif(WIN32) - -# use mkoctfile -if (NOT MKOCTFILE_EXECUTABLE) -set(MKOCTFILE_EXECUTABLE MKOCTFILE_EXECUTABLE-NOTFOUND) -endif() -find_program(MKOCTFILE_EXECUTABLE NAME mkoctfile - HINTS - ${OCTAVE_INSTALL_LOCATION} - PATHS - ${oct_paths} - PATH_SUFFIXES - bin - ) - -mark_as_advanced(MKOCTFILE_EXECUTABLE) - -if (NOT OCTAVE_EXECUTABLE) -set(OCTAVE_EXECUTABLE OCTAVE_EXECUTABLE-NOTFOUND) -endif() -find_program(OCTAVE_EXECUTABLE NAME octave octave.vbs - HINTS - ${OCTAVE_INSTALL_LOCATION} - PATHS - ${oct_paths} - PATH_SUFFIXES - bin - ) - -mark_as_advanced(OCTAVE_EXECUTABLE) - -get_filename_component(OCTAVE_EXECUTABLE_DIR ${OCTAVE_EXECUTABLE} DIRECTORY) - - -if(MKOCTFILE_EXECUTABLE) - set(OCTAVE_FOUND 1) - - execute_process( - COMMAND ${MKOCTFILE_EXECUTABLE} -p ALL_CXXFLAGS - OUTPUT_VARIABLE _mkoctfile_cppflags - RESULT_VARIABLE _mkoctfile_failed) - string(REGEX REPLACE "[\r\n]" " " _mkoctfile_cppflags "${_mkoctfile_cppflags}") - execute_process( - COMMAND ${MKOCTFILE_EXECUTABLE} -p INCFLAGS - OUTPUT_VARIABLE _mkoctfile_includedir - RESULT_VARIABLE _mkoctfile_failed) - string(REGEX REPLACE "[\r\n]" " " _mkoctfile_includedir "${_mkoctfile_includedir}") - execute_process( - COMMAND ${MKOCTFILE_EXECUTABLE} -p ALL_LDFLAGS - OUTPUT_VARIABLE _mkoctfile_ldflags - RESULT_VARIABLE _mkoctfile_failed) - string(REGEX REPLACE "[\r\n]" " " _mkoctfile_ldflags "${_mkoctfile_ldflags}") - execute_process( - COMMAND ${MKOCTFILE_EXECUTABLE} -p LFLAGS - OUTPUT_VARIABLE _mkoctfile_lflags - RESULT_VARIABLE _mkoctfile_failed) - string(REGEX REPLACE "[\r\n]" " " _mkoctfile_lflags "${_mkoctfile_lflags}") - execute_process( - COMMAND ${MKOCTFILE_EXECUTABLE} -p LIBS - OUTPUT_VARIABLE _mkoctfile_libs - RESULT_VARIABLE _mkoctfile_failed) - string(REGEX REPLACE "[\r\n]" " " _mkoctfile_libs "${_mkoctfile_libs}") - execute_process( - COMMAND ${MKOCTFILE_EXECUTABLE} -p OCTAVE_LIBS - OUTPUT_VARIABLE _mkoctfile_octlibs - RESULT_VARIABLE _mkoctfile_failed) - string(REGEX REPLACE "[\r\n]" " " _mkoctfile_octlibs "${_mkoctfile_octlibs}") - set(_mkoctfile_libs "${_mkoctfile_libs} ${_mkoctfile_octlibs}") - - string(REGEX MATCHALL "(^| )-l([./+-_\\a-zA-Z]*)" _mkoctfile_libs "${_mkoctfile_libs}") - string(REGEX REPLACE "(^| )-l" "" _mkoctfile_libs "${_mkoctfile_libs}") - - string(REGEX MATCHALL "(^| )-L([./+-_\\a-zA-Z]*)" _mkoctfile_ldirs "${_mkoctfile_lflags}") - string(REGEX REPLACE "(^| )-L" "" _mkoctfile_ldirs "${_mkoctfile_ldirs}") - - string(REGEX MATCHALL "(^| )-I([./+-_\\a-zA-Z]*)" _mkoctfile_includedir "${_mkoctfile_includedir}") - string(REGEX REPLACE "(^| )-I" "" _mkoctfile_includedir "${_mkoctfile_includedir}") - - string(REGEX REPLACE "(^| )-l([./+-_\\a-zA-Z]*)" " " _mkoctfile_ldflags "${_mkoctfile_ldflags}") - string(REGEX REPLACE "(^| )-L([./+-_\\a-zA-Z]*)" " " _mkoctfile_ldflags "${_mkoctfile_ldflags}") - - separate_arguments(_mkoctfile_includedir) - - set( OCTAVE_CXXFLAGS "${_mkoctfile_cppflags}" ) - set( OCTAVE_LINK_FLAGS "${_mkoctfile_ldflags}" ) - set( OCTAVE_INCLUDE_DIRS ${_mkoctfile_includedir}) - set( OCTAVE_LINK_DIRS ${_mkoctfile_ldirs}) - set( OCTAVE_LIBRARY ${_mkoctfile_libs}) - set( OCTAVE_LIBRARY_RELEASE ${OCTAVE_LIBRARY}) - set( OCTAVE_LIBRARY_DEBUG ${OCTAVE_LIBRARY}) - -endif() - -mark_as_advanced( - OCTAVE_LIBRARY_FOUND - OCTAVE_CXXFLAGS - OCTAVE_LINK_FLAGS - OCTAVE_INCLUDE_DIRS - OCTAVE_LINK_DIRS - OCTAVE_LIBRARY - OCTAVE_LIBRARY_RELEASE - OCTAVE_LIBRARY_DEBUG - OCTAVE_EXECUTABLE_DIR -) \ No newline at end of file diff --git a/ThirdParty/concurrency b/ThirdParty/concurrency index 3a06173deb..a051cd9327 160000 --- a/ThirdParty/concurrency +++ b/ThirdParty/concurrency @@ -1 +1 @@ -Subproject commit 3a06173debc18c6712245eb7b6e779d1837f179d +Subproject commit a051cd93273b6f051693f07d06f64f2292d517a6 diff --git a/ThirdParty/fmtlib b/ThirdParty/fmtlib index e69e5f977d..0c9fce2ffe 160000 --- a/ThirdParty/fmtlib +++ b/ThirdParty/fmtlib @@ -1 +1 @@ -Subproject commit e69e5f977d458f2650bb346dadf2ad30c5320281 +Subproject commit 0c9fce2ffefecfdce794e1859584e25877b7b592 diff --git a/ThirdParty/googletest b/ThirdParty/googletest new file mode 160000 index 0000000000..b514bdc898 --- /dev/null +++ b/ThirdParty/googletest @@ -0,0 +1 @@ +Subproject commit b514bdc898e2951020cbdca1304b75f5950d1f59 diff --git a/ThirdParty/helics/external/CLI11/CLI11.hpp b/ThirdParty/helics/external/CLI11/CLI11.hpp index ce1875e3a7..2e8c021aa4 100644 --- a/ThirdParty/helics/external/CLI11/CLI11.hpp +++ b/ThirdParty/helics/external/CLI11/CLI11.hpp @@ -1,11 +1,11 @@ -// CLI11: Version 2.4.1 +// CLI11: Version 2.4.2 // Originally designed by Henry Schreiner // https://github.com/CLIUtils/CLI11 // // This is a standalone header file generated by MakeSingleHeader.py in CLI11/scripts -// from: v2.4.0-14-g5f9141d +// from: v2.4.2-29-g2be38c5 // -// CLI11 2.4.1 Copyright (c) 2017-2024 University of Cincinnati, developed by Henry +// CLI11 2.4.2 Copyright (c) 2017-2024 University of Cincinnati, developed by Henry // Schreiner under NSF AWARD 1414736. All rights reserved. // // Redistribution and use in source and binary forms of CLI11, with or without @@ -66,8 +66,8 @@ #define CLI11_VERSION_MAJOR 2 #define CLI11_VERSION_MINOR 4 -#define CLI11_VERSION_PATCH 1 -#define CLI11_VERSION "2.4.1" +#define CLI11_VERSION_PATCH 2 +#define CLI11_VERSION "2.4.2" @@ -476,7 +476,12 @@ template std::string join(const T &v, std::string delim = ",") { while(beg != end) { s << delim << *beg++; } - return s.str(); + auto rval = s.str(); + if(!rval.empty() && delim.size() == 1 && rval.back() == delim[0]) { + // remove trailing delimiter if the last entry was empty + rval.pop_back(); + } + return rval; } /// Simple function to join a string from processed elements @@ -1118,7 +1123,8 @@ CLI11_INLINE std::string binary_escape_string(const std::string &string_to_escap if(escaped_string != string_to_escape) { auto sqLoc = escaped_string.find('\''); while(sqLoc != std::string::npos) { - escaped_string.replace(sqLoc, sqLoc + 1, "\\x27"); + escaped_string[sqLoc] = '\\'; + escaped_string.insert(sqLoc + 1, "x27"); sqLoc = escaped_string.find('\''); } escaped_string.insert(0, "'B\"("); @@ -1344,8 +1350,8 @@ class BadNameString : public ConstructionError { static BadNameString BadPositionalName(std::string name) { return BadNameString("Invalid positional Name: " + name); } - static BadNameString DashesOnly(std::string name) { - return BadNameString("Must have a name, not just dashes: " + name); + static BadNameString ReservedName(std::string name) { + return BadNameString("Names '-','--','++' are reserved and not allowed as option names " + name); } static BadNameString MultiPositionalNames(std::string name) { return BadNameString("Only one positional name allowed, remove: " + name); @@ -1451,22 +1457,22 @@ class RequiredError : public ParseError { if((min_option == 1) && (max_option == 1) && (used == 0)) return RequiredError("Exactly 1 option from [" + option_list + "]"); if((min_option == 1) && (max_option == 1) && (used > 1)) { - return {"Exactly 1 option from [" + option_list + "] is required and " + std::to_string(used) + + return {"Exactly 1 option from [" + option_list + "] is required but " + std::to_string(used) + " were given", ExitCodes::RequiredError}; } if((min_option == 1) && (used == 0)) return RequiredError("At least 1 option from [" + option_list + "]"); if(used < min_option) { - return {"Requires at least " + std::to_string(min_option) + " options used and only " + - std::to_string(used) + "were given from [" + option_list + "]", + return {"Requires at least " + std::to_string(min_option) + " options used but only " + + std::to_string(used) + " were given from [" + option_list + "]", ExitCodes::RequiredError}; } if(max_option == 1) return {"Requires at most 1 options be given from [" + option_list + "]", ExitCodes::RequiredError}; - return {"Requires at most " + std::to_string(max_option) + " options be used and " + std::to_string(used) + - "were given from [" + option_list + "]", + return {"Requires at most " + std::to_string(max_option) + " options be used but " + std::to_string(used) + + " were given from [" + option_list + "]", ExitCodes::RequiredError}; } }; @@ -1633,6 +1639,23 @@ template <> struct IsMemberType { using type = std::string; }; +namespace adl_detail { +/// Check for existence of user-supplied lexical_cast. +/// +/// This struct has to be in a separate namespace so that it doesn't see our lexical_cast overloads in CLI::detail. +/// Standard says it shouldn't see them if it's defined before the corresponding lexical_cast declarations, but this +/// requires a working implementation of two-phase lookup, and not all compilers can boast that (msvc, ahem). +template class is_lexical_castable { + template + static auto test(int) -> decltype(lexical_cast(std::declval(), std::declval()), std::true_type()); + + template static auto test(...) -> std::false_type; + + public: + static constexpr bool value = decltype(test(0))::value; +}; +} // namespace adl_detail + namespace detail { // These are utilities for IsMember and other transforming objects @@ -1714,7 +1737,7 @@ template class is_direct_constructible { #pragma diag_suppress 2361 #endif #endif - TT{std::declval()} + TT{std::declval()} #ifdef __CUDACC__ #ifdef __NVCC_DIAG_PRAGMA_SUPPORT__ #pragma nv_diag_default 2361 @@ -1722,8 +1745,8 @@ template class is_direct_constructible { #pragma diag_default 2361 #endif #endif - , - std::is_move_assignable()); + , + std::is_move_assignable()); template static auto test(int, std::false_type) -> std::false_type; @@ -2793,13 +2816,24 @@ bool lexical_cast(const std::string &input, T &output) { /// Non-string parsable by a stream template ::value == object_category::other && !std::is_assignable::value, + enable_if_t::value == object_category::other && !std::is_assignable::value && + is_istreamable::value, detail::enabler> = detail::dummy> bool lexical_cast(const std::string &input, T &output) { - static_assert(is_istreamable::value, + return from_stream(input, output); +} + +/// Fallback overload that prints a human-readable error for types that we don't recognize and that don't have a +/// user-supplied lexical_cast overload. +template ::value == object_category::other && !std::is_assignable::value && + !is_istreamable::value && !adl_detail::is_lexical_castable::value, + detail::enabler> = detail::dummy> +bool lexical_cast(const std::string & /*input*/, T & /*output*/) { + static_assert(!std::is_same::value, // Can't just write false here. "option object type must have a lexical cast overload or streaming input operator(>>) defined, if it " "is convertible from another type use the add_option(...) with XC being the known type"); - return from_stream(input, output); + return false; } /// Assign a value through lexical cast operations @@ -3405,8 +3439,8 @@ get_names(const std::vector &input) { long_names.push_back(name); else throw BadNameString::BadLongName(name); - } else if(name == "-" || name == "--") { - throw BadNameString::DashesOnly(name); + } else if(name == "-" || name == "--" || name == "++") { + throw BadNameString::ReservedName(name); } else { if(!pos_name.empty()) throw BadNameString::MultiPositionalNames(name); @@ -5993,7 +6027,9 @@ CLI11_NODISCARD CLI11_INLINE std::string Option::get_name(bool positional, bool } CLI11_INLINE void Option::run_callback() { + bool used_default_str = false; if(force_callback_ && results_.empty()) { + used_default_str = true; add_result(default_str_); } if(current_option_state_ == option_state::parsing) { @@ -6003,16 +6039,18 @@ CLI11_INLINE void Option::run_callback() { if(current_option_state_ < option_state::reduced) { _reduce_results(proc_results_, results_); - current_option_state_ = option_state::reduced; } - if(current_option_state_ >= option_state::reduced) { - current_option_state_ = option_state::callback_run; - if(!(callback_)) { - return; - } + + current_option_state_ = option_state::callback_run; + if(callback_) { const results_t &send_results = proc_results_.empty() ? results_ : proc_results_; bool local_result = callback_(send_results); - + if(used_default_str) { + // we only clear the results if the callback was actually used + // otherwise the callback is the storage of the default + results_.clear(); + proc_results_.clear(); + } if(!local_result) throw ConversionError(get_name(), results_); } @@ -6020,26 +6058,27 @@ CLI11_INLINE void Option::run_callback() { CLI11_NODISCARD CLI11_INLINE const std::string &Option::matching_name(const Option &other) const { static const std::string estring; + bool bothConfigurable = configurable_ && other.configurable_; for(const std::string &sname : snames_) { if(other.check_sname(sname)) return sname; - if(other.check_lname(sname)) + if(bothConfigurable && other.check_lname(sname)) return sname; } for(const std::string &lname : lnames_) { if(other.check_lname(lname)) return lname; - if(lname.size() == 1) { + if(lname.size() == 1 && bothConfigurable) { if(other.check_sname(lname)) { return lname; } } } - if(snames_.empty() && lnames_.empty() && !pname_.empty()) { + if(bothConfigurable && snames_.empty() && lnames_.empty() && !pname_.empty()) { if(other.check_sname(pname_) || other.check_lname(pname_) || pname_ == other.pname_) return pname_; } - if(other.snames_.empty() && other.fnames_.empty() && !other.pname_.empty()) { + if(bothConfigurable && other.snames_.empty() && other.fnames_.empty() && !other.pname_.empty()) { if(check_sname(other.pname_) || check_lname(other.pname_) || (pname_ == other.pname_)) return other.pname_; } @@ -6472,7 +6511,7 @@ class App { /// if error error on an extra argument, and if capture feed it to the app config_extras_mode allow_config_extras_{config_extras_mode::ignore}; - /// If true, return immediately on an unrecognized option (implies allow_extras) INHERITABLE + /// If true, cease processing on an unrecognized option (implies allow_extras) INHERITABLE bool prefix_command_{false}; /// If set to true the name was automatically generated from the command line vs a user set name @@ -6804,9 +6843,10 @@ class App { return this; } - /// Do not parse anything after the first unrecognized option and return - App *prefix_command(bool allow = true) { - prefix_command_ = allow; + /// Do not parse anything after the first unrecognized option (if true) all remaining arguments are stored in + /// remaining args + App *prefix_command(bool is_prefix = true) { + prefix_command_ = is_prefix; return this; } @@ -7702,6 +7742,11 @@ class Option_group : public App { : App(std::move(group_description), "", parent) { group(group_name); // option groups should have automatic fallthrough + if(group_name.empty() || group_name.front() == '+') { + // help will not be used by default in these contexts + set_help_flag(""); + set_help_all_flag(""); + } } using App::add_option; /// Add an existing option to the Option_group @@ -7954,19 +7999,19 @@ CLI11_INLINE Option *App::add_option(std::string option_name, } auto *op = get_option_no_throw(test_name); - if(op != nullptr) { + if(op != nullptr && op->get_configurable()) { throw(OptionAlreadyAdded("added option positional name matches existing option: " + test_name)); } } else if(parent_ != nullptr) { for(auto &ln : myopt.lnames_) { auto *op = parent_->get_option_no_throw(ln); - if(op != nullptr) { + if(op != nullptr && op->get_configurable()) { throw(OptionAlreadyAdded("added option matches existing positional option: " + ln)); } } for(auto &sn : myopt.snames_) { auto *op = parent_->get_option_no_throw(sn); - if(op != nullptr) { + if(op != nullptr && op->get_configurable()) { throw(OptionAlreadyAdded("added option matches existing positional option: " + sn)); } } @@ -8061,8 +8106,8 @@ App::set_version_flag(std::string flag_name, std::function vfunc, // Empty name will simply remove the version flag if(!flag_name.empty()) { - version_ptr_ = add_flag_callback( - flag_name, [vfunc]() { throw(CLI::CallForVersion(vfunc(), 0)); }, version_help); + version_ptr_ = + add_flag_callback(flag_name, [vfunc]() { throw(CLI::CallForVersion(vfunc(), 0)); }, version_help); version_ptr_->configurable(false); } @@ -8564,7 +8609,14 @@ CLI11_INLINE std::vector App::get_options(const std::functionget_name().empty() && !subc->get_group().empty() && subc->get_group().front() == '+') { + std::vector subcopts = subc->get_options(filter); + options.insert(options.end(), subcopts.begin(), subcopts.end()); + } + } return options; } @@ -8578,7 +8630,13 @@ CLI11_INLINE std::vector