Skip to content

Commit

Permalink
cmake: upgrade to Conan 2 (#2318)
Browse files Browse the repository at this point in the history
  • Loading branch information
battlmonstr committed Dec 26, 2024
1 parent e2f442f commit 81b78e1
Show file tree
Hide file tree
Showing 44 changed files with 353 additions and 269 deletions.
8 changes: 4 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ commands:
- run:
name: "Install Conan"
command: |
pip3 install --user --no-warn-script-location conan==1.64.1
pip3 install --user --no-warn-script-location conan==2.10.2
conan_path="$(python3 -m site --user-base)/bin"
echo "export \"PATH=$conan_path:\$PATH\"" >> "$BASH_ENV"
"$conan_path/conan" --version
Expand All @@ -109,7 +109,7 @@ commands:
command: |
if [[ "<<parameters.compiler_id>>" == "clang" ]]
then
conan_profile=linux_x64_clang_13_release
conan_profile=linux_x64_clang_16_release
else
conan_profile=linux_x64_gcc_11_release
fi
Expand All @@ -128,7 +128,7 @@ commands:
name: "Save Conan cache"
key: *conan-cache-key
paths:
- ~/.conan
- ~/.conan2

build_fuzzer:
steps:
Expand All @@ -146,7 +146,7 @@ commands:
- run:
name: "CMake Fuzzer"
working_directory: ~/build
command: cmake ../project -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCONAN_PROFILE=linux_x64_clang_13_release -DCMAKE_TOOLCHAIN_FILE=../project/cmake/toolchain/clang_libcxx.cmake -DSILKWORM_FUZZER=ON
command: cmake ../project -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCONAN_PROFILE=linux_x64_clang_16_release -DCMAKE_TOOLCHAIN_FILE=../project/cmake/toolchain/clang_libcxx.cmake -DSILKWORM_FUZZER=ON
- run:
name: "Build Fuzzer"
command: |
Expand Down
9 changes: 2 additions & 7 deletions .github/actions/fuzzer-common-steps/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,12 @@ runs:

- name: Temporary step - conan cache cleanup - to be executed only once per runner
shell: bash
run: conan remove "*" --force

- name: Preinstall Conan packages
shell: bash
working-directory: ${{runner.workspace}}/silkworm
run: CC=clang-16 CXX=clang++-16 conan install --install-folder=build/conan --build=missing --profile=cmake/profiles/experimental/linux_x64_clang_16_release .
run: /opt/conan2/bin/conan remove --confirm "*"

- name: Configure CMake
shell: bash
working-directory: ${{runner.workspace}}/silkworm/build
run: CC=clang-16 CXX=clang++-16 cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCONAN_PROFILE=experimental/linux_x64_clang_16_release -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain/clang_libcxx.cmake -DSILKWORM_FUZZER=ON -DSILKWORM_FUZZER_SANITIZERS=${{inputs.fuzzer_sanitizers}}
run: CC=clang-16 CXX=clang++-16 cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCONAN_PROFILE=linux_x64_clang_16_release -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchain/clang_libcxx.cmake -DSILKWORM_FUZZER=ON -DSILKWORM_FUZZER_SANITIZERS=${{inputs.fuzzer_sanitizers}}

- name: Build Silkworm Fuzzer Test
shell: bash
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/macOS.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:

- name: Install Prerequisites
run: |
pip3 install --user --break-system-packages --no-warn-script-location conan==1.64.1 chardet
pip3 install --user --break-system-packages --no-warn-script-location conan==2.10.2 chardet
conan_path="$(python3 -m site --user-base)/bin"
echo "$conan_path" >> $GITHUB_PATH
"$conan_path/conan" --version
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
id: conan
uses: turtlebrowser/get-conan@main
with:
version: 1.64.1
version: 2.10.2

- name: Create Build Environment
# Some projects don't allow in-source building, so create a separate build directory
Expand Down
21 changes: 15 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,38 @@
limitations under the License.
]]

cmake_minimum_required(VERSION 3.19.0)
cmake_minimum_required(VERSION 3.24.0)

if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/evmone/evmone/evmc/.git)
message(FATAL_ERROR "Git submodules not initialized, execute:\n git submodule update --init --recursive")
endif()

get_directory_property(SILKWORM_HAS_PARENT PARENT_DIRECTORY)
if(NOT SILKWORM_HAS_PARENT)
# reduce the log verbosity of evmone/cmake/cable
if(NOT CMAKE_MESSAGE_LOG_LEVEL)
set(CMAKE_MESSAGE_LOG_LEVEL_EMPTY YES)
set(CMAKE_MESSAGE_LOG_LEVEL NOTICE)
endif()

include(third_party/evmone/evmone/cmake/cable/bootstrap.cmake)
include(CableBuildType)
cable_set_build_type(DEFAULT Release CONFIGURATION_TYPES Release Debug)

# restore the log verbosity
if(CMAKE_MESSAGE_LOG_LEVEL_EMPTY)
unset(CMAKE_MESSAGE_LOG_LEVEL)
endif()

if(NOT CMAKE_TOOLCHAIN_FILE)
set(CMAKE_TOOLCHAIN_FILE
${CMAKE_CURRENT_SOURCE_DIR}/cmake/toolchain/cxx20.cmake
CACHE FILEPATH "" FORCE
)
include("${CMAKE_TOOLCHAIN_FILE}")
endif()

include(cmake/conan.cmake)
endif()

project(silkworm)
Expand Down Expand Up @@ -70,10 +83,6 @@ option(SILKWORM_FUZZER_SANITIZERS "CLang sanitizer options for fuzzers" OFF)
option(SILKWORM_USE_MIMALLOC "Enable using mimalloc for dynamic memory management" ON)
option(SILKWORM_ALLOW_UNUSED_VAR_WARNINGS "Turn unused variable errors into warnings" OFF)

if(NOT SILKWORM_HAS_PARENT)
include(cmake/conan.cmake)
endif()

set_property(
DIRECTORY
APPEND
Expand Down Expand Up @@ -125,5 +134,5 @@ if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
# avoid fatal error C1002: compiler is out of heap space
list(REMOVE_ITEM UNIT_TEST_TARGETS silkworm_rpcdaemon_test)
endif()
message(STATUS "UNIT_TEST_TARGETS: ${UNIT_TEST_TARGETS}")
message(VERBOSE "UNIT_TEST_TARGETS: ${UNIT_TEST_TARGETS}")
add_custom_target(all_unit_tests DEPENDS ${UNIT_TEST_TARGETS})
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ or AppleClang ([Xcode](https://developer.apple.com/xcode/) >= 15)

Conan requires Python, and can be installed using:

pip3 install --user conan==1.64.1 chardet
pip3 install --user conan==2.10.2 chardet

On Linux the conan binary gets installed into `$HOME/.local/bin` which is typically in PATH already.
On macOS need to add the binary to PATH manually:
Expand All @@ -122,9 +122,7 @@ will use "debug" configuration builds of dependencies.

See available profiles in [cmake/profiles](cmake/profiles).

The conan packages could also be pre-installed using [conan install](https://docs.conan.io/1/reference/commands/consumer/install.html):

conan install --install-folder=build/conan --build=missing --profile=cmake/profiles/macos_arm64_clang_13_debug .
During the cmake configuration step `conan_provider.cmake` runs a [conan install](https://docs.conan.io/2/reference/commands/install.html) command that downloads packages and builds some of them from source if needed. The exact arguments to this command are printed in the build log.


Then run the build itself
Expand Down
10 changes: 0 additions & 10 deletions cmake/compiler_settings.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,6 @@ elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES ".*Clang$")
link_libraries(c++abi)
endif()

# cmake-format: off
# abseil in conan is prebuilt with clang 13 (see profiles),
# linking absl::log with clang 18+ produces an error due to an ABI change:
# https://github.com/abseil/abseil-cpp/issues/1747
# https://github.com/llvm/llvm-project/issues/102443
# cmake-format: on
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 18)
add_compile_options(-fclang-abi-compat=17)
endif()

else()
message(WARNING "${CMAKE_CXX_COMPILER_ID} is not a supported compiler. Use at your own risk.")
endif()
Expand Down
134 changes: 105 additions & 29 deletions cmake/conan.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,18 @@
]]

include(${CMAKE_CURRENT_LIST_DIR}/compiler_settings_sanitize.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/conan_quiet.cmake)

function(guess_conan_profile)
if("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "" AND CMAKE_HOST_UNIX)
execute_process(
COMMAND uname -m
OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND_ERROR_IS_FATAL ANY
)
endif()

if("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "")
set(ARCH_NAME "")
elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL x86_64)
Expand All @@ -38,7 +48,7 @@ function(guess_conan_profile)
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND ARCH_NAME)
set(PROFILE macos_${ARCH_NAME}_clang_13_release)
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(PROFILE windows_msvc_16_release)
set(PROFILE windows_msvc_193_release)
else()
message(FATAL_ERROR "CONAN_PROFILE is not defined for ${CMAKE_HOST_SYSTEM_NAME} on ${CMAKE_HOST_SYSTEM_PROCESSOR}")
endif()
Expand All @@ -49,70 +59,136 @@ function(guess_conan_profile)
)
endfunction()

set(CONAN_BINARY_DIR "${CMAKE_BINARY_DIR}/conan")
list(APPEND CMAKE_MODULE_PATH ${CONAN_BINARY_DIR})
list(APPEND CMAKE_PREFIX_PATH ${CONAN_BINARY_DIR})
function(get_conan_build_type profile_path var)
file(READ "${profile_path}" CONTENTS)
string(REGEX MATCH "build_type=[A-Za-z0-9]+" VALUE "${CONTENTS}")
string(SUBSTRING "${VALUE}" 11 -1 VALUE)
set(${var}
"${VALUE}"
PARENT_SCOPE
)
endfunction()

# disable verbose logging from FindXXX.cmake files
set(CONAN_CMAKE_SILENT_OUTPUT ON)
macro(format_list_as_json_array list_var var)
list(JOIN ${list_var} "\",\"" ${var})
set(${var} "[\"${${var}}\"]")
endmacro()

include("${CMAKE_SOURCE_DIR}/third_party/cmake-conan/conan.cmake")
# unset(CONAN_COMMAND CACHE)
find_program(
CONAN_COMMAND "conan"
PATHS /opt/conan2/bin
NO_DEFAULT_PATH
)
if(NOT CONAN_COMMAND)
find_program(CONAN_COMMAND "conan" PATHS ~/.local/bin REQUIRED)
endif()

# provide a static conanfile.py instead of generating it with conan_cmake_configure()
file(COPY "${CMAKE_SOURCE_DIR}/conanfile.py" DESTINATION "${CONAN_BINARY_DIR}")
# use "verbose" for more detailed conan install logs
set(CONAN_VERBOSITY "error")
set(CONAN_BINARY_DIR "${CMAKE_BINARY_DIR}/conan2")

if(NOT DEFINED CONAN_PROFILE)
guess_conan_profile()
endif()
message(STATUS "CONAN_PROFILE: ${CONAN_PROFILE}")
message(VERBOSE "CONAN_PROFILE: ${CONAN_PROFILE}")
set(CONAN_PROFILE_PATH "${CMAKE_SOURCE_DIR}/cmake/profiles/${CONAN_PROFILE}")
set(CONAN_HOST_PROFILE "${CONAN_PROFILE_PATH}")
set(CONAN_BUILD_PROFILE "${CONAN_PROFILE_PATH}")
get_conan_build_type("${CONAN_PROFILE_PATH}" CONAN_BUILD_TYPE)

set(CONAN_BUILD "missing")
set(CONAN_CXXFLAGS_ARG)
set(CONAN_OPTIONS)
set(CONAN_SETTINGS "")
set(CONAN_OPTIONS "")
set(CONAN_CONF "")

if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
set(OS_VERSION_MIN_CXXFLAG "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
endif()

if(OS_VERSION_MIN_CXXFLAG AND NOT SILKWORM_SANITIZE_COMPILER_OPTIONS)
list(APPEND CONAN_CONF "libtorrent/*:tools.build:cxxflags=[\"${OS_VERSION_MIN_CXXFLAG}\"]")
endif()

if(SILKWORM_SANITIZE_COMPILER_OPTIONS)
set(CONAN_CXXFLAGS ${SILKWORM_SANITIZE_COMPILER_OPTIONS})

if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
list(APPEND CONAN_CXXFLAGS "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
if(OS_VERSION_MIN_CXXFLAG)
list(APPEND CONAN_CXXFLAGS ${OS_VERSION_MIN_CXXFLAG})
endif()

list(JOIN CONAN_CXXFLAGS "\", \"" CONAN_CXXFLAGS_STR)
set(CONAN_CXXFLAGS_STR "[\"${CONAN_CXXFLAGS_STR}\"]")
set(CONAN_CXXFLAGS_ARG "tools.build:cxxflags=${CONAN_CXXFLAGS_STR}")

list(APPEND CONAN_OPTIONS "boost:zlib=False")
list(APPEND CONAN_OPTIONS "boost/*:zlib=False")

# libraries that needs to be rebuilt with sanitize flags
# cmake-format: off
set(CONAN_BUILD
list(APPEND CONAN_BUILD
abseil
boost
grpc
libtorrent
protobuf
)
# cmake-format: on

format_list_as_json_array(CONAN_CXXFLAGS CONAN_CXXFLAGS_STR)
foreach(PACKAGE IN LISTS CONAN_BUILD)
if(NOT PACKAGE STREQUAL "missing")
list(APPEND CONAN_CONF "${PACKAGE}/*:tools.build:cxxflags=${CONAN_CXXFLAGS_STR}")
endif()
endforeach()
endif()

if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(CONAN_VERBOSITY "verbose")
# make sure to not rebuild anything from source unless required
set(CONAN_BUILD "missing:libtorrent/*")
# HACK: MSVC is "multi config" and conan_provider.cmake runs 2 conan install commands for both Release and Debug
# despite CMAKE_BUILD_TYPE. This adds an extra build_type setting to both commands to override and force the desired
# build type. It still runs 2 commands, but the 2nd one has no effect.
list(APPEND CONAN_SETTINGS "build_type=${CMAKE_BUILD_TYPE}")
# most Windows packages on ConanCenter are built for cppstd=14, but some packages require at least cppstd=17
# (otherwise report "Invalid" status)
list(APPEND CONAN_SETTINGS "asio-grpc/*:compiler.cppstd=17")
list(APPEND CONAN_SETTINGS "magic_enum/*:compiler.cppstd=17")
list(APPEND CONAN_SETTINGS "tomlplusplus/*:compiler.cppstd=17")
endif()

if(SILKWORM_USE_MIMALLOC)
# mimalloc override option causes a crash on macOS at startup in rpcdaemon, so we enable it just on Linux. mimalloc
# should not be used in sanitizer builds or at least its override option must be disabled
# (https://github.com/microsoft/mimalloc/issues/317#issuecomment-708506405)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" AND NOT SILKWORM_SANITIZE)
list(APPEND CONAN_OPTIONS "mimalloc:override=True")
list(APPEND CONAN_OPTIONS "mimalloc/*:override=True")
endif()
endif()

if(SILKWORM_CORE_ONLY)
set(CONAN_CXXFLAGS_ARG "catch2/*:tools.build:cxxflags=[\"-fno-exceptions\"]")
list(APPEND CONAN_CONF "catch2/*:tools.build:cxxflags=[\"-fno-exceptions\"]")
endif()

conan_cmake_install(
PATH_OR_REFERENCE "${CONAN_BINARY_DIR}"
INSTALL_FOLDER "${CONAN_BINARY_DIR}"
BUILD ${CONAN_BUILD}
OPTIONS ${CONAN_OPTIONS}
PROFILE "${CMAKE_SOURCE_DIR}/cmake/profiles/${CONAN_PROFILE}"
CONF "${CONAN_CXXFLAGS_ARG}"
# cmake-format: off
set(CONAN_INSTALL_ARGS
-v ${CONAN_VERBOSITY}
--output-folder "${CONAN_BINARY_DIR}"
# https://github.com/conan-io/cmake-conan/issues/607
--settings:all "&:build_type=${CMAKE_BUILD_TYPE}"
)
# cmake-format: on

foreach(VALUE IN LISTS CONAN_BUILD)
list(APPEND CONAN_INSTALL_ARGS --build=${VALUE})
endforeach()

foreach(VALUE IN LISTS CONAN_SETTINGS)
list(APPEND CONAN_INSTALL_ARGS --settings:all=${VALUE})
endforeach()

foreach(VALUE IN LISTS CONAN_OPTIONS)
list(APPEND CONAN_INSTALL_ARGS --options:all=${VALUE})
endforeach()

foreach(VALUE IN LISTS CONAN_CONF)
list(APPEND CONAN_INSTALL_ARGS --conf:all=${VALUE})
endforeach()

set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES "${CMAKE_SOURCE_DIR}/third_party/cmake-conan/conan_provider.cmake")
Loading

0 comments on commit 81b78e1

Please sign in to comment.