# Copyright (c) 2019, QuantStack and Mamba Contributors # # Distributed under the terms of the BSD 3-Clause License. # # The full license is in the file LICENSE, distributed with this software. cmake_minimum_required(VERSION 3.16) cmake_policy(SET CMP0025 NEW) # Introduced in cmake 3.0 cmake_policy(SET CMP0077 NEW) # Introduced in cmake 3.13 project(libmamba) set(LIBMAMBA_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) set(LIBMAMBA_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) set(LIBMAMBA_DATA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/data) # Versioning # =========== file( STRINGS "${LIBMAMBA_INCLUDE_DIR}/mamba/version.hpp" libmamba_version_defines REGEX "#define LIBMAMBA_VERSION_(MAJOR|MINOR|PATCH)" ) foreach(ver ${libmamba_version_defines}) if(ver MATCHES "#define LIBMAMBA_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$") set( LIBMAMBA_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}" CACHE INTERNAL "" ) endif() endforeach() set( ${PROJECT_NAME}_VERSION ${LIBMAMBA_VERSION_MAJOR}.${LIBMAMBA_VERSION_MINOR}.${LIBMAMBA_VERSION_PATCH} ) message(STATUS "Building libmamba v${${PROJECT_NAME}_VERSION}") # Binary version See the following URL for explanations about the binary versioning # https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info file( STRINGS "${LIBMAMBA_INCLUDE_DIR}/mamba/version.hpp" libmamba_version_defines REGEX "#define LIBMAMBA_BINARY_(CURRENT|REVISION|AGE)" ) foreach(ver ${libmamba_version_defines}) if(ver MATCHES "#define LIBMAMBA_BINARY_(CURRENT|REVISION|AGE) +([^ ]+)$") set( LIBMAMBA_BINARY_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}" CACHE INTERNAL "" ) endif() endforeach() set( LIBMAMBA_BINARY_VERSION ${LIBMAMBA_BINARY_CURRENT}.${LIBMAMBA_BINARY_REVISION}.${LIBMAMBA_BINARY_AGE} ) message(STATUS "libmamba binary version: v${LIBMAMBA_BINARY_VERSION}") # Build options # ============= set( BUILD_LOG_LEVEL "TRACE" CACHE STRING "Logger active level at compile time" ) if(NOT ${BUILD_LOG_LEVEL} MATCHES "^(TRACE|DEBUG|INFO|WARN|ERROR|CRITICAL|OFF)$") message( FATAL_ERROR "Invalid log level: ${BUILD_LOG_LEVEL}, should be one of { TRACE, DEBUG, INFO, WARN, ERROR, CRITICAL, OFF }" ) endif() # TODO: move this into the mamba_create_target macro if(BUILD_STATIC) add_definitions(-DLIBMAMBA_STATIC_DEPS) endif() if(WIN32) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) endif() option(ENABLE_ASAN "Enable AddressSanitizer (currently only supported on GCC and Clang)" OFF) if(ENABLE_ASAN) message( WARNING "AddressSanitizer instrumentation will be injected into binaries - do not release these binaries" ) add_compile_options(-fno-omit-frame-pointer -fsanitize=address) add_link_options(-fno-omit-frame-pointer -fsanitize=address) endif() option(ENABLE_TSAN "Enable ThreadSanitizer (currently only supported on GCC and Clang)" OFF) if(ENABLE_TSAN) message( WARNING "ThreadSanitizer instrumentation will be injected into binaries - do not release these binaries" ) add_compile_options(-fno-omit-frame-pointer -fsanitize=thread) add_link_options(-fno-omit-frame-pointer -fsanitize=thread) endif() option( ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (currently only supported on GCC and Clang)" OFF ) if(ENABLE_UBSAN) message( WARNING "UndefinedBehaviorSanitizer instrumentation will be injected into binaries - do not release these binaries" ) add_compile_options(-fno-omit-frame-pointer -fsanitize=undefined) add_link_options(-fno-omit-frame-pointer -fsanitize=undefined) endif() # Source files # ============ find_package(Python3 COMPONENTS Interpreter) set( SHELL_SCRIPTS mamba.sh mamba.csh mamba.bat activate.bat _mamba_activate.bat mamba_hook.bat mamba_hook.ps1 Mamba.psm1 mamba.xsh mamba.fish compile_pyc.py mamba_completion.posix ) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/shell_scripts) foreach(script ${SHELL_SCRIPTS}) string(REPLACE "." "_" script_var ${script}) add_custom_command( OUTPUT shell_scripts/${script}.cpp DEPENDS data/${script} COMMAND ${Python3_EXECUTABLE} ${LIBMAMBA_DATA_DIR}/bin2header.py --extern -v data_${script_var} -i ${CMAKE_CURRENT_SOURCE_DIR}/data/${script} -o ${CMAKE_CURRENT_BINARY_DIR}/shell_scripts/${script}.cpp ) endforeach() set( LIBMAMBA_SOURCES longpath.manifest ${LIBMAMBA_SOURCE_DIR}/version.cpp # Filesystem library ${LIBMAMBA_SOURCE_DIR}/fs/filesystem.cpp # C++ utility library ${LIBMAMBA_SOURCE_DIR}/util/cfile.cpp ${LIBMAMBA_SOURCE_DIR}/util/cryptography.cpp ${LIBMAMBA_SOURCE_DIR}/util/encoding.cpp ${LIBMAMBA_SOURCE_DIR}/util/environment.cpp ${LIBMAMBA_SOURCE_DIR}/util/os_linux.cpp ${LIBMAMBA_SOURCE_DIR}/util/os_osx.cpp ${LIBMAMBA_SOURCE_DIR}/util/os_unix.cpp ${LIBMAMBA_SOURCE_DIR}/util/os_win.cpp ${LIBMAMBA_SOURCE_DIR}/util/parsers.cpp ${LIBMAMBA_SOURCE_DIR}/util/path_manip.cpp ${LIBMAMBA_SOURCE_DIR}/util/random.cpp ${LIBMAMBA_SOURCE_DIR}/util/string.cpp ${LIBMAMBA_SOURCE_DIR}/util/url_manip.cpp ${LIBMAMBA_SOURCE_DIR}/util/url.cpp # Implementation of version and matching specs ${LIBMAMBA_SOURCE_DIR}/specs/archive.cpp ${LIBMAMBA_SOURCE_DIR}/specs/authentication_info.cpp ${LIBMAMBA_SOURCE_DIR}/specs/build_number_spec.cpp ${LIBMAMBA_SOURCE_DIR}/specs/channel.cpp ${LIBMAMBA_SOURCE_DIR}/specs/chimera_string_spec.cpp ${LIBMAMBA_SOURCE_DIR}/specs/conda_url.cpp ${LIBMAMBA_SOURCE_DIR}/specs/glob_spec.cpp ${LIBMAMBA_SOURCE_DIR}/specs/match_spec.cpp ${LIBMAMBA_SOURCE_DIR}/specs/package_info.cpp ${LIBMAMBA_SOURCE_DIR}/specs/platform.cpp ${LIBMAMBA_SOURCE_DIR}/specs/regex_spec.cpp ${LIBMAMBA_SOURCE_DIR}/specs/repo_data.cpp ${LIBMAMBA_SOURCE_DIR}/specs/unresolved_channel.cpp ${LIBMAMBA_SOURCE_DIR}/specs/version_spec.cpp ${LIBMAMBA_SOURCE_DIR}/specs/version.cpp # Solver generic interface ${LIBMAMBA_SOURCE_DIR}/solver/helpers.cpp ${LIBMAMBA_SOURCE_DIR}/solver/problems_graph.cpp # Solver libsolv implementation ${LIBMAMBA_SOURCE_DIR}/solver/libsolv/database.cpp ${LIBMAMBA_SOURCE_DIR}/solver/libsolv/helpers.cpp ${LIBMAMBA_SOURCE_DIR}/solver/libsolv/matcher.cpp ${LIBMAMBA_SOURCE_DIR}/solver/libsolv/parameters.cpp ${LIBMAMBA_SOURCE_DIR}/solver/libsolv/repo_info.cpp ${LIBMAMBA_SOURCE_DIR}/solver/libsolv/solver.cpp ${LIBMAMBA_SOURCE_DIR}/solver/libsolv/unsolvable.cpp # Artifacts validation ${LIBMAMBA_SOURCE_DIR}/validation/errors.cpp ${LIBMAMBA_SOURCE_DIR}/validation/keys.cpp ${LIBMAMBA_SOURCE_DIR}/validation/repo_checker.cpp ${LIBMAMBA_SOURCE_DIR}/validation/tools.cpp ${LIBMAMBA_SOURCE_DIR}/validation/update_framework_v0_6.cpp ${LIBMAMBA_SOURCE_DIR}/validation/update_framework_v1.cpp ${LIBMAMBA_SOURCE_DIR}/validation/update_framework.cpp # Downloaders and mirrors ${LIBMAMBA_SOURCE_DIR}/download/compression.cpp ${LIBMAMBA_SOURCE_DIR}/download/compression.hpp ${LIBMAMBA_SOURCE_DIR}/download/curl.cpp ${LIBMAMBA_SOURCE_DIR}/download/curl.hpp ${LIBMAMBA_SOURCE_DIR}/download/downloader_impl.hpp ${LIBMAMBA_SOURCE_DIR}/download/downloader.cpp ${LIBMAMBA_SOURCE_DIR}/download/mirror_impl.cpp ${LIBMAMBA_SOURCE_DIR}/download/mirror_impl.hpp ${LIBMAMBA_SOURCE_DIR}/download/mirror_map.cpp ${LIBMAMBA_SOURCE_DIR}/download/mirror.cpp ${LIBMAMBA_SOURCE_DIR}/download/request.cpp # Core API (low-level) ${LIBMAMBA_SOURCE_DIR}/core/activation.cpp ${LIBMAMBA_SOURCE_DIR}/core/channel_context.cpp ${LIBMAMBA_SOURCE_DIR}/core/context.cpp ${LIBMAMBA_SOURCE_DIR}/core/download_progress_bar.cpp ${LIBMAMBA_SOURCE_DIR}/core/env_lockfile.cpp ${LIBMAMBA_SOURCE_DIR}/core/environments_manager.cpp ${LIBMAMBA_SOURCE_DIR}/core/error_handling.cpp ${LIBMAMBA_SOURCE_DIR}/core/execution.cpp ${LIBMAMBA_SOURCE_DIR}/core/fsutil.cpp ${LIBMAMBA_SOURCE_DIR}/core/history.cpp ${LIBMAMBA_SOURCE_DIR}/core/link.cpp ${LIBMAMBA_SOURCE_DIR}/core/link.hpp ${LIBMAMBA_SOURCE_DIR}/core/menuinst.cpp ${LIBMAMBA_SOURCE_DIR}/core/output.cpp ${LIBMAMBA_SOURCE_DIR}/core/package_cache.cpp ${LIBMAMBA_SOURCE_DIR}/core/package_database_loader.cpp ${LIBMAMBA_SOURCE_DIR}/core/package_fetcher.cpp ${LIBMAMBA_SOURCE_DIR}/core/package_handling.cpp ${LIBMAMBA_SOURCE_DIR}/core/package_paths.cpp ${LIBMAMBA_SOURCE_DIR}/core/pinning.cpp ${LIBMAMBA_SOURCE_DIR}/core/prefix_data.cpp ${LIBMAMBA_SOURCE_DIR}/core/progress_bar_impl.cpp ${LIBMAMBA_SOURCE_DIR}/core/progress_bar.cpp ${LIBMAMBA_SOURCE_DIR}/core/query.cpp ${LIBMAMBA_SOURCE_DIR}/core/repo_checker_store.cpp ${LIBMAMBA_SOURCE_DIR}/core/run.cpp ${LIBMAMBA_SOURCE_DIR}/core/shell_init.cpp ${LIBMAMBA_SOURCE_DIR}/core/singletons.cpp ${LIBMAMBA_SOURCE_DIR}/core/subdir_index.cpp ${LIBMAMBA_SOURCE_DIR}/core/thread_utils.cpp ${LIBMAMBA_SOURCE_DIR}/core/timeref.cpp ${LIBMAMBA_SOURCE_DIR}/core/transaction_context.cpp ${LIBMAMBA_SOURCE_DIR}/core/transaction_context.hpp ${LIBMAMBA_SOURCE_DIR}/core/transaction.cpp ${LIBMAMBA_SOURCE_DIR}/core/util_os.cpp ${LIBMAMBA_SOURCE_DIR}/core/util.cpp ${LIBMAMBA_SOURCE_DIR}/core/virtual_packages.cpp # API (high-level) ${LIBMAMBA_SOURCE_DIR}/api/c_api.cpp ${LIBMAMBA_SOURCE_DIR}/api/channel_loader.cpp ${LIBMAMBA_SOURCE_DIR}/api/clean.cpp ${LIBMAMBA_SOURCE_DIR}/api/config.cpp ${LIBMAMBA_SOURCE_DIR}/api/configuration.cpp ${LIBMAMBA_SOURCE_DIR}/api/create.cpp ${LIBMAMBA_SOURCE_DIR}/api/env.cpp ${LIBMAMBA_SOURCE_DIR}/api/info.cpp ${LIBMAMBA_SOURCE_DIR}/api/install.cpp ${LIBMAMBA_SOURCE_DIR}/api/list.cpp ${LIBMAMBA_SOURCE_DIR}/api/utils.cpp ${LIBMAMBA_SOURCE_DIR}/api/utils.hpp ${LIBMAMBA_SOURCE_DIR}/api/remove.cpp ${LIBMAMBA_SOURCE_DIR}/api/repoquery.cpp ${LIBMAMBA_SOURCE_DIR}/api/shell.cpp ${LIBMAMBA_SOURCE_DIR}/api/update.cpp ) # TODO: remove when switch to C++20 if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") # This file uses capturing structured bindings, which was fixed in C++20 set_source_files_properties( ${LIBMAMBA_SOURCE_DIR}/download/mirror_impl.cpp PROPERTIES COMPILE_FLAGS -Wno-c++20-extensions ) endif() foreach(script ${SHELL_SCRIPTS}) list(APPEND LIBMAMBA_SOURCES shell_scripts/${script}.cpp) endforeach() set( LIBMAMBA_PUBLIC_HEADERS ${LIBMAMBA_INCLUDE_DIR}/mamba/version.hpp # Filesystem library ${LIBMAMBA_INCLUDE_DIR}/mamba/fs/filesystem.hpp # Utility library ${LIBMAMBA_INCLUDE_DIR}/mamba/util/build.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/cast.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/cfile.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/conditional.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/cryptography.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/deprecation.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/encoding.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/environment.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/flat_binary_tree.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/flat_bool_expr_tree.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/flat_set.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/graph.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/heap_optional.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/iterator.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/json.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/loop_control.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/os_linux.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/os_osx.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/os_unix.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/os_win.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/os.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/parsers.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/path_manip.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/random.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/string.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/synchronized_value.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/tuple_hash.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/type_traits.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/url_manip.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/url.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/variant_cmp.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/util/weakening_map.hpp # Implementation of version and matching specs ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/archive.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/authentication_info.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/build_number_spec.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/channel.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/chimera_string_spec.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/conda_url.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/error.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/glob_spec.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/match_spec.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/package_info.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/platform.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/regex_spec.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/repo_data.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/unresolved_channel.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/version_spec.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/specs/version.hpp # Solver generic interface ${LIBMAMBA_INCLUDE_DIR}/mamba/solver/problems_graph.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/solver/request.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/solver/solution.hpp # Solver libsolv implementation ${LIBMAMBA_INCLUDE_DIR}/mamba/solver/libsolv/database.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/solver/libsolv/parameters.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/solver/libsolv/repo_info.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/solver/libsolv/solver.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/solver/libsolv/unsolvable.hpp # Artifacts validation ${LIBMAMBA_INCLUDE_DIR}/mamba/validation/errors.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/validation/keys.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/validation/repo_checker.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/validation/tools.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/validation/update_framework_v0_6.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/validation/update_framework_v1.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/validation/update_framework.hpp # Downloaders and mirrors ${LIBMAMBA_INCLUDE_DIR}/mamba/download/downloader.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/download/mirror_map.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/download/mirror.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/download/request.hpp # Core API (low-level) ${LIBMAMBA_INCLUDE_DIR}/mamba/core/activation.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/channel_context.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/common_types.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/context.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/context_params.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/download_progress_bar.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/env_lockfile.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/environments_manager.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/error_handling.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/execution.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/fsutil.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/history.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/invoke.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/menuinst.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/output.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/package_cache.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/package_database_loader.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/package_fetcher.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/package_handling.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/package_paths.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/palette.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/pinning.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/prefix_data.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/progress_bar.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/query.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/repo_checker_store.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/run.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/shell_init.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/subdir_index.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/tasksync.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/thread_utils.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/timeref.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/transaction.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/util_os.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/util_scope.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/util.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/core/virtual_packages.hpp # API (high-level) ${LIBMAMBA_INCLUDE_DIR}/mamba/api/c_api.h ${LIBMAMBA_INCLUDE_DIR}/mamba/api/channel_loader.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/clean.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/config.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/configuration_impl.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/configuration.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/constants.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/create.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/env.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/info.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/install.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/list.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/remove.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/repoquery.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/shell.hpp ${LIBMAMBA_INCLUDE_DIR}/mamba/api/update.hpp ) # Targets and link # ================ find_package(fmt CONFIG REQUIRED) find_package(spdlog CONFIG REQUIRED) find_package(tl-expected CONFIG REQUIRED) find_package(nlohmann_json CONFIG REQUIRED) find_package(simdjson CONFIG REQUIRED) find_package(yaml-cpp CONFIG REQUIRED) find_package(reproc CONFIG REQUIRED) find_package(reproc++ CONFIG REQUIRED) find_package(Libsolv MODULE REQUIRED) add_subdirectory(ext/solv-cpp) macro(libmamba_create_target target_name linkage output_name) string(TOUPPER "${linkage}" linkage_upper) if(NOT ${linkage_upper} MATCHES "^(SHARED|STATIC)$") message(FATAL_ERROR "Invalid library linkage: ${linkage}") endif() # Output # ====== add_library(${target_name} ${linkage_upper} ${LIBMAMBA_PUBLIC_HEADERS} ${LIBMAMBA_SOURCES}) target_include_directories( ${target_name} PUBLIC $ $ PRIVATE ${LIBMAMBA_SOURCE_DIR} ) # Header only libraries are always linked the same way target_link_libraries(${target_name} PUBLIC tl::expected nlohmann_json::nlohmann_json) target_compile_features(${target_name} PUBLIC cxx_std_20) set_target_properties( ${target_name} PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO ) mamba_target_add_compile_warnings(${target_name} WARNING_AS_ERROR ${MAMBA_WARNING_AS_ERROR}) mamba_target_set_lto(${target_name} MODE ${MAMBA_LTO}) # For some reasons, using target_compile_definitions does not set the definitions properly add_compile_definitions( SPDLOG_FMT_EXTERNAL "SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_${BUILD_LOG_LEVEL}" ) if(${linkage_upper} STREQUAL "STATIC") message(" -> Statically linking against libmamba (static) dependencies") mamba_target_check_type(yaml-cpp::yaml-cpp STATIC_LIBRARY FATAL_ERROR) mamba_target_check_type(reproc STATIC_LIBRARY FATAL_ERROR) mamba_target_check_type(reproc++ STATIC_LIBRARY FATAL_ERROR) target_link_libraries( ${target_name} PUBLIC fmt::fmt-header-only spdlog::spdlog_header_only yaml-cpp::yaml-cpp PRIVATE reproc reproc++ simdjson::simdjson_static solv::libsolv_static solv::libsolvext_static solv::cpp ) if(UNIX) set( REQUIRED_STATIC_DEPS libcurl.a libssh2.a libgssapi_krb5.a libkrb5.a libk5crypto.a libkrb5support.a libcom_err.a libssl.a libcrypto.a libarchive.a libiconv.a libbz2.a liblz4.a libzstd.a libz.a liblzma.a libnghttp2.a ) if(APPLE) set(REQUIRED_STATIC_DEPS ${REQUIRED_STATIC_DEPS} libc++.a) endif() if(UNIX AND NOT APPLE) list(REMOVE_ITEM REQUIRED_STATIC_DEPS libiconv.a) endif() set(STATIC_DEPS "") foreach(LIB ${REQUIRED_STATIC_DEPS}) set(TMP_LIB "${LIB}-NOTFOUND") find_library(TMP_LIB NAMES "${LIB}") if(NOT ${TMP_LIB} STREQUAL "TMP_LIB-NOTFOUND") list(APPEND STATIC_DEPS "${TMP_LIB}") else() list(APPEND STATIC_DEPS "${LIB}-NOTFOUND") endif() endforeach(LIB) if(APPLE) find_library(SECURITY_LIBRARY Security) find_library(SYSTEMCONFIGURATION_LIBRARY SystemConfiguration) find_library(COREFOUNDATION_LIBRARY CoreFoundation) message("Found library: ${SECURITY_LIBRARY}\n${COREFOUNDATION_LIBRARY}") list( APPEND STATIC_DEPS ${COREFOUNDATION_LIBRARY} ${SECURITY_LIBRARY} ${SYSTEMCONFIGURATION_LIBRARY} ) endif() message(" -> Found static dependencies:") foreach(LIB ${STATIC_DEPS}) message(" - ${LIB}") endforeach(LIB) if(APPLE) set(MAMBA_FORCE_DYNAMIC_LIBS resolv c++abi) target_link_options(${target_name} PRIVATE -nostdlib++) elseif(UNIX) set(MAMBA_FORCE_DYNAMIC_LIBS rt dl resolv) target_link_options(${target_name} PUBLIC -static-libstdc++ -static-libgcc) endif() target_link_libraries(${target_name} PUBLIC ${STATIC_DEPS} ${MAMBA_FORCE_DYNAMIC_LIBS}) elseif(WIN32) set(CMAKE_PREFIX_PATH "$ENV{VCPKG_ROOT}/installed/x64-windows-static-md/") # TODO AND CONTEXT: We found a link error in libarchive which lacked a link to XmlLite # which is provided by Windows. libarchive has cmake scripts doing the necessary work to # link that library but for some reason we couldnt identify it is not linking in this # specific case (it was before but the version changed apparently). As a workaround we # manually link with that required library but a better solution would be to find why # libarchive doesnt do it itself. set(SYSTEM_PROVIDED_LIBRARIES XmlLite.lib) # required by libarchive set(ENABLE_WIN32_XMLLITE ON) # For Windows we have a vcpkg based build system right now. find_package(LibArchive MODULE REQUIRED) find_package(CURL CONFIG REQUIRED) find_library(LIBLZMA_LIBRARIES lzma REQUIRED) find_library(LZ4_LIBRARY NAMES lz4) find_library(LZO2_LIBRARY NAMES lzo2) find_package(zstd CONFIG REQUIRED) find_library(BZIP2_LIBRARIES NAMES bz2) find_library(CRYPTO_LIBRARIES NAMES libcrypto) find_library(LIBXML2_LIBRARY NAMES libxml2) find_library(ICONV_LIBRARY NAMES libiconv iconv) find_library(CHARSET_LIBRARY NAMES libcharset charset) message("Found: ${LIBXML2_LIBRARY} ${ICONV_LIBRARY} ${CHARSET_LIBRARY}") target_link_libraries( ${target_name} PUBLIC ${CRYPTO_LIBRARIES} ${SYSTEM_PROVIDED_LIBRARIES} ${LibArchive_LIBRARY} ${LIBXML2_LIBRARY} ${ICONV_LIBRARY} ${CHARSET_LIBRARY} zstd::libzstd_static ${LZ4_LIBRARY} ${LZO2_LIBRARY} ${BZIP2_LIBRARIES} ${LIBLZMA_LIBRARIES} CURL::libcurl ${sodium_LIBRARY_RELEASE} ) add_compile_definitions(LIBARCHIVE_STATIC CURL_STATICLIB) include_directories($ENV{CONDA_PREFIX}/Library/include/) include_directories($ENV{VCPKG_ROOT}/installed/x64-windows-static-md/include/) endif() else() message(" -> Dynamically linking against libmamba (shared) dependencies") mamba_target_check_type(yaml-cpp::yaml-cpp SHARED_LIBRARY WARNING) find_package(CURL REQUIRED) find_package(LibArchive REQUIRED) find_package(zstd REQUIRED) find_package(BZip2 REQUIRED) find_package(OpenSSL REQUIRED) target_link_libraries( ${target_name} PUBLIC ${LIBSOLV_LIBRARIES} ${LIBSOLVEXT_LIBRARIES} yaml-cpp::yaml-cpp fmt::fmt # Since conda-forge spdlog is built with a bundled version of fmt we use the header # only version to avoid chasing after the correct fmt version matching the one used # in the bundle spdlog::spdlog_header_only PRIVATE ${LibArchive_LIBRARIES} ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} BZip2::BZip2 reproc reproc++ simdjson::simdjson zstd::libzstd_shared solv::libsolv solv::libsolvext solv::cpp ) # CMake 3.17 provides a LibArchive::LibArchive target that could be used instead of # LIBRARIES/INCLUDE_DIRS target_include_directories(${target_name} PRIVATE "${LibArchive_INCLUDE_DIRS}") endif() if(WIN32) find_path( WINREG_INCLUDE_DIR NAMES WinReg.hpp PATH_SUFFIXES winreg ) target_include_directories(${target_name} PRIVATE ${WINREG_INCLUDE_DIR}) endif() if(UNIX) math(EXPR LIBMAMBA_BINARY_COMPATIBLE "${LIBMAMBA_BINARY_CURRENT} - ${LIBMAMBA_BINARY_AGE}") set_target_properties( ${target_name} PROPERTIES # PUBLIC_HEADER "${LIBMAMBA_PUBLIC_HEADERS}" COMPILE_DEFINITIONS "LIBMAMBA_EXPORTS" PREFIX "" VERSION "${LIBMAMBA_BINARY_COMPATIBLE}.${LIBMAMBA_BINARY_REVISION}.${LIBMAMBA_BINARY_AGE}" SOVERSION ${LIBMAMBA_BINARY_COMPATIBLE} OUTPUT_NAME "${output_name}" ) else() set_target_properties( ${target_name} PROPERTIES # PUBLIC_HEADER "${LIBMAMBA_PUBLIC_HEADERS}" COMPILE_DEFINITIONS "LIBMAMBA_EXPORTS" PREFIX "" VERSION ${LIBMAMBA_BINARY_VERSION} SOVERSION ${LIBMAMBA_BINARY_CURRENT} OUTPUT_NAME "${output_name}" ) target_compile_definitions(${target_name} PUBLIC GHC_WIN_DISABLE_WSTRING_STORAGE_TYPE) endif() if(${linkage_upper} STREQUAL "STATIC") find_package(Threads REQUIRED) target_link_libraries(${target_name} PUBLIC Threads::Threads) endif() list(APPEND libmamba_targets ${target_name}) add_library(mamba::${target_name} ALIAS ${target_name}) endmacro() set(libmamba_targets "") option( ENABLE_MAMBA_ROOT_PREFIX_FALLBACK "Enable mamba (shared) root prefix to be set to install prefix" ON ) if(BUILD_SHARED) message(STATUS "Adding shared libmamba target") libmamba_create_target(libmamba-dyn SHARED libmamba) if(ENABLE_MAMBA_ROOT_PREFIX_FALLBACK) # Use mamba installation prefix to set root prefix (base) target_compile_definitions(libmamba-dyn PUBLIC MAMBA_USE_INSTALL_PREFIX_AS_BASE) endif() endif() if(BUILD_STATIC) message(STATUS "Adding static libmamba target") # On Windows, a static library should use a different output name to avoid the conflict with the # import library of a shared one. if(CMAKE_HOST_WIN32) libmamba_create_target(libmamba-static STATIC libmamba_static) else() libmamba_create_target(libmamba-static STATIC libmamba) endif() endif() if(BUILD_SHARED_LIBS AND BUILD_SHARED) add_library(mamba::libmamba ALIAS libmamba-dyn) elseif(BUILD_STATIC) add_library(mamba::libmamba ALIAS libmamba-static) elseif(BUILD_SHARED) add_library(mamba::libmamba ALIAS libmamba-dyn) else() message(FATAL_ERROR "Select at least a build variant for libmamba") endif() # Tests if(BUILD_LIBMAMBA_TESTS) add_subdirectory(tests) endif() # Installation # ============ include(GNUInstallDirs) include(CMakePackageConfigHelpers) set( LIBMAMBA_CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" CACHE STRING "install path for libmambaConfig.cmake" ) install( TARGETS ${libmamba_targets} EXPORT ${PROJECT_NAME}Targets ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) install( DIRECTORY "${LIBMAMBA_INCLUDE_DIR}/" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h" ) # Configure 'mambaConfig.cmake' for a build tree set(MAMBA_CONFIG_CODE "####### Expanded from \@MAMBA_CONFIG_CODE\@ #######\n") set( MAMBA_CONFIG_CODE "${MAMBA_CONFIG_CODE}set(CMAKE_MODULE_PATH \"${CMAKE_CURRENT_SOURCE_DIR}/cmake;\${CMAKE_MODULE_PATH}\")\n" ) set(MAMBA_CONFIG_CODE "${MAMBA_CONFIG_CODE}##################################################") configure_package_config_file( ${PROJECT_NAME}Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" INSTALL_DESTINATION ${PROJECT_BINARY_DIR} ) # Configure 'mambaConfig.cmake' for an install tree set(MAMBA_CONFIG_CODE "") configure_package_config_file( ${PROJECT_NAME}Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" INSTALL_DESTINATION ${LIBMAMBA_CMAKECONFIG_INSTALL_DIR} ) write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake VERSION ${LIBMAMBA_VERSION_MAJOR}.${LIBMAMBA_VERSION_MINOR}.${LIBMAMBA_VERSION_PATCH} COMPATIBILITY AnyNewerVersion ) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake DESTINATION ${LIBMAMBA_CMAKECONFIG_INSTALL_DIR} ) install( EXPORT ${PROJECT_NAME}Targets NAMESPACE mamba:: DESTINATION ${LIBMAMBA_CMAKECONFIG_INSTALL_DIR} COMPONENT Mamba_Development ) export(EXPORT ${PROJECT_NAME}Targets NAMESPACE mamba::)