core update & conan for dep

This commit is contained in:
maxdcb
2026-04-21 13:49:31 +02:00
parent f066019da9
commit 7aa8fc3a1c
11 changed files with 956 additions and 24899 deletions
+1
View File
@@ -1,2 +1,3 @@
build
buildx86
build-*/
+100
View File
@@ -0,0 +1,100 @@
# AGENT.md — C2Implant
## Purpose
You are an expert C++/CMake contributor tasked with maintaining **C2Implant**.
- Keep the project buildable with the parent repository layout already in use.
- Treat `core/` as a shared codebase consumed by multiple parents, not as Windows-only code.
- Preserve the current release layout: Beacon executables and DLLs in `Release/Beacons`, module DLLs in `Release/Modules`.
## Repository Role
`C2Implant` is the Windows Beacon parent repository.
- The top-level `CMakeLists.txt` owns the Windows build, third-party dependencies, and output layout.
- `core/` contains the shared transport and module logic reused across other repositories such as `C2TeamServer` and Linux-oriented parents.
- `beacon/beacon/` contains the launcher targets that produce the final Beacon executables and DLLs.
- `libs/` and `thirdParty/` are vendored or submodule-based dependencies expected by this parent.
## Build Context
The main supported local build here is Windows with Visual Studio and Conan.
- Preferred generator: `Visual Studio 17 2022`
- Preferred configuration: `Release`
- Runtime: static CRT (`/MT`)
- Dependency manager: Conan 2, through the top-level `conan_provider.cmake`
Typical x64 flow from WSL or Git Bash, using the Visual Studio bundled CMake:
```bash
'/mnt/c/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin/cmake.exe' \
-S E:/Dev/C2Implant \
-B E:/Dev/C2Implant/build-conan \
-G "Visual Studio 17 2022"
'/mnt/c/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin/cmake.exe' \
--build E:/Dev/C2Implant/build-conan \
--config Release \
-- /m
```
Typical x86 flow:
```bash
cmake -S . -B build-conan-x86 -G "Visual Studio 17 2022" -A Win32
cmake --build build-conan-x86 --config Release -- /m
```
If running directly from a Windows developer prompt, the same commands can use `cmake` instead of the absolute Visual Studio CMake path.
The current Conan dependencies are declared in `conanfile.txt`:
- `libssh2`, consumed by `core/modules/SshExec`
- `nlohmann_json`, consumed by `core` beacon/listener/module command code
The top-level CMake sets `CMAKE_MSVC_RUNTIME_LIBRARY` before `project(...)` so local targets and Conan packages agree on the static MSVC runtime. Do not replace this with raw `-MT` or `/MT` flag edits; Conan will not reliably see those during provider initialization.
For Visual Studio multi-config generators, the project sets `CONAN_INSTALL_CONFIGURATIONS=Release`. This avoids building Debug Conan packages when the supported local validation is Release-only. If Debug builds become a requirement, update that cache variable to include both `Release` and `Debug` and expect Conan to build a second dependency set.
The parent builds `thirdParty/base64` as the `c2_base64` target. Shared `core/` code must link to `c2_base64` instead of assuming a raw include-only base64 dependency.
## Core Duality: Windows vs Linux
This repository consumes shared code from `core/`, but `core/` is not symmetric across platforms.
- On Windows Beacon-side code, HTTP/HTTPS and GitHub transports use WinHTTP, WinCrypt, BCrypt, and other WinAPI facilities.
- On Linux, the equivalent transport code may rely on `httplib` and OpenSSL.
- Because of that, **do not blindly link Linux transport dependencies on Windows targets** just because the shared source file lives under `core/`.
Current rule for Beacon-side shared libraries:
- `BeaconHttpLib` and `BeaconGithubLib` must not require `openssl::openssl` or `httplib::httplib` on Windows.
- Those dependencies are valid only for non-Windows builds unless the source code explicitly changes to require them on Windows too.
- When editing `core/beacon/CMakeLists.txt`, keep transport-specific link dependencies conditional on platform.
The same caution applies to tests:
- If a test target covers Linux-only transport plumbing, guard its link dependencies with platform checks.
- Do not make Windows test builds depend on Linux-only imported targets unless the Windows code path truly uses them.
## Editing Rules
- Prefer minimal CMake changes that keep the existing structure intact.
- Avoid moving ownership of build logic out of the top-level parent unless there is a clear repo-wide migration.
- When changing `core/`, assume the same code may be compiled by another parent with a different dependency graph.
- If a change in `core/` introduces new imported targets, add them conditionally and verify both the Windows parent behavior and the non-Windows intent.
- When adding a Conan dependency used by `core/`, expose a stable imported target name at the parent level if Conan's package target name differs from the name expected by `core`.
- Keep `c2_base64` as a normal CMake target. Do not reintroduce direct compilation of `base64.cpp` in multiple consumers.
## Validation
For Windows-facing changes, validate with a real Visual Studio build when possible.
- Regenerate with CMake after touching `CMakeLists.txt`.
- Confirm that `SshExec`, `BeaconTcp`, `BeaconSmb`, `BeaconDns`, `BeaconHttp`, and `BeaconGithub` all link successfully.
- Check timestamps or outputs in `Release/Beacons` if you need to distinguish freshly produced binaries from stale ones.
- Watch specifically for `LNK2038 RuntimeLibrary` and unresolved CRT externals from Conan libraries. Those usually mean a `/MD` vs `/MT` mismatch between local targets and Conan packages.
Warnings currently exist in the tree, especially around macro redefinitions from vendored dependencies. Do not confuse those with the transport-link regressions described above.
+120 -110
View File
@@ -1,110 +1,120 @@
cmake_minimum_required(VERSION 3.24.0 FATAL_ERROR)
project(C2Implant VERSION 0.0.0 LANGUAGES CXX C)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CXX_FLAGS_RELEASE "-MT -O1 -Ob0")
set(CMAKE_C_FLAGS_RELEASE "-MT -O1 -Ob0")
add_compile_definitions(
NOMINMAX # <-- disables Windows min/max macros
)
# --- Decide whether a prefix path was provided (var or env) ---
set(_prefixes "")
# Prefer the CMake var if set on the command line/cache.
if(DEFINED CMAKE_PREFIX_PATH AND NOT "${CMAKE_PREFIX_PATH}" STREQUAL "")
set(_prefixes "${CMAKE_PREFIX_PATH}")
elseif(DEFINED ENV{CMAKE_PREFIX_PATH} AND NOT "$ENV{CMAKE_PREFIX_PATH}" STREQUAL "")
# fall back to environment variable
set(_prefixes "$ENV{CMAKE_PREFIX_PATH}")
endif()
# Optional: normalize whitespace
string(STRIP "${_prefixes}" _prefixes)
if (C2CORE_BUILD_TESTS)
add_definitions(-DC2CORE_BUILD_TESTS)
# TODO add the right fetch
endif()
if(_prefixes)
message(STATUS "Using CMAKE_PREFIX_PATH: ${_prefixes}")
include_directories(thirdParty)
##
## C2Core dependency and build
##
find_package(C2Core CONFIG REQUIRED)
include_directories(thirdParty/base64)
add_subdirectory(beacon/beacon)
else()
message(STATUS "CMAKE_PREFIX_PATH not provided; using fallback strategy")
include_directories(thirdParty)
add_definitions(-DBUILD_IMPLANT)
##
## Fetch for core
##
include(FetchContent)
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libraries" FORCE)
set(BUILD_STATIC_LIBS ON CACHE BOOL "Build static libraries" FORCE)
set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(BUILD_TESTING OFF CACHE BOOL "" FORCE)
add_compile_definitions(LIBSSH2_LIBRARY) # needed for full static lib
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
FetchContent_Declare(
libssh2
GIT_REPOSITORY https://github.com/libssh2/libssh2.git
GIT_TAG libssh2-1.11.1
)
FetchContent_MakeAvailable(libssh2)
##
## Build
##
add_subdirectory(libs)
add_subdirectory(thirdParty)
include_directories(thirdParty/base64)
include_directories(thirdParty/donut/include)
include_directories(thirdParty/coffLoader/coffLoader)
include_directories(thirdParty/MemoryModule)
set(DONUT_BUILD_DIR "${CMAKE_BINARY_DIR}/thirdParty/donut")
add_library(Donut STATIC IMPORTED)
set_target_properties(Donut PROPERTIES
IMPORTED_LOCATION "${DONUT_BUILD_DIR}/lib/donut.lib"
)
add_subdirectory(core/modules)
add_subdirectory(core/beacon)
include_directories(core/listener)
include_directories(core/beacon)
include_directories(core/modules/ModuleCmd)
add_subdirectory(beacon/beacon)
endif()
cmake_minimum_required(VERSION 3.24.0 FATAL_ERROR)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>" CACHE STRING
"Use the static MSVC runtime so beacon targets and Conan libraries agree.")
set(C2_CONAN_PROVIDER "${CMAKE_CURRENT_LIST_DIR}/conan_provider.cmake")
if(EXISTS "${C2_CONAN_PROVIDER}")
list(PREPEND CMAKE_PROJECT_TOP_LEVEL_INCLUDES "${C2_CONAN_PROVIDER}")
endif()
project(C2Implant VERSION 0.0.0 LANGUAGES CXX C)
if(WIN32 AND NOT DEFINED CONAN_COMMAND)
file(GLOB C2_CONAN_HINT_DIRS LIST_DIRECTORIES TRUE
"$ENV{LOCALAPPDATA}/Programs/Python/Python*/Scripts"
"$ENV{APPDATA}/Python/Python*/Scripts")
find_program(CONAN_COMMAND
NAMES conan conan.exe
HINTS ${C2_CONAN_HINT_DIRS})
endif()
if(WIN32)
set(C2_CMAKE_COMMAND "${CMAKE_COMMAND}")
if(C2_CMAKE_COMMAND MATCHES " ")
file(GLOB C2_CONAN_CMAKE_CANDIDATES "$ENV{USERPROFILE}/.conan2/p/cmake*/p/bin/cmake.exe")
if(C2_CONAN_CMAKE_CANDIDATES)
list(SORT C2_CONAN_CMAKE_CANDIDATES ORDER DESCENDING)
list(GET C2_CONAN_CMAKE_CANDIDATES 0 C2_CMAKE_COMMAND)
endif()
endif()
file(TO_CMAKE_PATH "${C2_CMAKE_COMMAND}" C2_CMAKE_COMMAND)
set(CONAN_INSTALL_ARGS
"--build=missing;-c:h;tools.cmake:cmake_program=${C2_CMAKE_COMMAND};-c:b;tools.cmake:cmake_program=${C2_CMAKE_COMMAND}"
CACHE STRING "Conan install arguments for C2Implant" FORCE)
set(CONAN_INSTALL_CONFIGURATIONS Release CACHE STRING
"Only install the configuration built by C2Implant in Visual Studio generators." FORCE)
endif()
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if(MSVC)
add_compile_options($<$<CONFIG:Release>:/O1> $<$<CONFIG:Release>:/Ob0>)
else()
set(CMAKE_CXX_FLAGS_RELEASE "-O1")
set(CMAKE_C_FLAGS_RELEASE "-O1")
endif()
add_compile_definitions(
NOMINMAX # <-- disables Windows min/max macros
)
option(C2CORE_BUILD_TESTS "Enable C2Core tests from the parent project" OFF)
set(C2_RUNTIME_MODULE_OUTPUT_DIR "${CMAKE_SOURCE_DIR}/Release/Modules" CACHE PATH
"Directory where C2Core runtime modules are copied after build")
set(C2_TEST_BIN_OUTPUT_DIR "${CMAKE_BINARY_DIR}/tests" CACHE PATH
"Directory where C2Core test binaries are copied after build")
file(MAKE_DIRECTORY "${C2_RUNTIME_MODULE_OUTPUT_DIR}")
file(MAKE_DIRECTORY "${C2_TEST_BIN_OUTPUT_DIR}")
add_definitions(-DBUILD_IMPLANT)
##
## Conan Dependencies
##
find_package(Libssh2 QUIET CONFIG)
if(NOT Libssh2_FOUND)
find_package(libssh2 REQUIRED CONFIG)
endif()
if(TARGET libssh2::libssh2 AND NOT TARGET Libssh2::libssh2)
add_library(Libssh2::libssh2 INTERFACE IMPORTED)
target_link_libraries(Libssh2::libssh2 INTERFACE libssh2::libssh2)
endif()
find_package(nlohmann_json REQUIRED CONFIG)
include_directories(${CMAKE_INCLUDE_PATH})
get_target_property(C2_NLOHMANN_JSON_INCLUDE_DIRS nlohmann_json::nlohmann_json INTERFACE_INCLUDE_DIRECTORIES)
if(C2_NLOHMANN_JSON_INCLUDE_DIRS)
include_directories(BEFORE ${C2_NLOHMANN_JSON_INCLUDE_DIRS})
endif()
include_directories(thirdParty)
add_definitions(-DBUILD_IMPLANT)
##
## Build
##
add_subdirectory(libs)
add_subdirectory(thirdParty)
include_directories(thirdParty/base64)
include_directories(thirdParty/donut/include)
include_directories(thirdParty/coffLoader/coffLoader)
include_directories(thirdParty/MemoryModule)
set(DONUT_BUILD_DIR "${CMAKE_BINARY_DIR}/thirdParty/donut")
add_library(Donut STATIC IMPORTED)
set_target_properties(Donut PROPERTIES
IMPORTED_LOCATION "${DONUT_BUILD_DIR}/lib/donut.lib"
)
add_subdirectory(core/modules)
add_subdirectory(core/beacon)
include_directories(core/listener)
include_directories(core/beacon)
include_directories(core/modules/ModuleCmd)
add_subdirectory(beacon/beacon)
+35 -21
View File
@@ -41,62 +41,76 @@ This project relies on several third-party libraries and tools:
* [COFFLoader](https://github.com/trustedsec/COFFLoader): Executes object files such as those in [CS-Situational-Awareness-BOF](https://github.com/trustedsec/CS-Situational-Awareness-BOF).
* [MemoryModule](https://github.com/fancycode/MemoryModule): Enables runtime DLL loading.
* [UnmanagedPowerShell](https://github.com/leechristensen/UnmanagedPowerShell): Executes PowerShell from unmanaged code.
* [cpp-base64](https://github.com/ReneNyffenegger/cpp-base64): Base64 encoding/decoding.
* [nlohmann/json](https://github.com/nlohmann/json): JSON parsing.
* [cpp-base64](https://github.com/ReneNyffenegger/cpp-base64): Base64 encoding/decoding, built locally as the `c2_base64` CMake target.
* [libssh2](https://libssh2.org/): SSH client support for the `SshExec` module, provided by Conan.
* [nlohmann/json](https://github.com/nlohmann/json): JSON parsing, provided by Conan.
### Preparing the Environment
Install prerequisites:
* [Chocolatey](https://chocolatey.org/install)
* CMake:
* CMake
* Conan 2
* Visual Studio 2022 with the C++ toolchain
```bash
choco install cmake --pre
python -m pip install --user conan
```
Initialize submodules and set up the build directory:
Initialize submodules:
```bash
git submodule update --init
mkdir buildWindows
cd buildWindows
```
### Building the Windows Beacons and Modules
The supported local configuration is `Release` with the static MSVC runtime (`/MT`). The top-level CMake file configures Conan so `libssh2`, OpenSSL/zlib transitive dependencies, and local targets use the same runtime.
#### Windows x64
Using the "x64 Native Tools Command Prompt for VS":
```bash
cmake -G "Visual Studio 17 2022" ..
msbuild .\C2Implant.sln /property:Configuration=Release -m
cmake -S . -B build-conan -G "Visual Studio 17 2022"
cmake --build build-conan --config Release -- /m
```
Alternatively, open the generated `C2Implant.sln` in Visual Studio and build in **Release** mode. Ensure the Runtime Library is set to **Multi-threaded (/MT)**.
Project can also be build with the C2Core package:
From WSL, prefer the Visual Studio CMake executable so the generated paths stay Windows-native:
```bash
# download last windows package
set "CMAKE_PREFIX_PATH=path_to_C2Core-Windows"
cmake -G "Visual Studio 17 2022" ..
msbuild .\C2Implant.sln /property:Configuration=Release -m
'/mnt/c/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin/cmake.exe' \
-S E:/Dev/C2Implant \
-B E:/Dev/C2Implant/build-conan \
-G "Visual Studio 17 2022"
'/mnt/c/Program Files/Microsoft Visual Studio/2022/Community/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/bin/cmake.exe' \
--build E:/Dev/C2Implant/build-conan \
--config Release \
-- /m
```
#### Windows x86
```bash
cmake -G "Visual Studio 17 2022" -A "Win32" ..
msbuild .\C2Implant.sln /property:Configuration=Release /p:Platform=Win32 -m
cmake -S . -B build-conan-x86 -G "Visual Studio 17 2022" -A Win32
cmake --build build-conan-x86 --config Release -- /m
```
### Conan Notes
Dependencies are declared in `conanfile.txt`. The CMake provider runs `conan install` automatically during configuration.
For Visual Studio generators, only the `Release` Conan configuration is installed by default. If you need a Debug build, configure with a cache override such as:
```bash
cmake -S . -B build-conan -G "Visual Studio 17 2022" -DCONAN_INSTALL_CONFIGURATIONS="Release;Debug"
```
Do not manually force `/MT` through `CMAKE_CXX_FLAGS`; the project uses `CMAKE_MSVC_RUNTIME_LIBRARY` before `project()` so Conan detects the correct runtime.
### Output Locations
* Compiled Beacons: `Release\Beacons`
+10
View File
@@ -8,6 +8,11 @@
"/MicrosoftUpdate/ShellEx/KB242742/admin.aspx",
"/MicrosoftUpdate/ShellEx/KB242742/download.aspx"
],
"wsUri": [
"/ws1",
"/ws",
"/test/ws"
],
"client": {
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
@@ -29,6 +34,11 @@
"/MicrosoftUpdate/ShellEx/KB242742/upload.aspx",
"/MicrosoftUpdate/ShellEx/KB242742/config.aspx"
],
"wsUri": [
"/ws1",
"/ws",
"/test/ws"
],
"client": {
"headers": {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
+659
View File
@@ -0,0 +1,659 @@
# The MIT License (MIT)
#
# Copyright (c) 2024 JFrog
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
set(CONAN_MINIMUM_VERSION 2.0.5)
function(detect_os OS OS_API_LEVEL OS_SDK OS_SUBSYSTEM OS_VERSION)
# it could be cross compilation
message(STATUS "CMake-Conan: cmake_system_name=${CMAKE_SYSTEM_NAME}")
if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic")
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(${OS} Macos PARENT_SCOPE)
elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX")
set(${OS} Neutrino PARENT_SCOPE)
elseif(CMAKE_SYSTEM_NAME STREQUAL "CYGWIN")
set(${OS} Windows PARENT_SCOPE)
set(${OS_SUBSYSTEM} cygwin PARENT_SCOPE)
elseif(CMAKE_SYSTEM_NAME MATCHES "^MSYS")
set(${OS} Windows PARENT_SCOPE)
set(${OS_SUBSYSTEM} msys2 PARENT_SCOPE)
else()
set(${OS} ${CMAKE_SYSTEM_NAME} PARENT_SCOPE)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
if(DEFINED ANDROID_PLATFORM)
string(REGEX MATCH "[0-9]+" _OS_API_LEVEL ${ANDROID_PLATFORM})
elseif(DEFINED CMAKE_SYSTEM_VERSION)
set(_OS_API_LEVEL ${CMAKE_SYSTEM_VERSION})
endif()
message(STATUS "CMake-Conan: android api level=${_OS_API_LEVEL}")
set(${OS_API_LEVEL} ${_OS_API_LEVEL} PARENT_SCOPE)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS")
# CMAKE_OSX_SYSROOT contains the full path to the SDK for MakeFile/Ninja
# generators, but just has the original input string for Xcode.
if(NOT IS_DIRECTORY ${CMAKE_OSX_SYSROOT})
set(_OS_SDK ${CMAKE_OSX_SYSROOT})
else()
if(CMAKE_OSX_SYSROOT MATCHES Simulator)
set(apple_platform_suffix simulator)
else()
set(apple_platform_suffix os)
endif()
if(CMAKE_OSX_SYSROOT MATCHES AppleTV)
set(_OS_SDK "appletv${apple_platform_suffix}")
elseif(CMAKE_OSX_SYSROOT MATCHES iPhone)
set(_OS_SDK "iphone${apple_platform_suffix}")
elseif(CMAKE_OSX_SYSROOT MATCHES Watch)
set(_OS_SDK "watch${apple_platform_suffix}")
endif()
endif()
if(DEFINED _OS_SDK)
message(STATUS "CMake-Conan: cmake_osx_sysroot=${CMAKE_OSX_SYSROOT}")
set(${OS_SDK} ${_OS_SDK} PARENT_SCOPE)
endif()
if(DEFINED CMAKE_OSX_DEPLOYMENT_TARGET)
message(STATUS "CMake-Conan: cmake_osx_deployment_target=${CMAKE_OSX_DEPLOYMENT_TARGET}")
set(${OS_VERSION} ${CMAKE_OSX_DEPLOYMENT_TARGET} PARENT_SCOPE)
endif()
endif()
endif()
endfunction()
function(detect_arch ARCH)
# CMAKE_OSX_ARCHITECTURES can contain multiple architectures, but Conan only supports one.
# Therefore this code only finds one. If the recipes support multiple architectures, the
# build will work. Otherwise, there will be a linker error for the missing architecture(s).
if(DEFINED CMAKE_OSX_ARCHITECTURES)
string(REPLACE " " ";" apple_arch_list "${CMAKE_OSX_ARCHITECTURES}")
list(LENGTH apple_arch_list apple_arch_count)
if(apple_arch_count GREATER 1)
message(WARNING "CMake-Conan: Multiple architectures detected, this will only work if Conan recipe(s) produce fat binaries.")
endif()
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS" AND NOT CMAKE_OSX_ARCHITECTURES STREQUAL "")
set(host_arch ${CMAKE_OSX_ARCHITECTURES})
elseif(MSVC)
set(host_arch ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID})
else()
set(host_arch ${CMAKE_SYSTEM_PROCESSOR})
endif()
if(host_arch MATCHES "aarch64|arm64|ARM64")
set(_ARCH armv8)
elseif(host_arch MATCHES "armv7|armv7-a|armv7l|ARMV7")
set(_ARCH armv7)
elseif(host_arch MATCHES armv7s)
set(_ARCH armv7s)
elseif(host_arch MATCHES "i686|i386|X86")
set(_ARCH x86)
elseif(host_arch MATCHES "AMD64|amd64|x86_64|x64")
set(_ARCH x86_64)
endif()
message(STATUS "CMake-Conan: cmake_system_processor=${_ARCH}")
set(${ARCH} ${_ARCH} PARENT_SCOPE)
endfunction()
function(detect_cxx_standard CXX_STANDARD)
set(${CXX_STANDARD} ${CMAKE_CXX_STANDARD} PARENT_SCOPE)
if(CMAKE_CXX_EXTENSIONS)
set(${CXX_STANDARD} "gnu${CMAKE_CXX_STANDARD}" PARENT_SCOPE)
endif()
endfunction()
macro(detect_gnu_libstdcxx)
# _CONAN_IS_GNU_LIBSTDCXX true if GNU libstdc++
check_cxx_source_compiles("
#include <cstddef>
#if !defined(__GLIBCXX__) && !defined(__GLIBCPP__)
static_assert(false);
#endif
int main(){}" _CONAN_IS_GNU_LIBSTDCXX)
# _CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI true if C++11 ABI
check_cxx_source_compiles("
#include <string>
static_assert(sizeof(std::string) != sizeof(void*), \"using libstdc++\");
int main () {}" _CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI)
set(_CONAN_GNU_LIBSTDCXX_SUFFIX "")
if(_CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI)
set(_CONAN_GNU_LIBSTDCXX_SUFFIX "11")
endif()
unset (_CONAN_GNU_LIBSTDCXX_IS_CXX11_ABI)
endmacro()
macro(detect_libcxx)
# _CONAN_IS_LIBCXX true if LLVM libc++
check_cxx_source_compiles("
#include <cstddef>
#if !defined(_LIBCPP_VERSION)
static_assert(false);
#endif
int main(){}" _CONAN_IS_LIBCXX)
endmacro()
function(detect_lib_cxx LIB_CXX)
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
message(STATUS "CMake-Conan: android_stl=${CMAKE_ANDROID_STL_TYPE}")
set(${LIB_CXX} ${CMAKE_ANDROID_STL_TYPE} PARENT_SCOPE)
return()
endif()
include(CheckCXXSourceCompiles)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
detect_gnu_libstdcxx()
set(${LIB_CXX} "libstdc++${_CONAN_GNU_LIBSTDCXX_SUFFIX}" PARENT_SCOPE)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
set(${LIB_CXX} "libc++" PARENT_SCOPE)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
# Check for libc++
detect_libcxx()
if(_CONAN_IS_LIBCXX)
set(${LIB_CXX} "libc++" PARENT_SCOPE)
return()
endif()
# Check for libstdc++
detect_gnu_libstdcxx()
if(_CONAN_IS_GNU_LIBSTDCXX)
set(${LIB_CXX} "libstdc++${_CONAN_GNU_LIBSTDCXX_SUFFIX}" PARENT_SCOPE)
return()
endif()
# TODO: it would be an error if we reach this point
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
# Do nothing - compiler.runtime and compiler.runtime_type
# should be handled separately: https://github.com/conan-io/cmake-conan/pull/516
return()
else()
# TODO: unable to determine, ask user to provide a full profile file instead
endif()
endfunction()
function(detect_compiler COMPILER COMPILER_VERSION COMPILER_RUNTIME COMPILER_RUNTIME_TYPE)
if(DEFINED CMAKE_CXX_COMPILER_ID)
set(_COMPILER ${CMAKE_CXX_COMPILER_ID})
set(_COMPILER_VERSION ${CMAKE_CXX_COMPILER_VERSION})
else()
if(NOT DEFINED CMAKE_C_COMPILER_ID)
message(FATAL_ERROR "C or C++ compiler not defined")
endif()
set(_COMPILER ${CMAKE_C_COMPILER_ID})
set(_COMPILER_VERSION ${CMAKE_C_COMPILER_VERSION})
endif()
message(STATUS "CMake-Conan: CMake compiler=${_COMPILER}")
message(STATUS "CMake-Conan: CMake compiler version=${_COMPILER_VERSION}")
if(_COMPILER MATCHES MSVC)
set(_COMPILER "msvc")
string(SUBSTRING ${MSVC_VERSION} 0 3 _COMPILER_VERSION)
# Configure compiler.runtime and compiler.runtime_type settings for MSVC
if(CMAKE_MSVC_RUNTIME_LIBRARY)
set(_msvc_runtime_library ${CMAKE_MSVC_RUNTIME_LIBRARY})
else()
set(_msvc_runtime_library MultiThreaded$<$<CONFIG:Debug>:Debug>DLL) # default value documented by CMake
endif()
set(_KNOWN_MSVC_RUNTIME_VALUES "")
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded MultiThreadedDLL)
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreadedDebug MultiThreadedDebugDLL)
list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded$<$<CONFIG:Debug>:Debug> MultiThreaded$<$<CONFIG:Debug>:Debug>DLL)
# only accept the 6 possible values, otherwise we don't don't know to map this
if(NOT _msvc_runtime_library IN_LIST _KNOWN_MSVC_RUNTIME_VALUES)
message(FATAL_ERROR "CMake-Conan: unable to map MSVC runtime: ${_msvc_runtime_library} to Conan settings")
endif()
# Runtime is "dynamic" in all cases if it ends in DLL
if(_msvc_runtime_library MATCHES ".*DLL$")
set(_COMPILER_RUNTIME "dynamic")
else()
set(_COMPILER_RUNTIME "static")
endif()
message(STATUS "CMake-Conan: CMake compiler.runtime=${_COMPILER_RUNTIME}")
# Only define compiler.runtime_type when explicitly requested
# If a generator expression is used, let Conan handle it conditional on build_type
if(NOT _msvc_runtime_library MATCHES "<CONFIG:Debug>:Debug>")
if(_msvc_runtime_library MATCHES "Debug")
set(_COMPILER_RUNTIME_TYPE "Debug")
else()
set(_COMPILER_RUNTIME_TYPE "Release")
endif()
message(STATUS "CMake-Conan: CMake compiler.runtime_type=${_COMPILER_RUNTIME_TYPE}")
endif()
unset(_KNOWN_MSVC_RUNTIME_VALUES)
elseif(_COMPILER MATCHES AppleClang)
set(_COMPILER "apple-clang")
string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION})
list(GET VERSION_LIST 0 _COMPILER_VERSION)
elseif(_COMPILER MATCHES Clang)
set(_COMPILER "clang")
string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION})
list(GET VERSION_LIST 0 _COMPILER_VERSION)
elseif(_COMPILER MATCHES GNU)
set(_COMPILER "gcc")
string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION})
list(GET VERSION_LIST 0 _COMPILER_VERSION)
endif()
message(STATUS "CMake-Conan: [settings] compiler=${_COMPILER}")
message(STATUS "CMake-Conan: [settings] compiler.version=${_COMPILER_VERSION}")
if (_COMPILER_RUNTIME)
message(STATUS "CMake-Conan: [settings] compiler.runtime=${_COMPILER_RUNTIME}")
endif()
if (_COMPILER_RUNTIME_TYPE)
message(STATUS "CMake-Conan: [settings] compiler.runtime_type=${_COMPILER_RUNTIME_TYPE}")
endif()
set(${COMPILER} ${_COMPILER} PARENT_SCOPE)
set(${COMPILER_VERSION} ${_COMPILER_VERSION} PARENT_SCOPE)
set(${COMPILER_RUNTIME} ${_COMPILER_RUNTIME} PARENT_SCOPE)
set(${COMPILER_RUNTIME_TYPE} ${_COMPILER_RUNTIME_TYPE} PARENT_SCOPE)
endfunction()
function(detect_build_type BUILD_TYPE)
get_property(_MULTICONFIG_GENERATOR GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT _MULTICONFIG_GENERATOR)
# Only set when we know we are in a single-configuration generator
# Note: we may want to fail early if `CMAKE_BUILD_TYPE` is not defined
set(${BUILD_TYPE} ${CMAKE_BUILD_TYPE} PARENT_SCOPE)
endif()
endfunction()
macro(set_conan_compiler_if_appleclang lang command output_variable)
if(CMAKE_${lang}_COMPILER_ID STREQUAL "AppleClang")
execute_process(COMMAND xcrun --find ${command}
OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE)
cmake_path(GET _xcrun_out PARENT_PATH _xcrun_toolchain_path)
cmake_path(GET CMAKE_${lang}_COMPILER PARENT_PATH _compiler_parent_path)
if ("${_xcrun_toolchain_path}" STREQUAL "${_compiler_parent_path}")
set(${output_variable} "")
endif()
unset(_xcrun_out)
unset(_xcrun_toolchain_path)
unset(_compiler_parent_path)
endif()
endmacro()
macro(append_compiler_executables_configuration)
set(_conan_c_compiler "")
set(_conan_cpp_compiler "")
if(CMAKE_C_COMPILER)
set(_conan_c_compiler "\"c\":\"${CMAKE_C_COMPILER}\",")
set_conan_compiler_if_appleclang(C cc _conan_c_compiler)
else()
message(WARNING "CMake-Conan: The C compiler is not defined. "
"Please define CMAKE_C_COMPILER or enable the C language.")
endif()
if(CMAKE_CXX_COMPILER)
set(_conan_cpp_compiler "\"cpp\":\"${CMAKE_CXX_COMPILER}\"")
set_conan_compiler_if_appleclang(CXX c++ _conan_cpp_compiler)
else()
message(WARNING "CMake-Conan: The C++ compiler is not defined. "
"Please define CMAKE_CXX_COMPILER or enable the C++ language.")
endif()
if(NOT "x${_conan_c_compiler}${_conan_cpp_compiler}" STREQUAL "x")
string(APPEND PROFILE "tools.build:compiler_executables={${_conan_c_compiler}${_conan_cpp_compiler}}\n")
endif()
unset(_conan_c_compiler)
unset(_conan_cpp_compiler)
endmacro()
function(detect_host_profile output_file)
detect_os(MYOS MYOS_API_LEVEL MYOS_SDK MYOS_SUBSYSTEM MYOS_VERSION)
detect_arch(MYARCH)
detect_compiler(MYCOMPILER MYCOMPILER_VERSION MYCOMPILER_RUNTIME MYCOMPILER_RUNTIME_TYPE)
detect_cxx_standard(MYCXX_STANDARD)
detect_lib_cxx(MYLIB_CXX)
detect_build_type(MYBUILD_TYPE)
set(PROFILE "")
string(APPEND PROFILE "[settings]\n")
if(MYARCH)
string(APPEND PROFILE arch=${MYARCH} "\n")
endif()
if(MYOS)
string(APPEND PROFILE os=${MYOS} "\n")
endif()
if(MYOS_API_LEVEL)
string(APPEND PROFILE os.api_level=${MYOS_API_LEVEL} "\n")
endif()
if(MYOS_VERSION)
string(APPEND PROFILE os.version=${MYOS_VERSION} "\n")
endif()
if(MYOS_SDK)
string(APPEND PROFILE os.sdk=${MYOS_SDK} "\n")
endif()
if(MYOS_SUBSYSTEM)
string(APPEND PROFILE os.subsystem=${MYOS_SUBSYSTEM} "\n")
endif()
if(MYCOMPILER)
string(APPEND PROFILE compiler=${MYCOMPILER} "\n")
endif()
if(MYCOMPILER_VERSION)
string(APPEND PROFILE compiler.version=${MYCOMPILER_VERSION} "\n")
endif()
if(MYCOMPILER_RUNTIME)
string(APPEND PROFILE compiler.runtime=${MYCOMPILER_RUNTIME} "\n")
endif()
if(MYCOMPILER_RUNTIME_TYPE)
string(APPEND PROFILE compiler.runtime_type=${MYCOMPILER_RUNTIME_TYPE} "\n")
endif()
if(MYCXX_STANDARD)
string(APPEND PROFILE compiler.cppstd=${MYCXX_STANDARD} "\n")
endif()
if(MYLIB_CXX)
string(APPEND PROFILE compiler.libcxx=${MYLIB_CXX} "\n")
endif()
if(MYBUILD_TYPE)
string(APPEND PROFILE "build_type=${MYBUILD_TYPE}\n")
endif()
if(NOT DEFINED output_file)
set(_FN "${CMAKE_BINARY_DIR}/profile")
else()
set(_FN ${output_file})
endif()
string(APPEND PROFILE "[conf]\n")
string(APPEND PROFILE "tools.cmake.cmaketoolchain:generator=${CMAKE_GENERATOR}\n")
# propagate compilers via profile
append_compiler_executables_configuration()
if(MYOS STREQUAL "Android")
string(APPEND PROFILE "tools.android:ndk_path=${CMAKE_ANDROID_NDK}\n")
endif()
message(STATUS "CMake-Conan: Creating profile ${_FN}")
file(WRITE ${_FN} ${PROFILE})
message(STATUS "CMake-Conan: Profile: \n${PROFILE}")
endfunction()
function(conan_profile_detect_default)
message(STATUS "CMake-Conan: Checking if a default profile exists")
execute_process(COMMAND ${CONAN_COMMAND} profile path default
RESULT_VARIABLE return_code
OUTPUT_VARIABLE conan_stdout
ERROR_VARIABLE conan_stderr
ECHO_ERROR_VARIABLE # show the text output regardless
ECHO_OUTPUT_VARIABLE
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
if(NOT ${return_code} EQUAL "0")
message(STATUS "CMake-Conan: The default profile doesn't exist, detecting it.")
execute_process(COMMAND ${CONAN_COMMAND} profile detect
RESULT_VARIABLE return_code
OUTPUT_VARIABLE conan_stdout
ERROR_VARIABLE conan_stderr
ECHO_ERROR_VARIABLE # show the text output regardless
ECHO_OUTPUT_VARIABLE
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endif()
endfunction()
function(conan_install)
cmake_parse_arguments(ARGS CONAN_ARGS ${ARGN})
set(CONAN_OUTPUT_FOLDER ${CMAKE_BINARY_DIR}/conan)
# Invoke "conan install" with the provided arguments
set(CONAN_ARGS ${CONAN_ARGS} -of=${CONAN_OUTPUT_FOLDER})
message(STATUS "CMake-Conan: conan install ${CMAKE_SOURCE_DIR} ${CONAN_ARGS} ${ARGN}")
# In case there was not a valid cmake executable in the PATH, we inject the
# same we used to invoke the provider to the PATH
if(DEFINED PATH_TO_CMAKE_BIN)
set(_OLD_PATH $ENV{PATH})
set(ENV{PATH} "$ENV{PATH}:${PATH_TO_CMAKE_BIN}")
endif()
execute_process(COMMAND ${CONAN_COMMAND} install ${CMAKE_SOURCE_DIR} ${CONAN_ARGS} ${ARGN} --format=json
RESULT_VARIABLE return_code
OUTPUT_VARIABLE conan_stdout
ERROR_VARIABLE conan_stderr
ECHO_ERROR_VARIABLE # show the text output regardless
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
if(DEFINED PATH_TO_CMAKE_BIN)
set(ENV{PATH} "${_OLD_PATH}")
endif()
if(NOT "${return_code}" STREQUAL "0")
message(FATAL_ERROR "Conan install failed='${return_code}'")
endif()
# the files are generated in a folder that depends on the layout used, if
# one is specified, but we don't know a priori where this is.
# TODO: this can be made more robust if Conan can provide this in the json output
string(JSON CONAN_GENERATORS_FOLDER GET ${conan_stdout} graph nodes 0 generators_folder)
cmake_path(CONVERT ${CONAN_GENERATORS_FOLDER} TO_CMAKE_PATH_LIST CONAN_GENERATORS_FOLDER)
# message("conan stdout: ${conan_stdout}")
message(STATUS "CMake-Conan: CONAN_GENERATORS_FOLDER=${CONAN_GENERATORS_FOLDER}")
set_property(GLOBAL PROPERTY CONAN_GENERATORS_FOLDER "${CONAN_GENERATORS_FOLDER}")
# reconfigure on conanfile changes
string(JSON CONANFILE GET ${conan_stdout} graph nodes 0 label)
message(STATUS "CMake-Conan: CONANFILE=${CMAKE_SOURCE_DIR}/${CONANFILE}")
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/${CONANFILE}")
# success
set_property(GLOBAL PROPERTY CONAN_INSTALL_SUCCESS TRUE)
endfunction()
function(conan_get_version conan_command conan_current_version)
execute_process(
COMMAND ${conan_command} --version
OUTPUT_VARIABLE conan_output
RESULT_VARIABLE conan_result
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(conan_result)
message(FATAL_ERROR "CMake-Conan: Error when trying to run Conan")
endif()
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" conan_version ${conan_output})
set(${conan_current_version} ${conan_version} PARENT_SCOPE)
endfunction()
function(conan_version_check)
set(options )
set(oneValueArgs MINIMUM CURRENT)
set(multiValueArgs )
cmake_parse_arguments(CONAN_VERSION_CHECK
"${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(NOT CONAN_VERSION_CHECK_MINIMUM)
message(FATAL_ERROR "CMake-Conan: Required parameter MINIMUM not set!")
endif()
if(NOT CONAN_VERSION_CHECK_CURRENT)
message(FATAL_ERROR "CMake-Conan: Required parameter CURRENT not set!")
endif()
if(CONAN_VERSION_CHECK_CURRENT VERSION_LESS CONAN_VERSION_CHECK_MINIMUM)
message(FATAL_ERROR "CMake-Conan: Conan version must be ${CONAN_VERSION_CHECK_MINIMUM} or later")
endif()
endfunction()
macro(construct_profile_argument argument_variable profile_list)
set(${argument_variable} "")
if("${profile_list}" STREQUAL "CONAN_HOST_PROFILE")
set(_arg_flag "--profile:host=")
elseif("${profile_list}" STREQUAL "CONAN_BUILD_PROFILE")
set(_arg_flag "--profile:build=")
endif()
set(_profile_list "${${profile_list}}")
list(TRANSFORM _profile_list REPLACE "auto-cmake" "${CMAKE_BINARY_DIR}/conan_host_profile")
list(TRANSFORM _profile_list PREPEND ${_arg_flag})
set(${argument_variable} ${_profile_list})
unset(_arg_flag)
unset(_profile_list)
endmacro()
macro(conan_provide_dependency method package_name)
set_property(GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED TRUE)
get_property(_conan_install_success GLOBAL PROPERTY CONAN_INSTALL_SUCCESS)
if(NOT _conan_install_success)
find_program(CONAN_COMMAND "conan" REQUIRED)
conan_get_version(${CONAN_COMMAND} CONAN_CURRENT_VERSION)
conan_version_check(MINIMUM ${CONAN_MINIMUM_VERSION} CURRENT ${CONAN_CURRENT_VERSION})
message(STATUS "CMake-Conan: first find_package() found. Installing dependencies with Conan")
if("default" IN_LIST CONAN_HOST_PROFILE OR "default" IN_LIST CONAN_BUILD_PROFILE)
conan_profile_detect_default()
endif()
if("auto-cmake" IN_LIST CONAN_HOST_PROFILE)
detect_host_profile(${CMAKE_BINARY_DIR}/conan_host_profile)
endif()
construct_profile_argument(_host_profile_flags CONAN_HOST_PROFILE)
construct_profile_argument(_build_profile_flags CONAN_BUILD_PROFILE)
if(EXISTS "${CMAKE_SOURCE_DIR}/conanfile.py")
file(READ "${CMAKE_SOURCE_DIR}/conanfile.py" outfile)
if(NOT "${outfile}" MATCHES ".*CMakeDeps.*")
message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile")
endif()
set(generator "")
elseif (EXISTS "${CMAKE_SOURCE_DIR}/conanfile.txt")
file(READ "${CMAKE_SOURCE_DIR}/conanfile.txt" outfile)
if(NOT "${outfile}" MATCHES ".*CMakeDeps.*")
message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile. "
"Please define the generator as it will be mandatory in the future")
endif()
set(generator "-g;CMakeDeps")
endif()
get_property(_multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT _multiconfig_generator)
message(STATUS "CMake-Conan: Installing single configuration ${CMAKE_BUILD_TYPE}")
conan_install(${_host_profile_flags} ${_build_profile_flags} ${CONAN_INSTALL_ARGS} ${generator})
else()
if(CONAN_INSTALL_CONFIGURATIONS)
set(_conan_install_configurations ${CONAN_INSTALL_CONFIGURATIONS})
else()
set(_conan_install_configurations Release Debug)
endif()
message(STATUS "CMake-Conan: Installing configurations ${_conan_install_configurations}")
foreach(_conan_config IN LISTS _conan_install_configurations)
conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=${_conan_config} ${CONAN_INSTALL_ARGS} ${generator})
endforeach()
unset(_conan_install_configurations)
unset(_conan_config)
endif()
unset(_host_profile_flags)
unset(_build_profile_flags)
unset(_multiconfig_generator)
unset(_conan_install_success)
else()
message(STATUS "CMake-Conan: find_package(${ARGV1}) found, 'conan install' already ran")
unset(_conan_install_success)
endif()
get_property(_conan_generators_folder GLOBAL PROPERTY CONAN_GENERATORS_FOLDER)
# Ensure that we consider Conan-provided packages ahead of any other,
# irrespective of other settings that modify the search order or search paths
# This follows the guidelines from the find_package documentation
# (https://cmake.org/cmake/help/latest/command/find_package.html):
# find_package (<PackageName> PATHS paths... NO_DEFAULT_PATH)
# find_package (<PackageName>)
# Filter out `REQUIRED` from the argument list, as the first call may fail
set(_find_args_${package_name} "${ARGN}")
list(REMOVE_ITEM _find_args_${package_name} "REQUIRED")
if(NOT "MODULE" IN_LIST _find_args_${package_name})
find_package(${package_name} ${_find_args_${package_name}} BYPASS_PROVIDER PATHS "${_conan_generators_folder}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
unset(_find_args_${package_name})
endif()
# Invoke find_package a second time - if the first call succeeded,
# this will simply reuse the result. If not, fall back to CMake default search
# behaviour, also allowing modules to be searched.
if(NOT ${package_name}_FOUND)
list(FIND CMAKE_MODULE_PATH "${_conan_generators_folder}" _index)
if(_index EQUAL -1)
list(PREPEND CMAKE_MODULE_PATH "${_conan_generators_folder}")
endif()
unset(_index)
find_package(${package_name} ${ARGN} BYPASS_PROVIDER)
list(REMOVE_ITEM CMAKE_MODULE_PATH "${_conan_generators_folder}")
endif()
endmacro()
cmake_language(
SET_DEPENDENCY_PROVIDER conan_provide_dependency
SUPPORTED_METHODS FIND_PACKAGE
)
macro(conan_provide_dependency_check)
set(_CONAN_PROVIDE_DEPENDENCY_INVOKED FALSE)
get_property(_CONAN_PROVIDE_DEPENDENCY_INVOKED GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED)
if(NOT _CONAN_PROVIDE_DEPENDENCY_INVOKED)
message(WARNING "Conan is correctly configured as dependency provider, "
"but Conan has not been invoked. Please add at least one "
"call to `find_package()`.")
if(DEFINED CONAN_COMMAND)
# supress warning in case `CONAN_COMMAND` was specified but unused.
set(_CONAN_COMMAND ${CONAN_COMMAND})
unset(_CONAN_COMMAND)
endif()
endif()
unset(_CONAN_PROVIDE_DEPENDENCY_INVOKED)
endmacro()
# Add a deferred call at the end of processing the top-level directory
# to check if the dependency provider was invoked at all.
cmake_language(DEFER DIRECTORY "${CMAKE_SOURCE_DIR}" CALL conan_provide_dependency_check)
# Configurable variables for Conan profiles
set(CONAN_HOST_PROFILE "default;auto-cmake" CACHE STRING "Conan host profile")
set(CONAN_BUILD_PROFILE "default" CACHE STRING "Conan build profile")
set(CONAN_INSTALL_ARGS "--build=missing" CACHE STRING "Command line arguments for conan install")
set(CONAN_INSTALL_CONFIGURATIONS "" CACHE STRING "Conan build_type values to install for multi-config generators")
find_program(_cmake_program NAMES cmake NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_FIND_ROOT_PATH)
if(NOT _cmake_program)
get_filename_component(PATH_TO_CMAKE_BIN "${CMAKE_COMMAND}" DIRECTORY)
set(PATH_TO_CMAKE_BIN "${PATH_TO_CMAKE_BIN}" CACHE INTERNAL "Path where the CMake executable is")
endif()
+12
View File
@@ -0,0 +1,12 @@
[requires]
libssh2/1.11.1
nlohmann_json/3.12.0
[options]
libssh2/*:shared=False
[layout]
cmake_layout
[generators]
CMakeDeps
+1 -1
Submodule core updated: d2eb5fb047...16a62f486b
+17
View File
@@ -1,3 +1,20 @@
set(C2_BASE64_SOURCE_DIR "${CMAKE_SOURCE_DIR}/thirdParty/base64" CACHE PATH
"Path to the cpp-base64 source tree consumed by C2Core")
set(C2_DONUT_SOURCE_DIR "${CMAKE_SOURCE_DIR}/thirdParty/donut" CACHE PATH
"Path to the donut source tree consumed by C2Core")
add_library(c2_base64 STATIC
"${C2_BASE64_SOURCE_DIR}/base64.cpp"
)
target_include_directories(c2_base64 PUBLIC
"${C2_BASE64_SOURCE_DIR}"
)
set_target_properties(c2_base64 PROPERTIES
POSITION_INDEPENDENT_CODE ON
)
add_subdirectory(coffLoader)
add_subdirectory(MemoryModule)
-24766
View File
File diff suppressed because it is too large Load Diff