├── .gitignore ├── tests ├── integration │ ├── main.cpp │ └── CMakeLists.txt └── CMakeLists.txt ├── include └── somelib │ └── random.h ├── src └── random.cpp ├── .github ├── FUNDING.yml └── workflows │ └── test.yml ├── LICENSE ├── README.md ├── packaging ├── CMakeLists.txt └── SomeLibConfig.cmake ├── CMakeLists.txt └── .clang-format /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /build-shared/ 3 | /build-static/ 4 | .idea 5 | -------------------------------------------------------------------------------- /tests/integration/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | std::cout << "My very random number is: " << SomeLib::getRandomNumber() << "\n"; 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /include/somelib/random.h: -------------------------------------------------------------------------------- 1 | #ifndef SOMELIB_RANDOM_H 2 | #define SOMELIB_RANDOM_H 3 | 4 | #include "somelib/export.h" 5 | 6 | namespace SomeLib { 7 | 8 | SOMELIB_EXPORT int getRandomNumber(); 9 | 10 | } 11 | 12 | #endif //SOMELIB_RANDOM_H 13 | -------------------------------------------------------------------------------- /src/random.cpp: -------------------------------------------------------------------------------- 1 | #include "somelib/random.h" 2 | 3 | namespace SomeLib { 4 | 5 | int getRandomNumber() { 6 | return 42; // chosen by fair dice roll. 7 | // guaranteed to be random. 8 | } 9 | 10 | } // namespace SomeLib 11 | -------------------------------------------------------------------------------- /tests/integration/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.19) 2 | project(example) 3 | 4 | enable_testing() 5 | 6 | find_package(SomeLib 1 REQUIRED ${example_SomeLib_components}) 7 | 8 | add_executable(main main.cpp) 9 | target_link_libraries(main PRIVATE SomeLib::SomeLib) 10 | 11 | add_test(NAME random_is_42 COMMAND main) 12 | set_tests_properties(random_is_42 PROPERTIES 13 | PASS_REGULAR_EXPRESSION "is: 42" 14 | ENVIRONMENT "PATH=$") 15 | 16 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | #github: [alexreinking] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | #patreon: # Replace with a single Patreon username 5 | #open_collective: # Replace with a single Open Collective username 6 | #ko_fi: # Replace with a single Ko-fi username 7 | #tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | #community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | #liberapay: # Replace with a single Liberapay username 10 | #issuehunt: # Replace with a single IssueHunt username 11 | #otechie: # Replace with a single Otechie username 12 | custom: ['https://www.buymeacoffee.com/alexreinking'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Alex Reinking 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SharedStaticStarter 2 | 3 | ![Test workflow](https://github.com/alexreinking/SharedStaticStarter/actions/workflows/test.yml/badge.svg) 4 | 5 | A simple starter project showing how to distribute both static and shared libraries in CMake. 6 | 7 | The basic challenge is that CMake targets represent a single physical library, so there are a bunch of 8 | competing standards for determining whether `SomeLib::SomeLib` ought to be shared or static. In the 9 | associated blog post, I develop this solution from three basic principles: 10 | 11 | 1. The build interface should match the install interface. 12 | 2. Only strict build requirements belong in CMakeLists.txt. 13 | 3. A single project will not mix both shared and static versions of a library. 14 | 15 | For the full story, click here: https://alexreinking.com/blog/building-a-dual-shared-and-static-library-with-cmake.html 16 | 17 | --- 18 | 19 | If this example helps you with your work, consider saying thank you by buying me a coffee! 20 | 21 | [![Buy me a coffee](https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20coffee&emoji=&slug=alexreinking&button_colour=40DCA5&font_colour=ffffff&font_family=Lato&outline_colour=000000&coffee_colour=FFDD00)](https://www.buymeacoffee.com/alexreinking) 22 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: [ 'push' ] 3 | jobs: 4 | test: 5 | name: ${{ matrix.os }} 6 | runs-on: ${{ matrix.os }} 7 | strategy: 8 | fail-fast: false 9 | matrix: 10 | os: [ windows-latest, macos-latest, ubuntu-latest ] 11 | steps: 12 | - name: Install Windows dependencies 13 | if: runner.os == 'Windows' 14 | run: choco install cmake ninja 15 | - name: Install macOS dependencies 16 | if: runner.os == 'macOS' 17 | run: brew install cmake ninja 18 | - name: Install Linux dependencies 19 | if: runner.os == 'Linux' 20 | run: | 21 | wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null \ 22 | | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null 23 | sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main' 24 | sudo apt update 25 | sudo apt install cmake ninja-build 26 | - name: Enable Developer Command Prompt 27 | if: runner.os == 'Windows' 28 | uses: ilammy/msvc-dev-cmd@v1 29 | - name: Check out sources 30 | uses: actions/checkout@v2 31 | - name: Run tests 32 | run: | 33 | cmake -G Ninja -S tests -B build 34 | cd build 35 | ctest --output-on-failure 36 | -------------------------------------------------------------------------------- /packaging/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(GNUInstallDirs) 2 | include(CMakePackageConfigHelpers) 3 | 4 | if (NOT DEFINED SomeLib_INSTALL_CMAKEDIR) 5 | set(SomeLib_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/SomeLib" 6 | CACHE STRING "Path to SomeLib CMake files") 7 | endif () 8 | 9 | install(TARGETS SomeLib EXPORT SomeLib_Targets 10 | RUNTIME COMPONENT SomeLib_Runtime 11 | LIBRARY COMPONENT SomeLib_Runtime 12 | NAMELINK_COMPONENT SomeLib_Development 13 | ARCHIVE COMPONENT SomeLib_Development 14 | INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") 15 | 16 | install(DIRECTORY "${SomeLib_SOURCE_DIR}/include/" "${SomeLib_BINARY_DIR}/include/" 17 | TYPE INCLUDE 18 | COMPONENT SomeLib_Development) 19 | 20 | if (BUILD_SHARED_LIBS) 21 | set(type shared) 22 | else () 23 | set(type static) 24 | endif () 25 | 26 | install(EXPORT SomeLib_Targets 27 | DESTINATION "${SomeLib_INSTALL_CMAKEDIR}" 28 | NAMESPACE SomeLib:: 29 | FILE SomeLib-${type}-targets.cmake 30 | COMPONENT SomeLib_Development) 31 | 32 | write_basic_package_version_file( 33 | SomeLibConfigVersion.cmake 34 | COMPATIBILITY SameMajorVersion) 35 | 36 | install(FILES 37 | "${CMAKE_CURRENT_SOURCE_DIR}/SomeLibConfig.cmake" 38 | "${CMAKE_CURRENT_BINARY_DIR}/SomeLibConfigVersion.cmake" 39 | DESTINATION "${SomeLib_INSTALL_CMAKEDIR}" 40 | COMPONENT SomeLib_Development) 41 | 42 | # TODO: add additional CPack variables here 43 | include(CPack) 44 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.19) 2 | project(SomeLib VERSION 1.0.0) 3 | 4 | ## C++ language configuration boilerplate 5 | 6 | if (NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET AND 7 | NOT DEFINED CMAKE_VISIBILITY_INLINES_HIDDEN) 8 | set(CMAKE_CXX_VISIBILITY_PRESET hidden) 9 | set(CMAKE_VISIBILITY_INLINES_HIDDEN YES) 10 | endif () 11 | 12 | ## Let SomeLib_SHARED_LIBS override BUILD_SHARED_LIBS 13 | 14 | if (DEFINED SomeLib_SHARED_LIBS) 15 | set(BUILD_SHARED_LIBS "${SomeLib_SHARED_LIBS}") 16 | endif () 17 | 18 | ## Create the main SomeLib library target 19 | 20 | add_library(SomeLib src/random.cpp) 21 | add_library(SomeLib::SomeLib ALIAS SomeLib) 22 | set_target_properties(SomeLib PROPERTIES 23 | VERSION ${SomeLib_VERSION} 24 | SOVERSION ${SomeLib_VERSION_MAJOR}) 25 | target_include_directories( 26 | SomeLib PUBLIC "$") 27 | target_compile_features(SomeLib PUBLIC cxx_std_17) 28 | 29 | ## Generate the export header for SomeLib and attach it to the target 30 | 31 | include(GenerateExportHeader) 32 | generate_export_header(SomeLib EXPORT_FILE_NAME include/somelib/export.h) 33 | target_compile_definitions( 34 | SomeLib PUBLIC "$<$>:SOMELIB_STATIC_DEFINE>") 35 | target_include_directories( 36 | SomeLib PUBLIC "$") 37 | 38 | ## Include the install rules if the user wanted them (included by default when top-level) 39 | 40 | string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" is_top_level) 41 | option(SomeLib_INCLUDE_PACKAGING "Include packaging rules for SomeLib" "${is_top_level}") 42 | if (SomeLib_INCLUDE_PACKAGING) 43 | add_subdirectory(packaging) 44 | endif () 45 | -------------------------------------------------------------------------------- /packaging/SomeLibConfig.cmake: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.19) 2 | 3 | set(SomeLib_known_comps static shared) 4 | set(SomeLib_comp_static NO) 5 | set(SomeLib_comp_shared NO) 6 | foreach (SomeLib_comp IN LISTS ${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS) 7 | if (SomeLib_comp IN_LIST SomeLib_known_comps) 8 | set(SomeLib_comp_${SomeLib_comp} YES) 9 | else () 10 | set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE 11 | "SomeLib does not recognize component `${SomeLib_comp}`.") 12 | set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE) 13 | return() 14 | endif () 15 | endforeach () 16 | 17 | if (SomeLib_comp_static AND SomeLib_comp_shared) 18 | set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE 19 | "SomeLib `static` and `shared` components are mutually exclusive.") 20 | set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE) 21 | return() 22 | endif () 23 | 24 | set(SomeLib_static_targets "${CMAKE_CURRENT_LIST_DIR}/SomeLib-static-targets.cmake") 25 | set(SomeLib_shared_targets "${CMAKE_CURRENT_LIST_DIR}/SomeLib-shared-targets.cmake") 26 | 27 | macro(SomeLib_load_targets type) 28 | if (NOT EXISTS "${SomeLib_${type}_targets}") 29 | set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE 30 | "SomeLib `${type}` libraries were requested but not found.") 31 | set(${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE) 32 | return() 33 | endif () 34 | include("${SomeLib_${type}_targets}") 35 | endmacro() 36 | 37 | if (SomeLib_comp_static) 38 | SomeLib_load_targets(static) 39 | elseif (SomeLib_comp_shared) 40 | SomeLib_load_targets(shared) 41 | elseif (DEFINED SomeLib_SHARED_LIBS AND SomeLib_SHARED_LIBS) 42 | SomeLib_load_targets(shared) 43 | elseif (DEFINED SomeLib_SHARED_LIBS AND NOT SomeLib_SHARED_LIBS) 44 | SomeLib_load_targets(static) 45 | elseif (BUILD_SHARED_LIBS) 46 | if (EXISTS "${SomeLib_shared_targets}") 47 | SomeLib_load_targets(shared) 48 | else () 49 | SomeLib_load_targets(static) 50 | endif () 51 | else () 52 | if (EXISTS "${SomeLib_static_targets}") 53 | SomeLib_load_targets(static) 54 | else () 55 | SomeLib_load_targets(shared) 56 | endif () 57 | endif () 58 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | AccessModifierOffset: -4 3 | AlignAfterOpenBracket: Align 4 | AlignConsecutiveAssignments: false 5 | AlignOperands: Align 6 | AlignTrailingComments: true 7 | AllowAllArgumentsOnNextLine: false 8 | AllowAllConstructorInitializersOnNextLine: false 9 | AllowAllParametersOfDeclarationOnNextLine: false 10 | AllowShortBlocksOnASingleLine: Always 11 | AllowShortCaseLabelsOnASingleLine: false 12 | AllowShortFunctionsOnASingleLine: All 13 | AllowShortIfStatementsOnASingleLine: Always 14 | AllowShortLambdasOnASingleLine: All 15 | AllowShortLoopsOnASingleLine: true 16 | AlwaysBreakAfterReturnType: None 17 | AlwaysBreakTemplateDeclarations: Yes 18 | BreakBeforeBraces: Custom 19 | BraceWrapping: 20 | AfterCaseLabel: false 21 | AfterClass: false 22 | AfterControlStatement: Never 23 | AfterEnum: false 24 | AfterFunction: false 25 | AfterNamespace: false 26 | AfterUnion: false 27 | BeforeCatch: false 28 | BeforeElse: false 29 | IndentBraces: false 30 | SplitEmptyFunction: false 31 | SplitEmptyRecord: true 32 | BreakBeforeBinaryOperators: None 33 | BreakBeforeTernaryOperators: true 34 | BreakConstructorInitializers: BeforeColon 35 | BreakInheritanceList: BeforeColon 36 | ColumnLimit: 0 37 | CompactNamespaces: true 38 | ContinuationIndentWidth: 8 39 | IndentCaseLabels: true 40 | IndentPPDirectives: None 41 | IndentWidth: 4 42 | KeepEmptyLinesAtTheStartOfBlocks: true 43 | MaxEmptyLinesToKeep: 2 44 | NamespaceIndentation: None 45 | ObjCSpaceAfterProperty: false 46 | ObjCSpaceBeforeProtocolList: true 47 | PointerAlignment: Right 48 | ReflowComments: false 49 | SpaceAfterCStyleCast: true 50 | SpaceAfterLogicalNot: false 51 | SpaceAfterTemplateKeyword: false 52 | SpaceBeforeAssignmentOperators: true 53 | SpaceBeforeCpp11BracedList: false 54 | SpaceBeforeCtorInitializerColon: true 55 | SpaceBeforeInheritanceColon: true 56 | SpaceBeforeParens: ControlStatements 57 | SpaceBeforeRangeBasedForLoopColon: true 58 | SpaceInEmptyParentheses: false 59 | SpacesBeforeTrailingComments: 2 60 | SpacesInAngles: false 61 | SpacesInCStyleCastParentheses: false 62 | SpacesInContainerLiterals: false 63 | SpacesInParentheses: false 64 | SpacesInSquareBrackets: false 65 | TabWidth: 4 66 | UseTab: Never 67 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.19) 2 | project(tests LANGUAGES NONE) 3 | 4 | enable_testing() 5 | 6 | if (CMAKE_HOST_WIN32) 7 | set(static_opts -DCMAKE_RELEASE_POSTFIX=_static) 8 | set(LDD dumpbin /dependents) 9 | set(EXT .exe) 10 | elseif (CMAKE_HOST_APPLE) 11 | set(LDD otool -L) 12 | else () 13 | set(LDD ldd) 14 | endif () 15 | 16 | # Set up install trees for subsequent tests 17 | 18 | add_test(NAME build_shared 19 | COMMAND ${CMAKE_CTEST_COMMAND} 20 | --build-and-test "${CMAKE_CURRENT_LIST_DIR}/.." "${CMAKE_CURRENT_BINARY_DIR}/build-shared" 21 | --build-generator Ninja 22 | --build-options -DBUILD_SHARED_LIBS=YES -DCMAKE_BUILD_TYPE=Release) 23 | 24 | add_test(NAME build_static 25 | COMMAND ${CMAKE_CTEST_COMMAND} 26 | --build-and-test "${CMAKE_CURRENT_LIST_DIR}/.." "${CMAKE_CURRENT_BINARY_DIR}/build-static" 27 | --build-generator Ninja 28 | --build-options -DBUILD_SHARED_LIBS=NO ${static_opts} -DCMAKE_BUILD_TYPE=Release) 29 | 30 | add_test(NAME install_shared 31 | COMMAND ${CMAKE_COMMAND} --install "${CMAKE_CURRENT_BINARY_DIR}/build-shared" --prefix "${CMAKE_CURRENT_BINARY_DIR}/install-shared") 32 | 33 | add_test(NAME install_shared_both 34 | COMMAND ${CMAKE_COMMAND} --install "${CMAKE_CURRENT_BINARY_DIR}/build-shared" --prefix "${CMAKE_CURRENT_BINARY_DIR}/install-both") 35 | 36 | add_test(NAME install_static 37 | COMMAND ${CMAKE_COMMAND} --install "${CMAKE_CURRENT_BINARY_DIR}/build-static" --prefix "${CMAKE_CURRENT_BINARY_DIR}/install-static") 38 | 39 | add_test(NAME install_static_both 40 | COMMAND ${CMAKE_COMMAND} --install "${CMAKE_CURRENT_BINARY_DIR}/build-static" --prefix "${CMAKE_CURRENT_BINARY_DIR}/install-both") 41 | 42 | set_tests_properties(build_shared build_static PROPERTIES FIXTURES_SETUP "builds") 43 | 44 | set_tests_properties(install_shared install_static install_shared_both install_static_both 45 | PROPERTIES FIXTURES_SETUP "installs" FIXTURES_REQUIRED "builds") 46 | 47 | # Function to encapsulate test creation 48 | 49 | function(add_integration_test) 50 | cmake_parse_arguments(arg "" "NAME;ROOT;EXPECTED" "OPTIONS" ${ARGN}) 51 | 52 | add_test(NAME ${arg_NAME} 53 | COMMAND ${CMAKE_CTEST_COMMAND} 54 | --build-and-test "${CMAKE_CURRENT_LIST_DIR}/integration" "${CMAKE_CURRENT_BINARY_DIR}/${arg_NAME}" 55 | --build-generator ${CMAKE_GENERATOR} 56 | --build-options ${arg_OPTIONS} "-DSomeLib_ROOT=${CMAKE_CURRENT_BINARY_DIR}/${arg_ROOT}" 57 | --test-command ${CMAKE_CTEST_COMMAND}) 58 | 59 | add_test(NAME ${arg_NAME}_linkage_check 60 | COMMAND ${LDD} "${CMAKE_CURRENT_BINARY_DIR}/${arg_NAME}/main${EXT}") 61 | 62 | set_tests_properties(${arg_NAME} PROPERTIES 63 | FIXTURES_SETUP "${arg_NAME}" 64 | FIXTURES_REQUIRED "installs") 65 | 66 | set_tests_properties(${arg_NAME}_linkage_check PROPERTIES 67 | FIXTURES_REQUIRED "${arg_NAME};installs") 68 | 69 | if (arg_EXPECTED STREQUAL "shared") 70 | set_tests_properties(${arg_NAME}_linkage_check PROPERTIES PASS_REGULAR_EXPRESSION "SomeLib") 71 | elseif (arg_EXPECTED STREQUAL "static") 72 | set_tests_properties(${arg_NAME}_linkage_check PROPERTIES FAIL_REGULAR_EXPRESSION "SomeLib") 73 | else () 74 | set_tests_properties(${arg_NAME} PROPERTIES 75 | WILL_FAIL TRUE 76 | FAIL_REGULAR_EXPRESSION "${arg_EXPECTED}") 77 | set_tests_properties(${arg_NAME}_linkage_check PROPERTIES WILL_FAIL TRUE) 78 | endif () 79 | endfunction() 80 | 81 | ## Joint install directory tests 82 | 83 | add_integration_test( 84 | NAME default 85 | ROOT install-both 86 | EXPECTED static 87 | ) 88 | 89 | add_integration_test( 90 | NAME default-static 91 | ROOT install-both 92 | OPTIONS -DBUILD_SHARED_LIBS=NO 93 | EXPECTED static 94 | ) 95 | 96 | add_integration_test( 97 | NAME default-shared 98 | ROOT install-both 99 | OPTIONS -DBUILD_SHARED_LIBS=YES 100 | EXPECTED shared 101 | ) 102 | 103 | add_integration_test( 104 | NAME cache-shared 105 | ROOT install-both 106 | OPTIONS -DSomeLib_SHARED_LIBS=YES 107 | EXPECTED shared 108 | ) 109 | 110 | add_integration_test( 111 | NAME cache-static-override 112 | ROOT install-both 113 | OPTIONS -DSomeLib_SHARED_LIBS=NO -DBUILD_SHARED_LIBS=YES 114 | EXPECTED static 115 | ) 116 | 117 | add_integration_test( 118 | NAME cache-shared-override 119 | ROOT install-both 120 | OPTIONS -DSomeLib_SHARED_LIBS=YES -DBUILD_SHARED_LIBS=NO 121 | EXPECTED shared 122 | ) 123 | 124 | add_integration_test( 125 | NAME component-shared 126 | ROOT install-both 127 | OPTIONS -Dexample_SomeLib_components=shared 128 | EXPECTED shared 129 | ) 130 | 131 | add_integration_test( 132 | NAME component-static-override 133 | ROOT install-both 134 | OPTIONS -Dexample_SomeLib_components=static -DSomeLib_SHARED_LIBS=YES -DBUILD_SHARED_LIBS=YES 135 | EXPECTED static 136 | ) 137 | 138 | add_integration_test( 139 | NAME component-shared-override 140 | ROOT install-both 141 | OPTIONS -Dexample_SomeLib_components=shared -DSomeLib_SHARED_LIBS=NO -DBUILD_SHARED_LIBS=NO 142 | EXPECTED shared 143 | ) 144 | 145 | add_integration_test( 146 | NAME fail-component-both 147 | ROOT install-both 148 | OPTIONS "-Dexample_SomeLib_components=shared$static" 149 | EXPECTED "SomeLib `static` and `shared` components are mutually exclusive." 150 | ) 151 | 152 | add_integration_test( 153 | NAME fail-invalid-component 154 | ROOT install-both 155 | OPTIONS "-Dexample_SomeLib_components=foo" 156 | EXPECTED "SomeLib does not recognize component `foo`." 157 | ) 158 | 159 | ## Shared only 160 | 161 | add_integration_test( 162 | NAME default-shared-only 163 | ROOT install-shared 164 | EXPECTED shared 165 | ) 166 | 167 | add_integration_test( 168 | NAME cache-shared-only 169 | ROOT install-shared 170 | OPTIONS -DSomeLib_SHARED_LIBS=YES -DBUILD_SHARED_LIBS=NO 171 | EXPECTED shared 172 | ) 173 | 174 | add_integration_test( 175 | NAME fail-cache-static-shared-only 176 | ROOT install-shared 177 | OPTIONS -DSomeLib_SHARED_LIBS=NO 178 | EXPECTED "SomeLib `static` libraries were requested but not found" 179 | ) 180 | 181 | add_integration_test( 182 | NAME fail-component-static-shared-only 183 | ROOT install-shared 184 | OPTIONS -Dexample_SomeLib_components=static 185 | EXPECTED "SomeLib `static` libraries were requested but not found" 186 | ) 187 | 188 | ## Static only 189 | 190 | add_integration_test( 191 | NAME default-static-only 192 | ROOT install-static 193 | EXPECTED static 194 | ) 195 | 196 | add_integration_test( 197 | NAME cache-static-only 198 | ROOT install-static 199 | OPTIONS -DSomeLib_SHARED_LIBS=NO -DBUILD_SHARED_LIBS=YES 200 | EXPECTED static 201 | ) 202 | 203 | add_integration_test( 204 | NAME fail-cache-shared-static-only 205 | ROOT install-static 206 | OPTIONS -DSomeLib_SHARED_LIBS=YES 207 | EXPECTED "SomeLib `shared` libraries were requested but not found" 208 | ) 209 | 210 | add_integration_test( 211 | NAME fail-component-shared-static-only 212 | ROOT install-static 213 | OPTIONS -Dexample_SomeLib_components=shared 214 | EXPECTED "SomeLib `shared` libraries were requested but not found" 215 | ) 216 | --------------------------------------------------------------------------------