├── .clang-format ├── .dockerignore ├── .github ├── dependabot.yml └── workflows │ ├── aarch64_toolchain_cmake.yml │ ├── amd64_docker_cmake.yml │ ├── amd64_freebsd_cmake.yml │ ├── amd64_linux_cmake.yml │ ├── amd64_macos_cmake.yml │ ├── amd64_web_cmake.yml │ ├── amd64_windows_cmake.yml │ ├── arm64_docker_cmake.yml │ ├── arm64_macos_cmake.yml │ ├── arm_toolchain_cmake.yml │ ├── mips64_toolchain_cmake.yml │ ├── powerpc_toolchain_cmake.yml │ ├── riscv64_docker_cmake.yml │ ├── riscv64_toolchain_cmake.yml │ └── s390x_toolchain_cmake.yml ├── .gitignore ├── AUTHORS ├── Bar ├── CMakeLists.txt ├── include │ └── bar │ │ └── Bar.hpp ├── src │ └── Bar.cpp └── tests │ ├── CMakeLists.txt │ └── bar_test.cpp ├── CMakeLists.txt ├── CONTRIBUTING.md ├── CONTRIBUTORS ├── Foo ├── CMakeLists.txt ├── include │ └── foo │ │ └── Foo.hpp ├── src │ └── Foo.cpp └── tests │ ├── CMakeLists.txt │ └── foo_test.cpp ├── FooBar ├── CMakeLists.txt ├── include │ └── foobar │ │ └── FooBar.hpp ├── src │ └── FooBar.cpp └── tests │ ├── CMakeLists.txt │ └── foobar_test.cpp ├── FooBarApp ├── CMakeLists.txt └── src │ └── main.cpp ├── LICENSE ├── README.md ├── ci ├── Makefile ├── README.md ├── docker │ ├── almalinux │ │ └── Dockerfile │ ├── alpine │ │ └── Dockerfile │ ├── archlinux │ │ └── Dockerfile │ ├── debian │ │ └── Dockerfile │ ├── fedora │ │ └── Dockerfile │ ├── opensuse │ │ └── Dockerfile │ ├── rockylinux │ │ └── Dockerfile │ ├── toolchain │ │ └── Dockerfile │ ├── ubuntu │ │ └── Dockerfile │ └── web │ │ └── Dockerfile ├── docs │ ├── docker.dot │ ├── docker.svg │ └── generate_image.sh ├── samples │ ├── CMakeLists.txt │ └── main.cpp └── vagrant │ ├── freebsd │ └── Vagrantfile │ ├── netbsd │ └── Vagrantfile │ └── openbsd │ └── Vagrantfile ├── cmake ├── CMakeCppConfig.cmake.in ├── check_deps.cmake ├── cpp.cmake ├── dependencies │ └── CMakeLists.txt ├── host.CMakeLists.txt ├── host.cmake └── system_deps.cmake ├── examples ├── CMakeLists.txt └── example.cpp ├── patches ├── ZLIB-v1.3.1.patch ├── abseil-cpp-20250127.1.patch ├── googletest-v1.16.0.patch ├── protobuf-v30.2.patch └── re2-2024-04-01.patch └── tools └── cross_compile.sh /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: Mizux 4 | AccessModifierOffset: -1 5 | AlignAfterOpenBracket: AlwaysBreak 6 | AlignConsecutiveMacros: false 7 | AlignConsecutiveAssignments: true 8 | AlignConsecutiveDeclarations: true 9 | AlignEscapedNewlines: Left 10 | AlignOperands: true 11 | AlignTrailingComments: true 12 | AllowAllArgumentsOnNextLine: true 13 | AllowAllConstructorInitializersOnNextLine: true 14 | AllowAllParametersOfDeclarationOnNextLine: false 15 | AllowShortBlocksOnASingleLine: Never 16 | AllowShortCaseLabelsOnASingleLine: false 17 | AllowShortFunctionsOnASingleLine: Inline 18 | AllowShortLambdasOnASingleLine: All 19 | AllowShortIfStatementsOnASingleLine: Never 20 | AllowShortLoopsOnASingleLine: false 21 | AlwaysBreakAfterDefinitionReturnType: None 22 | AlwaysBreakAfterReturnType: None 23 | AlwaysBreakBeforeMultilineStrings: true 24 | AlwaysBreakTemplateDeclarations: Yes 25 | BinPackArguments: false 26 | BinPackParameters: false 27 | BraceWrapping: 28 | AfterCaseLabel: true 29 | AfterClass: true 30 | AfterControlStatement: false 31 | AfterEnum: false 32 | AfterFunction: false 33 | AfterNamespace: false 34 | AfterObjCDeclaration: false 35 | AfterStruct: false 36 | AfterUnion: false 37 | AfterExternBlock: false 38 | BeforeCatch: false 39 | BeforeElse: false 40 | IndentBraces: false 41 | SplitEmptyFunction: true 42 | SplitEmptyRecord: true 43 | SplitEmptyNamespace: true 44 | BreakBeforeBinaryOperators: None 45 | BreakBeforeBraces: Attach 46 | BreakBeforeInheritanceComma: false 47 | BreakInheritanceList: BeforeColon 48 | BreakBeforeTernaryOperators: true 49 | BreakConstructorInitializersBeforeComma: false 50 | BreakConstructorInitializers: BeforeColon 51 | BreakAfterJavaFieldAnnotations: false 52 | BreakStringLiterals: true 53 | ColumnLimit: 100 54 | CommentPragmas: '^ IWYU pragma:' 55 | CompactNamespaces: false 56 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 57 | ConstructorInitializerIndentWidth: 4 58 | ContinuationIndentWidth: 4 59 | Cpp11BracedListStyle: true 60 | DeriveLineEnding: true 61 | DerivePointerAlignment: false 62 | DisableFormat: false 63 | ExperimentalAutoDetectBinPacking: false 64 | FixNamespaceComments: true 65 | ForEachMacros: 66 | - foreach 67 | - Q_FOREACH 68 | - BOOST_FOREACH 69 | IncludeBlocks: Regroup 70 | IncludeCategories: 71 | - Regex: '^' 72 | Priority: 2 73 | SortPriority: 0 74 | - Regex: '^<.*\.h>' 75 | Priority: 1 76 | SortPriority: 0 77 | - Regex: '^<.*' 78 | Priority: 2 79 | SortPriority: 0 80 | - Regex: '.*' 81 | Priority: 3 82 | SortPriority: 0 83 | IncludeIsMainRegex: '([-_](test|unittest))?$' 84 | IncludeIsMainSourceRegex: '' 85 | IndentCaseLabels: true 86 | IndentGotoLabels: true 87 | IndentPPDirectives: None 88 | IndentWidth: 2 89 | IndentWrappedFunctionNames: false 90 | JavaScriptQuotes: Leave 91 | JavaScriptWrapImports: true 92 | KeepEmptyLinesAtTheStartOfBlocks: false 93 | MacroBlockBegin: '' 94 | MacroBlockEnd: '' 95 | MaxEmptyLinesToKeep: 1 96 | NamespaceIndentation: None 97 | ObjCBinPackProtocolList: Never 98 | ObjCBlockIndentWidth: 2 99 | ObjCSpaceAfterProperty: false 100 | ObjCSpaceBeforeProtocolList: true 101 | PenaltyBreakAssignment: 2 102 | PenaltyBreakBeforeFirstCallParameter: 1 103 | PenaltyBreakComment: 300 104 | PenaltyBreakFirstLessLess: 120 105 | PenaltyBreakString: 1000 106 | PenaltyBreakTemplateDeclaration: 10 107 | PenaltyExcessCharacter: 1000000 108 | PenaltyReturnTypeOnItsOwnLine: 200 109 | PointerAlignment: Left 110 | RawStringFormats: 111 | - Language: Cpp 112 | Delimiters: 113 | - cc 114 | - CC 115 | - cpp 116 | - Cpp 117 | - CPP 118 | - 'c++' 119 | - 'C++' 120 | CanonicalDelimiter: '' 121 | BasedOnStyle: google 122 | - Language: TextProto 123 | Delimiters: 124 | - pb 125 | - PB 126 | - proto 127 | - PROTO 128 | EnclosingFunctions: 129 | - EqualsProto 130 | - EquivToProto 131 | - PARSE_PARTIAL_TEXT_PROTO 132 | - PARSE_TEST_PROTO 133 | - PARSE_TEXT_PROTO 134 | - ParseTextOrDie 135 | - ParseTextProtoOrDie 136 | CanonicalDelimiter: '' 137 | BasedOnStyle: google 138 | ReflowComments: true 139 | SortIncludes: true 140 | SortUsingDeclarations: true 141 | SpaceAfterCStyleCast: false 142 | SpaceAfterLogicalNot: false 143 | SpaceAfterTemplateKeyword: false 144 | SpaceBeforeAssignmentOperators: true 145 | SpaceBeforeCpp11BracedList: false 146 | SpaceBeforeCtorInitializerColon: true 147 | SpaceBeforeInheritanceColon: true 148 | SpaceBeforeParens: ControlStatements 149 | SpaceBeforeRangeBasedForLoopColon: true 150 | SpaceInEmptyBlock: false 151 | SpaceInEmptyParentheses: false 152 | SpacesBeforeTrailingComments: 1 153 | SpacesInAngles: false 154 | SpacesInConditionalStatement: false 155 | SpacesInContainerLiterals: true 156 | SpacesInCStyleCastParentheses: false 157 | SpacesInParentheses: false 158 | SpacesInSquareBrackets: false 159 | SpaceBeforeSquareBrackets: false 160 | Standard: Latest 161 | StatementMacros: 162 | - Q_UNUSED 163 | - QT_REQUIRE_VERSION 164 | TabWidth: 8 165 | UseCRLF: false 166 | UseTab: Never 167 | ... 168 | 169 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Project Files unneeded by docker 2 | .dockerignore 3 | 4 | .git 5 | .gitignore 6 | .github 7 | .clang-format 8 | 9 | # CMake 10 | cmake/docs 11 | cmake/README.md 12 | 13 | ci/docker 14 | ci/docs 15 | ci/cache 16 | ci/Makefile 17 | 18 | AUTHORS 19 | CONTRIBUTORS 20 | LICENSE 21 | README.md 22 | CONTRIBUTING.md 23 | 24 | # Native cmake build 25 | build/ 26 | build*/ 27 | 28 | # Editor directories and files 29 | *.user 30 | *.swp 31 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # Keep GitHub Actions up to date with GitHub's Dependabot... 2 | # https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot 3 | # https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem 4 | version: 2 5 | updates: 6 | - package-ecosystem: github-actions 7 | directory: / 8 | groups: 9 | github-actions: 10 | patterns: 11 | - "*" # Group all Actions updates into a single larger pull request 12 | schedule: 13 | interval: weekly 14 | -------------------------------------------------------------------------------- /.github/workflows/aarch64_toolchain_cmake.yml: -------------------------------------------------------------------------------- 1 | # ref: https://toolchains.bootlin.com/ 2 | name: aarch64 Toolchain CMake 3 | 4 | on: [push, pull_request, workflow_dispatch] 5 | 6 | concurrency: 7 | group: ${{github.workflow}}-${{github.ref}} 8 | cancel-in-progress: true 9 | 10 | # Building using the github runner environement directly. 11 | jobs: 12 | aarch64: 13 | strategy: 14 | matrix: 15 | targets: [ 16 | # https://go.dev/doc/install/source#environment 17 | arm64, # alias to aarch64 18 | arm64be, # alias to aarch64be 19 | aarch64, # bootlin 20 | aarch64be # bootlin 21 | ] 22 | fail-fast: false 23 | name: Linux•Toolchain ${{matrix.targets}} 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v4 27 | - name: Build env stage 28 | run: make --directory=ci toolchain_${{matrix.targets}}_env 29 | - name: Build devel stage 30 | run: make --directory=ci toolchain_${{matrix.targets}}_devel 31 | - name: Build toolchain stage 32 | run: make --directory=ci toolchain_${{matrix.targets}}_toolchain 33 | - name: Build build stage 34 | run: make --directory=ci toolchain_${{matrix.targets}}_build 35 | - name: Build Test stage 36 | run: make --directory=ci toolchain_${{matrix.targets}}_test 37 | -------------------------------------------------------------------------------- /.github/workflows/amd64_docker_cmake.yml: -------------------------------------------------------------------------------- 1 | # ref: https://github.com/docker-library/official-images 2 | name: amd64 Docker CMake 3 | 4 | on: [push, pull_request, workflow_dispatch] 5 | 6 | concurrency: 7 | group: ${{github.workflow}}-${{github.ref}} 8 | cancel-in-progress: true 9 | 10 | jobs: 11 | docker: 12 | strategy: 13 | matrix: 14 | distro: [ 15 | almalinux, 16 | alpine, 17 | archlinux, 18 | debian, 19 | fedora, 20 | opensuse, 21 | rockylinux, 22 | ubuntu 23 | ] 24 | fail-fast: false 25 | name: amd64•${{matrix.distro}}•CMake 26 | runs-on: ubuntu-latest 27 | steps: 28 | - uses: actions/checkout@v4 29 | - name: Check docker 30 | run: | 31 | docker info 32 | docker buildx ls 33 | - name: Build env image 34 | run: make --directory=ci amd64_${{matrix.distro}}_env 35 | - name: Build devel image 36 | run: make --directory=ci amd64_${{matrix.distro}}_devel 37 | - name: Build project 38 | run: make --directory=ci amd64_${{matrix.distro}}_build 39 | - name: Test project 40 | run: make --directory=ci amd64_${{matrix.distro}}_test 41 | 42 | - name: Build install env image 43 | run: make --directory=ci amd64_${{matrix.distro}}_install_env 44 | - name: Build install devel image 45 | run: make --directory=ci amd64_${{matrix.distro}}_install_devel 46 | - name: Build install project 47 | run: make --directory=ci amd64_${{matrix.distro}}_install_build 48 | - name: Test install project 49 | run: make --directory=ci amd64_${{matrix.distro}}_install_test 50 | 51 | amd64_docker_cmake: 52 | runs-on: ubuntu-latest 53 | needs: docker 54 | steps: 55 | - uses: actions/checkout@v4 56 | -------------------------------------------------------------------------------- /.github/workflows/amd64_freebsd_cmake.yml: -------------------------------------------------------------------------------- 1 | name: amd64 FreeBSD CMake 2 | 3 | on: [push, pull_request, workflow_dispatch] 4 | 5 | concurrency: 6 | group: ${{github.workflow}}-${{github.ref}} 7 | cancel-in-progress: true 8 | 9 | jobs: 10 | # Only macos runner provide virtualisation with vagrant/virtualbox installed. 11 | freebsd: 12 | runs-on: macos-10.15 13 | steps: 14 | - uses: actions/checkout@v4 15 | - name: vagrant version 16 | run: Vagrant --version 17 | - name: VirtualBox version 18 | run: virtualbox -h 19 | - name: Build 20 | run: make --directory=ci freebsd_build 21 | -------------------------------------------------------------------------------- /.github/workflows/amd64_linux_cmake.yml: -------------------------------------------------------------------------------- 1 | # ref: https://github.com/actions/runner-images 2 | name: amd64 Linux CMake 3 | 4 | on: [push, pull_request, workflow_dispatch] 5 | 6 | concurrency: 7 | group: ${{github.workflow}}-${{github.ref}} 8 | cancel-in-progress: true 9 | 10 | # Building using the github runner environement directly. 11 | jobs: 12 | native: 13 | strategy: 14 | matrix: 15 | cmake: [ 16 | {generator: "Unix Makefiles", config: "Release"}, 17 | {generator: "Ninja", config: "Release"}, 18 | {generator: "Ninja Multi-Config", config: "Release"}, 19 | ] 20 | fail-fast: false 21 | name: Linux•CMake(${{matrix.cmake.generator}}) 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v4 25 | - name: Install Ninja 26 | run: | 27 | sudo apt-get update 28 | sudo apt-get install ninja-build 29 | - name: Check CMake 30 | run: cmake --version 31 | - name: Configure 32 | run: > 33 | cmake -S. -Bbuild 34 | -G "${{matrix.cmake.generator}}" 35 | -DCMAKE_BUILD_TYPE=${{matrix.cmake.config}} 36 | -DCMAKE_INSTALL_PREFIX=install 37 | - name: Build 38 | run: > 39 | cmake --build build 40 | --config ${{matrix.cmake.config}} 41 | --target all 42 | -v -j2 43 | - name: Test 44 | run: > 45 | CTEST_OUTPUT_ON_FAILURE=1 46 | cmake --build build 47 | --config ${{matrix.cmake.config}} 48 | --target test 49 | -v 50 | - name: Install 51 | run: > 52 | cmake --build build 53 | --config ${{matrix.cmake.config}} 54 | --target install 55 | -v 56 | 57 | amd64_linux_cmake: 58 | runs-on: ubuntu-latest 59 | needs: native 60 | steps: 61 | - uses: actions/checkout@v4 62 | -------------------------------------------------------------------------------- /.github/workflows/amd64_macos_cmake.yml: -------------------------------------------------------------------------------- 1 | # ref: https://github.com/actions/runner-images 2 | name: amd64 MacOS CMake 3 | 4 | on: [push, pull_request, workflow_dispatch] 5 | 6 | concurrency: 7 | group: ${{github.workflow}}-${{github.ref}} 8 | cancel-in-progress: true 9 | 10 | # Building using the github runner environement directly. 11 | jobs: 12 | native: 13 | strategy: 14 | matrix: 15 | cmake: [ 16 | {name: "Xcode", generator: "Xcode", config: Release, build_target: ALL_BUILD, test_target: RUN_TESTS, install_target: install}, 17 | {name: "Make", generator: "Unix Makefiles", config: Release, build_target: all, test_target: test, install_target: install}, 18 | ] 19 | fail-fast: false 20 | name: MacOS•CMake(${{matrix.cmake.name}}) 21 | runs-on: macos-13 # last macos intel based runner 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Check CMake 25 | run: cmake --version 26 | - name: Configure 27 | run: > 28 | cmake -S. -Bbuild 29 | -G "${{matrix.cmake.generator}}" 30 | -DCMAKE_BUILD_TYPE=${{matrix.cmake.config}} 31 | -DCMAKE_INSTALL_PREFIX=install 32 | - name: Build 33 | run: > 34 | cmake --build build 35 | --config ${{matrix.cmake.config}} 36 | --target ${{matrix.cmake.build_target}} 37 | -v -j2 38 | - name: Test 39 | run: > 40 | CTEST_OUTPUT_ON_FAILURE=1 41 | cmake --build build 42 | --config ${{matrix.cmake.config}} 43 | --target ${{matrix.cmake.test_target}} 44 | -v 45 | - name: Install 46 | run: > 47 | cmake --build build 48 | --config ${{matrix.cmake.config}} 49 | --target ${{matrix.cmake.install_target}} 50 | -v 51 | 52 | amd64_macos_cmake: 53 | runs-on: ubuntu-latest 54 | needs: native 55 | steps: 56 | - uses: actions/checkout@v4 57 | -------------------------------------------------------------------------------- /.github/workflows/amd64_web_cmake.yml: -------------------------------------------------------------------------------- 1 | # ref: https://github.com/docker-library/official-images 2 | name: amd64 Web CMake 3 | 4 | on: [push, pull_request, workflow_dispatch] 5 | 6 | concurrency: 7 | group: ${{github.workflow}}-${{github.ref}} 8 | cancel-in-progress: true 9 | 10 | jobs: 11 | Distros: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | - name: Check docker 16 | run: | 17 | docker info 18 | docker buildx ls 19 | - name: Build env image 20 | run: make --directory=ci web_env 21 | - name: Build devel project 22 | run: make --directory=ci web_devel 23 | - name: Build project 24 | run: make --directory=ci web_build 25 | - name: Test project 26 | run: make --directory=ci web_test 27 | -------------------------------------------------------------------------------- /.github/workflows/amd64_windows_cmake.yml: -------------------------------------------------------------------------------- 1 | # ref: https://github.com/actions/runner-images 2 | name: amd64 Windows CMake 3 | 4 | on: [push, pull_request, workflow_dispatch] 5 | 6 | concurrency: 7 | group: ${{github.workflow}}-${{github.ref}} 8 | cancel-in-progress: true 9 | 10 | # Building using the github runner environement directly. 11 | jobs: 12 | native: 13 | strategy: 14 | matrix: 15 | cmake: [ 16 | {name: "VS22", generator: "Visual Studio 17 2022", config: Release, build_target: ALL_BUILD, test_target: RUN_TESTS, install_target: INSTALL}, 17 | {name: "VS22", generator: "Visual Studio 17 2022", config: Debug, build_target: ALL_BUILD, test_target: RUN_TESTS, install_target: INSTALL}, 18 | ] 19 | fail-fast: false 20 | name: Windows•CMake(${{matrix.cmake.name}},${{matrix.cmake.config}}) 21 | runs-on: windows-latest 22 | env: 23 | CTEST_OUTPUT_ON_FAILURE: 1 24 | steps: 25 | - uses: actions/checkout@v4 26 | - name: Check CMake 27 | run: | 28 | cmake --version 29 | cmake -G || true 30 | - name: Configure 31 | run: > 32 | cmake -S. -Bbuild 33 | -G "${{matrix.cmake.generator}}" 34 | -DCMAKE_CONFIGURATION_TYPES=${{matrix.cmake.config}} 35 | -DCMAKE_INSTALL_PREFIX=install 36 | - name: Build 37 | run: > 38 | cmake --build build 39 | --config ${{matrix.cmake.config}} 40 | --target ${{matrix.cmake.build_target}} 41 | -v -j2 42 | - name: Test 43 | run: > 44 | cmake --build build 45 | --config ${{matrix.cmake.config}} 46 | --target ${{matrix.cmake.test_target}} 47 | -v 48 | - name: Install 49 | run: > 50 | cmake --build build 51 | --config ${{matrix.cmake.config}} 52 | --target ${{matrix.cmake.install_target}} 53 | -v 54 | 55 | amd64_windows_cmake: 56 | runs-on: ubuntu-latest 57 | needs: native 58 | steps: 59 | - uses: actions/checkout@v4 60 | -------------------------------------------------------------------------------- /.github/workflows/arm64_docker_cmake.yml: -------------------------------------------------------------------------------- 1 | # ref: https://github.com/docker-library/official-images 2 | name: arm64 Docker CMake 3 | 4 | on: [push, pull_request, workflow_dispatch] 5 | 6 | concurrency: 7 | group: ${{github.workflow}}-${{github.ref}} 8 | cancel-in-progress: true 9 | 10 | jobs: 11 | docker: 12 | strategy: 13 | matrix: 14 | distro: [ 15 | almalinux, 16 | alpine, 17 | debian, 18 | #fedora, # timeout 19 | #opensuse, # timeout 20 | rockylinux, 21 | ubuntu 22 | ] 23 | fail-fast: false 24 | name: arm64•${{matrix.distro}} 25 | runs-on: ubuntu-latest 26 | steps: 27 | - uses: actions/checkout@v4 28 | - name: Set up QEMU 29 | uses: docker/setup-qemu-action@v3 30 | - name: Check docker 31 | run: | 32 | docker info 33 | docker buildx ls 34 | - name: Build env image 35 | run: make --directory=ci arm64_${{matrix.distro}}_env 36 | - name: Build devel project 37 | run: make --directory=ci arm64_${{matrix.distro}}_devel 38 | - name: Build project 39 | run: make --directory=ci arm64_${{matrix.distro}}_build 40 | - name: Test project 41 | run: make --directory=ci arm64_${{matrix.distro}}_test 42 | 43 | - name: Build install env image 44 | run: make --directory=ci arm64_${{matrix.distro}}_install_env 45 | - name: Build install devel project 46 | run: make --directory=ci arm64_${{matrix.distro}}_install_devel 47 | - name: Build install project 48 | run: make --directory=ci arm64_${{matrix.distro}}_install_build 49 | - name: Test install project 50 | run: make --directory=ci arm64_${{matrix.distro}}_install_test 51 | 52 | arm64_docker_cmake: 53 | runs-on: ubuntu-latest 54 | needs: docker 55 | steps: 56 | - uses: actions/checkout@v4 57 | -------------------------------------------------------------------------------- /.github/workflows/arm64_macos_cmake.yml: -------------------------------------------------------------------------------- 1 | # ref: https://github.com/actions/runner-images 2 | name: arm64 MacOS CMake 3 | 4 | on: [push, pull_request, workflow_dispatch] 5 | 6 | concurrency: 7 | group: ${{github.workflow}}-${{github.ref}} 8 | cancel-in-progress: true 9 | 10 | # Building using the github runner environement directly. 11 | jobs: 12 | native: 13 | strategy: 14 | matrix: 15 | cmake: [ 16 | {name: "Xcode", generator: "Xcode", config: Release, build_target: ALL_BUILD, test_target: RUN_TESTS, install_target: install}, 17 | {name: "Make", generator: "Unix Makefiles", config: Release, build_target: all, test_target: test, install_target: install}, 18 | ] 19 | fail-fast: false 20 | name: MacOS•CMake(${{matrix.cmake.name}}) 21 | runs-on: macos-latest # M1 based runner 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Check CMake 25 | run: cmake --version 26 | - name: Configure 27 | run: > 28 | cmake -S. -Bbuild 29 | -G "${{matrix.cmake.generator}}" 30 | -DCMAKE_BUILD_TYPE=${{matrix.cmake.config}} 31 | -DCMAKE_INSTALL_PREFIX=install 32 | - name: Build 33 | run: > 34 | cmake --build build 35 | --config ${{matrix.cmake.config}} 36 | --target ${{matrix.cmake.build_target}} 37 | -v -j2 38 | - name: Test 39 | run: > 40 | CTEST_OUTPUT_ON_FAILURE=1 41 | cmake --build build 42 | --config ${{matrix.cmake.config}} 43 | --target ${{matrix.cmake.test_target}} 44 | -v 45 | - name: Install 46 | run: > 47 | cmake --build build 48 | --config ${{matrix.cmake.config}} 49 | --target ${{matrix.cmake.install_target}} 50 | -v 51 | 52 | arm64_macos_cmake: 53 | runs-on: ubuntu-latest 54 | needs: native 55 | steps: 56 | - uses: actions/checkout@v4 57 | -------------------------------------------------------------------------------- /.github/workflows/arm_toolchain_cmake.yml: -------------------------------------------------------------------------------- 1 | # ref: https://toolchains.bootlin.com/ 2 | name: arm Toolchain CMake 3 | 4 | on: [push, pull_request, workflow_dispatch] 5 | 6 | concurrency: 7 | group: ${{github.workflow}}-${{github.ref}} 8 | cancel-in-progress: true 9 | 10 | # Building using the github runner environement directly. 11 | jobs: 12 | arm: 13 | strategy: 14 | matrix: 15 | targets: [ 16 | # https://go.dev/doc/install/source#environment 17 | arm, # alias to armv7-eabihf 18 | armeb, # alias to armv7eb-eabihf 19 | armv7-eabihf, # bootlin 20 | armebv7-eabihf #bootlin 21 | ] 22 | fail-fast: false 23 | name: Linux•Toolchain ${{matrix.targets}} 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v4 27 | - name: Build env stage 28 | run: make --directory=ci toolchain_${{matrix.targets}}_env 29 | - name: Build devel stage 30 | run: make --directory=ci toolchain_${{matrix.targets}}_devel 31 | - name: Build toolchain stage 32 | run: make --directory=ci toolchain_${{matrix.targets}}_toolchain 33 | - name: Build build stage 34 | run: make --directory=ci toolchain_${{matrix.targets}}_build 35 | - name: Build Test stage 36 | run: make --directory=ci toolchain_${{matrix.targets}}_test 37 | -------------------------------------------------------------------------------- /.github/workflows/mips64_toolchain_cmake.yml: -------------------------------------------------------------------------------- 1 | # ref: https://toolchains.bootlin.com/ 2 | name: mips64 Toolchain CMake 3 | 4 | on: [push, pull_request, workflow_dispatch] 5 | 6 | concurrency: 7 | group: ${{github.workflow}}-${{github.ref}} 8 | cancel-in-progress: true 9 | 10 | # Building using the github runner environement directly. 11 | jobs: 12 | mips64: 13 | strategy: 14 | matrix: 15 | targets: [ 16 | # https://go.dev/doc/install/source#environment 17 | mips64, # alias to mips64-r6 18 | mips64el, # alias to mips64el-r6 19 | mips64-r6, # codescape 20 | mips64el-r6, # codescape 21 | ] 22 | fail-fast: false 23 | name: Linux•Toolchain ${{matrix.targets}} 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v4 27 | - name: Build env stage 28 | run: make --directory=ci toolchain_${{matrix.targets}}_env 29 | - name: Build devel stage 30 | run: make --directory=ci toolchain_${{matrix.targets}}_devel 31 | - name: Build toolchain stage 32 | run: make --directory=ci toolchain_${{matrix.targets}}_toolchain 33 | - name: Build build stage 34 | run: make --directory=ci toolchain_${{matrix.targets}}_build 35 | - name: Build Test stage 36 | run: make --directory=ci toolchain_${{matrix.targets}}_test 37 | -------------------------------------------------------------------------------- /.github/workflows/powerpc_toolchain_cmake.yml: -------------------------------------------------------------------------------- 1 | # ref: https://toolchains.bootlin.com/ 2 | name: powerpc Toolchain CMake 3 | 4 | on: [push, pull_request, workflow_dispatch] 5 | 6 | concurrency: 7 | group: ${{github.workflow}}-${{github.ref}} 8 | cancel-in-progress: true 9 | 10 | # Building using the github runner environement directly. 11 | jobs: 12 | powerpc: 13 | strategy: 14 | matrix: 15 | targets: [ 16 | # https://go.dev/doc/install/source#environment 17 | ppc64, # alias to ppc64-power8 18 | ppc64le, # alias ppc64le-power8 19 | ppc64-power8, # bootlin 20 | ppc64le-power8, # bootlin 21 | ] 22 | fail-fast: false 23 | name: Linux•Toolchain ${{matrix.targets}} 24 | runs-on: ubuntu-latest 25 | steps: 26 | - uses: actions/checkout@v4 27 | - name: Build env stage 28 | run: make --directory=ci toolchain_${{matrix.targets}}_env 29 | - name: Build devel stage 30 | run: make --directory=ci toolchain_${{matrix.targets}}_devel 31 | - name: Build toolchain stage 32 | run: make --directory=ci toolchain_${{matrix.targets}}_toolchain 33 | - name: Build build stage 34 | run: make --directory=ci toolchain_${{matrix.targets}}_build 35 | - name: Build Test stage 36 | run: make --directory=ci toolchain_${{matrix.targets}}_test 37 | -------------------------------------------------------------------------------- /.github/workflows/riscv64_docker_cmake.yml: -------------------------------------------------------------------------------- 1 | # ref: https://github.com/docker-library/official-images 2 | name: riscv64 Docker CMake 3 | 4 | on: [push, pull_request, workflow_dispatch] 5 | 6 | concurrency: 7 | group: ${{github.workflow}}-${{github.ref}} 8 | cancel-in-progress: true 9 | 10 | jobs: 11 | docker: 12 | strategy: 13 | matrix: 14 | distro: [ 15 | # almalinux, 16 | alpine, 17 | debian, # currently only unstable not latest 18 | # fedora, 19 | # opensuse, 20 | # rockylinux, 21 | #ubuntu, 22 | ] 23 | fail-fast: false 24 | name: riscv64•${{matrix.distro}} 25 | runs-on: ubuntu-latest 26 | steps: 27 | - uses: actions/checkout@v4 28 | - name: Set up QEMU 29 | uses: docker/setup-qemu-action@v3 30 | - name: Check docker 31 | run: | 32 | docker info 33 | docker buildx ls 34 | - name: Build env image 35 | run: make --directory=ci riscv64_${{matrix.distro}}_env 36 | - name: Build devel project 37 | run: make --directory=ci riscv64_${{matrix.distro}}_devel 38 | - name: Build project 39 | run: make --directory=ci riscv64_${{matrix.distro}}_build 40 | - name: Test project 41 | run: make --directory=ci riscv64_${{matrix.distro}}_test 42 | 43 | - name: Build install env image 44 | run: make --directory=ci riscv64_${{matrix.distro}}_install_env 45 | - name: Build install devel project 46 | run: make --directory=ci riscv64_${{matrix.distro}}_install_devel 47 | - name: Build install project 48 | run: make --directory=ci riscv64_${{matrix.distro}}_install_build 49 | - name: Test install project 50 | run: make --directory=ci riscv64_${{matrix.distro}}_install_test 51 | 52 | riscv64_docker_cmake: 53 | runs-on: ubuntu-latest 54 | needs: docker 55 | steps: 56 | - uses: actions/checkout@v4 57 | -------------------------------------------------------------------------------- /.github/workflows/riscv64_toolchain_cmake.yml: -------------------------------------------------------------------------------- 1 | # ref: https://toolchains.bootlin.com/ 2 | name: riscv64 Toolchain CMake 3 | 4 | on: [push, pull_request, workflow_dispatch] 5 | 6 | concurrency: 7 | group: ${{github.workflow}}-${{github.ref}} 8 | cancel-in-progress: true 9 | 10 | # Building using the github runner environement directly. 11 | jobs: 12 | riscv64: 13 | strategy: 14 | matrix: 15 | targets: [ 16 | # https://go.dev/doc/install/source#environment 17 | riscv64, # bootlin 18 | ] 19 | fail-fast: false 20 | name: Linux•Toolchain ${{matrix.targets}} 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Build env stage 25 | run: make --directory=ci toolchain_${{matrix.targets}}_env 26 | - name: Build devel stage 27 | run: make --directory=ci toolchain_${{matrix.targets}}_devel 28 | - name: Build toolchain stage 29 | run: make --directory=ci toolchain_${{matrix.targets}}_toolchain 30 | - name: Build build stage 31 | run: make --directory=ci toolchain_${{matrix.targets}}_build 32 | - name: Build Test stage 33 | run: make --directory=ci toolchain_${{matrix.targets}}_test 34 | -------------------------------------------------------------------------------- /.github/workflows/s390x_toolchain_cmake.yml: -------------------------------------------------------------------------------- 1 | # ref: https://toolchains.bootlin.com/ 2 | name: s390x Toolchain CMake 3 | 4 | on: [push, pull_request, workflow_dispatch] 5 | 6 | concurrency: 7 | group: ${{github.workflow}}-${{github.ref}} 8 | cancel-in-progress: true 9 | 10 | # Building using the github runner environement directly. 11 | jobs: 12 | s390x: 13 | strategy: 14 | matrix: 15 | targets: [ 16 | # https://go.dev/doc/install/source#environment 17 | s390x, # bootlin 18 | ] 19 | fail-fast: false 20 | name: Linux•Toolchain ${{matrix.targets}} 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v4 24 | - name: Build env stage 25 | run: make --directory=ci toolchain_${{matrix.targets}}_env 26 | - name: Build devel stage 27 | run: make --directory=ci toolchain_${{matrix.targets}}_devel 28 | - name: Build toolchain stage 29 | run: make --directory=ci toolchain_${{matrix.targets}}_toolchain 30 | - name: Build build stage 31 | run: make --directory=ci toolchain_${{matrix.targets}}_build 32 | - name: Build Test stage 33 | run: make --directory=ci toolchain_${{matrix.targets}}_test 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | build*/ 3 | export/ 4 | cache/ 5 | 6 | .vagrant/ 7 | 8 | # IDE 9 | .vs/ 10 | .cache/ 11 | # Kdevelop 12 | .kdev4/ 13 | *.kdev4 14 | # vim 15 | compile_commands.json 16 | *.swp 17 | *.user 18 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of authors for copyright purposes. 2 | # This file is distinct from the CONTRIBUTORS files. 3 | # See the latter for an explanation. 4 | 5 | # Names should be added to this file as one of 6 | # Organization's name 7 | # Individual's name 8 | # Individual's name 9 | # See CONTRIBUTORS for the meaning of multiple email addresses. 10 | 11 | # Please keep the list sorted. 12 | Google LLC 13 | Mizux Seiha 14 | -------------------------------------------------------------------------------- /Bar/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(Bar) 2 | target_sources(Bar 3 | PRIVATE 4 | include/bar/Bar.hpp 5 | src/Bar.cpp) 6 | target_include_directories(Bar 7 | PUBLIC 8 | $ 9 | $) 10 | target_compile_features(Bar PUBLIC cxx_std_20) 11 | set_target_properties(Bar PROPERTIES 12 | VERSION ${PROJECT_VERSION} 13 | POSITION_INDEPENDENT_CODE ON 14 | PUBLIC_HEADER include/bar/Bar.hpp) 15 | if(APPLE) 16 | set_target_properties(Bar PROPERTIES INSTALL_RPATH "@loader_path") 17 | elseif(UNIX) 18 | set_target_properties(Bar PROPERTIES INSTALL_RPATH "$ORIGIN") 19 | endif() 20 | target_link_libraries(Bar PRIVATE absl::log) 21 | add_library(${PROJECT_NAMESPACE}::Bar ALIAS Bar) 22 | 23 | add_subdirectory(tests) 24 | 25 | # Install 26 | include(GNUInstallDirs) 27 | install(TARGETS Bar 28 | EXPORT ${PROJECT_NAME}Targets 29 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/bar 30 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 31 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 32 | #RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 33 | ) 34 | -------------------------------------------------------------------------------- /Bar/include/bar/Bar.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | //! @namespace bar The Bar namespace 8 | namespace bar { 9 | //! @defgroup StringVector Vector of String usage. 10 | //! @{ 11 | /*! @brief Test returning a vector of string. 12 | * @param level Scope level. 13 | * @return A vector of string.*/ 14 | std::vector stringVectorOutput(int level); 15 | /*! @brief Test using a vector of string passed by value. 16 | * @param data Input data. 17 | * @return The size of the data vector.*/ 18 | int stringVectorInput(std::vector data); 19 | /*! @brief Test using a vector of string passed by const ref. 20 | * @param data Input data. 21 | * @return The size of the data vector.*/ 22 | int stringVectorRefInput(const std::vector& data); 23 | //! @} 24 | 25 | //! @defgroup StringJaggedArray Vector of Vector of String usage. 26 | //! @{ 27 | /*! @brief Test returning a jagged array of string. 28 | * @param level Scope level. 29 | * @return A jagged array of string.*/ 30 | std::vector> stringJaggedArrayOutput(int level); 31 | /*! @brief Test using a jagged array of string passed by value. 32 | * @param data Input data. 33 | * @return The size of the data outer vector.*/ 34 | int stringJaggedArrayInput(std::vector> data); 35 | /*! @brief Test using a jagged array of string passed by const ref. 36 | * @param data Input data. 37 | * @return The size of the data outer vector.*/ 38 | int stringJaggedArrayRefInput(const std::vector>& data); 39 | //! @} 40 | 41 | //! @defgroup PairVector Vector of Pair usage. 42 | //! @{ 43 | /*! @brief Test returning a vector of pair. 44 | * @param level Scope level. 45 | * @return A vector of pair.*/ 46 | std::vector> pairVectorOutput(int level); 47 | /*! @brief Test using a vector of pair passed by value. 48 | * @param data Input data. 49 | * @return The size of the data vector.*/ 50 | int pairVectorInput(std::vector> data); 51 | /*! @brief Test using a vector of pair passed by const ref. 52 | * @param data Input data. 53 | * @return The size of the data vector.*/ 54 | int pairVectorRefInput(const std::vector>& data); 55 | //! @} 56 | 57 | //! @defgroup PairJaggedArray Jagged array of Pair usage. 58 | //! @{ 59 | /*! @brief Test returning a jagged array of pair. 60 | * @param level Scope level. 61 | * @return A jagged array of pair.*/ 62 | std::vector>> pairJaggedArrayOutput(int level); 63 | /*! @brief Test using a jagged array of pair passed by value. 64 | * @param data Input data. 65 | * @return The size of the data outer vector.*/ 66 | int pairJaggedArrayInput(std::vector>> data); 67 | /*! @brief Test using a jagged of pair passed by const ref. 68 | * @param data Input data. 69 | * @return The size of the data outer vector.*/ 70 | int pairJaggedArrayRefInput(const std::vector>>& data); 71 | //! @} 72 | 73 | //! @defgroup FreeFunction Free function usage. 74 | //! @{ 75 | /*! @brief Free function in bar namespace. 76 | * @param level Scope level.*/ 77 | void freeFunction(int level); 78 | /*! @brief Free function in bar namespace. 79 | * @param level Scope level.*/ 80 | void freeFunction(int64_t level); 81 | //! @} 82 | 83 | //! @brief Class Bar. 84 | class Bar { 85 | public: 86 | //! @defgroup StaticMembers Static members 87 | //! @{ 88 | 89 | /*! @brief Static method of Bar class. 90 | * @param[in] level Scope level.*/ 91 | static void staticFunction(int level); 92 | 93 | /*! @brief Static method of Bar class. 94 | * @param[in] level Scope level.*/ 95 | static void staticFunction(int64_t level); 96 | 97 | //! @} 98 | 99 | //! @defgroup IntegerMembers Integer members 100 | //! @{ 101 | 102 | /*! @brief Method (getter) of Bar class. 103 | * @return A member value.*/ 104 | int getInt() const; 105 | /*! @brief Method (setter) of Bar class. 106 | * @param[in] input A member value.*/ 107 | void setInt(int input); 108 | 109 | //! @} 110 | 111 | //! @defgroup Int64Members Long Integer members 112 | //! @{ 113 | 114 | /*! @brief Method (getter) of Bar class. 115 | * @return A member value.*/ 116 | int64_t getInt64() const; 117 | /*! @brief Method (setter) of Bar class. 118 | * @param[in] input A member value.*/ 119 | void setInt64(int64_t input); 120 | 121 | //! @} 122 | 123 | //! @brief Print object for debug. 124 | std::string operator()() const; 125 | 126 | private: 127 | int _intValue = 0; 128 | int64_t _int64Value = 0; 129 | }; 130 | } // namespace bar 131 | -------------------------------------------------------------------------------- /Bar/src/Bar.cpp: -------------------------------------------------------------------------------- 1 | #include "bar/Bar.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "absl/log/log.h" 8 | 9 | namespace bar { 10 | std::vector stringVectorOutput(int level) { 11 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "()" << std::endl; 12 | std::vector result(level, std::to_string(level)); 13 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "()" << std::endl; 14 | return result; 15 | } 16 | 17 | int stringVectorInput(std::vector data) { 18 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 19 | LOG(INFO) << "{"; 20 | for (const auto& item : data) { 21 | LOG(INFO) << item << ", "; 22 | } 23 | LOG(INFO) << "}" << std::endl; 24 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 25 | return data.size(); 26 | } 27 | 28 | int stringVectorRefInput(const std::vector& data) { 29 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 30 | LOG(INFO) << "{"; 31 | for (const auto& item : data) { 32 | LOG(INFO) << item << ", "; 33 | } 34 | LOG(INFO) << "}" << std::endl; 35 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 36 | return data.size(); 37 | } 38 | 39 | std::vector> stringJaggedArrayOutput(int level) { 40 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "()" << std::endl; 41 | std::vector> result; 42 | result.reserve(level); 43 | for (int i = 1; i <= level; ++i) { 44 | result.emplace_back(std::vector(i, std::to_string(i))); 45 | } 46 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "()" << std::endl; 47 | return result; 48 | } 49 | 50 | int stringJaggedArrayInput(std::vector> data) { 51 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 52 | LOG(INFO) << "{"; 53 | for (const auto& inner : data) { 54 | LOG(INFO) << "{"; 55 | for (const auto& item : inner) { 56 | LOG(INFO) << item << ", "; 57 | } 58 | LOG(INFO) << "}, "; 59 | } 60 | LOG(INFO) << "}" << std::endl; 61 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 62 | return data.size(); 63 | } 64 | 65 | int stringJaggedArrayRefInput(const std::vector>& data) { 66 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 67 | LOG(INFO) << "{"; 68 | for (const auto& inner : data) { 69 | LOG(INFO) << "{"; 70 | for (const auto& item : inner) { 71 | LOG(INFO) << item << ", "; 72 | } 73 | LOG(INFO) << "}, "; 74 | } 75 | LOG(INFO) << "}" << std::endl; 76 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 77 | return data.size(); 78 | } 79 | 80 | std::vector> pairVectorOutput(int level) { 81 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "()" << std::endl; 82 | std::vector> result(level, std::make_pair(level, level)); 83 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "()" << std::endl; 84 | return result; 85 | } 86 | 87 | int pairVectorInput(std::vector> data) { 88 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 89 | LOG(INFO) << "{"; 90 | for (const auto& item : data) { 91 | LOG(INFO) << "[" << item.first << "," << item.second << "], "; 92 | } 93 | LOG(INFO) << "}" << std::endl; 94 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 95 | return data.size(); 96 | } 97 | 98 | int pairVectorRefInput(const std::vector>& data) { 99 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 100 | LOG(INFO) << "{"; 101 | for (const auto& item : data) { 102 | LOG(INFO) << "[" << item.first << "," << item.second << "], "; 103 | } 104 | LOG(INFO) << "}" << std::endl; 105 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 106 | return data.size(); 107 | } 108 | 109 | std::vector>> pairJaggedArrayOutput(int level) { 110 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "()" << std::endl; 111 | std::vector>> result; 112 | result.reserve(level); 113 | for (int i = 1; i <= level; ++i) { 114 | result.emplace_back(std::vector>(i, std::make_pair(i, i))); 115 | } 116 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "()" << std::endl; 117 | return result; 118 | } 119 | 120 | int pairJaggedArrayInput(std::vector>> data) { 121 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 122 | LOG(INFO) << "{"; 123 | for (const auto& inner : data) { 124 | LOG(INFO) << "{"; 125 | for (const auto& item : inner) { 126 | LOG(INFO) << "[" << item.first << "," << item.second << "], "; 127 | } 128 | LOG(INFO) << "}, "; 129 | } 130 | LOG(INFO) << "}" << std::endl; 131 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 132 | return data.size(); 133 | } 134 | 135 | int pairJaggedArrayRefInput(const std::vector>>& data) { 136 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 137 | LOG(INFO) << "{"; 138 | for (const auto& inner : data) { 139 | LOG(INFO) << "{"; 140 | for (const auto& item : inner) { 141 | LOG(INFO) << "[" << item.first << "," << item.second << "], "; 142 | } 143 | LOG(INFO) << "}, "; 144 | } 145 | LOG(INFO) << "}" << std::endl; 146 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 147 | return data.size(); 148 | } 149 | 150 | void freeFunction(int level) { 151 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "(int)" << std::endl; 152 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "(int)" << std::endl; 153 | } 154 | 155 | void freeFunction(int64_t level) { 156 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "(int64_t)" << std::endl; 157 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "(int64_t)" << std::endl; 158 | } 159 | 160 | void Bar::staticFunction(int level) { 161 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "(int)" << std::endl; 162 | freeFunction(level + 1); 163 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "(int)" << std::endl; 164 | } 165 | 166 | void Bar::staticFunction(int64_t level) { 167 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "(int64_t)" << std::endl; 168 | freeFunction(level + 1); 169 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "(int64_t)" << std::endl; 170 | } 171 | 172 | int Bar::getInt() const { 173 | return _intValue; 174 | } 175 | 176 | void Bar::setInt(int input) { 177 | _intValue = input; 178 | } 179 | 180 | int64_t Bar::getInt64() const { 181 | return _int64Value; 182 | } 183 | 184 | void Bar::setInt64(int64_t input) { 185 | _int64Value = input; 186 | } 187 | 188 | std::string Bar::operator()() const { 189 | return std::string{"\"Bar\":{\"int\":"} + std::to_string(_intValue) + 190 | ",\"int64\":" + std::to_string(_int64Value) + "}"; 191 | } 192 | 193 | namespace { 194 | void* kVar = [] { 195 | std::cerr << "kBar" << std::endl; 196 | return nullptr; 197 | }(); 198 | } // namespace 199 | 200 | } // namespace bar 201 | -------------------------------------------------------------------------------- /Bar/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(NOT BUILD_TESTING) 2 | return() 3 | endif() 4 | 5 | add_executable(bar_test) 6 | target_sources(bar_test PRIVATE bar_test.cpp) 7 | target_include_directories(bar_test PUBLIC 8 | $) 9 | target_compile_features(bar_test PRIVATE cxx_std_20) 10 | set_target_properties(bar_test PROPERTIES 11 | VERSION ${PROJECT_VERSION} 12 | POSITION_INDEPENDENT_CODE ON 13 | ) 14 | if(APPLE) 15 | set_target_properties(bar_test PROPERTIES 16 | INSTALL_RPATH "@loader_path/../${CMAKE_INSTALL_LIBDIR};@loader_path") 17 | elseif(UNIX) 18 | set_target_properties(bar_test PROPERTIES 19 | INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}:$ORIGIN") 20 | endif() 21 | target_link_libraries(bar_test PRIVATE 22 | GTest::gtest_main 23 | ${PROJECT_NAMESPACE}::Bar) 24 | 25 | add_test(NAME bar_test COMMAND bar_test) 26 | -------------------------------------------------------------------------------- /Bar/tests/bar_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace bar { 9 | 10 | TEST(BarTest, FreeFunction) { 11 | EXPECT_NO_THROW(freeFunction(42)); 12 | EXPECT_NO_THROW(freeFunction(int64_t{42})); 13 | } 14 | 15 | TEST(BarTest, StringVectorOutput) { 16 | std::vector result; 17 | ASSERT_NO_THROW(result = stringVectorOutput(8)); 18 | EXPECT_EQ(result.size(), 8); 19 | for (const auto& it : result) { 20 | EXPECT_EQ(it, std::to_string(8)); 21 | } 22 | } 23 | 24 | TEST(BarTest, StringVectorValueInput) { 25 | const std::vector data{"1", "2", "3", "4", "5"}; 26 | int size = 0; 27 | ASSERT_NO_THROW(size = stringVectorInput(data)); 28 | EXPECT_EQ(size, 5); 29 | } 30 | 31 | TEST(BarTest, StringVectorRefInput) { 32 | const std::vector data{"1", "2", "3", "4", "5"}; 33 | int size = 0; 34 | ASSERT_NO_THROW(size = stringVectorRefInput(data)); 35 | EXPECT_EQ(size, 5); 36 | } 37 | 38 | TEST(BarTest, StringJaggedArrayOutput) { 39 | std::vector> result; 40 | ASSERT_NO_THROW(result = stringJaggedArrayOutput(8)); 41 | EXPECT_EQ(result.size(), 8); 42 | for (std::size_t i = 0; i < result.size(); ++i) { 43 | EXPECT_EQ(i + 1, result[i].size()); 44 | } 45 | for (std::size_t i = 1; i <= result.size(); ++i) { 46 | const auto& inner = result[i - 1]; 47 | for (const auto& it : inner) { 48 | EXPECT_EQ(it, std::to_string(i)); 49 | } 50 | } 51 | } 52 | 53 | TEST(BarTest, StringJaggedArrayValueInput) { 54 | const std::vector> data{{"1", "2", "3"}, {"4", "5"}}; 55 | int size = 0; 56 | ASSERT_NO_THROW(size = stringJaggedArrayInput(data)); 57 | EXPECT_EQ(size, 2); 58 | } 59 | 60 | TEST(BarTest, StringJaggedArrayRefInput) { 61 | const std::vector> data{{"1", "2", "3"}, {"4", "5"}}; 62 | int size = 0; 63 | ASSERT_NO_THROW(size = stringJaggedArrayRefInput(data)); 64 | EXPECT_EQ(size, 2); 65 | } 66 | 67 | TEST(BarTest, PairVectorOutput) { 68 | std::vector> result; 69 | ASSERT_NO_THROW(result = pairVectorOutput(8)); 70 | EXPECT_EQ(result.size(), 8); 71 | for (const auto& it : result) { 72 | EXPECT_EQ(it.first, 8); 73 | EXPECT_EQ(it.second, 8); 74 | } 75 | } 76 | 77 | TEST(BarTest, PairVectorValueInput) { 78 | const std::vector> data{{1, 2}, {3, 4}, {5, 6}}; 79 | int size = 0; 80 | ASSERT_NO_THROW(size = pairVectorInput(data)); 81 | EXPECT_EQ(size, 3); 82 | } 83 | 84 | TEST(BarTest, PairVectorRefInput) { 85 | const std::vector> data{{1, 2}, {3, 4}, {5, 6}}; 86 | int size = 0; 87 | ASSERT_NO_THROW(size = pairVectorRefInput(data)); 88 | EXPECT_EQ(size, 3); 89 | } 90 | 91 | TEST(BarTest, PairJaggedArrayOutput) { 92 | std::vector>> result; 93 | ASSERT_NO_THROW(result = pairJaggedArrayOutput(8)); 94 | EXPECT_EQ(result.size(), 8); 95 | for (std::size_t i = 0; i < result.size(); ++i) { 96 | EXPECT_EQ(i + 1, result[i].size()); 97 | } 98 | for (int i = 1; i <= static_cast(result.size()); ++i) { 99 | const auto& inner = result[i - 1]; 100 | for (const auto& it : inner) { 101 | EXPECT_EQ(it, std::make_pair(i, i)); 102 | } 103 | } 104 | } 105 | 106 | TEST(BarTest, PairJaggedArrayValueInput) { 107 | std::vector>> data{{{1, 1}, {2, 2}, {3, 3}}, {{4, 4}, {5, 5}}}; 108 | int size = 0; 109 | ASSERT_NO_THROW(size = pairJaggedArrayInput(data)); 110 | EXPECT_EQ(size, 2); 111 | } 112 | 113 | TEST(BarTest, PairJaggedArrayRefInput) { 114 | std::vector>> data{{{1, 1}, {2, 2}, {3, 3}}, {{4, 4}, {5, 5}}}; 115 | int size = 0; 116 | ASSERT_NO_THROW(size = pairJaggedArrayRefInput(data)); 117 | EXPECT_EQ(size, 2); 118 | } 119 | 120 | TEST(BarTest, StaticMethods) { 121 | EXPECT_NO_THROW(Bar::staticFunction(42)); 122 | EXPECT_NO_THROW(Bar::staticFunction(int64_t{42})); 123 | } 124 | 125 | TEST(BarTest, Constructor) { 126 | Bar* b = new Bar(); 127 | EXPECT_NE(b, nullptr); 128 | } 129 | 130 | TEST(BarTest, IntMethods) { 131 | Bar bar; 132 | ASSERT_NO_THROW(bar.setInt(42)); 133 | EXPECT_EQ(42, bar.getInt()); 134 | } 135 | 136 | TEST(BarTest, Int64Methods) { 137 | Bar bar; 138 | ASSERT_NO_THROW(bar.setInt64(31)); 139 | EXPECT_EQ(31, bar.getInt64()); 140 | } 141 | 142 | TEST(BarTest, PrintMethod) { 143 | Bar bar; 144 | std::string str(""); 145 | ASSERT_NO_THROW(str = bar()); 146 | EXPECT_EQ("\"Bar\":{\"int\":0,\"int64\":0}", str); 147 | } 148 | 149 | } // namespace bar 150 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file is just an orchestration 2 | cmake_minimum_required(VERSION 3.16..3.31) 3 | list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 4 | 5 | # Enable output of compile commands during generation. 6 | option(CMAKE_EXPORT_COMPILE_COMMANDS "Export compile command" ON) 7 | 8 | project(CMakeCpp VERSION 1.0.0 LANGUAGES CXX) 9 | set(PROJECT_NAMESPACE CMakeCpp) 10 | message(STATUS "${PROJECT_NAME} version: ${PROJECT_VERSION}") 11 | #message(STATUS "major: ${PROJECT_VERSION_MAJOR}") 12 | #message(STATUS "minor: ${PROJECT_VERSION_MINOR}") 13 | #message(STATUS "patch: ${PROJECT_VERSION_PATCH}") 14 | 15 | message(STATUS "system name: ${CMAKE_SYSTEM_NAME}") 16 | # Set max os target version. 17 | set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15) 18 | 19 | set(CMAKE_CXX_STANDARD 20) 20 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 21 | set(CMAKE_CXX_EXTENSIONS OFF) 22 | 23 | # Default Build Type to be Release 24 | get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) 25 | if(isMultiConfig) 26 | if(NOT CMAKE_CONFIGURATION_TYPES) 27 | set(CMAKE_CONFIGURATION_TYPES "Release;Debug" CACHE STRING 28 | "Choose the type of builds, options are: Debug Release RelWithDebInfo MinSizeRel. (default: Release;Debug)" 29 | FORCE) 30 | endif() 31 | message(STATUS "Configuration types: ${CMAKE_CONFIGURATION_TYPES}") 32 | else() 33 | if(NOT CMAKE_BUILD_TYPE) 34 | set(CMAKE_BUILD_TYPE "Release" CACHE STRING 35 | "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel. (default: Release)" 36 | FORCE) 37 | endif() 38 | message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") 39 | endif() 40 | 41 | # Layout build dir like install dir 42 | include(GNUInstallDirs) 43 | if(UNIX) 44 | option(BUILD_SHARED_LIBS "Build shared libraries (.so or .dylib)." ON) 45 | set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) 46 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) 47 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) 48 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) 49 | # for multi-config build system (e.g. Xcode, Ninja Multi-Config) 50 | foreach(OutputConfig IN LISTS CMAKE_CONFIGURATION_TYPES) 51 | string(TOUPPER ${OutputConfig} OUTPUTCONFIG) 52 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OutputConfig}/${CMAKE_INSTALL_LIBDIR}) 53 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OutputConfig}/${CMAKE_INSTALL_LIBDIR}) 54 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OutputConfig}/${CMAKE_INSTALL_BINDIR}) 55 | endforeach() 56 | else() 57 | # Currently Only support static build for windows 58 | option(BUILD_SHARED_LIBS "Build shared libraries (.dll)." OFF) 59 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) 60 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) 61 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}) 62 | # for multi-config builds (e.g. msvc) 63 | foreach(OutputConfig IN LISTS CMAKE_CONFIGURATION_TYPES) 64 | string(TOUPPER ${OutputConfig} OUTPUTCONFIG) 65 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OutputConfig}/${CMAKE_INSTALL_BINDIR}) 66 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OutputConfig}/${CMAKE_INSTALL_BINDIR}) 67 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${OutputConfig}/${CMAKE_INSTALL_BINDIR}) 68 | endforeach() 69 | endif() 70 | 71 | if(MSVC AND BUILD_SHARED_LIBS) 72 | set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) 73 | endif() 74 | 75 | # Disable CTest targets 76 | set_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1) 77 | include(CTest) 78 | 79 | option(BUILD_ZLIB "Build the ZLIB dependency Library" ON) 80 | message(STATUS "Build ZLIB: ${BUILD_ZLIB}") 81 | 82 | option(BUILD_absl "Build the abseil-cpp dependency Library" ON) 83 | message(STATUS "Build abseil-cpp: ${BUILD_absl}") 84 | 85 | option(BUILD_Protobuf "Build the Protobuf dependency Library" ON) 86 | message(STATUS "Build protobuf: ${BUILD_Protobuf}") 87 | 88 | option(BUILD_re2 "Build the re2 dependency Library" ON) 89 | message(STATUS "Build re2: ${BUILD_re2}") 90 | 91 | if(BUILD_TESTING) 92 | option(BUILD_googletest "Build googletest" ON) 93 | option(BUILD_benchmark "Build benchmark" ON) 94 | else() 95 | set(BUILD_googletest OFF) 96 | set(BUILD_benchmark OFF) 97 | endif() 98 | message(STATUS "Build googletest: ${BUILD_googletest}") 99 | message(STATUS "Build benchmark: ${BUILD_benchmark}") 100 | 101 | # Find system deps 102 | include(system_deps) 103 | 104 | # Build Needed dependencies 105 | add_subdirectory(cmake/dependencies dependencies) 106 | 107 | include(host) 108 | # verify deps 109 | include(check_deps) 110 | 111 | include(cpp) 112 | 113 | ## Examples 114 | option(BUILD_EXAMPLES "Build examples" ON) 115 | message(STATUS "Build examples: ${BUILD_EXAMPLES}") 116 | add_subdirectory(examples) 117 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution, 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This is the official list of people who can contribute 2 | # (and typically have contributed) code to this repository. 3 | # The AUTHORS file lists the copyright holders; this file 4 | # lists people. For example, Google employees are listed here 5 | # but not in AUTHORS, because Google holds the copyright. 6 | # 7 | # The submission process automatically checks to make sure 8 | # that people submitting code are listed in this file (by email address). 9 | # 10 | # Names should be added to this file only after verifying that 11 | # the individual or the individual's organization has agreed to 12 | # the appropriate Contributor License Agreement, found here: 13 | # 14 | # http://code.google.com/legal/individual-cla-v1.0.html 15 | # http://code.google.com/legal/corporate-cla-v1.0.html 16 | # 17 | # The agreement for individuals can be filled out on the web. 18 | # 19 | # When adding J Random Contributor's name to this file, 20 | # either J's name or J's organization's name should be 21 | # added to the AUTHORS file, depending on whether the 22 | # individual or corporate CLA was used. 23 | 24 | # Names should be added to this file like so: 25 | # Individual's name 26 | # Individual's name 27 | # 28 | # An entry with multiple email addresses specifies that the 29 | # first address should be used in the submit logs and 30 | # that the other addresses should be recognized as the 31 | # same person when interacting with Gerrit. 32 | 33 | # Please keep the list sorted. 34 | 35 | -------------------------------------------------------------------------------- /Foo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(Foo) 2 | target_sources(Foo 3 | PRIVATE 4 | include/foo/Foo.hpp 5 | src/Foo.cpp) 6 | target_include_directories(Foo 7 | PUBLIC 8 | $ 9 | $) 10 | target_compile_features(Foo PUBLIC cxx_std_20) 11 | set_target_properties(Foo PROPERTIES 12 | VERSION ${PROJECT_VERSION} 13 | POSITION_INDEPENDENT_CODE ON 14 | PUBLIC_HEADER include/foo/Foo.hpp) 15 | if(APPLE) 16 | set_target_properties(Foo PROPERTIES INSTALL_RPATH "@loader_path") 17 | elseif(UNIX) 18 | set_target_properties(Foo PROPERTIES INSTALL_RPATH "$ORIGIN") 19 | endif() 20 | target_link_libraries(Foo PRIVATE absl::log) 21 | add_library(${PROJECT_NAMESPACE}::Foo ALIAS Foo) 22 | 23 | add_subdirectory(tests) 24 | 25 | # Install 26 | include(GNUInstallDirs) 27 | install(TARGETS Foo 28 | EXPORT ${PROJECT_NAME}Targets 29 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/foo 30 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 31 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 32 | #RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 33 | ) 34 | -------------------------------------------------------------------------------- /Foo/include/foo/Foo.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | //! @namespace foo The Foo namespace 8 | namespace foo { 9 | //! @defgroup StringVector Vector of String usage. 10 | //! @{ 11 | /*! @brief Test returning a vector of string. 12 | * @param level Scope level. 13 | * @return A vector of string.*/ 14 | std::vector stringVectorOutput(int level); 15 | /*! @brief Test using a vector of string passed by value. 16 | * @param data Input data. 17 | * @return The size of the data vector.*/ 18 | int stringVectorInput(std::vector data); 19 | /*! @brief Test using a vector of string passed by const ref. 20 | * @param data Input data. 21 | * @return The size of the data vector.*/ 22 | int stringVectorRefInput(const std::vector& data); 23 | //! @} 24 | 25 | //! @defgroup StringJaggedArray Vector of Vector of String usage. 26 | //! @{ 27 | /*! @brief Test returning a jagged array of string. 28 | * @param level Scope level. 29 | * @return A jagged array of string.*/ 30 | std::vector> stringJaggedArrayOutput(int level); 31 | /*! @brief Test using a jagged array of string passed by value. 32 | * @param data Input data. 33 | * @return The size of the data outer vector.*/ 34 | int stringJaggedArrayInput(std::vector> data); 35 | /*! @brief Test using a jagged array of string passed by const ref. 36 | * @param data Input data. 37 | * @return The size of the data outer vector.*/ 38 | int stringJaggedArrayRefInput(const std::vector>& data); 39 | //! @} 40 | 41 | //! @defgroup PairVector Vector of Pair usage. 42 | //! @{ 43 | /*! @brief Test returning a vector of pair. 44 | * @param level Scope level. 45 | * @return A vector of pair.*/ 46 | std::vector> pairVectorOutput(int level); 47 | /*! @brief Test using a vector of pair passed by value. 48 | * @param data Input data. 49 | * @return The size of the data vector.*/ 50 | int pairVectorInput(std::vector> data); 51 | /*! @brief Test using a vector of pair passed by const ref. 52 | * @param data Input data. 53 | * @return The size of the data vector.*/ 54 | int pairVectorRefInput(const std::vector>& data); 55 | //! @} 56 | 57 | //! @defgroup PairJaggedArray Jagged array of Pair usage. 58 | //! @{ 59 | /*! @brief Test returning a jagged array of pair. 60 | * @param level Scope level. 61 | * @return A jagged array of pair.*/ 62 | std::vector>> pairJaggedArrayOutput(int level); 63 | /*! @brief Test using a jagged array of pair passed by value. 64 | * @param data Input data. 65 | * @return The size of the data outer vector.*/ 66 | int pairJaggedArrayInput(std::vector>> data); 67 | /*! @brief Test using a jagged of pair passed by const ref. 68 | * @param data Input data. 69 | * @return The size of the data outer vector.*/ 70 | int pairJaggedArrayRefInput(const std::vector>>& data); 71 | //! @} 72 | 73 | //! @defgroup FreeFunction Free function usage. 74 | //! @{ 75 | /*! @brief Free function in foo namespace. 76 | * @param level Scope level.*/ 77 | void freeFunction(int level); 78 | /*! @brief Free function in foo namespace. 79 | * @param level Scope level.*/ 80 | void freeFunction(int64_t level); 81 | //! @} 82 | 83 | //! @brief Class Foo. 84 | class Foo { 85 | public: 86 | //! @defgroup StaticMembers Static members 87 | //! @{ 88 | 89 | /*! @brief Static method of Foo class. 90 | * @param[in] level Scope level.*/ 91 | static void staticFunction(int level); 92 | 93 | /*! @brief Static method of Foo class. 94 | * @param[in] level Scope level.*/ 95 | static void staticFunction(int64_t level); 96 | 97 | //! @} 98 | 99 | //! @defgroup IntegerMembers Integer members 100 | //! @{ 101 | 102 | /*! @brief Method (getter) of Foo class. 103 | * @return A member value.*/ 104 | int getInt() const; 105 | /*! @brief Method (setter) of Foo class. 106 | * @param[in] input A member value.*/ 107 | void setInt(int input); 108 | 109 | //! @} 110 | 111 | //! @defgroup Int64Members Long Integer members 112 | //! @{ 113 | 114 | /*! @brief Method (getter) of Foo class. 115 | * @return A member value.*/ 116 | int64_t getInt64() const; 117 | /*! @brief Method (setter) of Foo class. 118 | * @param[in] input A member value.*/ 119 | void setInt64(int64_t input); 120 | 121 | //! @} 122 | 123 | //! @brief Print object for debug. 124 | std::string operator()() const; 125 | 126 | private: 127 | int _intValue = 0; 128 | int64_t _int64Value = 0; 129 | }; 130 | } // namespace foo 131 | -------------------------------------------------------------------------------- /Foo/src/Foo.cpp: -------------------------------------------------------------------------------- 1 | #include "foo/Foo.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | namespace foo { 10 | std::vector stringVectorOutput(int level) { 11 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "()" << std::endl; 12 | std::vector result(level, std::to_string(level)); 13 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "()" << std::endl; 14 | return result; 15 | } 16 | 17 | int stringVectorInput(std::vector data) { 18 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 19 | LOG(INFO) << "{"; 20 | for (const auto& item : data) { 21 | LOG(INFO) << item << ", "; 22 | } 23 | LOG(INFO) << "}" << std::endl; 24 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 25 | return data.size(); 26 | } 27 | 28 | int stringVectorRefInput(const std::vector& data) { 29 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 30 | LOG(INFO) << "{"; 31 | for (const auto& item : data) { 32 | LOG(INFO) << item << ", "; 33 | } 34 | LOG(INFO) << "}" << std::endl; 35 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 36 | return data.size(); 37 | } 38 | 39 | std::vector> stringJaggedArrayOutput(int level) { 40 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "()" << std::endl; 41 | std::vector> result; 42 | result.reserve(level); 43 | for (int i = 1; i <= level; ++i) { 44 | result.emplace_back(std::vector(i, std::to_string(i))); 45 | } 46 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "()" << std::endl; 47 | return result; 48 | } 49 | 50 | int stringJaggedArrayInput(std::vector> data) { 51 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 52 | LOG(INFO) << "{"; 53 | for (const auto& inner : data) { 54 | LOG(INFO) << "{"; 55 | for (const auto& item : inner) { 56 | LOG(INFO) << item << ", "; 57 | } 58 | LOG(INFO) << "}, "; 59 | } 60 | LOG(INFO) << "}" << std::endl; 61 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 62 | return data.size(); 63 | } 64 | 65 | int stringJaggedArrayRefInput(const std::vector>& data) { 66 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 67 | LOG(INFO) << "{"; 68 | for (const auto& inner : data) { 69 | LOG(INFO) << "{"; 70 | for (const auto& item : inner) { 71 | LOG(INFO) << item << ", "; 72 | } 73 | LOG(INFO) << "}, "; 74 | } 75 | LOG(INFO) << "}" << std::endl; 76 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 77 | return data.size(); 78 | } 79 | 80 | std::vector> pairVectorOutput(int level) { 81 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "()" << std::endl; 82 | std::vector> result(level, std::make_pair(level, level)); 83 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "()" << std::endl; 84 | return result; 85 | } 86 | 87 | int pairVectorInput(std::vector> data) { 88 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 89 | LOG(INFO) << "{"; 90 | for (const auto& item : data) { 91 | LOG(INFO) << "[" << item.first << "," << item.second << "], "; 92 | } 93 | LOG(INFO) << "}" << std::endl; 94 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 95 | return data.size(); 96 | } 97 | 98 | int pairVectorRefInput(const std::vector>& data) { 99 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 100 | LOG(INFO) << "{"; 101 | for (const auto& item : data) { 102 | LOG(INFO) << "[" << item.first << "," << item.second << "], "; 103 | } 104 | LOG(INFO) << "}" << std::endl; 105 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 106 | return data.size(); 107 | } 108 | 109 | std::vector>> pairJaggedArrayOutput(int level) { 110 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "()" << std::endl; 111 | std::vector>> result; 112 | result.reserve(level); 113 | for (int i = 1; i <= level; ++i) { 114 | result.emplace_back(std::vector>(i, std::make_pair(i, i))); 115 | } 116 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "()" << std::endl; 117 | return result; 118 | } 119 | 120 | int pairJaggedArrayInput(std::vector>> data) { 121 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 122 | LOG(INFO) << "{"; 123 | for (const auto& inner : data) { 124 | LOG(INFO) << "{"; 125 | for (const auto& item : inner) { 126 | LOG(INFO) << "[" << item.first << "," << item.second << "], "; 127 | } 128 | LOG(INFO) << "}, "; 129 | } 130 | LOG(INFO) << "}" << std::endl; 131 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 132 | return data.size(); 133 | } 134 | 135 | int pairJaggedArrayRefInput(const std::vector>>& data) { 136 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 137 | LOG(INFO) << "{"; 138 | for (const auto& inner : data) { 139 | LOG(INFO) << "{"; 140 | for (const auto& item : inner) { 141 | LOG(INFO) << "[" << item.first << "," << item.second << "], "; 142 | } 143 | LOG(INFO) << "}, "; 144 | } 145 | LOG(INFO) << "}" << std::endl; 146 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 147 | return data.size(); 148 | } 149 | 150 | void freeFunction(int level) { 151 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "(int)" << std::endl; 152 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "(int)" << std::endl; 153 | } 154 | 155 | void freeFunction(int64_t level) { 156 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "(int64_t)" << std::endl; 157 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "(int64_t)" << std::endl; 158 | } 159 | 160 | void Foo::staticFunction(int level) { 161 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "(int)" << std::endl; 162 | freeFunction(level + 1); 163 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "(int)" << std::endl; 164 | } 165 | 166 | void Foo::staticFunction(int64_t level) { 167 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "(int64_t)" << std::endl; 168 | freeFunction(level + 1); 169 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "(int64_t)" << std::endl; 170 | } 171 | 172 | int Foo::getInt() const { 173 | return _intValue; 174 | } 175 | 176 | void Foo::setInt(int input) { 177 | _intValue = input; 178 | } 179 | 180 | int64_t Foo::getInt64() const { 181 | return _int64Value; 182 | } 183 | 184 | void Foo::setInt64(int64_t input) { 185 | _int64Value = input; 186 | } 187 | 188 | std::string Foo::operator()() const { 189 | return std::string{"\"Foo\":{\"int\":"} + std::to_string(_intValue) + 190 | ",\"int64\":" + std::to_string(_int64Value) + "}"; 191 | } 192 | 193 | namespace { 194 | void* kVar = [] { 195 | std::cerr << "kFoo" << std::endl; 196 | return nullptr; 197 | }(); 198 | } // namespace 199 | 200 | } // namespace foo 201 | -------------------------------------------------------------------------------- /Foo/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(NOT BUILD_TESTING) 2 | return() 3 | endif() 4 | 5 | add_executable(foo_test) 6 | target_sources(foo_test PRIVATE foo_test.cpp) 7 | target_include_directories(foo_test PUBLIC 8 | $) 9 | target_compile_features(foo_test PRIVATE cxx_std_20) 10 | set_target_properties(foo_test PROPERTIES 11 | VERSION ${PROJECT_VERSION} 12 | POSITION_INDEPENDENT_CODE ON 13 | ) 14 | if(APPLE) 15 | set_target_properties(foo_test PROPERTIES 16 | INSTALL_RPATH "@loader_path/../${CMAKE_INSTALL_LIBDIR};@loader_path") 17 | elseif(UNIX) 18 | set_target_properties(foo_test PROPERTIES 19 | INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}:$ORIGIN") 20 | endif() 21 | target_link_libraries(foo_test PRIVATE 22 | GTest::gtest_main 23 | ${PROJECT_NAMESPACE}::Foo) 24 | 25 | add_test(NAME foo_test COMMAND foo_test) 26 | -------------------------------------------------------------------------------- /Foo/tests/foo_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace foo { 9 | 10 | TEST(FooTest, FreeFunction) { 11 | EXPECT_NO_THROW(freeFunction(42)); 12 | EXPECT_NO_THROW(freeFunction(int64_t{42})); 13 | } 14 | 15 | TEST(FooTest, StringVectorOutput) { 16 | std::vector result; 17 | ASSERT_NO_THROW(result = stringVectorOutput(8)); 18 | EXPECT_EQ(result.size(), 8); 19 | for (const auto& it : result) { 20 | EXPECT_EQ(it, std::to_string(8)); 21 | } 22 | } 23 | 24 | TEST(FooTest, StringVectorValueInput) { 25 | const std::vector data{"1", "2", "3", "4", "5"}; 26 | int size = 0; 27 | ASSERT_NO_THROW(size = stringVectorInput(data)); 28 | EXPECT_EQ(size, 5); 29 | } 30 | 31 | TEST(FooTest, StringVectorRefInput) { 32 | const std::vector data{"1", "2", "3", "4", "5"}; 33 | int size = 0; 34 | ASSERT_NO_THROW(size = stringVectorRefInput(data)); 35 | EXPECT_EQ(size, 5); 36 | } 37 | 38 | TEST(FooTest, StringJaggedArrayOutput) { 39 | std::vector> result; 40 | ASSERT_NO_THROW(result = stringJaggedArrayOutput(8)); 41 | EXPECT_EQ(result.size(), 8); 42 | for (std::size_t i = 0; i < result.size(); ++i) { 43 | EXPECT_EQ(i + 1, result[i].size()); 44 | } 45 | for (std::size_t i = 1; i <= result.size(); ++i) { 46 | const auto& inner = result[i - 1]; 47 | for (const auto& it : inner) { 48 | EXPECT_EQ(it, std::to_string(i)); 49 | } 50 | } 51 | } 52 | 53 | TEST(FooTest, StringJaggedArrayValueInput) { 54 | const std::vector> data{{"1", "2", "3"}, {"4", "5"}}; 55 | int size = 0; 56 | ASSERT_NO_THROW(size = stringJaggedArrayInput(data)); 57 | EXPECT_EQ(size, 2); 58 | } 59 | 60 | TEST(FooTest, StringJaggedArrayRefInput) { 61 | const std::vector> data{{"1", "2", "3"}, {"4", "5"}}; 62 | int size = 0; 63 | ASSERT_NO_THROW(size = stringJaggedArrayRefInput(data)); 64 | EXPECT_EQ(size, 2); 65 | } 66 | 67 | TEST(FooTest, PairVectorOutput) { 68 | std::vector> result; 69 | ASSERT_NO_THROW(result = pairVectorOutput(8)); 70 | EXPECT_EQ(result.size(), 8); 71 | for (const auto& it : result) { 72 | EXPECT_EQ(it.first, 8); 73 | EXPECT_EQ(it.second, 8); 74 | } 75 | } 76 | 77 | TEST(FooTest, PairVectorValueInput) { 78 | const std::vector> data{{1, 2}, {3, 4}, {5, 6}}; 79 | int size = 0; 80 | ASSERT_NO_THROW(size = pairVectorInput(data)); 81 | EXPECT_EQ(size, 3); 82 | } 83 | 84 | TEST(FooTest, PairVectorRefInput) { 85 | const std::vector> data{{1, 2}, {3, 4}, {5, 6}}; 86 | int size = 0; 87 | ASSERT_NO_THROW(size = pairVectorRefInput(data)); 88 | EXPECT_EQ(size, 3); 89 | } 90 | 91 | TEST(FooTest, PairJaggedArrayOutput) { 92 | std::vector>> result; 93 | ASSERT_NO_THROW(result = pairJaggedArrayOutput(8)); 94 | EXPECT_EQ(result.size(), 8); 95 | for (std::size_t i = 0; i < result.size(); ++i) { 96 | EXPECT_EQ(i + 1, result[i].size()); 97 | } 98 | for (int i = 1; i <= static_cast(result.size()); ++i) { 99 | const auto& inner = result[i - 1]; 100 | for (const auto& it : inner) { 101 | EXPECT_EQ(it, std::make_pair(i, i)); 102 | } 103 | } 104 | } 105 | 106 | TEST(FooTest, PairJaggedArrayValueInput) { 107 | std::vector>> data{{{1, 1}, {2, 2}, {3, 3}}, {{4, 4}, {5, 5}}}; 108 | int size = 0; 109 | ASSERT_NO_THROW(size = pairJaggedArrayInput(data)); 110 | EXPECT_EQ(size, 2); 111 | } 112 | 113 | TEST(FooTest, PairJaggedArrayRefInput) { 114 | std::vector>> data{{{1, 1}, {2, 2}, {3, 3}}, {{4, 4}, {5, 5}}}; 115 | int size = 0; 116 | ASSERT_NO_THROW(size = pairJaggedArrayRefInput(data)); 117 | EXPECT_EQ(size, 2); 118 | } 119 | 120 | TEST(FooTest, StaticMethods) { 121 | EXPECT_NO_THROW(Foo::staticFunction(42)); 122 | EXPECT_NO_THROW(Foo::staticFunction(int64_t{42})); 123 | } 124 | 125 | TEST(FooTest, Constructor) { 126 | Foo* b = new Foo(); 127 | EXPECT_NE(b, nullptr); 128 | } 129 | 130 | TEST(FooTest, IntMethods) { 131 | Foo foo; 132 | ASSERT_NO_THROW(foo.setInt(42)); 133 | EXPECT_EQ(42, foo.getInt()); 134 | } 135 | 136 | TEST(FooTest, Int64Methods) { 137 | Foo foo; 138 | ASSERT_NO_THROW(foo.setInt64(31)); 139 | EXPECT_EQ(31, foo.getInt64()); 140 | } 141 | 142 | TEST(FooTest, PrintMethod) { 143 | Foo foo; 144 | std::string str(""); 145 | ASSERT_NO_THROW(str = foo()); 146 | EXPECT_EQ("\"Foo\":{\"int\":0,\"int64\":0}", str); 147 | } 148 | 149 | } // namespace foo 150 | -------------------------------------------------------------------------------- /FooBar/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(FooBar) 2 | target_sources(FooBar 3 | PRIVATE 4 | include/foobar/FooBar.hpp 5 | src/FooBar.cpp) 6 | target_include_directories(FooBar 7 | PUBLIC 8 | $ 9 | $) 10 | target_compile_features(FooBar PUBLIC cxx_std_20) 11 | set_target_properties(FooBar PROPERTIES 12 | VERSION ${PROJECT_VERSION} 13 | POSITION_INDEPENDENT_CODE ON 14 | PUBLIC_HEADER include/foobar/FooBar.hpp) 15 | # note: macOS is APPLE and also UNIX ! 16 | if(APPLE) 17 | set_target_properties(FooBar PROPERTIES INSTALL_RPATH "@loader_path") 18 | elseif(UNIX) 19 | set_target_properties(FooBar PROPERTIES INSTALL_RPATH "$ORIGIN") 20 | endif() 21 | target_link_libraries(FooBar PUBLIC absl::log Bar Foo) 22 | add_library(${PROJECT_NAMESPACE}::FooBar ALIAS FooBar) 23 | 24 | add_subdirectory(tests) 25 | 26 | # Install 27 | include(GNUInstallDirs) 28 | install(TARGETS FooBar 29 | EXPORT ${PROJECT_NAME}Targets 30 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/foobar 31 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 32 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 33 | #RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 34 | ) 35 | -------------------------------------------------------------------------------- /FooBar/include/foobar/FooBar.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace bar { 9 | class Bar; 10 | } 11 | namespace foo { 12 | class Foo; 13 | } 14 | 15 | 16 | //! @namespace foobar The FooBar namespace 17 | namespace foobar { 18 | //! @defgroup StringVector Vector of String usage. 19 | //! @{ 20 | /*! @brief Test returning a vector of string. 21 | * @param level Scope level. 22 | * @return A vector of string.*/ 23 | std::vector stringVectorOutput(int level); 24 | /*! @brief Test using a vector of string passed by value. 25 | * @param data Input data. 26 | * @return The size of the data vector.*/ 27 | int stringVectorInput(std::vector data); 28 | /*! @brief Test using a vector of string passed by const ref. 29 | * @param data Input data. 30 | * @return The size of the data vector.*/ 31 | int stringVectorRefInput(const std::vector& data); 32 | //! @} 33 | 34 | //! @defgroup StringJaggedArray Vector of Vector of String usage. 35 | //! @{ 36 | /*! @brief Test returning a jagged array of string. 37 | * @param level Scope level. 38 | * @return A jagged array of string.*/ 39 | std::vector> stringJaggedArrayOutput(int level); 40 | /*! @brief Test using a jagged array of string passed by value. 41 | * @param data Input data. 42 | * @return The size of the data outer vector.*/ 43 | int stringJaggedArrayInput(std::vector> data); 44 | /*! @brief Test using a jagged array of string passed by const ref. 45 | * @param data Input data. 46 | * @return The size of the data outer vector.*/ 47 | int stringJaggedArrayRefInput(const std::vector>& data); 48 | //! @} 49 | 50 | //! @defgroup PairVector Vector of Pair usage. 51 | //! @{ 52 | /*! @brief Test returning a vector of pair. 53 | * @param level Scope level. 54 | * @return A vector of pair.*/ 55 | std::vector> pairVectorOutput(int level); 56 | /*! @brief Test using a vector of pair passed by value. 57 | * @param data Input data. 58 | * @return The size of the data vector.*/ 59 | int pairVectorInput(std::vector> data); 60 | /*! @brief Test using a vector of pair passed by const ref. 61 | * @param data Input data. 62 | * @return The size of the data vector.*/ 63 | int pairVectorRefInput(const std::vector>& data); 64 | //! @} 65 | 66 | //! @defgroup PairJaggedArray Jagged array of Pair usage. 67 | //! @{ 68 | /*! @brief Test returning a jagged array of pair. 69 | * @param level Scope level. 70 | * @return A jagged array of pair.*/ 71 | std::vector>> pairJaggedArrayOutput(int level); 72 | /*! @brief Test using a jagged array of pair passed by value. 73 | * @param data Input data. 74 | * @return The size of the data outer vector.*/ 75 | int pairJaggedArrayInput(std::vector>> data); 76 | /*! @brief Test using a jagged of pair passed by const ref. 77 | * @param data Input data. 78 | * @return The size of the data outer vector.*/ 79 | int pairJaggedArrayRefInput(const std::vector>>& data); 80 | //! @} 81 | 82 | //! @defgroup FreeFunction Free function usage. 83 | //! @{ 84 | /*! @brief Free function in foobar namespace. 85 | * @param level Scope level.*/ 86 | void freeFunction(int level); 87 | /*! @brief Free function in foobar namespace. 88 | * @param level Scope level.*/ 89 | void freeFunction(int64_t level); 90 | //! @} 91 | 92 | //! @brief Class FooBar. 93 | class FooBar { 94 | public: 95 | //! @defgroup StaticMembers Static members 96 | //! @{ 97 | 98 | /*! @brief Static method of FooBar class. 99 | * @param[in] level Scope level.*/ 100 | static void staticFunction(int level); 101 | 102 | /*! @brief Static method of FooBar class. 103 | * @param[in] level Scope level.*/ 104 | static void staticFunction(int64_t level); 105 | 106 | //! @} 107 | 108 | //! @defgroup IntegerMembers Integer members 109 | //! @{ 110 | 111 | FooBar(); 112 | ~FooBar(); 113 | 114 | /*! @brief Method (getter) of FooBar class. 115 | * @return A member value.*/ 116 | int getInt() const; 117 | /*! @brief Method (setter) of Bar nested class. 118 | * @param[in] input A member value.*/ 119 | void setBarInt(int input); 120 | /*! @brief Method (setter) of Foo nested class. 121 | * @param[in] input A member value.*/ 122 | void setFooInt(int input); 123 | 124 | //! @} 125 | 126 | //! @defgroup Int64Members Long Integer members 127 | //! @{ 128 | 129 | /*! @brief Method (getter) of FooBar class. 130 | * @return A member value.*/ 131 | int64_t getInt64() const; 132 | /*! @brief Set value of internal Bar nested class. 133 | * @param[in] input A member value.*/ 134 | void setBarInt64(int64_t input); 135 | /*! @brief Set value of internal Foo nested class. 136 | * @param[in] input A member value.*/ 137 | void setFooInt64(int64_t input); 138 | 139 | //! @} 140 | 141 | //! @brief Print object for debug. 142 | std::string operator()() const; 143 | 144 | private: 145 | std::unique_ptr _bar; 146 | std::unique_ptr _foo; 147 | }; 148 | } // namespace foobar 149 | -------------------------------------------------------------------------------- /FooBar/src/FooBar.cpp: -------------------------------------------------------------------------------- 1 | #include "foobar/FooBar.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include "bar/Bar.hpp" 10 | #include "foo/Foo.hpp" 11 | 12 | namespace foobar { 13 | using std::make_unique; 14 | 15 | std::vector stringVectorOutput(int level) { 16 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "()" << std::endl; 17 | std::vector result; 18 | auto foo_vec = foo::stringVectorOutput(level + 1); 19 | auto bar_vec = bar::stringVectorOutput(level + 1); 20 | result.insert(result.end(), foo_vec.begin(), foo_vec.end()); 21 | result.insert(result.end(), bar_vec.begin(), bar_vec.end()); 22 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "()" << std::endl; 23 | return result; 24 | } 25 | 26 | int stringVectorInput(std::vector data) { 27 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 28 | LOG(INFO) << "{"; 29 | for (const auto& item : data) { 30 | LOG(INFO) << item << ", "; 31 | } 32 | LOG(INFO) << "}" << std::endl; 33 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 34 | return data.size(); 35 | } 36 | 37 | int stringVectorRefInput(const std::vector& data) { 38 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 39 | LOG(INFO) << "{"; 40 | for (const auto& item : data) { 41 | LOG(INFO) << item << ", "; 42 | } 43 | LOG(INFO) << "}" << std::endl; 44 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 45 | return data.size(); 46 | } 47 | 48 | std::vector> stringJaggedArrayOutput(int level) { 49 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "()" << std::endl; 50 | std::vector> result; 51 | result.reserve(level); 52 | for (int i = 1; i <= level; ++i) { 53 | result.emplace_back(std::vector(i, std::to_string(i))); 54 | } 55 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "()" << std::endl; 56 | return result; 57 | } 58 | 59 | int stringJaggedArrayInput(std::vector> data) { 60 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 61 | LOG(INFO) << "{"; 62 | for (const auto& inner : data) { 63 | LOG(INFO) << "{"; 64 | for (const auto& item : inner) { 65 | LOG(INFO) << item << ", "; 66 | } 67 | LOG(INFO) << "}, "; 68 | } 69 | LOG(INFO) << "}" << std::endl; 70 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 71 | return data.size(); 72 | } 73 | 74 | int stringJaggedArrayRefInput(const std::vector>& data) { 75 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 76 | LOG(INFO) << "{"; 77 | for (const auto& inner : data) { 78 | LOG(INFO) << "{"; 79 | for (const auto& item : inner) { 80 | LOG(INFO) << item << ", "; 81 | } 82 | LOG(INFO) << "}, "; 83 | } 84 | LOG(INFO) << "}" << std::endl; 85 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 86 | return data.size(); 87 | } 88 | 89 | std::vector> pairVectorOutput(int level) { 90 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "()" << std::endl; 91 | std::vector> result; 92 | auto foo_vec = foo::pairVectorOutput(level + 1); 93 | auto bar_vec = bar::pairVectorOutput(level + 1); 94 | result.insert(result.end(), foo_vec.begin(), foo_vec.end()); 95 | result.insert(result.end(), bar_vec.begin(), bar_vec.end()); 96 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "()" << std::endl; 97 | return result; 98 | } 99 | 100 | int pairVectorInput(std::vector> data) { 101 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 102 | LOG(INFO) << "{"; 103 | for (const auto& item : data) { 104 | LOG(INFO) << "[" << item.first << "," << item.second << "], "; 105 | } 106 | LOG(INFO) << "}" << std::endl; 107 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 108 | return data.size(); 109 | } 110 | 111 | int pairVectorRefInput(const std::vector>& data) { 112 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 113 | LOG(INFO) << "{"; 114 | for (const auto& item : data) { 115 | LOG(INFO) << "[" << item.first << "," << item.second << "], "; 116 | } 117 | LOG(INFO) << "}" << std::endl; 118 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 119 | return data.size(); 120 | } 121 | 122 | std::vector>> pairJaggedArrayOutput(int level) { 123 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "()" << std::endl; 124 | std::vector>> result; 125 | result.reserve(level); 126 | for (int i = 1; i <= level; ++i) { 127 | result.emplace_back(std::vector>(i, std::make_pair(i, i))); 128 | } 129 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "()" << std::endl; 130 | return result; 131 | } 132 | 133 | int pairJaggedArrayInput(std::vector>> data) { 134 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 135 | LOG(INFO) << "{"; 136 | for (const auto& inner : data) { 137 | LOG(INFO) << "{"; 138 | for (const auto& item : inner) { 139 | LOG(INFO) << "[" << item.first << "," << item.second << "], "; 140 | } 141 | LOG(INFO) << "}, "; 142 | } 143 | LOG(INFO) << "}" << std::endl; 144 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 145 | return data.size(); 146 | } 147 | 148 | int pairJaggedArrayRefInput(const std::vector>>& data) { 149 | LOG(INFO) << "Enter " << __func__ << "()" << std::endl; 150 | LOG(INFO) << "{"; 151 | for (const auto& inner : data) { 152 | LOG(INFO) << "{"; 153 | for (const auto& item : inner) { 154 | LOG(INFO) << "[" << item.first << "," << item.second << "], "; 155 | } 156 | LOG(INFO) << "}, "; 157 | } 158 | LOG(INFO) << "}" << std::endl; 159 | LOG(INFO) << "Exit " << __func__ << "()" << std::endl; 160 | return data.size(); 161 | } 162 | 163 | void freeFunction(int level) { 164 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "(int)" << std::endl; 165 | foo::freeFunction(level + 1); 166 | bar::freeFunction(level + 1); 167 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "(int)" << std::endl; 168 | } 169 | 170 | void freeFunction(int64_t level) { 171 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "(int64_t)" << std::endl; 172 | foo::freeFunction(level + 1); 173 | bar::freeFunction(level + 1); 174 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "(int64_t)" << std::endl; 175 | } 176 | 177 | void FooBar::staticFunction(int level) { 178 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "(int)" << std::endl; 179 | freeFunction(level + 1); 180 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "(int)" << std::endl; 181 | } 182 | 183 | void FooBar::staticFunction(int64_t level) { 184 | LOG(INFO) << "[" << level << "] Enter " << __func__ << "(int64_t)" << std::endl; 185 | freeFunction(level + 1); 186 | LOG(INFO) << "[" << level << "] Exit " << __func__ << "(int64_t)" << std::endl; 187 | } 188 | 189 | FooBar::FooBar() { 190 | _bar = make_unique(); 191 | _foo = make_unique(); 192 | } 193 | 194 | FooBar::~FooBar() {} 195 | 196 | int FooBar::getInt() const { 197 | return _bar->getInt() + _foo->getInt(); 198 | } 199 | 200 | void FooBar::setBarInt(int input) { 201 | _bar->setInt(input); 202 | } 203 | 204 | void FooBar::setFooInt(int input) { 205 | _foo->setInt(input); 206 | } 207 | 208 | int64_t FooBar::getInt64() const { 209 | return _bar->getInt64() + _foo->getInt64(); 210 | } 211 | 212 | void FooBar::setBarInt64(int64_t input) { 213 | _bar->setInt64(input); 214 | } 215 | 216 | void FooBar::setFooInt64(int64_t input) { 217 | _foo->setInt64(input); 218 | } 219 | 220 | std::string FooBar::operator()() const { 221 | return std::string{"\"FooBar\":{"} + (*_bar)() + "," + (*_foo)() + "}"; 222 | } 223 | 224 | namespace { 225 | void* kVar = [] { 226 | std::cerr << "kFooBar" << std::endl; 227 | return nullptr; 228 | }(); 229 | } // namespace 230 | 231 | } // namespace foobar 232 | -------------------------------------------------------------------------------- /FooBar/tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(NOT BUILD_TESTING) 2 | return() 3 | endif() 4 | 5 | add_executable(foobar_test) 6 | target_sources(foobar_test PRIVATE foobar_test.cpp) 7 | target_include_directories(foobar_test PUBLIC 8 | $) 9 | target_compile_features(foobar_test PRIVATE cxx_std_20) 10 | set_target_properties(foobar_test PROPERTIES 11 | VERSION ${PROJECT_VERSION} 12 | POSITION_INDEPENDENT_CODE ON 13 | ) 14 | if(APPLE) 15 | set_target_properties(foobar_test PROPERTIES 16 | INSTALL_RPATH "@loader_path/../${CMAKE_INSTALL_LIBDIR};@loader_path") 17 | elseif(UNIX) 18 | set_target_properties(foobar_test PROPERTIES 19 | INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}:$ORIGIN") 20 | endif() 21 | target_link_libraries(foobar_test PRIVATE 22 | GTest::gtest_main 23 | ${PROJECT_NAMESPACE}::FooBar) 24 | 25 | add_test(NAME foobar_test COMMAND foobar_test) 26 | -------------------------------------------------------------------------------- /FooBar/tests/foobar_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace foobar { 9 | 10 | TEST(FooBarTest, FreeFunction) { 11 | EXPECT_NO_THROW(freeFunction(42)); 12 | EXPECT_NO_THROW(freeFunction(int64_t{42})); 13 | } 14 | 15 | TEST(FooBarTest, StringVectorOutput) { 16 | std::vector result; 17 | ASSERT_NO_THROW(result = stringVectorOutput(8)); 18 | EXPECT_EQ(result.size(), 18); 19 | for (const auto& it : result) { 20 | EXPECT_EQ(it, std::to_string(9)); 21 | } 22 | } 23 | 24 | TEST(FooBarTest, StringVectorValueInput) { 25 | const std::vector data{"1", "2", "3", "4", "5"}; 26 | int size = 0; 27 | ASSERT_NO_THROW(size = stringVectorInput(data)); 28 | EXPECT_EQ(size, 5); 29 | } 30 | 31 | TEST(FooBarTest, StringVectorRefInput) { 32 | const std::vector data{"1", "2", "3", "4", "5"}; 33 | int size = 0; 34 | ASSERT_NO_THROW(size = stringVectorRefInput(data)); 35 | EXPECT_EQ(size, 5); 36 | } 37 | 38 | TEST(FooBarTest, StringJaggedArrayOutput) { 39 | std::vector> result; 40 | ASSERT_NO_THROW(result = stringJaggedArrayOutput(8)); 41 | EXPECT_EQ(result.size(), 8); 42 | for (std::size_t i = 0; i < result.size(); ++i) { 43 | EXPECT_EQ(i + 1, result[i].size()); 44 | } 45 | for (std::size_t i = 1; i <= result.size(); ++i) { 46 | const auto& inner = result[i - 1]; 47 | for (const auto& it : inner) { 48 | EXPECT_EQ(it, std::to_string(i)); 49 | } 50 | } 51 | } 52 | 53 | TEST(FooBarTest, StringJaggedArrayValueInput) { 54 | const std::vector> data{{"1", "2", "3"}, {"4", "5"}}; 55 | int size = 0; 56 | ASSERT_NO_THROW(size = stringJaggedArrayInput(data)); 57 | EXPECT_EQ(size, 2); 58 | } 59 | 60 | TEST(FooBarTest, StringJaggedArrayRefInput) { 61 | const std::vector> data{{"1", "2", "3"}, {"4", "5"}}; 62 | int size = 0; 63 | ASSERT_NO_THROW(size = stringJaggedArrayRefInput(data)); 64 | EXPECT_EQ(size, 2); 65 | } 66 | 67 | TEST(FooBarTest, PairVectorOutput) { 68 | std::vector> result; 69 | ASSERT_NO_THROW(result = pairVectorOutput(8)); 70 | EXPECT_EQ(result.size(), 18); 71 | for (const auto& it : result) { 72 | EXPECT_EQ(it.first, 9); 73 | EXPECT_EQ(it.second, 9); 74 | } 75 | } 76 | 77 | TEST(FooBarTest, PairVectorValueInput) { 78 | const std::vector> data{{1, 2}, {3, 4}, {5, 6}}; 79 | int size = 0; 80 | ASSERT_NO_THROW(size = pairVectorInput(data)); 81 | EXPECT_EQ(size, 3); 82 | } 83 | 84 | TEST(FooBarTest, PairVectorRefInput) { 85 | const std::vector> data{{1, 2}, {3, 4}, {5, 6}}; 86 | int size = 0; 87 | ASSERT_NO_THROW(size = pairVectorRefInput(data)); 88 | EXPECT_EQ(size, 3); 89 | } 90 | 91 | TEST(FooBarTest, PairJaggedArrayOutput) { 92 | std::vector>> result; 93 | ASSERT_NO_THROW(result = pairJaggedArrayOutput(8)); 94 | EXPECT_EQ(result.size(), 8); 95 | for (std::size_t i = 0; i < result.size(); ++i) { 96 | EXPECT_EQ(i + 1, result[i].size()); 97 | } 98 | for (int i = 1; i <= static_cast(result.size()); ++i) { 99 | const auto& inner = result[i - 1]; 100 | for (const auto& it : inner) { 101 | EXPECT_EQ(it, std::make_pair(i, i)); 102 | } 103 | } 104 | } 105 | 106 | TEST(FooBarTest, PairJaggedArrayValueInput) { 107 | std::vector>> data{{{1, 1}, {2, 2}, {3, 3}}, {{4, 4}, {5, 5}}}; 108 | int size = 0; 109 | ASSERT_NO_THROW(size = pairJaggedArrayInput(data)); 110 | EXPECT_EQ(size, 2); 111 | } 112 | 113 | TEST(FooBarTest, PairJaggedArrayRefInput) { 114 | std::vector>> data{{{1, 1}, {2, 2}, {3, 3}}, {{4, 4}, {5, 5}}}; 115 | int size = 0; 116 | ASSERT_NO_THROW(size = pairJaggedArrayRefInput(data)); 117 | EXPECT_EQ(size, 2); 118 | } 119 | 120 | TEST(FooBarTest, StaticMethods) { 121 | EXPECT_NO_THROW(FooBar::staticFunction(42)); 122 | EXPECT_NO_THROW(FooBar::staticFunction(int64_t{42})); 123 | } 124 | 125 | TEST(FooBarTest, Constructor) { 126 | FooBar* b = new FooBar(); 127 | EXPECT_NE(b, nullptr); 128 | } 129 | 130 | TEST(FooBarTest, IntMethods) { 131 | FooBar foobar; 132 | ASSERT_NO_THROW(foobar.setBarInt(31)); 133 | ASSERT_NO_THROW(foobar.setFooInt(42)); 134 | EXPECT_EQ(73, foobar.getInt()); 135 | } 136 | 137 | TEST(FooBarTest, Int64Methods) { 138 | FooBar foobar; 139 | ASSERT_NO_THROW(foobar.setBarInt64(13)); 140 | ASSERT_NO_THROW(foobar.setFooInt64(17)); 141 | EXPECT_EQ(30, foobar.getInt64()); 142 | } 143 | 144 | TEST(FooBarTest, PrintMethod) { 145 | FooBar foobar; 146 | ASSERT_NO_THROW(foobar.setBarInt(1)); 147 | ASSERT_NO_THROW(foobar.setFooInt(2)); 148 | ASSERT_NO_THROW(foobar.setBarInt64(3)); 149 | ASSERT_NO_THROW(foobar.setFooInt64(4)); 150 | 151 | std::string str(""); 152 | ASSERT_NO_THROW(str = foobar()); 153 | EXPECT_EQ("\"FooBar\":{\"Bar\":{\"int\":1,\"int64\":3},\"Foo\":{\"int\":2,\"int64\":4}}", str); 154 | } 155 | 156 | } // namespace foobar 157 | -------------------------------------------------------------------------------- /FooBarApp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(FooBarApp) 2 | target_sources(FooBarApp PRIVATE src/main.cpp) 3 | target_include_directories(FooBarApp PRIVATE 4 | $ 5 | ) 6 | target_compile_features(FooBarApp PRIVATE cxx_std_20) 7 | set_target_properties(FooBarApp PROPERTIES 8 | VERSION ${PROJECT_VERSION} 9 | POSITION_INDEPENDENT_CODE ON 10 | ) 11 | # note: macOS is APPLE and also UNIX ! 12 | if(APPLE) 13 | set_target_properties(FooBarApp PROPERTIES 14 | INSTALL_RPATH "@loader_path/../${CMAKE_INSTALL_LIBDIR}") 15 | elseif(UNIX AND NOT APPLE) 16 | set_target_properties(FooBarApp PROPERTIES 17 | INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}") 18 | endif() 19 | target_link_libraries(FooBarApp PRIVATE 20 | absl::flags 21 | absl::flags_parse 22 | absl::log 23 | absl::log_globals 24 | absl::log_initialize 25 | absl::log_severity 26 | absl::strings 27 | protobuf::libprotobuf 28 | CMakeCpp::FooBar 29 | ) 30 | 31 | add_executable(${PROJECT_NAMESPACE}::FooBarApp ALIAS FooBarApp) 32 | 33 | if(BUILD_TESTING) 34 | add_test(NAME cpp_FooBarApp_test COMMAND FooBarApp) 35 | endif() 36 | 37 | # Install 38 | include(GNUInstallDirs) 39 | install(TARGETS FooBarApp 40 | EXPORT ${PROJECT_NAME}Targets 41 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 42 | ) 43 | -------------------------------------------------------------------------------- /FooBarApp/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | void* kVar = [] { 17 | std::cerr << "kFooBarApp\n"; 18 | return nullptr; 19 | }(); 20 | 21 | 22 | int main(int argc, char* argv[]) { 23 | absl::InitializeLog(); 24 | absl::SetProgramUsageMessage("FooBarApp"); 25 | absl::EnableLogPrefix(false); 26 | absl::SetStderrThreshold(absl::LogSeverity::kInfo); 27 | absl::ParseCommandLine(argc, argv); 28 | { 29 | const std::vector v = {"foo","bar","baz"}; 30 | std::string s = absl::StrJoin(v, "-"); 31 | LOG(INFO) << "Joined string: " << s << "\n"; 32 | } 33 | 34 | foobar::freeFunction(int{0}); 35 | LOG(INFO) << std::endl; 36 | foobar::freeFunction(int64_t{1}); 37 | LOG(INFO) << std::endl; 38 | 39 | foobar::FooBar::staticFunction(int{2}); 40 | LOG(INFO) << std::endl; 41 | foobar::FooBar::staticFunction(int64_t{3}); 42 | LOG(INFO) << std::endl; 43 | 44 | foobar::FooBar f; 45 | f.setBarInt(13); 46 | f.setFooInt(17); 47 | LOG(INFO) << std::to_string(f.getInt()) << std::endl; 48 | 49 | f.setBarInt64(int64_t{31}); 50 | f.setFooInt64(int64_t{42}); 51 | LOG(INFO) << std::to_string(f.getInt64()) << std::endl; 52 | 53 | LOG(INFO) << f() << std::endl; 54 | 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Github-CI:
2 | [![Build Status][amd64_linux_status]][amd64_linux_link] 3 | [![Build Status][amd64_macos_status]][amd64_macos_link] 4 | [![Build Status][arm64_macos_status]][arm64_macos_link] 5 | [![Build Status][amd64_windows_status]][amd64_windows_link]
6 | 7 | [![Build Status][amd64_docker_status]][amd64_docker_link] 8 | [![Build Status][arm64_docker_status]][arm64_docker_link] 9 | [![Build Status][riscv64_docker_status]][riscv64_docker_link]
10 | 11 | [![Build Status][arm_toolchain_status]][arm_toolchain_link] 12 | [![Build Status][aarch64_toolchain_status]][aarch64_toolchain_link] 13 | [![Build Status][mips64_toolchain_status]][mips64_toolchain_link] 14 | [![Build Status][powerpc_toolchain_status]][powerpc_toolchain_link] 15 | [![Build Status][riscv64_toolchain_status]][riscv64_toolchain_link]
16 | 17 | [amd64_linux_status]: ./../../actions/workflows/amd64_linux_cmake.yml/badge.svg 18 | [amd64_linux_link]: ./../../actions/workflows/amd64_linux_cmake.yml 19 | [amd64_macos_status]: ./../../actions/workflows/amd64_macos_cmake.yml/badge.svg 20 | [amd64_macos_link]: ./../../actions/workflows/amd64_macos_cmake.yml 21 | [arm64_macos_status]: ./../../actions/workflows/arm64_macos_cmake.yml/badge.svg 22 | [arm64_macos_link]: ./../../actions/workflows/arm64_macos_cmake.yml 23 | [amd64_windows_status]: ./../../actions/workflows/amd64_windows_cmake.yml/badge.svg 24 | [amd64_windows_link]: ./../../actions/workflows/amd64_windows_cmake.yml 25 | 26 | [amd64_docker_status]: ./../../actions/workflows/amd64_docker_cmake.yml/badge.svg 27 | [amd64_docker_link]: ./../../actions/workflows/amd64_docker_cmake.yml 28 | [arm64_docker_status]: ./../../actions/workflows/arm64_docker_cmake.yml/badge.svg 29 | [arm64_docker_link]: ./../../actions/workflows/arm64_docker_cmake.yml 30 | [riscv64_docker_status]: ./../../actions/workflows/riscv64_docker_cmake.yml/badge.svg 31 | [riscv64_docker_link]: ./../../actions/workflows/riscv64_docker_cmake.yml 32 | 33 | [arm_toolchain_status]: ./../../actions/workflows/arm_toolchain_cmake.yml/badge.svg 34 | [arm_toolchain_link]: ./../../actions/workflows/arm_toolchain_cmake.yml 35 | [aarch64_toolchain_status]: ./../../actions/workflows/aarch64_toolchain_cmake.yml/badge.svg 36 | [aarch64_toolchain_link]: ./../../actions/workflows/aarch64_toolchain_cmake.yml 37 | [mips64_toolchain_status]: ./../../actions/workflows/mips64_toolchain_cmake.yml/badge.svg 38 | [mips64_toolchain_link]: ./../../actions/workflows/mips64_toolchain_cmake.yml 39 | [powerpc_toolchain_status]: ./../../actions/workflows/powerpc_toolchain_cmake.yml/badge.svg 40 | [powerpc_toolchain_link]: ./../../actions/workflows/powerpc_toolchain_cmake.yml 41 | [riscv64_toolchain_status]: ./../../actions/workflows/riscv64_toolchain_cmake.yml/badge.svg 42 | [riscv64_toolchain_link]: ./../../actions/workflows/riscv64_toolchain_cmake.yml 43 | 44 | # Introduction 45 | 46 | 56 | 57 | This is an example of how to create a Modern [CMake](https://cmake.org/) C++ Project. 58 | 59 | This project should run on GNU/Linux, MacOS and Windows. 60 | 61 | ## Requirement 62 | 63 | You'll need: 64 | 65 | * "CMake >= 3.16". 66 | 67 | ## Codemap 68 | 69 | The project layout is as follow: 70 | 71 | * [CMakeLists.txt](CMakeLists.txt) Top-level for [CMake](https://cmake.org/cmake/help/latest/) based build. 72 | * [cmake](cmake) Subsidiary CMake files. 73 | 74 | * [ci](ci) Root directory for continuous integration. 75 | 76 | * [Foo](Foo) Root directory for `Foo` library. 77 | * [CMakeLists.txt](Foo/CMakeLists.txt) for `Foo`. 78 | * [include](Foo/include) public folder. 79 | * [foo](Foo/include/foo) 80 | * [Foo.hpp](Foo/include/foo/Foo.hpp) 81 | * [src](Foo/src) private folder. 82 | * [src/Foo.cpp](Foo/src/Foo.cpp) 83 | * [Bar](Bar) Root directory for `Bar` library. 84 | * [CMakeLists.txt](Bar/CMakeLists.txt) for `Bar`. 85 | * [include](Bar/include) public folder. 86 | * [bar](Bar/include/bar) 87 | * [Bar.hpp](Bar/include/bar/Bar.hpp) 88 | * [src](Bar/src) private folder. 89 | * [src/Bar.cpp](Bar/src/Bar.cpp) 90 | * [FooBar](FooBar) Root directory for `FooBar` library. 91 | * [CMakeLists.txt](FooBar/CMakeLists.txt) for `FooBar`. 92 | * [include](FooBar/include) public folder. 93 | * [foobar](FooBar/include/foobar) 94 | * [FooBar.hpp](FooBar/include/foobar/FooBar.hpp) 95 | * [src](FooBar/src) private folder. 96 | * [src/FooBar.cpp](FooBar/src/FooBar.cpp) 97 | * [FooBarApp](FooBarApp) Root directory for `FooBarApp` executable. 98 | * [CMakeLists.txt](FooBarApp/CMakeLists.txt) for `FooBarApp`. 99 | * [src](FooBarApp/src) private folder. 100 | * [src/main.cpp](FooBarApp/src/main.cpp) 101 | 102 | ## Dependencies 103 | 104 | To complexify a little, the CMake project is composed of three libraries (Foo, Bar and FooBar) 105 | with the following dependencies: 106 | 107 | ```sh 108 | Foo: 109 | Bar: 110 | FooBar: PUBLIC Foo PRIVATE Bar 111 | FooBarApp: PRIVATE FooBar 112 | ``` 113 | 114 | note: Since `Foo` is a public dependency of `FooBar`, then `FooBarApp` will 115 | *see* `Foo` inlude directories 116 | 117 | ## Build 118 | 119 | To build the C++ project, as usual: 120 | 121 | ```sh 122 | cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release 123 | cmake --build build --config Release 124 | CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --config Release --target test 125 | ``` 126 | ## Build directory layout 127 | Since we want to use the [CMAKE_BINARY_DIR](https://cmake.org/cmake/help/latest/variable/CMAKE_BINARY_DIR.html) to generate the binary package. 128 | We want this layout (tree build --prune -P "*.so|FooApp"): 129 | 130 | ``` 131 | build 132 | ├── bin 133 | │   └── FooBarApp 134 | └── lib 135 |    └── lib*.so 136 | ``` 137 | 138 | ## Appendices 139 | 140 | Few links on the subject... 141 | 142 | ### Resources 143 | 144 | Project layout: 145 | * [The Pitchfork Layout Revision 1 (cxx-pflR1)](https://github.com/vector-of-bool/pitchfork) 146 | 147 | CMake: 148 | * https://llvm.org/docs/CMakePrimer.html 149 | * https://cliutils.gitlab.io/modern-cmake/ 150 | * https://cgold.readthedocs.io/en/latest/ 151 | 152 | # Contributing 153 | 154 | The [CONTRIBUTING.md](./CONTRIBUTING.md) file contains instructions on how to 155 | file the Contributor License Agreement before sending any pull requests (PRs). 156 | Of course, if you're new to the project, it's usually best to discuss any 157 | proposals and reach consensus before sending your first PR. 158 | 159 | ## License 160 | 161 | Apache 2. See the LICENSE file for details. 162 | 163 | ## Disclaimer 164 | 165 | This is not an official Google product, it is just code that happens to be 166 | owned by Google. 167 | 168 | -------------------------------------------------------------------------------- /ci/Makefile: -------------------------------------------------------------------------------- 1 | PROJECT := cmake-cpp 2 | BRANCH := $(shell git rev-parse --abbrev-ref HEAD) 3 | SHA1 := $(shell git rev-parse --verify HEAD) 4 | 5 | # General commands 6 | .PHONY: help 7 | BOLD:=\e[1m 8 | RESET:=\e[0m 9 | 10 | help: 11 | @echo -e "${BOLD}SYNOPSIS${RESET}" 12 | @echo -e "\tmake [NOCACHE=1] [VERBOSE=1]" 13 | @echo 14 | @echo -e "${BOLD}DESCRIPTION${RESET}" 15 | @echo -e "\ttest build inside docker container to have a reproductible build." 16 | @echo 17 | @echo -e "${BOLD}MAKE TARGETS${RESET}" 18 | @echo -e "\t${BOLD}help${RESET}: display this help and exit." 19 | @echo 20 | @echo -e "\tBuild using docker and the host platform." 21 | @echo -e "\t${BOLD}_${RESET}: build a docker image for a specific distro." 22 | @echo -e "\t${BOLD}save__${RESET}: Save a docker image for a specific distro." 23 | @echo -e "\t${BOLD}sh__${RESET}: run a container using the docker image specified (debug purpose)." 24 | @echo -e "\t${BOLD}clean__${RESET}: Remove a docker image for a specific distro." 25 | @echo -e "\t${BOLD}clean_all${RESET}: Remove ALL caches and docker images." 26 | @echo 27 | @echo -e "\tWith ${BOLD}${RESET}:" 28 | @echo -e "\t\t${BOLD}almalinux${RESET} (latest)" 29 | @echo -e "\t\t${BOLD}alpine${RESET} (edge)" 30 | @echo -e "\t\t${BOLD}archlinux${RESET} (latest)" 31 | @echo -e "\t\t${BOLD}debian${RESET} (latest)" 32 | @echo -e "\t\t${BOLD}fedora${RESET} (latest)" 33 | @echo -e "\t\t${BOLD}opensuse${RESET} (tumbleweed)" 34 | @echo -e "\t\t${BOLD}rockylinux${RESET} (9)" 35 | @echo -e "\t\t${BOLD}ubuntu${RESET} (rolling)" 36 | @echo -e "\t\t${BOLD}all${RESET}: trigger ALL DISTROS." 37 | @echo 38 | @echo -e "\tWith ${BOLD}${RESET}:" 39 | @echo -e "\t\t${BOLD}env${RESET}" 40 | @echo -e "\t\t${BOLD}devel${RESET}" 41 | @echo -e "\t\t${BOLD}build${RESET}" 42 | @echo -e "\t\t${BOLD}test${RESET}" 43 | @echo -e "\t\t${BOLD}install_env${RESET}" 44 | @echo -e "\t\t${BOLD}install_devel${RESET}" 45 | @echo -e "\t\t${BOLD}install_build${RESET}" 46 | @echo -e "\t\t${BOLD}install_test${RESET}" 47 | @echo -e "\te.g. 'make ubuntu_test'" 48 | @echo 49 | @echo -e "\tBuild using docker buildx with a platform specified." 50 | @echo -e "\t${BOLD}_${RESET}: build docker images for ALL DISTROS." 51 | @echo -e "\t${BOLD}__${RESET}: build docker image for a specific distro." 52 | @echo -e "\t${BOLD}save__${RESET}: Save docker images for ALL DISTROS." 53 | @echo -e "\t${BOLD}save___${RESET}: Save the docker image for a specific distro." 54 | @echo -e "\t${BOLD}sh___${RESET}: run a container using the docker image specified (debug purpose)." 55 | @echo -e "\t${BOLD}clean___${RESET}: Remove cache and docker image." 56 | @echo -e "\t${BOLD}clean_platforms${RESET}: Remove ALL cache and docker image." 57 | @echo 58 | @echo -e "\tWith ${BOLD}${RESET}:" 59 | @echo -e "\t\t${BOLD}amd64${RESET}: linux/amd64 (x86_64)" 60 | @echo -e "\t\t${BOLD}386${RESET}: linux/386 (x86)" 61 | @echo -e "\t\t${BOLD}arm${RESET}: linux/arm (armv7)" 62 | @echo -e "\t\t${BOLD}arm64${RESET}: linux/arm64 (aarch64, arm64v8)" 63 | @echo -e "\t\t${BOLD}mips${RESET}: linux/mips (mips 32bits)" 64 | @echo -e "\t\t${BOLD}mipsle${RESET}: linux/mipsle (mips 32bits Little Endian)" 65 | @echo -e "\t\t${BOLD}mips64${RESET}: linux/mips64 (mips 64bits)" 66 | @echo -e "\t\t${BOLD}mips64le${RESET}: linux/mips64le (mips 64bits Little Endian)" 67 | @echo -e "\t\t${BOLD}ppc64${RESET}: linux/ppc64 (PowerPC 64Bits)" 68 | @echo -e "\t\t${BOLD}ppc64le${RESET}: linux/ppc64le (PowerPC 64Bits Little Endian)" 69 | @echo -e "\t\t${BOLD}riscv64${RESET}: linux/riscv64 (RISC-V 64bits)" 70 | @echo -e "\t\t${BOLD}s390x${RESET}: linux/s390x (IBM System/390x)" 71 | @echo -e "\te.g. 'make amd64_ubuntu_test'" 72 | @echo -e "\tDocker image unavailable: arm64_archlinux" 73 | @echo 74 | @echo -e "\tBuild using a toolchain." 75 | @echo -e "\t${BOLD}toolchain__${RESET}: build docker image for a specific toolchain target." 76 | @echo -e "\t${BOLD}save_toolchain__${RESET}: Save the docker image for a specific platform." 77 | @echo -e "\t${BOLD}sh_toolchain__${RESET}: run a container using the docker image specified (debug purpose)." 78 | @echo -e "\t${BOLD}clean_toolchain__${RESET}: Remove cache and docker image." 79 | @echo -e "\t${BOLD}clean_toolchains${RESET}: Remove ALL cache and docker image." 80 | @echo 81 | @echo -e "\tWith ${BOLD}${RESET}:" 82 | @echo -e "\t\t${BOLD}armv7-eabihf${RESET} (alias: arm) (bootlin toolchain)" 83 | @echo -e "\t\t${BOLD}armebv7-eabihf${RESET} (alias: armeb) (bootlin toolchain)" 84 | @echo -e "\t\t${BOLD}aarch64${RESET} (alias: arm64) (bootlin toolchain)" 85 | @echo -e "\t\t${BOLD}aarch64be${RESET} (alias: arm64be) (bootlin toolchain)" 86 | @echo -e "\t\t${BOLD}mips32-r6${RESET} (alias: mips) (codespace toolchain)" 87 | @echo -e "\t\t${BOLD}mips64-r6${RESET} (alias: mips64) (codespace toolchain)" 88 | @echo -e "\t\t${BOLD}mips32el-r6${RESET} (alias: mipsel) (codespace toolchain)" 89 | @echo -e "\t\t${BOLD}mips64el-r6${RESET} (alias: mips64el) (codespace toolchain)" 90 | @echo -e "\t\t${BOLD}mips32-r2${RESET} (codespace toolchain)" 91 | @echo -e "\t\t${BOLD}mips64-r2${RESET} (codespace toolchain)" 92 | @echo -e "\t\t${BOLD}mips32el-r2${RESET} (codespace toolchain)" 93 | @echo -e "\t\t${BOLD}mips64el-r2${RESET} (codespace toolchain)" 94 | @echo -e "\t\t${BOLD}ppc-440fp${RESET} (alias: ppc) (bootlin toolchain)" 95 | @echo -e "\t\t${BOLD}ppc-e500mc${RESET} (bootlin toolchain)" 96 | @echo -e "\t\t${BOLD}ppc64-power8${RESET} (alias: ppc64) (bootlin toolchain)" 97 | @echo -e "\t\t${BOLD}ppc64le-power8${RESET} (alias: ppc64le) (bootlin toolchain)" 98 | @echo -e "\t\t${BOLD}riscv32${RESET} (bootlin toolchain)" 99 | @echo -e "\t\t${BOLD}riscv64${RESET} (bootlin toolchain)" 100 | @echo -e "\t\t${BOLD}s390x${RESET} (bootlin toolchain)" 101 | @echo 102 | @echo -e "\tWith ${BOLD}${RESET}:" 103 | @echo -e "\t\t${BOLD}env${RESET}" 104 | @echo -e "\t\t${BOLD}devel${RESET}" 105 | @echo -e "\t\t${BOLD}toolchain${RESET}" 106 | @echo -e "\t\t${BOLD}build${RESET}" 107 | @echo -e "\t\t${BOLD}test${RESET}" 108 | @echo -e "\te.g. 'make toolchain_mips64_build'" 109 | @echo -e "\te.g. 'make toolchain_arm64_test'" 110 | @echo 111 | @echo -e "\tBuild for web using emscripten." 112 | @echo -e "\t${BOLD}web_${RESET}: build the emscripten ." 113 | @echo -e "\t${BOLD}save_web_${RESET}: Save the docker image." 114 | @echo -e "\t${BOLD}sh_web_${RESET}: run a container using the docker image specified (debug purpose)." 115 | @echo -e "\t${BOLD}clean_web_${RESET}: Remove cache and docker image." 116 | @echo -e "\t${BOLD}clean_web${RESET}: Remove ALL cache and docker image." 117 | @echo 118 | @echo -e "\tWith ${BOLD}${RESET}:" 119 | @echo -e "\t\t${BOLD}env${RESET}" 120 | @echo -e "\t\t${BOLD}devel${RESET}" 121 | @echo -e "\t\t${BOLD}build${RESET}" 122 | @echo -e "\t\t${BOLD}test${RESET}" 123 | @echo -e "\te.g. 'make web_build'" 124 | @echo 125 | @echo -e "\tBuild using a vagrant machine." 126 | @echo -e "\t${BOLD}_${RESET}: build the vagrant virtual machine." 127 | @echo -e "\t${BOLD}sh__${RESET}: ssh to the vagrant machine specified (debug purpose)." 128 | @echo -e "\t${BOLD}clean_${RESET}: Remove virtual machine for the specified vm." 129 | @echo -e "\t${BOLD}clean_vms${RESET}: Remove ALL vagrant box." 130 | @echo 131 | @echo -e "\tWith ${BOLD}${RESET}:" 132 | @echo -e "\t\t${BOLD}freebsd${RESET} (FreeBSD 14)" 133 | @echo -e "\t\t${BOLD}netbsd${RESET} (NetBSD 9)" 134 | @echo -e "\t\t${BOLD}openbsd${RESET} (OpenBSD 7)" 135 | @echo 136 | @echo -e "\tWith ${BOLD}${RESET}:" 137 | @echo -e "\t\t${BOLD}build${RESET}" 138 | @echo -e "\te.g. 'make freebsd_build'" 139 | @echo 140 | @echo -e "\tGlobal targets." 141 | @echo -e "\t${BOLD}clean${RESET}: Remove ALL caches and docker images." 142 | @echo -e "\t${BOLD}distclean${RESET}: Remove everything." 143 | @echo 144 | @echo -e "\t${BOLD}NOCACHE=1${RESET}: use 'docker build --no-cache' when building container (default use cache)." 145 | @echo -e "\t${BOLD}VERBOSE=1${RESET}: use 'docker build --progress=plain' when building container." 146 | @echo 147 | @echo -e "branch: $(BRANCH)" 148 | @echo -e "sha1: $(SHA1)" 149 | 150 | # Need to add cmd_distro to PHONY otherwise target are ignored since they do not 151 | # contain recipe (using FORCE do not work here) 152 | .PHONY: all 153 | all: all_test 154 | 155 | # Delete all implicit rules to speed up makefile 156 | MAKEFLAGS += --no-builtin-rules 157 | .SUFFIXES: 158 | # Remove some rules from gmake that .SUFFIXES does not remove. 159 | SUFFIXES := 160 | # Keep all intermediate files 161 | # ToDo: try to remove it later 162 | .SECONDARY: 163 | 164 | # Docker image name prefix. 165 | IMAGE := ${PROJECT} 166 | 167 | DOCKER_BUILD_CMD := docker build 168 | DOCKER_BUILDX_CMD := docker buildx build 169 | ifdef NOCACHE 170 | DOCKER_BUILD_CMD := ${DOCKER_BUILD_CMD} --no-cache 171 | DOCKER_BUILDX_CMD := ${DOCKER_BUILDX_CMD} --no-cache 172 | endif 173 | ifdef VERBOSE 174 | DOCKER_BUILD_CMD := ${DOCKER_BUILD_CMD} --progress=plain 175 | DOCKER_BUILDX_CMD := ${DOCKER_BUILDX_CMD} --progress=plain 176 | endif 177 | DOCKER_RUN_CMD := docker run --rm --init --net=host 178 | 179 | # Currently supported distro 180 | DISTROS := \ 181 | almalinux \ 182 | alpine \ 183 | archlinux \ 184 | debian \ 185 | fedora \ 186 | opensuse \ 187 | rockylinux \ 188 | ubuntu 189 | 190 | # $* stem 191 | # $< first prerequist 192 | # $@ target name 193 | 194 | ############ 195 | ## STAGES ## 196 | ############ 197 | STAGES := env devel build test install_env install_devel install_build install_test 198 | 199 | define make-stage-target = 200 | #$$(info STAGE: $1) 201 | #$$(info Create targets: all_$1 $(addsuffix _$1, $(DISTROS)).) 202 | targets_$1 := $(addsuffix _$1, $(DISTROS)) 203 | .PHONY: all_$1 $$(targets_$1) 204 | all_$1: $$(targets_$1) 205 | $$(targets_$1): %_$1: docker/%/Dockerfile 206 | #@docker image rm -f ${IMAGE}:$$*_$1 2>/dev/null 207 | ${DOCKER_BUILD_CMD} --target=$1 --tag ${IMAGE}:$$*_$1 -f $$< .. 208 | 209 | #$$(info Create targets: save_all_$1 $(addprefix save_, $(addsuffix _$1, $(DISTROS))) (debug).) 210 | save_targets_$1 := $(addprefix save_, $(addsuffix _$1, $(DISTROS))) 211 | .PHONY: save_all_$1 $$(save_targets_$1) 212 | save_all_$1: $$(save_targets_$1) 213 | $$(save_targets_$1): save_%_$1: cache/%/docker_$1.tar 214 | cache/%/docker_$1.tar: %_$1 215 | @rm -f $$@ 216 | mkdir -p cache/$$* 217 | docker save ${IMAGE}:$$*_$1 -o $$@ 218 | 219 | #$$(info Create targets: $(addprefix sh_, $(addsuffix _$1, $(DISTROS))) (debug).) 220 | sh_targets_$1 := $(addprefix sh_, $(addsuffix _$1, $(DISTROS))) 221 | .PHONY: $$(sh_targets_$1) 222 | $$(sh_targets_$1): sh_%_$1: %_$1 223 | ${DOCKER_RUN_CMD} -it --name ${PROJECT}_$$*_$1 ${IMAGE}:$$*_$1 224 | 225 | #$$(info Create targets: clean_all_$1 $(addprefix clean_, $(addsuffix _$1, $(DISTROS))).) 226 | clean_targets_$1 := $(addprefix clean_, $(addsuffix _$1, $(DISTROS))) 227 | .PHONY: clean_all_$1 $$(clean_targets_$1) 228 | clean_all_$1: $$(clean_targets_$1) 229 | $$(clean_targets_$1): clean_%_$1: 230 | docker image rm -f ${IMAGE}:$$*_$1 2>/dev/null 231 | rm -f cache/$$*/docker_$1.tar 232 | endef 233 | 234 | $(foreach stage,$(STAGES),$(eval $(call make-stage-target,$(stage)))) 235 | 236 | ## MERGE ## 237 | .PHONY: clean_all 238 | clean_all: $(addprefix clean_all_, $(STAGES)) 239 | rm -f $(addprefix cache/, $(DISTROS)) 240 | 241 | ############## 242 | ## PLATFORM ## 243 | ############## 244 | # ref: https://go.dev/doc/install/source#environment 245 | # ref: https://github.com/containerd/containerd/blob/269548fa27e0089a8b8278fc4fc781d7f65a939b/platforms/platforms.go#L80-L94 246 | PLATFORMS := \ 247 | 386 amd64 \ 248 | arm arm64 \ 249 | mips mipsle mips64 mips64le \ 250 | ppc64 ppc64le \ 251 | riscv64 \ 252 | s390x 253 | 254 | define make-platform-stage-target = 255 | #$$(info PLATFORM: '$1' STAGE: '$2') 256 | #$$(info Create targets: $1_all_$2 $(addprefix $1_, $(addsuffix _$2, $(DISTROS))).) 257 | targets_$1_$2 := $(addprefix $1_, $(addsuffix _$2, $(DISTROS))) 258 | .PHONY: $1_all_$2 $$(targets_$1_$2) 259 | $1_all_$2: $$(targets_$1_$2) 260 | $$(targets_$1_$2): $1_%_$2: docker/%/Dockerfile 261 | #@docker image rm -f ${IMAGE}:$1_$$*_$2 2>/dev/null 262 | ${DOCKER_BUILDX_CMD} --platform linux/$1 --target=$2 --tag ${IMAGE}:$1_$$*_$2 -f $$< .. 263 | 264 | #$$(info Create save targets: save_$1_all_$2 $(addprefix save_$1_, $(addsuffix _$2, $(DISTROS))) (debug).) 265 | save_targets_$1_$2 := $(addprefix save_$1_, $(addsuffix _$2, $(DISTROS))) 266 | .PHONY: save_$1_all_$2 $$(save_targets_$1_$2) 267 | save_$1_all_$2: $$(save_targets_$1_$2) 268 | $$(save_targets_$1_$2): save_$1_%_$2: cache/$1/%/docker_$2.tar 269 | cache/$1/%/docker_$2.tar: $1_%_$2 270 | @rm -f $$@ 271 | mkdir -p cache/$1/$$* 272 | docker save ${IMAGE}:$1_$$*_$2 -o $$@ 273 | 274 | #$$(info Create sh targets: $(addprefix sh_$1_, $(addsuffix _$2, $(DISTROS))) (debug).) 275 | sh_targets_$1_$2 := $(addprefix sh_$1_, $(addsuffix _$2, $(DISTROS))) 276 | .PHONY: $$(sh_targets_$1_$2) 277 | $$(sh_targets_$1_$2): sh_$1_%_$2: $1_%_$2 278 | ${DOCKER_RUN_CMD} --platform linux/$1 -it --name ${IMAGE}_$1_$$*_$2 ${IMAGE}:$1_$$*_$2 279 | 280 | #$$(info Create targets: clean_$1_all_$2 $(addprefix clean_$1_, $(addsuffix _$2, $(DISTROS))).) 281 | clean_targets_$1_$2 := $(addprefix clean_$1_, $(addsuffix _$2, $(DISTROS))) 282 | .PHONY: clean_$1_all_$2 $$(clean_targets_$1_$2) 283 | clean_$1_all_$2: $$(clean_targets_$1_$2) 284 | $$(clean_targets_$1_$2): clean_$1_%_$2: 285 | docker image rm -f ${IMAGE}:$1_$$*_$2 2>/dev/null 286 | rm -f cache/$1/$$*/docker_$2.tar 287 | endef 288 | 289 | define make-platform-target = 290 | #$$(info PLATFORM: $1) 291 | $(foreach stage,$(STAGES),$(eval $(call make-platform-stage-target,$1,$(stage)))) 292 | 293 | # merge 294 | .PHONY: clean_$1 295 | clean_$1: $(addprefix clean_$1_all_, $(STAGES)) 296 | -rmdir $(addprefix cache/$1/, $(DISTROS)) 297 | -rmdir cache/$1 298 | endef 299 | 300 | $(foreach platform,$(PLATFORMS),$(eval $(call make-platform-target,$(platform)))) 301 | 302 | ## MERGE ## 303 | .PHONY: clean_platforms 304 | clean_platforms: $(addprefix clean_, $(PLATFORMS)) 305 | 306 | ############### 307 | ## TOOLCHAIN ## 308 | ############### 309 | TOOLCHAIN_TARGETS := \ 310 | arm armv7-eabihf \ 311 | armeb armebv7-eabihf \ 312 | arm64 aarch64 \ 313 | arm64be aarch64be \ 314 | mips mips32-r6 mips32-r2 \ 315 | mipsel mips32el-r6 mips32el-r2 \ 316 | mips64 mips64-r6 mips64-r2 \ 317 | mips64el mips64el-r6 mips64el-r2 \ 318 | ppc ppc-440fp ppc-e500mc \ 319 | ppc64 ppc64-power8 \ 320 | ppc64le ppc64le-power8 \ 321 | riscv32 riscv64 \ 322 | s390x 323 | TOOLCHAIN_STAGES := env devel toolchain build test 324 | 325 | define toolchain-stage-target = 326 | #$$(info STAGE: $1) 327 | #$$(info Create targets: toolchain_$1 $(addprefix toolchain_, $(addsuffix _$1, $(TOOLCHAIN_TARGETS))).) 328 | targets_toolchain_$1 := $(addprefix toolchain_, $(addsuffix _$1, $(TOOLCHAIN_TARGETS))) 329 | .PHONY: toolchain_$1 $$(targets_toolchain_$1) 330 | toolchain_$1: $$(targets_toolchain_$1) 331 | $$(targets_toolchain_$1): toolchain_%_$1: docker/toolchain/Dockerfile 332 | #@docker image rm -f ${IMAGE}:toolchain_$$*_$1 2>/dev/null 333 | ${DOCKER_BUILD_CMD} \ 334 | --tag ${IMAGE}:toolchain_$$*_$1 \ 335 | --build-arg TARGET=$$* \ 336 | --target=$1 \ 337 | -f $$< \ 338 | .. 339 | 340 | #$$(info Create targets: save_toolchain_$1 $(addprefix save_toolchain_, $(addsuffix _$1, $(TOOLCHAIN_TARGETS))) (debug).) 341 | save_targets_toolchain_$1 := $(addprefix save_toolchain_, $(addsuffix _$1, $(TOOLCHAIN_TARGETS))) 342 | .PHONY: save_toolchain_$1 $$(save_targets_toolchain_$1) 343 | save_toolchain_$1: $$(save_targets_toolchain_$1) 344 | $$(save_targets_toolchain_$1): save_toolchain_%_$1: cache/%/docker_$1.tar 345 | cache/%/docker_$1.tar: %_$1 346 | @rm -f $$@ 347 | mkdir -p cache/$$* 348 | docker save ${IMAGE}:toolchain_$$*_$1 -o $$@ 349 | 350 | #$$(info Create targets: $(addprefix sh_toolchain_, $(addsuffix _$1, $(TOOLCHAIN_TARGETS))) (debug).) 351 | sh_targets_toolchain_$1 = $(addprefix sh_toolchain_, $(addsuffix _$1, $(TOOLCHAIN_TARGETS))) 352 | .PHONY: $$(sh_targets_toolchain_$1) 353 | $$(sh_targets_toolchain_$1): sh_toolchain_%_$1: %_$1 354 | ${DOCKER_RUN_CMD} -it --name ${PROJECT}_toolchain_$$*_$1 ${IMAGE}:toolchain_$$*_$1 355 | 356 | #$$(info Create targets: clean_toolchain_$1 $(addprefix clean_toolchain_, $(addsuffix _$1, $(TOOLCHAIN_TARGETS))).) 357 | clean_targets_toolchain_$1 = $(addprefix clean_toolchain_, $(addsuffix _$1, $(TOOLCHAIN_TARGETS))) 358 | .PHONY: clean_toolchain_$1 $$(clean_targets_toolchain_$1) 359 | clean_toolchain_$1: $$(clean_targets_toolchain_$1) 360 | $$(clean_targets_toolchain_$1): clean_toolchain_%_$1: 361 | docker image rm -f ${IMAGE}:toolchain_$$*_$1 2>/dev/null 362 | rm -f cache/$$*/docker_$1.tar 363 | endef 364 | 365 | $(foreach stage,$(TOOLCHAIN_STAGES),$(eval $(call toolchain-stage-target,$(stage)))) 366 | 367 | ## MERGE ## 368 | .PHONY: clean_toolchains 369 | clean_toolchains: $(addprefix clean_toolchain_, $(TOOLCHAIN_STAGES)) 370 | -rmdir $(addprefix cache/, $(TOOLCHAIN_TARGETS)) 371 | 372 | ######### 373 | ## WEB ## 374 | ######### 375 | WEB_STAGES := env devel build test 376 | 377 | define make-web-stage-target = 378 | #$$(info STAGE: $1) 379 | #$$(info Create target: web_$1.) 380 | .PHONY: web_$1 381 | web_$1: docker/web/Dockerfile 382 | #@docker image rm -f ${IMAGE}:web_$1 2>/dev/null 383 | ${DOCKER_BUILD_CMD} --target=$1 --tag ${IMAGE}:web_$1 -f $$< .. 384 | 385 | #$$(info Create target: save_web_$1 (debug).) 386 | .PHONY: save_web_$1 387 | save_web_$1: cache/web/docker_$1.tar 388 | cache/web/docker_$1.tar: web_$1 389 | @rm -f $$@ 390 | mkdir -p cache/web 391 | docker save ${IMAGE}:web_$1 -o $$@ 392 | 393 | #$$(info Create target: sh_web_$1 (debug).) 394 | .PHONY: sh_web_$1 395 | sh_web_$1: web_$1 396 | ${DOCKER_RUN_CMD} -it --name ${PROJECT}_web_$1 ${IMAGE}:web_$1 397 | 398 | #$$(info Create target: clean_web_$1.) 399 | .PHONY: clean_web_$1 400 | clean_web_$1: 401 | docker image rm -f ${IMAGE}:web_$1 2>/dev/null 402 | rm -f cache/web/docker_$1.tar 403 | endef 404 | 405 | $(foreach stage,$(WEB_STAGES),$(eval $(call make-web-stage-target,$(stage)))) 406 | 407 | ## MERGE ## 408 | .PHONY: clean_web 409 | clean_web: $(addprefix clean_web_, $(WEB_STAGES)) 410 | rm -f cache/web 411 | 412 | ############# 413 | ## VAGRANT ## 414 | ############# 415 | VAGRANT_VMS := \ 416 | freebsd \ 417 | netbsd \ 418 | openbsd 419 | 420 | vms_targets := $(addsuffix _build, $(VAGRANT_VMS)) 421 | .PHONY: vms_build $(vms_targets) 422 | vms_build: $(vms_targets) 423 | $(vms_targets): %_build: vagrant/%/Vagrantfile 424 | @cd vagrant/$* && vagrant destroy -f 425 | cd vagrant/$* && vagrant up 426 | 427 | sh_vms_targets := $(addprefix sh_,$(addsuffix _build, $(VAGRANT_VMS))) 428 | .PHONY: $(sh_vms_targets) 429 | $(sh_vms_targets): sh_%_build: vagrant/%/Vagrantfile 430 | cd vagrant/$* && vagrant up 431 | cd vagrant/$* && vagrant ssh 432 | 433 | clean_vms_targets := $(addprefix clean_, $(VAGRANT_VMS)) 434 | .PHONY: clean_vms $(clean_vms_targets) 435 | clean_vms: $(clean_vms_targets) 436 | $(clean_vms_targets): clean_%: vagrant/%/Vagrantfile 437 | cd vagrant/$* && vagrant destroy -f 438 | -rm -rf vagrant/$*/.vagrant 439 | 440 | ########### 441 | ## CLEAN ## 442 | ########### 443 | .PHONY: clean 444 | clean: clean_all clean_platforms clean_toolchains clean_web clean_vms 445 | docker container prune -f 446 | docker image prune -f 447 | -rmdir cache 448 | 449 | .PHONY: distclean 450 | distclean: clean 451 | -docker container rm -f $$(docker container ls -aq) 452 | -docker image rm -f $$(docker image ls -aq) 453 | -vagrant box remove -f generic/freebsd14 454 | -------------------------------------------------------------------------------- /ci/README.md: -------------------------------------------------------------------------------- 1 | # CI: Makefile/Docker testing 2 | 3 | To test the build on various distro, I'm using docker containers and a Makefile for orchestration. 4 | 5 | pros: 6 | * You are independent of third party CI runner VM images (e.g. [github actions/virtual-environments](https://github.com/actions/virtual-environments)). 7 | * You can run it locally on any host having a linux docker image support. 8 | * Most CI provide runner with docker and Makefile installed. 9 | 10 | cons: 11 | * Only GNU/Linux distro supported. 12 | * Could take few GiB (~30 GiB for all distro and all languages) 13 | * ~500MiB OS + C++/CMake tools, 14 | 15 | ## Usage 16 | 17 | To get the help simply type: 18 | ```sh 19 | make 20 | ``` 21 | 22 | note: you can also use from top directory 23 | ```sh 24 | make --directory=ci 25 | ``` 26 | 27 | ### Example 28 | 29 | For example to test inside an `Alpine` container: 30 | ```sh 31 | make alpine_test 32 | ``` 33 | 34 | ## Docker layers 35 | 36 | Dockerfile is splitted in several stages. 37 | 38 | ![docker](docs/docker.svg) 39 | 40 | ### Run arm64v8 image on amd64 machine 41 | 42 | You can build and run `arm64v8` (i.e. `aarch64`) docker container on a `amd64` host (`x86_64`) by enabling qemu support: 43 | ```sh 44 | docker run --pull always --rm --privileged multiarch/qemu-user-static --reset -p yes 45 | ``` 46 | ref: https://github.com/multiarch/qemu-user-static#getting-started 47 | 48 | Then you should be able to run them, e.g.: 49 | ```sh 50 | docker run --rm -it arm64v8/ubuntu 51 | ``` 52 | ref: https://github.com/docker-library/official-images#architectures-other-than-amd64 53 | 54 | ### Docker buildx 55 | 56 | ref: https://docs.docker.com/buildx/working-with-buildx/ 57 | 58 | On you enable qemu support (see above), you can list available platform using: 59 | ```sh 60 | docker buildx ls 61 | ``` 62 | Then you can build a docker image using one of the available platform 63 | ```sh 64 | docker buildx build --platform linux/arm64 ... 65 | ``` 66 | 67 | ## Custom CMake install 68 | 69 | To control the version of CMake, instead of using the 70 | [version provided by the distro package manager](https://repology.org/project/cmake/badges), you can: 71 | * Install the prebuilt binaries (recommanded) 72 | * Build it from source (slower) 73 | * Install it using the [pypi package cmake](https://pypi.org/project/cmake/) (need a python stack) 74 | 75 | ### Install prebuilt 76 | 77 | The recommended and faster way is to use the prebuilt version: 78 | ```Dockerfile 79 | # Install CMake 3.25.2 80 | RUN wget "https://cmake.org/files/v3.25/cmake-3.25.2-linux-x86_64.sh" \ 81 | && chmod a+x cmake-3.25.2-linux-x86_64.sh \ 82 | && ./cmake-3.25.2-linux-x86_64.sh --prefix=/usr/local/ --skip-license \ 83 | && rm cmake-3.25.2-linux-x86_64.sh 84 | ``` 85 | 86 | **warning**: Since [CMake 3.20](https://cmake.org/files/v3.20/) Kitware use a lowercase `linux` instead of `Linux` (e.g. [CMake 3.19](https://cmake.org/files/v3.19/)). 87 | 88 | ### Build from source 89 | 90 | To build from source you can use the following snippet: 91 | ```Dockerfile 92 | # Install CMake 3.25.2 93 | RUN wget "https://cmake.org/files/v3.25/cmake-3.25.2.tar.gz" \ 94 | && tar xzf cmake-3.25.2.tar.gz \ 95 | && rm cmake-3.25.2.tar.gz \ 96 | && cd cmake-3.25.2 \ 97 | && ./bootstrap --prefix=/usr/local/ \ 98 | && make \ 99 | && make install \ 100 | && cd .. \ 101 | && rm -rf cmake-3.25.2 102 | ``` 103 | 104 | -------------------------------------------------------------------------------- /ci/docker/almalinux/Dockerfile: -------------------------------------------------------------------------------- 1 | # Create a virtual environment with all tools installed 2 | # ref: https://hub.docker.com/_/almalinux 3 | FROM almalinux:latest AS env 4 | 5 | # Install system build dependencies 6 | ENV PATH=/usr/local/bin:$PATH 7 | RUN dnf -y update \ 8 | && dnf -y install git wget openssl-devel cmake \ 9 | && dnf -y group install "Development Tools" \ 10 | && dnf clean all \ 11 | && rm -rf /var/cache/dnf 12 | CMD [ "/usr/bin/bash" ] 13 | 14 | # Add the library src to our build env 15 | FROM env AS devel 16 | WORKDIR /home/project 17 | COPY . . 18 | 19 | FROM devel AS build 20 | RUN cmake --version 21 | RUN cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release 22 | RUN cmake --build build --target all -v 23 | RUN cmake --build build --target install -v 24 | 25 | FROM build AS test 26 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 27 | 28 | # Test install rules 29 | FROM env AS install_env 30 | COPY --from=build /usr/local/ /usr/local/ 31 | 32 | FROM install_env AS install_devel 33 | WORKDIR /home/samples 34 | COPY ci/samples . 35 | 36 | FROM install_devel AS install_build 37 | RUN cmake -S. -Bbuild 38 | RUN cmake --build build --target all -v 39 | 40 | FROM install_build AS install_test 41 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 42 | -------------------------------------------------------------------------------- /ci/docker/alpine/Dockerfile: -------------------------------------------------------------------------------- 1 | # Create a virtual environment with all tools installed 2 | # ref: https://hub.docker.com/_/alpine 3 | FROM alpine:edge AS env 4 | 5 | # Install system build dependencies 6 | ENV PATH=/usr/local/bin:$PATH 7 | RUN apk add --no-cache git build-base linux-headers cmake 8 | 9 | # Add the library src to our build env 10 | FROM env AS devel 11 | WORKDIR /home/project 12 | COPY . . 13 | 14 | FROM devel AS build 15 | RUN cmake --version 16 | RUN cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release 17 | RUN cmake --build build --target all -v 18 | RUN cmake --build build --target install -v 19 | 20 | FROM build AS test 21 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 22 | 23 | # Test install rules 24 | FROM env AS install_env 25 | COPY --from=build /usr/local/ /usr/local/ 26 | 27 | FROM install_env AS install_devel 28 | WORKDIR /home/samples 29 | COPY ci/samples . 30 | 31 | FROM install_devel AS install_build 32 | RUN cmake -S. -Bbuild 33 | RUN cmake --build build --target all -v 34 | 35 | FROM install_build AS install_test 36 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 37 | -------------------------------------------------------------------------------- /ci/docker/archlinux/Dockerfile: -------------------------------------------------------------------------------- 1 | # Create a virtual environment with all tools installed 2 | # ref: https://hub.docker.com/_/archlinux/ 3 | FROM archlinux:latest AS env 4 | 5 | # Install system build dependencies 6 | ENV PATH=/usr/local/bin:$PATH 7 | RUN pacman -Syu --noconfirm git base-devel cmake 8 | 9 | # Add the library src to our build env 10 | FROM env AS devel 11 | WORKDIR /home/project 12 | COPY . . 13 | 14 | FROM devel AS build 15 | RUN cmake --version 16 | RUN cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release 17 | RUN cmake --build build --target all -v 18 | RUN cmake --build build --target install -v 19 | 20 | FROM build AS test 21 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 22 | 23 | # Test install rules 24 | FROM env AS install_env 25 | COPY --from=build /usr/local/ /usr/local/ 26 | 27 | FROM install_env AS install_devel 28 | WORKDIR /home/samples 29 | COPY ci/samples . 30 | 31 | FROM install_devel AS install_build 32 | RUN cmake -S. -Bbuild 33 | RUN cmake --build build --target all -v 34 | 35 | FROM install_build AS install_test 36 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 37 | -------------------------------------------------------------------------------- /ci/docker/debian/Dockerfile: -------------------------------------------------------------------------------- 1 | # Create a virtual environment with all tools installed 2 | # ref: https://hub.docker.com/_/debian 3 | FROM debian:unstable AS env 4 | 5 | # Install system build dependencies 6 | ENV PATH=/usr/local/bin:$PATH 7 | RUN apt-get update -qq \ 8 | && apt-get install -yq \ 9 | git wget libssl-dev build-essential cmake \ 10 | && apt-get clean \ 11 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 12 | 13 | # Add the library src to our build env 14 | FROM env AS devel 15 | WORKDIR /home/project 16 | COPY . . 17 | 18 | FROM devel AS build 19 | RUN cmake --version 20 | RUN cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release 21 | RUN cmake --build build --target all -v 22 | RUN cmake --build build --target install -v 23 | 24 | FROM build AS test 25 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 26 | 27 | # Test install rules 28 | FROM env AS install_env 29 | COPY --from=build /usr/local/ /usr/local/ 30 | 31 | FROM install_env AS install_devel 32 | WORKDIR /home/samples 33 | COPY ci/samples . 34 | 35 | FROM install_devel AS install_build 36 | RUN cmake -S. -Bbuild 37 | RUN cmake --build build --target all -v 38 | 39 | FROM install_build AS install_test 40 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 41 | -------------------------------------------------------------------------------- /ci/docker/fedora/Dockerfile: -------------------------------------------------------------------------------- 1 | # Create a virtual environment with all tools installed 2 | # ref: https://hub.docker.com/_/fedora 3 | FROM fedora:latest AS env 4 | 5 | # Install system build dependencies 6 | ENV PATH=/usr/local/bin:$PATH 7 | RUN dnf -y update \ 8 | && dnf -y install git wget \ 9 | && dnf -y install @development-tools \ 10 | && dnf -y install gcc-c++ cmake \ 11 | && dnf clean all 12 | 13 | # Add the library src to our build env 14 | FROM env AS devel 15 | WORKDIR /home/project 16 | COPY . . 17 | 18 | FROM devel AS build 19 | RUN cmake --version 20 | RUN cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release 21 | RUN cmake --build build --target all -v 22 | RUN cmake --build build --target install -v 23 | 24 | FROM build AS test 25 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 26 | 27 | # Test install rules 28 | FROM env AS install_env 29 | COPY --from=build /usr/local/ /usr/local/ 30 | 31 | FROM install_env AS install_devel 32 | WORKDIR /home/samples 33 | COPY ci/samples . 34 | 35 | FROM install_devel AS install_build 36 | RUN cmake -S. -Bbuild 37 | RUN cmake --build build --target all -v 38 | 39 | FROM install_build AS install_test 40 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 41 | -------------------------------------------------------------------------------- /ci/docker/opensuse/Dockerfile: -------------------------------------------------------------------------------- 1 | # Create a virtual environment with all tools installed 2 | # ref: https://hub.docker.com/r/opensuse/tumbleweed 3 | FROM opensuse/tumbleweed AS env 4 | 5 | # Install system build dependencies 6 | ENV PATH=/usr/local/bin:$PATH 7 | RUN zypper refresh \ 8 | && zypper install -y git gcc gcc-c++ cmake \ 9 | && zypper clean -a 10 | ENV CC=gcc CXX=g++ 11 | 12 | # Add the library src to our build env 13 | FROM env AS devel 14 | WORKDIR /home/project 15 | COPY . . 16 | 17 | FROM devel AS build 18 | RUN cmake --version 19 | RUN cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release 20 | RUN cmake --build build --target all -v 21 | RUN cmake --build build --target install -v 22 | 23 | FROM build AS test 24 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 25 | 26 | # Test install rules 27 | FROM env AS install_env 28 | COPY --from=build /usr/local/ /usr/local/ 29 | 30 | FROM install_env AS install_devel 31 | WORKDIR /home/samples 32 | COPY ci/samples . 33 | 34 | FROM install_devel AS install_build 35 | RUN cmake -S. -Bbuild 36 | RUN cmake --build build --target all -v 37 | 38 | FROM install_build AS install_test 39 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 40 | -------------------------------------------------------------------------------- /ci/docker/rockylinux/Dockerfile: -------------------------------------------------------------------------------- 1 | # Create a virtual environment with all tools installed 2 | # ref: https://hub.docker.com/_/rockylinux 3 | FROM rockylinux:9 AS env 4 | 5 | # Install system build dependencies 6 | ENV PATH=/usr/local/bin:$PATH 7 | RUN dnf -y update \ 8 | && dnf -y install git wget openssl-devel cmake \ 9 | && dnf -y group install "Development Tools" \ 10 | && dnf clean all \ 11 | && rm -rf /var/cache/dnf 12 | CMD [ "/usr/bin/bash" ] 13 | 14 | # Add the library src to our build env 15 | FROM env AS devel 16 | WORKDIR /home/project 17 | COPY . . 18 | 19 | FROM devel AS build 20 | RUN cmake --version 21 | RUN cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release 22 | RUN cmake --build build --target all -v 23 | RUN cmake --build build --target install -v 24 | 25 | FROM build AS test 26 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 27 | 28 | # Test install rules 29 | FROM env AS install_env 30 | COPY --from=build /usr/local/ /usr/local/ 31 | 32 | FROM install_env AS install_devel 33 | WORKDIR /home/samples 34 | COPY ci/samples . 35 | 36 | FROM install_devel AS install_build 37 | RUN cmake -S. -Bbuild 38 | RUN cmake --build build --target all -v 39 | 40 | FROM install_build AS install_test 41 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 42 | -------------------------------------------------------------------------------- /ci/docker/toolchain/Dockerfile: -------------------------------------------------------------------------------- 1 | # Create a virtual environment with all tools installed 2 | # ref: https://hub.docker.com/_/ubuntu 3 | FROM ubuntu:latest AS env 4 | 5 | # Install system build dependencies 6 | ENV PATH=/usr/local/bin:$PATH 7 | RUN apt-get update -qq \ 8 | && DEBIAN_FRONTEND=noninteractive apt-get install -yq \ 9 | git wget libssl-dev build-essential \ 10 | cmake ninja-build \ 11 | python3 python3-venv \ 12 | pkgconf libglib2.0-dev \ 13 | && apt-get clean \ 14 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 15 | ENTRYPOINT ["/usr/bin/bash", "-c"] 16 | CMD ["/usr/bin/bash"] 17 | 18 | FROM env AS devel 19 | WORKDIR /home/project 20 | COPY . . 21 | 22 | ARG TARGET 23 | ENV TARGET=${TARGET:-unknown} 24 | 25 | FROM devel AS toolchain 26 | RUN ./tools/cross_compile.sh toolchain 27 | 28 | FROM toolchain AS build 29 | RUN cmake --version 30 | RUN ./tools/cross_compile.sh build 31 | 32 | FROM build AS test 33 | RUN ./tools/cross_compile.sh qemu 34 | RUN ./tools/cross_compile.sh test 35 | -------------------------------------------------------------------------------- /ci/docker/ubuntu/Dockerfile: -------------------------------------------------------------------------------- 1 | # Create a virtual environment with all tools installed 2 | # ref: https://hub.docker.com/_/ubuntu 3 | FROM ubuntu:latest AS env 4 | 5 | # Install system build dependencies 6 | ENV PATH=/usr/local/bin:$PATH 7 | RUN apt update -q \ 8 | && DEBIAN_FRONTEND=noninteractive apt install -yq \ 9 | git wget libssl-dev \ 10 | build-essential cmake \ 11 | && apt-get clean \ 12 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 13 | 14 | FROM env AS devel 15 | WORKDIR /home/project 16 | COPY . . 17 | 18 | FROM devel AS build 19 | RUN cmake --version 20 | RUN cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release 21 | RUN cmake --build build --target all -v 22 | RUN cmake --build build --target install -v 23 | 24 | FROM build AS test 25 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 26 | 27 | # Test install rules 28 | FROM env AS install_env 29 | COPY --from=build /usr/local/ /usr/local/ 30 | 31 | FROM install_env AS install_devel 32 | WORKDIR /home/samples 33 | COPY ci/samples . 34 | 35 | FROM install_devel AS install_build 36 | RUN cmake -S. -Bbuild 37 | RUN cmake --build build --target all -v 38 | 39 | FROM install_build AS install_test 40 | RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test -v 41 | -------------------------------------------------------------------------------- /ci/docker/web/Dockerfile: -------------------------------------------------------------------------------- 1 | # Create a virtual environment with all tools installed 2 | # ref: https://hub.docker.com/_/archlinux/ 3 | FROM archlinux:latest AS env 4 | 5 | # Install system build dependencies 6 | ENV PATH=/usr/local/bin:$PATH 7 | RUN pacman -Syu --noconfirm git base-devel glibc cmake 8 | RUN cmake -version 9 | RUN pacman -Syu --noconfirm nodejs emscripten 10 | ENV PATH=/usr/lib/emscripten:$PATH 11 | RUN emcc -v 12 | 13 | # Add the library src to our build env 14 | FROM env AS devel 15 | WORKDIR /home/project 16 | COPY . . 17 | 18 | FROM devel AS build 19 | RUN emcmake cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release 20 | RUN cmake --build build --target all -v 21 | #RUN cmake --build build --target install -v 22 | 23 | FROM build AS test 24 | #RUN CTEST_OUTPUT_ON_FAILURE=1 cmake --build build --target test 25 | RUN cd build && ctest -V 26 | -------------------------------------------------------------------------------- /ci/docs/docker.dot: -------------------------------------------------------------------------------- 1 | @startdot 2 | digraph DockerDeps { 3 | //rankdir=BT; 4 | rankdir=TD; 5 | node [shape=cylinder, style="rounded,filled", color=black, fillcolor=royalblue]; 6 | DISTRO_IMG [label=":latest"]; 7 | PKG [label="packages\ne.g. cmake, g++", shape=box3d]; 8 | SRC [label="git repo", shape=folder]; 9 | SPL [label="samples", shape=folder]; 10 | 11 | subgraph clusterDockerfile { 12 | ENV_IMG [label="cmake-cpp:_env\nenv"]; 13 | DEVEL_IMG [label="cmake-cpp:_devel\ndevel"]; 14 | BUILD_IMG [label="cmake-cpp:_build\nbuild"]; 15 | TEST_IMG [label="cmake-cpp:_test\ntest"]; 16 | INSTALL_ENV_IMG [label="cmake-cpp:_install_env\ninstall_env"]; 17 | INSTALL_DEVEL_IMG [label="cmake-cpp:_install_devel\ninstall_devel"]; 18 | INSTALL_BUILD_IMG [label="cmake-cpp:_install_build\ninstall_build"]; 19 | INSTALL_TEST_IMG [label="cmake-cpp:_install_test\ninstall_test"]; 20 | 21 | ENV_IMG -> DEVEL_IMG; 22 | DEVEL_IMG -> BUILD_IMG; 23 | BUILD_IMG -> TEST_IMG; 24 | 25 | ENV_IMG -> INSTALL_ENV_IMG; 26 | BUILD_IMG -> INSTALL_ENV_IMG [label="copy install", style="dashed"]; 27 | INSTALL_ENV_IMG -> INSTALL_DEVEL_IMG; 28 | SPL -> INSTALL_DEVEL_IMG [label="copy", style="dashed"]; 29 | INSTALL_DEVEL_IMG -> INSTALL_BUILD_IMG; 30 | INSTALL_BUILD_IMG -> INSTALL_TEST_IMG; 31 | 32 | color=royalblue; 33 | label = "docker//Dockerfile"; 34 | } 35 | DISTRO_IMG -> ENV_IMG; 36 | PKG -> ENV_IMG [label="install", style="dashed"]; 37 | SRC -> DEVEL_IMG [label="copy", style="dashed"]; 38 | 39 | subgraph clusterCache { 40 | node [shape=note, style="rounded,filled", color=black, fillcolor=royalblue]; 41 | ENV_TAR [label="docker_env.tar"]; 42 | DEVEL_TAR [label="docker_devel.tar"]; 43 | BUILD_TAR [label="docker_build.tar"]; 44 | TEST_TAR [label="docker_test.tar"]; 45 | INSTALL_ENV_TAR [label="docker_install_env.tar"]; 46 | INSTALL_DEVEL_TAR [label="docker_install_devel.tar"]; 47 | INSTALL_BUILD_TAR [label="docker_install_build.tar"]; 48 | INSTALL_TEST_TAR [label="docker_install_test.tar"]; 49 | 50 | edge [color=red]; 51 | ENV_IMG -> ENV_TAR [label="make save__env"]; 52 | DEVEL_IMG -> DEVEL_TAR [label="make save__devel"]; 53 | BUILD_IMG -> BUILD_TAR [label="make save__build"]; 54 | TEST_IMG -> TEST_TAR [label="make save__test"]; 55 | INSTALL_ENV_IMG -> INSTALL_ENV_TAR [label="make save__install_env"]; 56 | INSTALL_DEVEL_IMG -> INSTALL_DEVEL_TAR [label="make save__install_devel"]; 57 | INSTALL_BUILD_IMG -> INSTALL_BUILD_TAR [label="make save__install_build"]; 58 | INSTALL_TEST_IMG -> INSTALL_TEST_TAR [label="make save__install_test"]; 59 | 60 | color=royalblue; 61 | label = "cache//"; 62 | } 63 | } 64 | @enddot 65 | -------------------------------------------------------------------------------- /ci/docs/generate_image.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eux 3 | 4 | # Check plantuml is in PATH 5 | command -v plantuml 6 | 7 | #rm -f "*.png" 8 | rm -f "*.svg" 9 | for i in *.dot; do 10 | #plantuml -Tpng "$i"; 11 | plantuml -Tsvg "$i"; 12 | done 13 | -------------------------------------------------------------------------------- /ci/samples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | project(Sample VERSION 1.0.0 LANGUAGES CXX) 3 | 4 | include(CTest) 5 | find_package(CMakeCpp REQUIRED) 6 | 7 | add_executable(sample main.cpp) 8 | target_compile_features(sample PUBLIC cxx_std_17) 9 | set_target_properties(sample PROPERTIES 10 | CXX_STANDARD 17 11 | CXX_STANDARD_REQUIRED ON 12 | VERSION ${PROJECT_VERSION}) 13 | target_link_libraries(sample PRIVATE 14 | CMakeCpp::Foo 15 | CMakeCpp::Bar 16 | CMakeCpp::FooBar 17 | ) 18 | 19 | if(BUILD_TESTING) 20 | add_test(NAME sample_UT COMMAND sample) 21 | endif() 22 | 23 | include(GNUInstallDirs) 24 | install(TARGETS sample 25 | EXPORT SampleTargets 26 | DESTINATION ${CMAKE_INSTALL_BINDIR}) 27 | -------------------------------------------------------------------------------- /ci/samples/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main(int /*argc*/, char** /*argv*/) { 8 | foo::freeFunction(0); 9 | bar::freeFunction(1); 10 | foobar::freeFunction(2); 11 | std::cout << std::endl; 12 | 13 | foo::Foo::staticFunction(int{0}); 14 | bar::Bar::staticFunction(int{1}); 15 | foobar::FooBar::staticFunction(int{2}); 16 | std::cout << std::endl; 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /ci/vagrant/freebsd/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # All Vagrant configuration is done below. The "2" in Vagrant.configure 5 | # configures the configuration version (we support older styles for 6 | # backwards compatibility). Please don't change it unless you know what 7 | # you're doing. 8 | Vagrant.configure("2") do |config| 9 | # The most common configuration options are documented and commented below. 10 | # For a complete reference, please see the online documentation at 11 | # https://docs.vagrantup.com. 12 | 13 | # Every Vagrant development environment requires a box. You can search for 14 | # boxes at https://vagrantcloud.com/search. 15 | config.vm.guest = :freebsd 16 | config.vm.box = "generic/freebsd14" 17 | config.vm.provider "virtualbox" do |v| 18 | v.name = "ci_freebsd" 19 | end 20 | config.ssh.shell = "sh" 21 | 22 | # Disable automatic box update checking. If you disable this, then 23 | # boxes will only be checked for updates when the user runs 24 | # `vagrant box outdated`. This is not recommended. 25 | # config.vm.box_check_update = false 26 | 27 | # Create a forwarded port mapping which allows access to a specific port 28 | # within the machine from a port on the host machine. In the example below, 29 | # accessing "localhost:8080" will access port 80 on the guest machine. 30 | # NOTE: This will enable public access to the opened port 31 | # config.vm.network "forwarded_port", guest: 80, host: 8080 32 | 33 | # Create a forwarded port mapping which allows access to a specific port 34 | # within the machine from a port on the host machine and only allow access 35 | # via 127.0.0.1 to disable public access 36 | # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" 37 | 38 | # Create a private network, which allows host-only access to the machine 39 | # using a specific IP. 40 | # config.vm.network "private_network", ip: "192.168.33.10" 41 | 42 | # Create a public network, which generally matched to bridged network. 43 | # Bridged networks make the machine appear as another physical device on 44 | # your network. 45 | # config.vm.network "public_network" 46 | 47 | # Share an additional folder to the guest VM. The first argument is 48 | # the path on the host to the actual folder. The second argument is 49 | # the path on the guest to mount the folder. And the optional third 50 | # argument is a set of non-required options. 51 | #config.vm.synced_folder "../../..", "/home/vagrant/project" 52 | config.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true 53 | 54 | 55 | # Provider-specific configuration so you can fine-tune various 56 | # backing providers for Vagrant. These expose provider-specific options. 57 | # Example for VirtualBox: 58 | # 59 | # config.vm.provider "virtualbox" do |vb| 60 | # # Display the VirtualBox GUI when booting the machine 61 | # vb.gui = true 62 | # 63 | # # Customize the amount of memory on the VM: 64 | # vb.memory = "1024" 65 | # end 66 | # 67 | # View the documentation for the provider you are using for more 68 | # information on available options. 69 | 70 | # Enable provisioning with a shell script. Additional provisioners such as 71 | # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the 72 | # documentation for more information about their specific syntax and use. 73 | # note: clang installed by default 74 | config.vm.provision "env", type: "shell", inline:<<-SHELL 75 | set -x 76 | pkg update -f 77 | pkg install -y git cmake 78 | SHELL 79 | 80 | config.vm.provision "file", source: "../../../CMakeLists.txt", destination: "$HOME/project/" 81 | config.vm.provision "file", source: "../../../cmake", destination: "$HOME/project/" 82 | config.vm.provision "file", source: "../../../Foo", destination: "$HOME/project/" 83 | config.vm.provision "file", source: "../../../Bar", destination: "$HOME/project/" 84 | config.vm.provision "file", source: "../../../FooBar", destination: "$HOME/project/" 85 | config.vm.provision "file", source: "../../../FooBarApp", destination: "$HOME/project/" 86 | config.vm.provision "file", source: "../../../examples", destination: "$HOME/project/" 87 | 88 | config.vm.provision "devel", type: "shell", inline:<<-SHELL 89 | set -x 90 | cd project 91 | ls 92 | SHELL 93 | 94 | config.vm.provision "configure", type: "shell", inline:<<-SHELL 95 | set -x 96 | cd project 97 | cmake -S. -Bbuild 98 | SHELL 99 | 100 | config.vm.provision "build", type: "shell", inline:<<-SHELL 101 | set -x 102 | cd project 103 | cmake --build build -v 104 | SHELL 105 | 106 | config.vm.provision "test", type: "shell", inline:<<-SHELL 107 | set -x 108 | cd project 109 | cmake --build build --target test -v 110 | SHELL 111 | end 112 | -------------------------------------------------------------------------------- /ci/vagrant/netbsd/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # All Vagrant configuration is done below. The "2" in Vagrant.configure 5 | # configures the configuration version (we support older styles for 6 | # backwards compatibility). Please don't change it unless you know what 7 | # you're doing. 8 | Vagrant.configure("2") do |config| 9 | # The most common configuration options are documented and commented below. 10 | # For a complete reference, please see the online documentation at 11 | # https://docs.vagrantup.com. 12 | 13 | # Every Vagrant development environment requires a box. You can search for 14 | # boxes at https://vagrantcloud.com/search. 15 | config.vm.guest = :netbsd 16 | config.vm.box = "generic/netbsd9" 17 | config.vm.provider "virtualbox" do |v| 18 | v.name = "ci_netbsd" 19 | end 20 | config.ssh.shell = "sh" 21 | 22 | # Disable automatic box update checking. If you disable this, then 23 | # boxes will only be checked for updates when the user runs 24 | # `vagrant box outdated`. This is not recommended. 25 | # config.vm.box_check_update = false 26 | 27 | # Create a forwarded port mapping which allows access to a specific port 28 | # within the machine from a port on the host machine. In the example below, 29 | # accessing "localhost:8080" will access port 80 on the guest machine. 30 | # NOTE: This will enable public access to the opened port 31 | # config.vm.network "forwarded_port", guest: 80, host: 8080 32 | 33 | # Create a forwarded port mapping which allows access to a specific port 34 | # within the machine from a port on the host machine and only allow access 35 | # via 127.0.0.1 to disable public access 36 | # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" 37 | 38 | # Create a private network, which allows host-only access to the machine 39 | # using a specific IP. 40 | # config.vm.network "private_network", ip: "192.168.33.10" 41 | 42 | # Create a public network, which generally matched to bridged network. 43 | # Bridged networks make the machine appear as another physical device on 44 | # your network. 45 | # config.vm.network "public_network" 46 | 47 | # Share an additional folder to the guest VM. The first argument is 48 | # the path on the host to the actual folder. The second argument is 49 | # the path on the guest to mount the folder. And the optional third 50 | # argument is a set of non-required options. 51 | #config.vm.synced_folder "../../..", "/home/vagrant/project" 52 | config.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true 53 | 54 | 55 | # Provider-specific configuration so you can fine-tune various 56 | # backing providers for Vagrant. These expose provider-specific options. 57 | # Example for VirtualBox: 58 | # 59 | # config.vm.provider "virtualbox" do |vb| 60 | # # Display the VirtualBox GUI when booting the machine 61 | # vb.gui = true 62 | # 63 | # # Customize the amount of memory on the VM: 64 | # vb.memory = "1024" 65 | # end 66 | # 67 | # View the documentation for the provider you are using for more 68 | # information on available options. 69 | 70 | # Enable provisioning with a shell script. Additional provisioners such as 71 | # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the 72 | # documentation for more information about their specific syntax and use. 73 | # note: clang installed by default 74 | config.vm.provision "env", type: "shell", inline:<<-SHELL 75 | set -x 76 | pkg update -f 77 | pkg install -y git cmake 78 | SHELL 79 | 80 | config.vm.provision "file", source: "../../../CMakeLists.txt", destination: "$HOME/project/" 81 | config.vm.provision "file", source: "../../../cmake", destination: "$HOME/project/" 82 | config.vm.provision "file", source: "../../../Foo", destination: "$HOME/project/" 83 | config.vm.provision "file", source: "../../../Bar", destination: "$HOME/project/" 84 | config.vm.provision "file", source: "../../../FooBar", destination: "$HOME/project/" 85 | config.vm.provision "file", source: "../../../FooBarApp", destination: "$HOME/project/" 86 | config.vm.provision "file", source: "../../../examples", destination: "$HOME/project/" 87 | 88 | config.vm.provision "devel", type: "shell", inline:<<-SHELL 89 | set -x 90 | cd project 91 | ls 92 | SHELL 93 | 94 | config.vm.provision "configure", type: "shell", inline:<<-SHELL 95 | set -x 96 | cd project 97 | cmake -S. -Bbuild 98 | SHELL 99 | 100 | config.vm.provision "build", type: "shell", inline:<<-SHELL 101 | set -x 102 | cd project 103 | cmake --build build -v 104 | SHELL 105 | 106 | config.vm.provision "test", type: "shell", inline:<<-SHELL 107 | set -x 108 | cd project 109 | cmake --build build --target test -v 110 | SHELL 111 | end 112 | -------------------------------------------------------------------------------- /ci/vagrant/openbsd/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # All Vagrant configuration is done below. The "2" in Vagrant.configure 5 | # configures the configuration version (we support older styles for 6 | # backwards compatibility). Please don't change it unless you know what 7 | # you're doing. 8 | Vagrant.configure("2") do |config| 9 | # The most common configuration options are documented and commented below. 10 | # For a complete reference, please see the online documentation at 11 | # https://docs.vagrantup.com. 12 | 13 | # Every Vagrant development environment requires a box. You can search for 14 | # boxes at https://vagrantcloud.com/search. 15 | config.vm.guest = :openbsd 16 | config.vm.box = "generic/openbsd7" 17 | config.vm.provider "virtualbox" do |v| 18 | v.name = "ci_openbsd" 19 | end 20 | config.ssh.shell = "sh" 21 | 22 | # Disable automatic box update checking. If you disable this, then 23 | # boxes will only be checked for updates when the user runs 24 | # `vagrant box outdated`. This is not recommended. 25 | # config.vm.box_check_update = false 26 | 27 | # Create a forwarded port mapping which allows access to a specific port 28 | # within the machine from a port on the host machine. In the example below, 29 | # accessing "localhost:8080" will access port 80 on the guest machine. 30 | # NOTE: This will enable public access to the opened port 31 | # config.vm.network "forwarded_port", guest: 80, host: 8080 32 | 33 | # Create a forwarded port mapping which allows access to a specific port 34 | # within the machine from a port on the host machine and only allow access 35 | # via 127.0.0.1 to disable public access 36 | # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" 37 | 38 | # Create a private network, which allows host-only access to the machine 39 | # using a specific IP. 40 | # config.vm.network "private_network", ip: "192.168.33.10" 41 | 42 | # Create a public network, which generally matched to bridged network. 43 | # Bridged networks make the machine appear as another physical device on 44 | # your network. 45 | # config.vm.network "public_network" 46 | 47 | # Share an additional folder to the guest VM. The first argument is 48 | # the path on the host to the actual folder. The second argument is 49 | # the path on the guest to mount the folder. And the optional third 50 | # argument is a set of non-required options. 51 | #config.vm.synced_folder "../../..", "/home/vagrant/project" 52 | config.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true 53 | 54 | 55 | # Provider-specific configuration so you can fine-tune various 56 | # backing providers for Vagrant. These expose provider-specific options. 57 | # Example for VirtualBox: 58 | # 59 | # config.vm.provider "virtualbox" do |vb| 60 | # # Display the VirtualBox GUI when booting the machine 61 | # vb.gui = true 62 | # 63 | # # Customize the amount of memory on the VM: 64 | # vb.memory = "1024" 65 | # end 66 | # 67 | # View the documentation for the provider you are using for more 68 | # information on available options. 69 | 70 | # Enable provisioning with a shell script. Additional provisioners such as 71 | # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the 72 | # documentation for more information about their specific syntax and use. 73 | # note: clang installed by default 74 | config.vm.provision "env", type: "shell", inline:<<-SHELL 75 | set -x 76 | pkg update -f 77 | pkg install -y git cmake 78 | SHELL 79 | 80 | config.vm.provision "file", source: "../../../CMakeLists.txt", destination: "$HOME/project/" 81 | config.vm.provision "file", source: "../../../cmake", destination: "$HOME/project/" 82 | config.vm.provision "file", source: "../../../Foo", destination: "$HOME/project/" 83 | config.vm.provision "file", source: "../../../Bar", destination: "$HOME/project/" 84 | config.vm.provision "file", source: "../../../FooBar", destination: "$HOME/project/" 85 | config.vm.provision "file", source: "../../../FooBarApp", destination: "$HOME/project/" 86 | config.vm.provision "file", source: "../../../examples", destination: "$HOME/project/" 87 | 88 | config.vm.provision "devel", type: "shell", inline:<<-SHELL 89 | set -x 90 | cd project 91 | ls 92 | SHELL 93 | 94 | config.vm.provision "configure", type: "shell", inline:<<-SHELL 95 | set -x 96 | cd project 97 | cmake -S. -Bbuild 98 | SHELL 99 | 100 | config.vm.provision "build", type: "shell", inline:<<-SHELL 101 | set -x 102 | cd project 103 | cmake --build build -v 104 | SHELL 105 | 106 | config.vm.provision "test", type: "shell", inline:<<-SHELL 107 | set -x 108 | cd project 109 | cmake --build build --target test -v 110 | SHELL 111 | end 112 | -------------------------------------------------------------------------------- /cmake/CMakeCppConfig.cmake.in: -------------------------------------------------------------------------------- 1 | # CMakeCpp CMake configuration file 2 | 3 | include(CMakeFindDependencyMacro) 4 | find_dependency(ZLIB REQUIRED NO_MODULE) 5 | find_dependency(absl REQUIRED NO_MODULE) 6 | find_dependency(Protobuf REQUIRED NO_MODULE) 7 | 8 | include("${CMAKE_CURRENT_LIST_DIR}/CMakeCppTargets.cmake") 9 | -------------------------------------------------------------------------------- /cmake/check_deps.cmake: -------------------------------------------------------------------------------- 1 | # Check dependencies 2 | if(NOT TARGET ZLIB::ZLIB) 3 | message(FATAL_ERROR "Target ZLIB::ZLIB not available.") 4 | endif() 5 | 6 | if(NOT TARGET absl::base) 7 | message(FATAL_ERROR "Target absl::base not available.") 8 | endif() 9 | set(ABSL_DEPS 10 | absl::base 11 | absl::core_headers 12 | absl::absl_check 13 | absl::absl_log 14 | absl::check 15 | absl::die_if_null 16 | absl::flags 17 | absl::flags_commandlineflag 18 | absl::flags_marshalling 19 | absl::flags_parse 20 | absl::flags_reflection 21 | absl::flags_usage 22 | absl::log 23 | absl::log_flags 24 | absl::log_globals 25 | absl::log_initialize 26 | absl::log_internal_message 27 | absl::cord 28 | absl::random_random 29 | absl::raw_hash_set 30 | absl::hash 31 | absl::leak_check 32 | absl::memory 33 | absl::meta 34 | absl::stacktrace 35 | absl::status 36 | absl::statusor 37 | absl::str_format 38 | absl::strings 39 | absl::synchronization 40 | absl::time 41 | absl::any 42 | ) 43 | 44 | if(NOT TARGET protobuf::libprotobuf) 45 | message(FATAL_ERROR "Target protobuf::libprotobuf not available.") 46 | endif() 47 | 48 | if(NOT TARGET re2::re2) 49 | message(FATAL_ERROR "Target re2::re2 not available.") 50 | endif() 51 | 52 | # CXX Test 53 | if(BUILD_TESTING) 54 | if(NOT TARGET GTest::gtest_main) 55 | message(FATAL_ERROR "Target GTest::gtest_main not available.") 56 | endif() 57 | if(NOT TARGET benchmark::benchmark) 58 | message(FATAL_ERROR "Target benchmark::benchmark not available.") 59 | endif() 60 | endif() 61 | -------------------------------------------------------------------------------- /cmake/cpp.cmake: -------------------------------------------------------------------------------- 1 | # Check primitive types 2 | option(CHECK_TYPE "Check primitive type size" OFF) 3 | if(CHECK_TYPE) 4 | include(CMakePushCheckState) 5 | cmake_push_check_state(RESET) 6 | set(CMAKE_EXTRA_INCLUDE_FILES "cstdint") 7 | include(CheckTypeSize) 8 | check_type_size("long" SIZEOF_LONG LANGUAGE CXX) 9 | message(STATUS "Found long size: ${SIZEOF_LONG}") 10 | check_type_size("long long" SIZEOF_LONG_LONG LANGUAGE CXX) 11 | message(STATUS "Found long long size: ${SIZEOF_LONG_LONG}") 12 | check_type_size("int64_t" SIZEOF_INT64_T LANGUAGE CXX) 13 | message(STATUS "Found int64_t size: ${SIZEOF_INT64_T}") 14 | 15 | check_type_size("unsigned long" SIZEOF_ULONG LANGUAGE CXX) 16 | message(STATUS "Found unsigned long size: ${SIZEOF_ULONG}") 17 | check_type_size("unsigned long long" SIZEOF_ULONG_LONG LANGUAGE CXX) 18 | message(STATUS "Found unsigned long long size: ${SIZEOF_ULONG_LONG}") 19 | check_type_size("uint64_t" SIZEOF_UINT64_T LANGUAGE CXX) 20 | message(STATUS "Found uint64_t size: ${SIZEOF_UINT64_T}") 21 | 22 | check_type_size("int *" SIZEOF_INT_P LANGUAGE CXX) 23 | message(STATUS "Found int * size: ${SIZEOF_INT_P}") 24 | check_type_size("intptr_t" SIZEOF_INTPTR_T LANGUAGE CXX) 25 | message(STATUS "Found intptr_t size: ${SIZEOF_INTPTR_T}") 26 | check_type_size("uintptr_t" SIZEOF_UINTPTR_T LANGUAGE CXX) 27 | message(STATUS "Found uintptr_t size: ${SIZEOF_UINTPTR_T}") 28 | cmake_pop_check_state() 29 | endif() 30 | 31 | include(GNUInstallDirs) 32 | 33 | add_subdirectory(Foo) 34 | add_subdirectory(Bar) 35 | add_subdirectory(FooBar) 36 | 37 | add_subdirectory(FooBarApp) 38 | 39 | # Install 40 | install(EXPORT ${PROJECT_NAME}Targets 41 | NAMESPACE ${PROJECT_NAMESPACE}:: 42 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} 43 | COMPONENT Devel) 44 | include(CMakePackageConfigHelpers) 45 | configure_package_config_file(cmake/${PROJECT_NAME}Config.cmake.in 46 | "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" 47 | INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" 48 | NO_SET_AND_CHECK_MACRO 49 | NO_CHECK_REQUIRED_COMPONENTS_MACRO) 50 | write_basic_package_version_file( 51 | "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 52 | COMPATIBILITY SameMajorVersion) 53 | install( 54 | FILES 55 | "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" 56 | "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 57 | DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" 58 | COMPONENT Devel) 59 | -------------------------------------------------------------------------------- /cmake/dependencies/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(FetchContent) 2 | set(FETCHCONTENT_QUIET OFF) 3 | set(FETCHCONTENT_UPDATES_DISCONNECTED ON) 4 | set(BUILD_SHARED_LIBS ON) 5 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 6 | set(BUILD_TESTING OFF) 7 | set(CMAKE_Fortran_COMPILER OFF) 8 | 9 | # ############################################################################## 10 | # ZLIB 11 | # ############################################################################## 12 | if(BUILD_ZLIB) 13 | message(CHECK_START "Fetching ZLIB") 14 | list(APPEND CMAKE_MESSAGE_INDENT " ") 15 | set(ZLIB_BUILD_EXAMPLES OFF) 16 | FetchContent_Declare( 17 | ZLIB 18 | GIT_REPOSITORY "https://github.com/madler/ZLIB.git" 19 | GIT_TAG "v1.3.1" 20 | PATCH_COMMAND git apply --ignore-whitespace 21 | "${CMAKE_CURRENT_LIST_DIR}/../../patches/ZLIB-v1.3.1.patch") 22 | FetchContent_MakeAvailable(ZLIB) 23 | list(POP_BACK CMAKE_MESSAGE_INDENT) 24 | message(CHECK_PASS "fetched") 25 | endif() 26 | 27 | # ############################################################################## 28 | # ABSEIL-CPP 29 | # ############################################################################## 30 | if(BUILD_absl) 31 | message(CHECK_START "Fetching Abseil-cpp") 32 | list(APPEND CMAKE_MESSAGE_INDENT " ") 33 | set(ABSL_USE_SYSTEM_INCLUDES ON) 34 | # We want Abseil to declare what C++ standard it was compiled with. 35 | set(ABSL_PROPAGATE_CXX_STD ON) 36 | # We want Abseil to keep the INSTALL rules enabled, even though it is a 37 | # subproject. Otherwise the install rules in this project break. 38 | set(ABSL_ENABLE_INSTALL ON) 39 | set(ABSL_BUILD_TESTING OFF) 40 | FetchContent_Declare( 41 | absl 42 | GIT_REPOSITORY "https://github.com/abseil/abseil-cpp.git" 43 | GIT_TAG "20250127.1" 44 | GIT_SHALLOW TRUE 45 | PATCH_COMMAND git apply --ignore-whitespace 46 | "${CMAKE_CURRENT_LIST_DIR}/../../patches/abseil-cpp-20250127.1.patch" 47 | OVERRIDE_FIND_PACKAGE 48 | ) 49 | FetchContent_MakeAvailable(absl) 50 | list(POP_BACK CMAKE_MESSAGE_INDENT) 51 | message(CHECK_PASS "fetched") 52 | endif() 53 | 54 | # ############################################################################## 55 | # Protobuf 56 | # ############################################################################## 57 | if(BUILD_Protobuf) 58 | message(CHECK_START "Fetching Protobuf") 59 | list(APPEND CMAKE_MESSAGE_INDENT " ") 60 | set(protobuf_BUILD_TESTS OFF) 61 | set(protobuf_BUILD_SHARED_LIBS ON) 62 | set(protobuf_BUILD_EXPORT OFF) 63 | set(protobuf_MSVC_STATIC_RUNTIME OFF) 64 | #set(protobuf_BUILD_LIBUPB ON) 65 | FetchContent_Declare( 66 | Protobuf 67 | GIT_REPOSITORY "https://github.com/protocolbuffers/protobuf.git" 68 | GIT_TAG "v30.2" 69 | GIT_SHALLOW TRUE 70 | GIT_SUBMODULES "" 71 | PATCH_COMMAND git apply --ignore-whitespace 72 | "${CMAKE_CURRENT_LIST_DIR}/../../patches/protobuf-v30.2.patch" 73 | ) 74 | FetchContent_MakeAvailable(Protobuf) 75 | list(POP_BACK CMAKE_MESSAGE_INDENT) 76 | message(CHECK_PASS "fetched") 77 | endif() 78 | 79 | # ############################################################################## 80 | # RE2 81 | # ############################################################################## 82 | if(BUILD_re2) 83 | message(CHECK_START "Fetching re2") 84 | list(APPEND CMAKE_MESSAGE_INDENT " ") 85 | set(RE2_BUILD_TESTING OFF) 86 | FetchContent_Declare( 87 | re2 88 | GIT_REPOSITORY "https://github.com/google/re2.git" 89 | GIT_TAG "2024-04-01" 90 | GIT_SHALLOW TRUE 91 | PATCH_COMMAND git apply --ignore-whitespace 92 | "${CMAKE_CURRENT_LIST_DIR}/../../patches/re2-2024-04-01.patch" 93 | ) 94 | FetchContent_MakeAvailable(re2) 95 | list(POP_BACK CMAKE_MESSAGE_INDENT) 96 | message(CHECK_PASS "fetched") 97 | endif() 98 | 99 | ############### 100 | ## TESTING ## 101 | ############### 102 | if(BUILD_googletest) 103 | message(CHECK_START "Fetching googletest") 104 | list(APPEND CMAKE_MESSAGE_INDENT " ") 105 | FetchContent_Declare( 106 | googletest 107 | GIT_REPOSITORY https://github.com/google/googletest.git 108 | GIT_TAG v1.16.0 109 | GIT_SHALLOW TRUE 110 | PATCH_COMMAND git apply --ignore-whitespace 111 | "${CMAKE_CURRENT_LIST_DIR}/../../patches/googletest-v1.16.0.patch" 112 | #PATCH_COMMAND git apply --ignore-whitespace "" 113 | ) 114 | set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) 115 | set(INSTALL_GTEST OFF) 116 | set(GTEST_HAS_ABSL ON) 117 | FetchContent_MakeAvailable(googletest) 118 | list(POP_BACK CMAKE_MESSAGE_INDENT) 119 | message(CHECK_PASS "fetched") 120 | endif() 121 | 122 | if(BUILD_benchmark) 123 | message(CHECK_START "Fetching benchmark") 124 | list(APPEND CMAKE_MESSAGE_INDENT " ") 125 | FetchContent_Declare( 126 | benchmark 127 | GIT_REPOSITORY https://github.com/google/benchmark.git 128 | GIT_TAG v1.9.1 129 | GIT_SHALLOW TRUE 130 | #PATCH_COMMAND git apply --ignore-whitespace "" 131 | ) 132 | set(BENCHMARK_ENABLE_TESTING OFF) 133 | set(BENCHMARK_ENABLE_WERROR OFF) 134 | set(BENCHMARK_ENABLE_INSTALL OFF) 135 | FetchContent_MakeAvailable(benchmark) 136 | list(POP_BACK CMAKE_MESSAGE_INDENT) 137 | message(CHECK_PASS "fetched") 138 | endif() 139 | -------------------------------------------------------------------------------- /cmake/host.CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | 3 | # fetch_git_dependency() 4 | # 5 | # CMake function to download, build and install (in staging area) a dependency at configure 6 | # time. 7 | # 8 | # Parameters: 9 | # NAME: name of the dependency 10 | # REPOSITORY: git url of the dependency 11 | # TAG: tag of the dependency 12 | # PATCH_COMMAND: apply patch 13 | # SOURCE_SUBDIR: Path to source CMakeLists.txt relative to root dir 14 | # CMAKE_ARGS: List of specific CMake args to add 15 | # 16 | # e.g.: 17 | # fetch_git_dependency( 18 | # NAME 19 | # abseil-cpp 20 | # URL 21 | # https://github.com/abseil/abseil-cpp.git 22 | # TAG 23 | # main 24 | # PATCH_COMMAND 25 | # "git apply ${CMAKE_SOURCE_DIR}/patches/abseil-cpp.patch" 26 | # ) 27 | function(fetch_git_dependency) 28 | set(options "") 29 | set(oneValueArgs NAME REPOSITORY TAG PATCH_COMMAND SOURCE_SUBDIR) 30 | set(multiValueArgs CMAKE_ARGS) 31 | cmake_parse_arguments(GIT_DEP 32 | "${options}" 33 | "${oneValueArgs}" 34 | "${multiValueArgs}" 35 | ${ARGN} 36 | ) 37 | message(STATUS "Building ${GIT_DEP_NAME}: ...") 38 | string(TOLOWER ${GIT_DEP_NAME} NAME_LOWER) 39 | 40 | if(GIT_DEP_PATCH_COMMAND) 41 | set(PATCH_CMD "${GIT_DEP_PATCH_COMMAND}") 42 | else() 43 | set(PATCH_CMD "") 44 | endif() 45 | configure_file( 46 | ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt.in 47 | ${CMAKE_BINARY_DIR}/_deps/${NAME_LOWER}-subbuild/CMakeLists.txt @ONLY) 48 | 49 | execute_process( 50 | COMMAND ${CMAKE_COMMAND} -S. -Bproject_build -G "${CMAKE_GENERATOR}" 51 | RESULT_VARIABLE result 52 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/_deps/${NAME_LOWER}-subbuild) 53 | if(result) 54 | message(FATAL_ERROR "CMake step for ${GIT_DEP_NAME} failed: ${result}") 55 | endif() 56 | 57 | execute_process( 58 | COMMAND ${CMAKE_COMMAND} --build project_build --config ${CMAKE_BUILD_TYPE} 59 | RESULT_VARIABLE result 60 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/_deps/${NAME_LOWER}-subbuild) 61 | if(result) 62 | message(FATAL_ERROR "Build step for ${GIT_DEP_NAME} failed: ${result}") 63 | endif() 64 | 65 | if(GIT_DEP_SOURCE_SUBDIR) 66 | add_subdirectory( 67 | ${CMAKE_BINARY_DIR}/_deps/${NAME_LOWER}-src/${GIT_DEP_SOURCE_SUBDIR} 68 | ${CMAKE_BINARY_DIR}/_deps/${NAME_LOWER}-build) 69 | else() 70 | add_subdirectory( 71 | ${CMAKE_BINARY_DIR}/_deps/${NAME_LOWER}-src 72 | ${CMAKE_BINARY_DIR}/_deps/${NAME_LOWER}-build) 73 | endif() 74 | 75 | message(STATUS "Building ${GIT_DEP_NAME}: ...DONE") 76 | endfunction() 77 | 78 | project(host-meta CXX) 79 | 80 | include(FetchContent) 81 | set(FETCHCONTENT_QUIET OFF) 82 | set(FETCHCONTENT_UPDATES_DISCONNECTED ON) 83 | set(BUILD_SHARED_LIBS OFF) 84 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 85 | set(BUILD_TESTING OFF) 86 | 87 | message(CHECK_START "Fetching Abseil-cpp") 88 | list(APPEND CMAKE_MESSAGE_INDENT " ") 89 | set(ABSL_ENABLE_INSTALL ON) 90 | set(ABSL_USE_SYSTEM_INCLUDES ON) 91 | set(ABSL_PROPAGATE_CXX_STD ON) 92 | set(ABSL_BUILD_TESTING OFF) 93 | FetchContent_Declare( 94 | absl 95 | GIT_REPOSITORY "https://github.com/abseil/abseil-cpp.git" 96 | GIT_TAG "20250127.1" 97 | GIT_SHALLOW TRUE 98 | PATCH_COMMAND git apply --ignore-whitespace 99 | "${CMAKE_CURRENT_LIST_DIR}/@PATCHES_PATH@/abseil-cpp-20250127.1.patch" 100 | ) 101 | FetchContent_MakeAvailable(absl) 102 | list(POP_BACK CMAKE_MESSAGE_INDENT) 103 | message(CHECK_PASS "fetched") 104 | 105 | message(CHECK_START "Fetching Protobuf") 106 | list(APPEND CMAKE_MESSAGE_INDENT " ") 107 | set(protobuf_BUILD_TESTS OFF) 108 | set(protobuf_BUILD_SHARED_LIBS ON) 109 | set(protobuf_BUILD_EXPORT OFF) 110 | set(protobuf_MSVC_STATIC_RUNTIME OFF) 111 | set(protobuf_WITH_ZLIB OFF) 112 | FetchContent_Declare( 113 | protobuf 114 | GIT_REPOSITORY "https://github.com/protocolbuffers/protobuf.git" 115 | GIT_TAG "v30.2" 116 | GIT_SHALLOW TRUE 117 | GIT_SUBMODULES "" 118 | PATCH_COMMAND git apply --ignore-whitespace 119 | "${CMAKE_CURRENT_LIST_DIR}/@PATCHES_PATH@/protobuf-v30.2.patch" 120 | ) 121 | FetchContent_MakeAvailable(protobuf) 122 | list(POP_BACK CMAKE_MESSAGE_INDENT) 123 | message(CHECK_PASS "fetched") 124 | -------------------------------------------------------------------------------- /cmake/host.cmake: -------------------------------------------------------------------------------- 1 | if(NOT CMAKE_CROSSCOMPILING) 2 | set(PROTOC_PRG protobuf::protoc) 3 | return() 4 | endif() 5 | 6 | message(STATUS "Subproject: HostTools...") 7 | 8 | file(RELATIVE_PATH 9 | PATCHES_PATH 10 | ${CMAKE_CURRENT_BINARY_DIR}/host_tools 11 | ${CMAKE_CURRENT_SOURCE_DIR}/patches) 12 | 13 | configure_file( 14 | ${CMAKE_CURRENT_SOURCE_DIR}/cmake/host.CMakeLists.txt 15 | ${CMAKE_CURRENT_BINARY_DIR}/host_tools/CMakeLists.txt 16 | @ONLY) 17 | 18 | add_custom_command( 19 | OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/host_tools 20 | COMMAND ${CMAKE_COMMAND} -E remove_directory build 21 | COMMAND ${CMAKE_COMMAND} -S. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=${CMAKE_CURRENT_BINARY_DIR}/host_tools/bin 22 | COMMAND ${CMAKE_COMMAND} --build build --config Release -v 23 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/host_tools 24 | ) 25 | 26 | add_custom_target(host_tools 27 | DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/host_tools 28 | WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 29 | 30 | add_executable(host_protoc IMPORTED GLOBAL) 31 | set_target_properties(host_protoc PROPERTIES 32 | IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/host_tools/bin/protoc) 33 | 34 | add_dependencies(host_protoc host_tools) 35 | set(PROTOC_PRG host_protoc) 36 | 37 | message(STATUS "Subproject: HostTools...DONE") 38 | -------------------------------------------------------------------------------- /cmake/system_deps.cmake: -------------------------------------------------------------------------------- 1 | # Check dependencies 2 | set(CMAKE_THREAD_PREFER_PTHREAD TRUE) 3 | set(THREAD_PREFER_PTHREAD_FLAG TRUE) 4 | find_package(Threads REQUIRED) 5 | 6 | # Tell find_package() to try “Config” mode before “Module” mode if no mode was specified. 7 | # This should avoid find_package() to first find our FindXXX.cmake modules if 8 | # distro package already provide a CMake config file... 9 | set(CMAKE_FIND_PACKAGE_PREFER_CONFIG TRUE) 10 | 11 | # libprotobuf force us to depends on ZLIB::ZLIB target 12 | if(NOT BUILD_ZLIB AND NOT TARGET ZLIB::ZLIB) 13 | find_package(ZLIB REQUIRED) 14 | endif() 15 | 16 | if(NOT BUILD_absl AND NOT TARGET absl::base) 17 | find_package(absl REQUIRED) 18 | endif() 19 | 20 | if(NOT BUILD_Protobuf AND NOT TARGET protobuf::libprotobuf) 21 | find_package(Protobuf REQUIRED) 22 | endif() 23 | 24 | if(NOT BUILD_re2 AND NOT TARGET re2::re2) 25 | find_package(re2 REQUIRED) 26 | endif() 27 | 28 | # CXX Test 29 | if(BUILD_TESTING) 30 | if(NOT BUILD_googletest AND NOT TARGET GTest::gtest_main) 31 | find_package(GTest REQUIRED) 32 | endif() 33 | 34 | if(NOT BUILD_benchmark AND NOT TARGET benchmark::benchmark) 35 | find_package(benchmark REQUIRED) 36 | endif() 37 | endif() 38 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | if(NOT BUILD_EXAMPLES) 2 | return() 3 | endif() 4 | 5 | add_executable(example) 6 | target_sources(example PRIVATE example.cpp) 7 | target_include_directories(example PUBLIC 8 | $) 9 | target_compile_features(example PRIVATE cxx_std_20) 10 | set_target_properties(example PROPERTIES 11 | VERSION ${PROJECT_VERSION} 12 | POSITION_INDEPENDENT_CODE ON 13 | ) 14 | if(APPLE) 15 | set_target_properties(example PROPERTIES 16 | INSTALL_RPATH "@loader_path/../${CMAKE_INSTALL_LIBDIR};@loader_path") 17 | elseif(UNIX) 18 | set_target_properties(example PROPERTIES 19 | INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}:$ORIGIN") 20 | endif() 21 | target_link_libraries(example PRIVATE 22 | #GTest::gtest_main 23 | ${PROJECT_NAMESPACE}::Foo 24 | ${PROJECT_NAMESPACE}::Bar 25 | ${PROJECT_NAMESPACE}::FooBar 26 | ) 27 | 28 | add_test(NAME example COMMAND example) 29 | -------------------------------------------------------------------------------- /examples/example.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int main(int /*argc*/, char** /*argv*/) { 8 | foo::freeFunction(0); 9 | bar::freeFunction(1); 10 | foobar::freeFunction(2); 11 | std::cout << std::endl; 12 | 13 | foo::Foo::staticFunction(int{0}); 14 | bar::Bar::staticFunction(int{1}); 15 | foobar::FooBar::staticFunction(int{2}); 16 | std::cout << std::endl; 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /patches/ZLIB-v1.3.1.patch: -------------------------------------------------------------------------------- 1 | diff --git a/CMakeLists.txt b/CMakeLists.txt 2 | index 15ceebe..03825a2 100644 3 | --- a/CMakeLists.txt 4 | +++ b/CMakeLists.txt 5 | @@ -1,23 +1,21 @@ 6 | -cmake_minimum_required(VERSION 2.4.4...3.15.0) 7 | -set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) 8 | +cmake_minimum_required(VERSION 3.15) 9 | 10 | -project(zlib C) 11 | - 12 | -set(VERSION "1.3.1") 13 | +project(zlib VERSION 1.3.1 LANGUAGES C) 14 | 15 | option(ZLIB_BUILD_EXAMPLES "Enable Zlib Examples" ON) 16 | 17 | -set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables") 18 | -set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") 19 | -set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers") 20 | -set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages") 21 | -set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") 22 | +include(GNUInstallDirs) 23 | +set(INSTALL_BIN_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH "Installation directory for executables") 24 | +set(INSTALL_LIB_DIR "${CMAKE_INSTALL_LIBDIR}" CACHE PATH "Installation directory for libraries") 25 | +set(INSTALL_INC_DIR "${CMAKE_INSTALL_INCLUDEDIR}" CACHE PATH "Installation directory for headers") 26 | +set(INSTALL_MAN_DIR "${CMAKE_INSTALL_MANDIR}" CACHE PATH "Installation directory for manual pages") 27 | +set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_DATADIR}/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") 28 | 29 | include(CheckTypeSize) 30 | include(CheckFunctionExists) 31 | include(CheckIncludeFile) 32 | include(CheckCSourceCompiles) 33 | -enable_testing() 34 | +include(CTest) 35 | 36 | check_include_file(sys/types.h HAVE_SYS_TYPES_H) 37 | check_include_file(stdint.h HAVE_STDINT_H) 38 | @@ -149,12 +147,21 @@ if(MINGW) 39 | set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) 40 | endif(MINGW) 41 | 42 | -add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) 43 | -target_include_directories(zlib PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) 44 | -add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) 45 | -target_include_directories(zlibstatic PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) 46 | -set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) 47 | -set_target_properties(zlib PROPERTIES SOVERSION 1) 48 | +if(BUILD_SHARED_LIBS) 49 | + add_library(ZLIB SHARED ${ZLIB_SRCS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) 50 | + set_target_properties(ZLIB PROPERTIES DEFINE_SYMBOL ZLIB_DLL) 51 | + set_target_properties(ZLIB PROPERTIES SOVERSION 1) 52 | +else() 53 | + add_library(ZLIB STATIC ${ZLIB_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) 54 | +endif() 55 | + 56 | +target_include_directories(ZLIB PUBLIC 57 | + $ 58 | + $ 59 | + $) 60 | + 61 | +add_library(ZLIB::ZLIB ALIAS ZLIB) 62 | + 63 | 64 | if(NOT CYGWIN) 65 | # This property causes shared libraries on Linux to have the full version 66 | @@ -164,26 +171,45 @@ if(NOT CYGWIN) 67 | # 68 | # This has no effect with MSVC, on that platform the version info for 69 | # the DLL comes from the resource file win32/zlib1.rc 70 | - set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION}) 71 | + set_target_properties(ZLIB PROPERTIES VERSION ${ZLIB_FULL_VERSION}) 72 | endif() 73 | 74 | if(UNIX) 75 | # On unix-like platforms the library is almost always called libz 76 | - set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z) 77 | - if(NOT APPLE AND NOT(CMAKE_SYSTEM_NAME STREQUAL AIX)) 78 | - set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"") 79 | + set_target_properties(ZLIB PROPERTIES OUTPUT_NAME z) 80 | + if(NOT APPLE AND NOT(CMAKE_SYSTEM_NAME STREQUAL AIX) AND BUILD_SHARED_LIBS) 81 | + set_target_properties(ZLIB PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"") 82 | endif() 83 | elseif(BUILD_SHARED_LIBS AND WIN32) 84 | # Creates zlib1.dll when building shared library version 85 | - set_target_properties(zlib PROPERTIES SUFFIX "1.dll") 86 | + set_target_properties(ZLIB PROPERTIES SUFFIX "1.dll") 87 | +endif() 88 | + 89 | +if(NOT UNIX) 90 | + set_target_properties(ZLIB PROPERTIES OUTPUT_NAME zlib) 91 | endif() 92 | 93 | -if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL ) 94 | - install(TARGETS zlib zlibstatic 95 | - RUNTIME DESTINATION "${INSTALL_BIN_DIR}" 96 | - ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" 97 | - LIBRARY DESTINATION "${INSTALL_LIB_DIR}" ) 98 | +if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) 99 | + install(TARGETS ZLIB 100 | + EXPORT ZLIBTargets 101 | + RUNTIME DESTINATION "${INSTALL_BIN_DIR}" 102 | + ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" 103 | + LIBRARY DESTINATION "${INSTALL_LIB_DIR}") 104 | + install(EXPORT ZLIBTargets 105 | + NAMESPACE ZLIB:: 106 | + DESTINATION lib/cmake/ZLIB) 107 | + include(CMakePackageConfigHelpers) 108 | + write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/ZLIBConfigVersion.cmake" 109 | + VERSION ${PROJECT_VERSION} 110 | + COMPATIBILITY SameMajorVersion) 111 | + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/ZLIBConfig.cmake" 112 | + "include(\"\${CMAKE_CURRENT_LIST_DIR}/ZLIBTargets.cmake\")" 113 | + ) 114 | + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ZLIBConfig.cmake" 115 | + "${CMAKE_CURRENT_BINARY_DIR}/ZLIBConfigVersion.cmake" 116 | + DESTINATION lib/cmake/ZLIB) 117 | endif() 118 | + 119 | if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL ) 120 | install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}") 121 | endif() 122 | @@ -199,20 +225,20 @@ endif() 123 | #============================================================================ 124 | if(ZLIB_BUILD_EXAMPLES) 125 | add_executable(example test/example.c) 126 | - target_link_libraries(example zlib) 127 | + target_link_libraries(example ZLIB) 128 | add_test(example example) 129 | 130 | add_executable(minigzip test/minigzip.c) 131 | - target_link_libraries(minigzip zlib) 132 | + target_link_libraries(minigzip ZLIB) 133 | 134 | if(HAVE_OFF64_T) 135 | add_executable(example64 test/example.c) 136 | - target_link_libraries(example64 zlib) 137 | + target_link_libraries(example64 ZLIB) 138 | set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") 139 | add_test(example64 example64) 140 | 141 | add_executable(minigzip64 test/minigzip.c) 142 | - target_link_libraries(minigzip64 zlib) 143 | + target_link_libraries(minigzip64 ZLIB) 144 | set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") 145 | endif() 146 | endif() 147 | -------------------------------------------------------------------------------- /patches/abseil-cpp-20250127.1.patch: -------------------------------------------------------------------------------- 1 | diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake 2 | index 32cc28f..e51d6df 100644 3 | --- a/CMake/AbseilDll.cmake 4 | +++ b/CMake/AbseilDll.cmake 5 | @@ -699,31 +699,44 @@ set(ABSL_INTERNAL_TEST_DLL_TARGETS 6 | 7 | include(CheckCXXSourceCompiles) 8 | 9 | -check_cxx_source_compiles( 10 | - [==[ 11 | -#ifdef _MSC_VER 12 | -# if _MSVC_LANG < 201703L 13 | -# error "The compiler defaults or is configured for C++ < 17" 14 | -# endif 15 | -#elif __cplusplus < 201703L 16 | -# error "The compiler defaults or is configured for C++ < 17" 17 | -#endif 18 | -int main() { return 0; } 19 | -]==] 20 | +message(WARNING "ABSL_CXX_STANDARD: ${ABSL_CXX_STANDARD}") 21 | +message(WARNING "CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}") 22 | +message(WARNING "CMAKE_CXX_STANDARD_REQUIRED: ${CMAKE_CXX_STANDARD_REQUIRED}") 23 | +message(WARNING "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") 24 | + 25 | +if(CMAKE_CXX_STANDARD GREATER_EQUAL 17) 26 | + set(ABSL_INTERNAL_AT_LEAST_CXX17 TRUE) 27 | +else() 28 | + check_cxx_source_compiles( 29 | + [==[ 30 | + #ifdef _MSC_VER 31 | + # if _MSVC_LANG < 201703L 32 | + # error "The compiler defaults or is configured for C++ < 17" 33 | + # endif 34 | + #elif __cplusplus < 201703L 35 | + # error "The compiler defaults or is configured for C++ < 17" 36 | + #endif 37 | + int main() { return 0; } 38 | + ]==] 39 | ABSL_INTERNAL_AT_LEAST_CXX17) 40 | +endif() 41 | 42 | -check_cxx_source_compiles( 43 | - [==[ 44 | -#ifdef _MSC_VER 45 | -# if _MSVC_LANG < 202002L 46 | -# error "The compiler defaults or is configured for C++ < 20" 47 | -# endif 48 | -#elif __cplusplus < 202002L 49 | -# error "The compiler defaults or is configured for C++ < 20" 50 | -#endif 51 | -int main() { return 0; } 52 | -]==] 53 | +if(CMAKE_CXX_STANDARD GREATER_EQUAL 20) 54 | + set(ABSL_INTERNAL_AT_LEAST_CXX20 TRUE) 55 | +else() 56 | + check_cxx_source_compiles( 57 | + [==[ 58 | + #ifdef _MSC_VER 59 | + # if _MSVC_LANG < 202002L 60 | + # error "The compiler defaults or is configured for C++ < 20" 61 | + # endif 62 | + #elif __cplusplus < 202002L 63 | + # error "The compiler defaults or is configured for C++ < 20" 64 | + #endif 65 | + int main() { return 0; } 66 | + ]==] 67 | ABSL_INTERNAL_AT_LEAST_CXX20) 68 | +endif() 69 | 70 | if(ABSL_INTERNAL_AT_LEAST_CXX20) 71 | set(ABSL_INTERNAL_CXX_STD_FEATURE cxx_std_20) 72 | @@ -731,6 +744,7 @@ elseif(ABSL_INTERNAL_AT_LEAST_CXX17) 73 | set(ABSL_INTERNAL_CXX_STD_FEATURE cxx_std_17) 74 | else() 75 | set(ABSL_INTERNAL_CXX_STD_FEATURE cxx_std_14) 76 | + message(FATAL_ERROR "Should not pass here !!!") 77 | endif() 78 | 79 | function(absl_internal_dll_contains) 80 | diff --git a/absl/flags/declare.h b/absl/flags/declare.h 81 | index 8d2a856..a154046 100644 82 | --- a/absl/flags/declare.h 83 | +++ b/absl/flags/declare.h 84 | @@ -59,10 +59,15 @@ ABSL_NAMESPACE_END 85 | 86 | // Internal implementation of ABSL_DECLARE_FLAG to allow macro expansion of its 87 | // arguments. Clients must use ABSL_DECLARE_FLAG instead. 88 | +#if defined(_MSC_VER) 89 | +#define ABSL_DECLARE_FLAG_INTERNAL(type, name) \ 90 | + extern absl::Flag FLAGS_##name 91 | +#else 92 | #define ABSL_DECLARE_FLAG_INTERNAL(type, name) \ 93 | extern absl::Flag FLAGS_##name; \ 94 | namespace absl /* block flags in namespaces */ {} \ 95 | /* second redeclaration is to allow applying attributes */ \ 96 | extern absl::Flag FLAGS_##name 97 | +#endif // _MSC_VER 98 | 99 | #endif // ABSL_FLAGS_DECLARE_H_ 100 | -------------------------------------------------------------------------------- /patches/googletest-v1.16.0.patch: -------------------------------------------------------------------------------- 1 | diff --git a/googlemock/include/gmock/internal/gmock-port.h b/googlemock/include/gmock/internal/gmock-port.h 2 | index e9d9e32..ca55646 100644 3 | --- a/googlemock/include/gmock/internal/gmock-port.h 4 | +++ b/googlemock/include/gmock/internal/gmock-port.h 5 | @@ -85,11 +85,11 @@ 6 | 7 | // Macros for declaring flags. 8 | #define GMOCK_DECLARE_bool_(name) \ 9 | - ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name)) 10 | + GTEST_API_ ABSL_DECLARE_FLAG(bool, GMOCK_FLAG_NAME_(name)) 11 | #define GMOCK_DECLARE_int32_(name) \ 12 | - ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name)) 13 | + GTEST_API_ ABSL_DECLARE_FLAG(int32_t, GMOCK_FLAG_NAME_(name)) 14 | #define GMOCK_DECLARE_string_(name) \ 15 | - ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name)) 16 | + GTEST_API_ ABSL_DECLARE_FLAG(std::string, GMOCK_FLAG_NAME_(name)) 17 | 18 | #define GMOCK_FLAG_GET(name) ::absl::GetFlag(GMOCK_FLAG(name)) 19 | #define GMOCK_FLAG_SET(name, value) \ 20 | diff --git a/googletest/cmake/internal_utils.cmake b/googletest/cmake/internal_utils.cmake 21 | index 580ac1c..b338398 100644 22 | --- a/googletest/cmake/internal_utils.cmake 23 | +++ b/googletest/cmake/internal_utils.cmake 24 | @@ -11,6 +11,7 @@ 25 | # - The functions/macros defined in this file may depend on Google 26 | # Test and Google Mock's option() definitions, and thus must be 27 | # called *after* the options have been defined. 28 | +include(GNUInstallDirs) 29 | 30 | # Tweaks CMake's default compiler/linker settings to suit Google Test's needs. 31 | # 32 | @@ -170,11 +171,11 @@ function(cxx_library_with_type name type cxx_flags) 33 | # Set the output directory for build artifacts. 34 | set_target_properties(${name} 35 | PROPERTIES 36 | - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" 37 | - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" 38 | - ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" 39 | - PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" 40 | - COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") 41 | + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}" 42 | + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}" 43 | + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}" 44 | + PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}" 45 | + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") 46 | # Make PDBs match library name. 47 | get_target_property(pdb_debug_postfix ${name} DEBUG_POSTFIX) 48 | set_target_properties(${name} 49 | @@ -185,11 +186,19 @@ function(cxx_library_with_type name type cxx_flags) 50 | COMPILE_PDB_NAME_DEBUG "${name}${pdb_debug_postfix}") 51 | 52 | if (BUILD_SHARED_LIBS OR type STREQUAL "SHARED") 53 | - set_target_properties(${name} 54 | - PROPERTIES 55 | - COMPILE_DEFINITIONS "GTEST_CREATE_SHARED_LIBRARY=1") 56 | + target_compile_definitions(${name} PRIVATE 57 | + "GTEST_CREATE_SHARED_LIBRARY=1") 58 | target_compile_definitions(${name} INTERFACE 59 | - $) 60 | + $ 61 | + $ 62 | + ) 63 | + if(APPLE) 64 | + set_target_properties(${name} PROPERTIES 65 | + INSTALL_RPATH "@loader_path") 66 | + elseif(UNIX) 67 | + set_target_properties(${name} PROPERTIES 68 | + INSTALL_RPATH "$ORIGIN") 69 | + endif() 70 | endif() 71 | if (DEFINED GTEST_HAS_PTHREAD) 72 | target_link_libraries(${name} PUBLIC Threads::Threads) 73 | @@ -226,9 +235,8 @@ function(cxx_executable_with_flags name cxx_flags libs) 74 | COMPILE_FLAGS "${cxx_flags}") 75 | endif() 76 | if (BUILD_SHARED_LIBS) 77 | - set_target_properties(${name} 78 | - PROPERTIES 79 | - COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1") 80 | + target_compile_definitions(${name} PRIVATE 81 | + "GTEST_LINKED_AS_SHARED_LIBRARY=1") 82 | endif() 83 | # To support mixing linking in static and dynamic libraries, link each 84 | # library in with an extra call to target_link_libraries. 85 | diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h 86 | index 8d27c2c..890c953 100644 87 | --- a/googletest/include/gtest/internal/gtest-port.h 88 | +++ b/googletest/include/gtest/internal/gtest-port.h 89 | @@ -867,10 +867,10 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; 90 | #ifndef GTEST_API_ 91 | 92 | #ifdef _MSC_VER 93 | -#if defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY 94 | -#define GTEST_API_ __declspec(dllimport) 95 | -#elif defined(GTEST_CREATE_SHARED_LIBRARY) && GTEST_CREATE_SHARED_LIBRARY 96 | +#if defined(GTEST_CREATE_SHARED_LIBRARY) && GTEST_CREATE_SHARED_LIBRARY 97 | #define GTEST_API_ __declspec(dllexport) 98 | +#elif defined(GTEST_LINKED_AS_SHARED_LIBRARY) && GTEST_LINKED_AS_SHARED_LIBRARY 99 | +#define GTEST_API_ __declspec(dllimport) 100 | #endif 101 | #elif GTEST_HAVE_ATTRIBUTE_(visibility) 102 | #define GTEST_API_ __attribute__((visibility("default"))) 103 | @@ -2287,11 +2287,11 @@ using TimeInMillis = int64_t; // Represents time in milliseconds. 104 | 105 | // Macros for declaring flags. 106 | #define GTEST_DECLARE_bool_(name) \ 107 | - ABSL_DECLARE_FLAG(bool, GTEST_FLAG_NAME_(name)) 108 | + GTEST_API_ ABSL_DECLARE_FLAG(bool, GTEST_FLAG_NAME_(name)) 109 | #define GTEST_DECLARE_int32_(name) \ 110 | - ABSL_DECLARE_FLAG(int32_t, GTEST_FLAG_NAME_(name)) 111 | + GTEST_API_ ABSL_DECLARE_FLAG(int32_t, GTEST_FLAG_NAME_(name)) 112 | #define GTEST_DECLARE_string_(name) \ 113 | - ABSL_DECLARE_FLAG(std::string, GTEST_FLAG_NAME_(name)) 114 | + GTEST_API_ ABSL_DECLARE_FLAG(std::string, GTEST_FLAG_NAME_(name)) 115 | 116 | #define GTEST_FLAG_SAVER_ ::absl::FlagSaver 117 | 118 | -------------------------------------------------------------------------------- /patches/protobuf-v30.2.patch: -------------------------------------------------------------------------------- 1 | diff --git a/CMakeLists.txt b/CMakeLists.txt 2 | index 807ef014..8937d5eb 100644 3 | --- a/CMakeLists.txt 4 | +++ b/CMakeLists.txt 5 | @@ -42,7 +42,7 @@ else (BUILD_SHARED_LIBS) 6 | endif (BUILD_SHARED_LIBS) 7 | option(protobuf_BUILD_SHARED_LIBS "Build Shared Libraries" ${protobuf_BUILD_SHARED_LIBS_DEFAULT}) 8 | include(CMakeDependentOption) 9 | -cmake_dependent_option(protobuf_MSVC_STATIC_RUNTIME "Link static runtime libraries" ON 10 | +cmake_dependent_option(protobuf_MSVC_STATIC_RUNTIME "Link static runtime libraries" OFF 11 | "NOT protobuf_BUILD_SHARED_LIBS" OFF) 12 | set(protobuf_WITH_ZLIB_DEFAULT ON) 13 | option(protobuf_WITH_ZLIB "Build with zlib support" ${protobuf_WITH_ZLIB_DEFAULT}) 14 | @@ -160,24 +160,16 @@ endif() 15 | 16 | set(_protobuf_FIND_ZLIB) 17 | if (protobuf_WITH_ZLIB) 18 | - find_package(ZLIB) 19 | - if (ZLIB_FOUND) 20 | - set(HAVE_ZLIB 1) 21 | - # FindZLIB module define ZLIB_INCLUDE_DIRS variable 22 | - # Set ZLIB_INCLUDE_DIRECTORIES for compatible 23 | - set(ZLIB_INCLUDE_DIRECTORIES ${ZLIB_INCLUDE_DIRECTORIES} ${ZLIB_INCLUDE_DIRS}) 24 | - # Using imported target if exists 25 | - if (TARGET ZLIB::ZLIB) 26 | - set(ZLIB_LIBRARIES ZLIB::ZLIB) 27 | - set(_protobuf_FIND_ZLIB "if(NOT ZLIB_FOUND)\n find_package(ZLIB)\nendif()") 28 | - endif (TARGET ZLIB::ZLIB) 29 | - else (ZLIB_FOUND) 30 | - set(HAVE_ZLIB 0) 31 | - # Explicitly set these to empty (override NOT_FOUND) so cmake doesn't 32 | - # complain when we use them later. 33 | - set(ZLIB_INCLUDE_DIRECTORIES) 34 | - set(ZLIB_LIBRARIES) 35 | - endif (ZLIB_FOUND) 36 | + if (NOT TARGET ZLIB::ZLIB) 37 | + find_package(ZLIB REQUIRED) 38 | + endif() 39 | + set(HAVE_ZLIB 1) 40 | + # FindZLIB module define ZLIB_INCLUDE_DIRS variable 41 | + # Set ZLIB_INCLUDE_DIRECTORIES for compatible 42 | + set(ZLIB_INCLUDE_DIRECTORIES ${ZLIB_INCLUDE_DIRECTORIES} ${ZLIB_INCLUDE_DIRS}) 43 | + # Using imported target if exists 44 | + set(ZLIB_LIBRARIES ZLIB::ZLIB) 45 | + set(_protobuf_FIND_ZLIB "if(NOT ZLIB_FOUND AND NOT TARGET ZLIB::ZLIB)\n find_package(ZLIB REQUIRED)\nendif()") 46 | endif (protobuf_WITH_ZLIB) 47 | 48 | # We need to link with libatomic on systems that do not have builtin atomics, or 49 | @@ -279,7 +271,6 @@ else (MSVC) 50 | endif (MSVC) 51 | 52 | include_directories( 53 | - ${ZLIB_INCLUDE_DIRECTORIES} 54 | ${protobuf_BINARY_DIR} 55 | # Support #include-ing other top-level directories, i.e. upb_generator. 56 | ${protobuf_SOURCE_DIR} 57 | -------------------------------------------------------------------------------- /patches/re2-2024-04-01.patch: -------------------------------------------------------------------------------- 1 | diff --git a/CMakeLists.txt b/CMakeLists.txt 2 | index bdac5af..cedaf6e 100644 3 | --- a/CMakeLists.txt 4 | +++ b/CMakeLists.txt 5 | @@ -131,6 +131,13 @@ set(RE2_HEADERS 6 | 7 | add_library(re2 ${RE2_SOURCES}) 8 | target_compile_features(re2 PUBLIC cxx_std_14) 9 | +if(APPLE) 10 | + set_target_properties(re2 PROPERTIES 11 | + INSTALL_RPATH "@loader_path") 12 | +elseif(UNIX) 13 | + set_target_properties(re2 PROPERTIES 14 | + INSTALL_RPATH "$ORIGIN") 15 | +endif() 16 | target_include_directories(re2 PUBLIC $) 17 | # CMake gives "set_target_properties called with incorrect number of arguments." 18 | # errors if we don't quote ${RE2_HEADERS}, so quote it despite prevailing style. 19 | -------------------------------------------------------------------------------- /tools/cross_compile.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail 3 | 4 | function extract() { 5 | echo "Extracting ${1}..." 6 | case $1 in 7 | *.tar.bz2) tar xjf "$1" ;; 8 | *.tar.xz) tar xJf "$1" ;; 9 | *.tar.gz) tar xzf "$1" ;; 10 | *) 11 | >&2 echo "don't know how to extract '$1'..." 12 | exit 1 13 | esac 14 | } 15 | 16 | function unpack() { 17 | mkdir -p "${ARCHIVE_DIR}" 18 | cd "${ARCHIVE_DIR}" || exit 2 19 | local -r URL=$1 20 | local -r RELATIVE_DIR=$2 21 | local -r DESTINATION="${ARCHIVE_DIR}/${RELATIVE_DIR}" 22 | if [[ ! -d "${DESTINATION}" ]] ; then 23 | echo "Downloading ${URL}..." 24 | local -r ARCHIVE_NAME=$(basename "${URL}") 25 | [[ -f "${ARCHIVE_NAME}" ]] || wget --no-verbose "${URL}" 26 | extract "${ARCHIVE_NAME}" 27 | rm -f "${ARCHIVE_NAME}" 28 | fi 29 | } 30 | 31 | function install_qemu() { 32 | if [[ "${QEMU_ARCH}" == "DISABLED" ]]; then 33 | >&2 echo 'QEMU is disabled !' 34 | return 0 35 | fi 36 | local -r QEMU_VERSION=${QEMU_VERSION:=9.0.2} 37 | local -r QEMU_TARGET=${QEMU_ARCH}-linux-user 38 | 39 | if echo "${QEMU_VERSION} ${QEMU_TARGET}" | cmp --silent "${QEMU_INSTALL}/.build" -; then 40 | echo "qemu ${QEMU_VERSION} up to date!" 41 | return 0 42 | fi 43 | 44 | echo "QEMU_VERSION: ${QEMU_VERSION}" 45 | echo "QEMU_TARGET: ${QEMU_TARGET}" 46 | 47 | rm -rf "${QEMU_INSTALL}" 48 | 49 | # Checking for a tarball before downloading makes testing easier :-) 50 | local -r QEMU_URL="https://download.qemu.org/qemu-${QEMU_VERSION}.tar.xz" 51 | local -r QEMU_DIR="qemu-${QEMU_VERSION}" 52 | unpack "${QEMU_URL}" "${QEMU_DIR}" 53 | cd "${QEMU_DIR}" || exit 2 54 | 55 | ./configure \ 56 | --prefix="${QEMU_INSTALL}" \ 57 | --target-list="${QEMU_TARGET}" \ 58 | --audio-drv-list= \ 59 | --disable-brlapi \ 60 | --disable-curl \ 61 | --disable-curses \ 62 | --disable-docs \ 63 | --disable-gcrypt \ 64 | --disable-gnutls \ 65 | --disable-gtk \ 66 | --disable-libnfs \ 67 | --disable-libssh \ 68 | --disable-nettle \ 69 | --disable-opengl \ 70 | --disable-sdl \ 71 | --disable-virglrenderer \ 72 | --disable-vte 73 | 74 | # wrapper on ninja 75 | make -j8 76 | make install 77 | 78 | echo "$QEMU_VERSION $QEMU_TARGET" > "${QEMU_INSTALL}/.build" 79 | } 80 | 81 | function assert_defined(){ 82 | if [[ -z "${!1}" ]]; then 83 | >&2 echo "Variable '${1}' must be defined" 84 | exit 1 85 | fi 86 | } 87 | 88 | function clean_build() { 89 | # Cleanup previous build 90 | rm -rf "${BUILD_DIR}" 91 | mkdir -p "${BUILD_DIR}" 92 | } 93 | 94 | function expand_bootlin_config() { 95 | # ref: https://toolchains.bootlin.com/ 96 | case "${TARGET}" in 97 | "arm" | "armv7-eabihf") 98 | local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/armv7-eabihf/tarballs/armv7-eabihf--glibc--stable-2024.05-1.tar.xz" 99 | local -r GCC_PREFIX="arm" 100 | local -r GCC_SUFFIX="eabihf" 101 | ;; 102 | "armeb" | "armebv7-eabihf") 103 | local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/armebv7-eabihf/tarballs/armebv7-eabihf--glibc--stable-2024.05-1.tar.xz" 104 | local -r GCC_PREFIX="armeb" 105 | local -r GCC_SUFFIX="eabihf" 106 | ;; 107 | "arm64" | "aarch64") 108 | local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64/tarballs/aarch64--glibc--stable-2024.05-1.tar.xz" 109 | local -r GCC_PREFIX="aarch64" 110 | local -r GCC_SUFFIX="" 111 | ;; 112 | "arm64be" | "aarch64be") 113 | local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64be/tarballs/aarch64be--glibc--stable-2024.05-1.tar.xz" 114 | local -r GCC_PREFIX="aarch64_be" 115 | local -r GCC_SUFFIX="" 116 | ;; 117 | "ppc" | "ppc-440fp") 118 | local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/powerpc-440fp/tarballs/powerpc-440fp--glibc--stable-2024.05-1.tar.xz" 119 | local -r GCC_PREFIX="powerpc" 120 | local -r GCC_SUFFIX="" 121 | ;; 122 | "ppc-e500mc") 123 | local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/powerpc-e500mc/tarballs/powerpc-e500mc--glibc--stable-2024.05-1.tar.xz" 124 | local -r GCC_PREFIX="powerpc" 125 | local -r GCC_SUFFIX="" 126 | QEMU_ARGS+=( -cpu "e500mc" ) 127 | ;; 128 | "ppc64" | "ppc64-power8") 129 | local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/powerpc64-power8/tarballs/powerpc64-power8--glibc--stable-2024.05-1.tar.xz" 130 | local -r GCC_PREFIX="powerpc64" 131 | local -r GCC_SUFFIX="" 132 | ;; 133 | "ppc64le" | "ppc64le-power8") 134 | local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/powerpc64le-power8/tarballs/powerpc64le-power8--glibc--stable-2024.05-1.tar.xz" 135 | local -r GCC_PREFIX="powerpc64le" 136 | local -r GCC_SUFFIX="" 137 | ;; 138 | "riscv32") 139 | local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/riscv32-ilp32d/tarballs/riscv32-ilp32d--glibc--bleeding-edge-2024.05-1.tar.xz" 140 | local -r GCC_PREFIX="riscv32" 141 | local -r GCC_SUFFIX="" 142 | ;; 143 | "riscv64") 144 | local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/riscv64-lp64d/tarballs/riscv64-lp64d--glibc--stable-2024.05-1.tar.xz" 145 | local -r GCC_PREFIX="riscv64" 146 | local -r GCC_SUFFIX="" 147 | ;; 148 | "s390x") 149 | local -r TOOLCHAIN_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/s390x-z13/tarballs/s390x-z13--glibc--stable-2024.05-1.tar.xz" 150 | local -r GCC_PREFIX="s390x" 151 | local -r GCC_SUFFIX="" 152 | ;; 153 | *) 154 | >&2 echo 'unknown power platform' 155 | exit 1 ;; 156 | esac 157 | 158 | local -r TOOLCHAIN_RELATIVE_DIR="${TARGET}" 159 | unpack "${TOOLCHAIN_URL}" "${TOOLCHAIN_RELATIVE_DIR}" 160 | local -r EXTRACT_DIR="${ARCHIVE_DIR}/$(basename ${TOOLCHAIN_URL%.tar.xz})" 161 | 162 | local -r TOOLCHAIN_DIR=${ARCHIVE_DIR}/${TOOLCHAIN_RELATIVE_DIR} 163 | if [[ -d "${EXTRACT_DIR}" ]]; then 164 | mv "${EXTRACT_DIR}" "${TOOLCHAIN_DIR}" 165 | fi 166 | 167 | local -r SYSROOT_DIR="${TOOLCHAIN_DIR}/${GCC_PREFIX}-buildroot-linux-gnu${GCC_SUFFIX}/sysroot" 168 | #local -r STAGING_DIR=${SYSROOT_DIR}-stage 169 | 170 | # Write a Toolchain file 171 | # note: This is manadatory to use a file in order to have the CMake variable 172 | # 'CMAKE_CROSSCOMPILING' set to TRUE. 173 | # ref: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-linux 174 | cat >"${TOOLCHAIN_FILE}" <&2 echo 'unknown platform' 215 | exit 1 ;; 216 | esac 217 | 218 | local -r GCC_URL=${CODESCAPE_URL} 219 | unpack "${GCC_URL}" "${GCC_RELATIVE_DIR}" 220 | 221 | local -r GCC_DIR=${ARCHIVE_DIR}/${GCC_RELATIVE_DIR} 222 | 223 | case "${TARGET}" in 224 | "mips" | "mips32-r6") 225 | local -r MIPS_FLAGS="-EB -mips32r6 -mabi=32" 226 | local -r FLAVOUR="mips-r6-hard" 227 | local -r LIBC_DIR_SUFFIX="lib" 228 | ;; 229 | "mipsel" | "mips32el-r6") 230 | local -r MIPS_FLAGS="-EL -mips32r6 -mabi=32" 231 | local -r FLAVOUR="mipsel-r6-hard" 232 | local -r LIBC_DIR_SUFFIX="lib" 233 | ;; 234 | "mips64" | "mips64-r6") 235 | local -r MIPS_FLAGS="-EB -mips64r6 -mabi=64" 236 | local -r FLAVOUR="mips-r6-hard" 237 | local -r LIBC_DIR_SUFFIX="lib64" 238 | ;; 239 | "mips64el" | "mips64el-r6") 240 | local -r MIPS_FLAGS="-EL -mips64r6 -mabi=64" 241 | local -r FLAVOUR="mipsel-r6-hard" 242 | local -r LIBC_DIR_SUFFIX="lib64" 243 | ;; 244 | *) 245 | >&2 echo 'unknown mips platform' 246 | exit 1 ;; 247 | esac 248 | local -r SYSROOT_DIR=${GCC_DIR}/sysroot 249 | local -r STAGING_DIR=${SYSROOT_DIR}-stage 250 | 251 | # Write a Toolchain file 252 | # note: This is manadatory to use a file in order to have the CMake variable 253 | # 'CMAKE_CROSSCOMPILING' set to TRUE. 254 | # ref: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-linux 255 | cat >"${TOOLCHAIN_FILE}" <&2 echo "QEMU is disabled for ${TARGET}" 295 | return 296 | fi 297 | install_qemu 298 | RUN_CMD="${QEMU_INSTALL}/bin/qemu-${QEMU_ARCH} ${QEMU_ARGS[*]}" 299 | 300 | cd "${BUILD_DIR}" || exit 2 301 | set -x 302 | for test_binary in \ 303 | "${BUILD_DIR}"/bin/FooBarApp \ 304 | "${BUILD_DIR}"/bin/*_test ; do 305 | ${RUN_CMD} "${test_binary}" 306 | done 307 | set +x 308 | } 309 | 310 | function usage() { 311 | local -r NAME=$(basename "$0") 312 | echo -e "$NAME - Build using a cross toolchain. 313 | 314 | SYNOPSIS 315 | \t$NAME [-h|--help] [toolchain|build|qemu|test|all] 316 | 317 | DESCRIPTION 318 | \tCross compile using a cross toolchain. 319 | 320 | \tYou MUST define the following variables before running this script: 321 | \t* TARGET: 322 | \t\tx86_64 323 | \t\tarmv7-eabihf(arm) armebv7-eabihf(armeb) (bootlin) 324 | \t\taarch64(arm64) aarch64be(arm64be) (bootlin) 325 | \t\tmips32-r6(mips) mips32el-r6(mipsel) (codespace) 326 | \t\tmips64-r6(mips64) mips64el-r6(mips64el) (codespace) 327 | \t\tppc-440fp(ppc) ppc-e500mc (bootlin) 328 | \t\tppc64 ppc64le (bootlin) 329 | \t\triscv32 riscv64 (bootlin) 330 | \t\ts390x (bootlin) 331 | 332 | OPTIONS 333 | \t-h --help: show this help text 334 | \ttoolchain: download, unpack toolchain and generate CMake toolchain file 335 | \tbuild: toolchain + build the project using the toolchain file (note: remove previous build dir) 336 | \tqemu: download, unpack and build qemu 337 | \ttest: qemu + run all executable using qemu (note: don't build !) 338 | \tall: build + test (default) 339 | 340 | EXAMPLES 341 | * Using export: 342 | export TARGET=aarch64-linux-gnu 343 | $0 344 | 345 | * One-liner: 346 | TARGET=aarch64-linux-gnu $0" 347 | } 348 | 349 | # Main 350 | function main() { 351 | case ${1} in 352 | -h | --help) 353 | usage; exit ;; 354 | esac 355 | 356 | assert_defined TARGET 357 | 358 | # shellcheck disable=SC2155 359 | declare -r PROJECT_DIR="$(cd -P -- "$(dirname -- "$0")/.." && pwd -P)" 360 | declare -r ARCHIVE_DIR="${PROJECT_DIR}/build_cross/archives" 361 | declare -r BUILD_DIR="${PROJECT_DIR}/build_cross/${TARGET}" 362 | declare -r TOOLCHAIN_FILE=${ARCHIVE_DIR}/toolchain_${TARGET}.cmake 363 | 364 | echo "Target: '${TARGET}'" 365 | 366 | echo "Project dir: '${PROJECT_DIR}'" 367 | echo "Archive dir: '${ARCHIVE_DIR}'" 368 | echo "Build dir: '${BUILD_DIR}'" 369 | echo "toolchain file: '${TOOLCHAIN_FILE}'" 370 | 371 | declare -a CMAKE_DEFAULT_ARGS=( -G ${CMAKE_GENERATOR:-"Unix Makefiles"} ) 372 | declare -a CMAKE_ADDITIONAL_ARGS=() 373 | 374 | declare -a QEMU_ARGS=() 375 | # ref: https://go.dev/doc/install/source#environment 376 | case ${TARGET} in 377 | x86_64) 378 | declare -r QEMU_ARCH=x86_64 ;; 379 | 380 | arm | armv7-eabihf) 381 | expand_bootlin_config 382 | declare -r QEMU_ARCH=arm ;; 383 | armeb | armebv7-eabihf) 384 | expand_bootlin_config 385 | declare -r QEMU_ARCH=DISABLED ;; 386 | arm64 | aarch64) 387 | expand_bootlin_config 388 | declare -r QEMU_ARCH=aarch64 ;; 389 | arm64be | aarch64be) 390 | expand_bootlin_config 391 | declare -r QEMU_ARCH=aarch64_be ;; 392 | 393 | mips | mips32-r6) 394 | expand_codescape_config 395 | declare -r QEMU_ARCH=mips ;; 396 | mipsel | mips32el-r6) 397 | expand_codescape_config 398 | declare -r QEMU_ARCH=mipsel ;; 399 | mips64 | mips64-r6) 400 | expand_codescape_config 401 | declare -r QEMU_ARCH=mips64 ;; 402 | mips64el | mips64el-r6) 403 | expand_codescape_config 404 | declare -r QEMU_ARCH=mips64el ;; 405 | 406 | ppc | ppc-440fp | ppc-e500mc ) 407 | expand_bootlin_config 408 | declare -r QEMU_ARCH=ppc ;; 409 | ppc64 | ppc64-power8) 410 | expand_bootlin_config 411 | declare -r QEMU_ARCH=ppc64 ;; 412 | ppc64le | ppc64le-power8) 413 | expand_bootlin_config 414 | declare -r QEMU_ARCH=ppc64le ;; 415 | 416 | riscv32) 417 | expand_bootlin_config 418 | declare -r QEMU_ARCH=riscv32 ;; 419 | riscv64) 420 | expand_bootlin_config 421 | declare -r QEMU_ARCH=riscv64 ;; 422 | 423 | s390x) 424 | expand_bootlin_config 425 | declare -r QEMU_ARCH=s390x ;; 426 | *) 427 | >&2 echo "Unknown TARGET '${TARGET}'..." 428 | exit 1 ;; 429 | esac 430 | declare -r QEMU_INSTALL=${ARCHIVE_DIR}/qemu-${QEMU_ARCH} 431 | 432 | case ${1} in 433 | toolchain) 434 | exit ;; 435 | build) 436 | build ;; 437 | qemu) 438 | install_qemu ;; 439 | test) 440 | run_test ;; 441 | *) 442 | build 443 | run_test ;; 444 | esac 445 | } 446 | 447 | main "${1:-all}" 448 | --------------------------------------------------------------------------------