# LLFIO cmake # (C) 2016-2025 Niall Douglas # File Created: June 2016 # # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License in the accompanying file # Licence.txt or at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # # Distributed under the Boost Software License, Version 1.0. # (See accompanying file Licence.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) cmake_minimum_required(VERSION 3.10 FATAL_ERROR) set(LLFIO_DEPENDENCY_QUICKCPPLIB_GIT_TAG "master" CACHE STRING "Which git tag to use for the QuickCppLib dependency") set(LLFIO_DEPENDENCY_OUTCOME_GIT_TAG "develop" CACHE STRING "Which git tag to use for the Outcome dependency") if(NOT LLFIO_DEPENDENCY_QUICKCPPLIB_GIT_TAG STREQUAL "master") # Don't reuse the bootstrapped git clone as the dependency itself if(CMAKE_BINARY_DIR) set(CTEST_QUICKCPPLIB_CLONE_DIR "${CMAKE_BINARY_DIR}/quickcpplib-bootstrap") else() set(CTEST_QUICKCPPLIB_CLONE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/quickcpplib-bootstrap") endif() endif() include(cmake/QuickCppLibBootstrap.cmake) include(QuickCppLibRequireOutOfSourceBuild) include(QuickCppLibUtils) include(QuickCppLibPolicies) option(LLFIO_USE_EXPERIMENTAL_SG14_STATUS_CODE "Whether to use SG14 status_code for failure handling" OFF) option(LLFIO_ENABLE_DEPENDENCY_SMOKE_TEST "Whether to build executables which are smoke tests that LLFIO is fully working. Used by various package managers such as vcpkg." OFF) option(LLFIO_ASSUME_CROSS_COMPILING "Whether to assume we are cross compiling. Normally automatically detected, but if automatic detection doesn't work, a working will not be found during cmake configure." OFF) option(LLFIO_FORCE_CONCEPTS_OFF "Whether to not auto detect and enable concepts for the LLFIO cmake targets" OFF) option(LLFIO_FORCE_COROUTINES_OFF "Whether to not auto detect and enable coroutines for the LLFIO cmake targets" OFF) option(LLFIO_FORCE_MAPPED_FILES_OFF "Whether to disable memory mapped files support in LLFIO" OFF) option(LLFIO_FORCE_SIGNAL_DETECTION_OFF "Whether to disable detection of signal raises in LLFIO" OFF) option(UNIT_TESTS_BUILD_ALL "Whether to run all of the unit test suite." OFF) set(UNIT_TESTS_CXX_VERSION "latest" CACHE STRING "The version of C++ to use in the header-only unit tests") if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR APPLE) option(LLFIO_USE_LIBDISPATCH "Whether to use libdispatch/Grand Unified Dispatch (defaults on on BSD/Mac OS)" ON) else() option(LLFIO_USE_LIBDISPATCH "Whether to use libdispatch/Grand Unified Dispatch (defaults on on BSD/Mac OS)" OFF) endif() ensure_git_subrepo("${CMAKE_CURRENT_SOURCE_DIR}/include/llfio/ntkernel-error-category/include" "https://github.com/ned14/ntkernel-error-category.git") # Parse the version we tell cmake directly from the version header file ParseProjectVersionFromHpp("${CMAKE_CURRENT_SOURCE_DIR}/include/llfio/version.hpp" VERSIONSTRING) # Sets the usual PROJECT_NAME etc project(llfio VERSION ${VERSIONSTRING} LANGUAGES C CXX) # Also set a *cmake* namespace for this project set(PROJECT_NAMESPACE) # Setup this cmake environment for this project include(QuickCppLibSetupProject) if(NOT llfio_IS_DEPENDENCY) # This file should be updated with the last git SHA next commit UpdateRevisionHppFromGit("${CMAKE_CURRENT_SOURCE_DIR}/include/llfio/revision.hpp") endif() # Find my library dependencies find_quickcpplib_library(quickcpplib GIT_REPOSITORY "https://github.com/ned14/quickcpplib.git" GIT_TAG "${LLFIO_DEPENDENCY_QUICKCPPLIB_GIT_TAG}" REQUIRED IS_HEADER_ONLY ) find_quickcpplib_library(outcome GIT_REPOSITORY "https://github.com/ned14/outcome.git" GIT_TAG "${LLFIO_DEPENDENCY_OUTCOME_GIT_TAG}" REQUIRED IS_HEADER_ONLY ) if(WIN32) set(ntkernel-error-category_IS_DEPENDENCY On) add_subdirectory("include/llfio/ntkernel-error-category" EXCLUDE_FROM_ALL) endif() # Make the standard static and shared libraries, and if supported by this compiler, C++ modules # for both static and shared libraries as well. For the non-C++ module variants, makes the # interface headers into precompiled headers. Only builds all of them if this is the topmost # CMakeLists, else built only if something upstream is dependent on one of them. include(QuickCppLibMakeLibrary) # Make an interface only library so dependent CMakeLists can bring in this header-only library include(QuickCppLibMakeHeaderOnlyLibrary) # If we have concepts, enable those for both myself and all inclusions if(NOT LLFIO_FORCE_CONCEPTS_OFF) apply_cxx_concepts_to(INTERFACE llfio_hl) apply_cxx_concepts_to(PUBLIC llfio_sl llfio_dl) endif() # If we have coroutines, enable those for both myself and all inclusions if(NOT LLFIO_FORCE_COROUTINES_OFF) apply_cxx_coroutines_to(INTERFACE llfio_hl) apply_cxx_coroutines_to(PUBLIC llfio_sl llfio_dl) endif() # Make preprocessed edition of this library target if(NOT llfio_IS_DEPENDENCY AND (NOT DEFINED BUILD_TESTING OR BUILD_TESTING)) if(NOT PYTHONINTERP_FOUND) indented_message(WARNING "NOT rebuilding preprocessed edition of library due to python not being installed") else() function(make_single_header target name) add_partial_preprocess(${target} "${name}" "${CMAKE_CURRENT_SOURCE_DIR}/include/llfio/revision.hpp" ${ARGN} -I ../quickcpplib/include -I ../outcome/include --passthru-defines --passthru-unfound-includes --passthru-unknown-exprs --passthru-comments --line-directive --compress # --debug -U QUICKCPPLIB_ENABLE_VALGRIND -U DOXYGEN_SHOULD_SKIP_THIS -U DOXYGEN_IS_IN_THE_HOUSE -U STANDARDESE_IS_IN_THE_HOUSE -U __cpp_modules -D LLFIO_INCLUDE_ALL WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" ) if(NOT CMAKE_VERSION VERSION_LESS 3.3) add_dependencies(llfio_hl ${target}) endif() endfunction() make_single_header(llfio_hl-pp "${CMAKE_CURRENT_SOURCE_DIR}/single-header/llfio.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/include/llfio/v2.0/llfio.hpp" #-D QUICKCPPLIB_USE_STD_BYTE -D QUICKCPPLIB_USE_STD_OPTIONAL -D QUICKCPPLIB_USE_STD_SPAN #-U gsl_COMPILER_MSVC_VERSION -U gsl_HAS_CPP0X -D gsl_CPLUSPLUS=201703 -D __cplusplus=201703 #-D LLFIO_LEAN_AND_MEAN -U _WIN32 #-D LLFIO_EXPERIMENTAL_STATUS_CODE=1 ) make_single_header(llfio_hl-pp-abi "${CMAKE_CURRENT_SOURCE_DIR}/single-header/abi.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/include/llfio/v2.0/llfio.hpp" -D LLFIO_EXPERIMENTAL_STATUS_CODE=1 -D LLFIO_DISABLE_ABI_PERMUTATION=1 -D OUTCOME_DISABLE_ABI_PERMUTATION=1 -D QUICKCPPLIB_DISABLE_ABI_PERMUTATION=1 -U LLFIO_UNSTABLE_VERSION -U OUTCOME_UNSTABLE_VERSION) # add_partial_preprocess(llfio_hl-docs # "${CMAKE_CURRENT_SOURCE_DIR}/single-header/docs.hpp" # "${CMAKE_CURRENT_SOURCE_DIR}/include/llfio/revision.hpp" # "${CMAKE_CURRENT_SOURCE_DIR}/include/llfio/v2.0/llfio.hpp" # -D QUICKCPPLIB_USE_STD_BYTE -D QUICKCPPLIB_USE_STD_OPTIONAL -D QUICKCPPLIB_USE_STD_SPAN # -U gsl_COMPILER_MSVC_VERSION -U gsl_HAS_CPP0X -D gsl_CPLUSPLUS=201703 -D __cplusplus=201703 # -D LLFIO_HEADERS_ONLY=0 # -D LLFIO_DISABLE_ABI_PERMUTATION=1 # -D OUTCOME_DISABLE_ABI_PERMUTATION=1 # -D QUICKCPPLIB_DISABLE_ABI_PERMUTATION=1 # -U LLFIO_UNSTABLE_VERSION # -U OUTCOME_UNSTABLE_VERSION # -I ../quickcpplib/include -I ../outcome/include # --passthru-unfound-includes # --passthru-comments # --debug # -U QUICKCPPLIB_ENABLE_VALGRIND # -D DOXYGEN_SHOULD_SKIP_THIS -D DOXYGEN_IS_IN_THE_HOUSE # -U __cpp_modules # -D LLFIO_INCLUDE_ALL # WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" # ) # if(NOT CMAKE_VERSION VERSION_LESS 3.3) # add_dependencies(llfio_hl llfio_hl-docs) # endif() endif() # Create a custom doxygen generation target include(QuickCppLibMakeDoxygen) endif() # Set the standard definitions for these libraries and bring in the all_* helper functions include(QuickCppLibApplyDefaultDefinitions) # Set the C++ features this library requires all_compile_features(PUBLIC cxx_std_17) set(check_cxx_source_linkage_flags) if(NOT CMAKE_CXX_STANDARD) if(MSVC) set(check_cxx_source_linkage_flags /std:c++17) else() set(check_cxx_source_linkage_flags -std=c++17) endif() endif() # Set the library dependencies this library has all_link_libraries(PUBLIC Threads::Threads $<$:rt>) if(LLFIO_FORCE_SIGNAL_DETECTION_OFF) all_compile_definitions(PRIVATE LLFIO_DISABLE_SIGNAL_GUARD=1) endif() if(TARGET outcome::hl) all_link_libraries(PUBLIC outcome::hl) endif() if(TARGET quickcpplib::hl) all_link_libraries(PUBLIC quickcpplib::hl) endif() # Set the system dependencies this library has include(CheckCXXSourceCompiles) include(CheckCXXSourceRuns) function(check_cxx_source_linkage prog var) set(CMAKE_REQUIRED_FLAGS ${check_cxx_source_linkage_flags}) if(MSVC AND CMAKE_GENERATOR MATCHES "Ninja") set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} /EHsc") endif() if(CMAKE_CXX_STANDARD) if(MSVC) set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} /std:c++${CMAKE_CXX_STANDARD}") else() set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++${CMAKE_CXX_STANDARD}") endif() endif() if(CMAKE_SYSTEM_PROCESSOR STREQUAL ${CMAKE_HOST_SYSTEM_PROCESSOR} AND NOT LLFIO_ASSUME_CROSS_COMPILING) check_cxx_source_runs("${prog}" ${var}) else() check_cxx_source_compiles("${prog}" ${var}) endif() set(${var} "${${var}}" PARENT_SCOPE) endfunction() # Do we have native that just works without any extra effort? # We have to check if it runs, as binaries may link, but fail to run due to missing symbols check_cxx_source_linkage(" #include int main() { try { return std::filesystem::path(\"hi\").empty(); } catch(std::filesystem::filesystem_error) { return 1; } } " CXX_HAS_CXX17_FILESYSTEM) if(NOT CXX_HAS_CXX17_FILESYSTEM) indented_message(FATAL_ERROR "FATAL: C++ 17 is not available, use a LLFIO from before year 2025 if you want legacy polyfill support") endif() if(LLFIO_FORCE_MAPPED_FILES_OFF) all_compile_definitions(PUBLIC LLFIO_EXCLUDE_MAPPED_FILE_HANDLE=1) endif() if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") all_link_libraries(PUBLIC util) endif() # Set any macros this library requires all_compile_definitions(PRIVATE LLFIO_INCLUDE_STORAGE_PROFILE=1) foreach(target ${llfio_EXAMPLE_TARGETS}) target_compile_definitions(${target} PRIVATE LLFIO_INCLUDE_STORAGE_PROFILE=1) endforeach() if(LLFIO_USE_EXPERIMENTAL_SG14_STATUS_CODE) all_compile_definitions(PUBLIC LLFIO_EXPERIMENTAL_STATUS_CODE=1) endif() if(WIN32) all_compile_definitions(PRIVATE _WIN32_WINNT=0x601) ## Target Win7 target_compile_definitions(llfio_hl INTERFACE _WIN32_WINNT=0x601) ## Target Win7 if(NOT LLFIO_USE_EXPERIMENTAL_SG14_STATUS_CODE) target_link_libraries(llfio_hl INTERFACE ntkernel-error-category::hl) target_link_libraries(llfio_dl PUBLIC ntkernel-error-category::dl) target_link_libraries(llfio_sl PUBLIC ntkernel-error-category::sl) endif() endif() # Anyone using the static or dynamic libraries is not using the header only variant target_compile_definitions(llfio_sl INTERFACE LLFIO_HEADERS_ONLY=0) target_compile_definitions(llfio_dl INTERFACE LLFIO_HEADERS_ONLY=0) target_compile_definitions(llfio_sl PRIVATE LLFIO_SOURCE=1 LLFIO_STATIC_LINK=1) target_compile_definitions(llfio_dl PRIVATE LLFIO_SOURCE=1 LLFIO_DYN_LINK=1) foreach(special ${SPECIAL_BUILDS}) target_compile_definitions(llfio_sl-${special} INTERFACE LLFIO_HEADERS_ONLY=0) target_compile_definitions(llfio_dl-${special} INTERFACE LLFIO_HEADERS_ONLY=0) target_compile_definitions(llfio_sl-${special} PRIVATE LLFIO_SOURCE=1 LLFIO_STATIC_LINK=1) target_compile_definitions(llfio_dl-${special} PRIVATE LLFIO_SOURCE=1 LLFIO_DYN_LINK=1) endforeach() if(TARGET llfio-example_single-header) target_compile_features(llfio-example_single-header PRIVATE cxx_std_17) endif() if(NOT llfio_IS_DEPENDENCY AND (NOT DEFINED BUILD_TESTING OR BUILD_TESTING)) # For all possible configurations of this library, add each test set(llfio_TESTS_DISABLE_PRECOMPILE_HEADERS "llfio_hl--coroutines" "llfio_sl--coroutines" "llfio_dl--coroutines" ) include(QuickCppLibMakeStandardTests) # For each test target, set definitions and linkage foreach(target ${llfio_COMPILE_TEST_TARGETS} ${llfio_TEST_TARGETS}) target_compile_definitions(${target} PRIVATE LLFIO_INCLUDE_STORAGE_PROFILE=1) endforeach() find_quickcpplib_library(kerneltest GIT_REPOSITORY "https://github.com/ned14/kerneltest.git" REQUIRED IS_HEADER_ONLY ) foreach(test_target ${llfio_TEST_TARGETS}) target_link_libraries(${test_target} PRIVATE kerneltest::hl) if(test_target MATCHES coroutines) apply_cxx_coroutines_to(PRIVATE ${test_target}) endif() endforeach() if(MSVC) foreach(test_target ${llfio_TEST_TARGETS}) target_compile_options(${test_target} PRIVATE /wd4503) ## decorated name length exceeded if(NOT CLANG) target_compile_options(${test_target} PRIVATE /permissive-) ## future parsing endif() endforeach() endif() # Duplicate all tests into C++ exceptions disabled forms set(noexcept_tests) set(first_test_target_noexcept) set(first_test_target_permissive) foreach(testtarget ${llfio_TEST_TARGETS}) if(testtarget MATCHES "llfio_hl--(.+)$") set(testname ${CMAKE_MATCH_1}) if(TRUE) get_target_property(testsource ${testtarget} SOURCES) set(target_name "llfio_hl--${testname}-noexcept") add_executable(${target_name} "${testsource}") if(NOT first_test_target_noexcept) set(first_test_target_noexcept ${target_name}) endif() set_target_properties(${target_name} PROPERTIES DISABLE_PRECOMPILE_HEADERS On) target_link_libraries(${target_name} PRIVATE kerneltest::hl) add_dependencies(_hl ${target_name}) list(APPEND noexcept_tests ${target_name}) if(MSVC AND NOT CLANG) # Disable warnings "C++ exception handler used" and "noexcept used with no exception handling" target_compile_options(${target_name} PRIVATE /wd4530 /wd4577) # target_compile_options(${target_name} PRIVATE /permissive-) # test bug report #142 endif() target_link_libraries(${target_name} PRIVATE llfio::hl) set_target_properties(${target_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" POSITION_INDEPENDENT_CODE ON CXX_EXCEPTIONS OFF CXX_RTTI OFF ) add_test(NAME ${target_name} CONFIGURATIONS Debug Release RelWithDebInfo MinSizeRel COMMAND $ --reporter junit --out $.junit.xml ) if(MSVC AND NOT CLANG) set(target_name "llfio_hl--${testname}-permissive") add_executable(${target_name} "${testsource}") if(NOT first_test_target_permissive) set(first_test_target_permissive ${target_name}) elseif(${target_name} MATCHES "coroutines") set_target_properties(${target_name} PROPERTIES DISABLE_PRECOMPILE_HEADERS On) elseif(COMMAND target_precompile_headers) target_precompile_headers(${target_name} REUSE_FROM ${first_test_target_permissive}) endif() target_link_libraries(${target_name} PRIVATE kerneltest::hl) add_dependencies(_hl ${target_name}) target_link_libraries(${target_name} PRIVATE llfio::hl) target_compile_options(${target_name} PRIVATE /permissive) set_target_properties(${target_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" POSITION_INDEPENDENT_CODE ON ) endif() endif() endif() endforeach() add_custom_target(${PROJECT_NAME}-noexcept COMMENT "Building all tests with C++ exceptions disabled ...") add_dependencies(${PROJECT_NAME}-noexcept ${noexcept_tests}) # Example targets should have an example- prefix foreach(target ${llfio_COMPILE_TEST_TARGETS}) get_target_property(prop ${target} SOURCES) list(GET prop 0 prop) if(prop MATCHES "example/.*") get_target_property(prop ${target} OUTPUT_NAME) if(NOT prop) set(prop "${target}") endif() string(REGEX REPLACE "llfio_([^-][^-])-([^-]*)-(.+)" "llfio_\\1-\\2-example_\\3" prop "${prop}") set_target_properties(${target} PROPERTIES OUTPUT_NAME "${prop}") endif() endforeach() # Turn on latest C++ where possible for the test suite if(UNIT_TESTS_CXX_VERSION STREQUAL "latest") set(LATEST_CXX_FEATURE) foreach(feature ${CMAKE_CXX_COMPILE_FEATURES}) if(feature STREQUAL "cxx_std_26") if(NOT MSVC OR MSVC_VERSION VERSION_GREATER_EQUAL 1930) set(LATEST_CXX_FEATURE "cxx_std_26") indented_message(STATUS "NOTE: This compiler claims to support C++ 26, enabling for header-only unit test suite") endif() endif() endforeach() if(NOT LATEST_CXX_FEATURE) foreach(feature ${CMAKE_CXX_COMPILE_FEATURES}) if(feature STREQUAL "cxx_std_23") if(NOT MSVC OR MSVC_VERSION VERSION_GREATER_EQUAL 1930) set(LATEST_CXX_FEATURE "cxx_std_23") indented_message(STATUS "NOTE: This compiler claims to support C++ 23, enabling for header-only unit test suite") endif() endif() endforeach() endif() if(NOT LATEST_CXX_FEATURE) foreach(feature ${CMAKE_CXX_COMPILE_FEATURES}) if(feature STREQUAL "cxx_std_20") if(NOT MSVC OR MSVC_VERSION VERSION_GREATER_EQUAL 1930) set(LATEST_CXX_FEATURE "cxx_std_20") indented_message(STATUS "NOTE: This compiler claims to support C++ 20, enabling for header-only unit test suite") endif() endif() endforeach() endif() elseif(UNIT_TESTS_CXX_VERSION) set(LATEST_CXX_FEATURE "cxx_std_${UNIT_TESTS_CXX_VERSION}") endif() if(LATEST_CXX_FEATURE) # Turn on latest C++ where possible for the header only test suite foreach(test_target ${llfio_TEST_TARGETS} ${llfio_EXAMPLE_TARGETS}) if(test_target MATCHES _hl) target_compile_features(${test_target} PUBLIC ${LATEST_CXX_FEATURE}) endif() endforeach() endif() endif() if(LLFIO_ENABLE_DEPENDENCY_SMOKE_TEST) set(LLFIO_SMOKE_TESTS) add_executable(llfio-dependency-smoke-test "test-packaging/example.cpp") list(APPEND LLFIO_SMOKE_TESTS llfio-dependency-smoke-test) foreach(target ${LLFIO_SMOKE_TESTS}) target_link_libraries(${target} PRIVATE llfio::dl) set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" ) add_test(NAME ${target} CONFIGURATIONS Debug Release RelWithDebInfo MinSizeRel COMMAND $ --reporter junit --out $.junit.xml ) endforeach() endif() # Cache this library's auto scanned sources for later reuse include(QuickCppLibCacheLibrarySources) # Dependencies needed to consume our cmake package set(PROJECT_PACKAGE_DEPENDENCIES [=[ include(CMakeFindDependencyMacro) find_dependency(quickcpplib) find_dependency(outcome) ]=]) # Make available this library for install and export include(QuickCppLibMakeInstall) if(WIN32 AND NOT LLFIO_USE_EXPERIMENTAL_SG14_STATUS_CODE) set_target_properties(ntkernel-error-category_hl PROPERTIES EXPORT_NAME ntkernel-error-category_hl) set_target_properties(ntkernel-error-category_sl PROPERTIES EXPORT_NAME ntkernel-error-category_sl) set_target_properties(ntkernel-error-category_dl PROPERTIES EXPORT_NAME ntkernel-error-category_dl) install(TARGETS ntkernel-error-category_hl EXPORT llfioExports COMPONENT headers INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" ) install(TARGETS ntkernel-error-category_sl EXPORT llfioSlExports COMPONENT sl INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" ) install(TARGETS ntkernel-error-category_dl EXPORT llfioDlExports COMPONENT dl INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" ) endif() include(QuickCppLibMakeExport)