Skip to content

Commit

Permalink
Allow customization of the --build flag
Browse files Browse the repository at this point in the history
  • Loading branch information
ssrobins committed Nov 20, 2023
1 parent c53fbf5 commit c89a554
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ If you need to customize the profile, you can do so by modifying the value of `C
* `-DCONAN_BUILD_PROFILE=/path/to/profile`: alternatively, provide a path to a profile file that may be anywhere in the filesystem.
* `-DCONAN_HOST_PROFILE=default;custom`: semi-colon separated list of profiles. A compound profile will be used (see [docs](https://docs.conan.io/2.0/reference/commands/install.html#profiles-settings-options-conf)) - compunded from left to right, where right has the highest priority.

### Customizing Conan install --build flag
By default, the CMake-Conan dependency provider will pass the `--build=missing` flag to `conan install` to build any packages that don't have a compatible binary. If you would like to override this setting, you can pass one or more `--build` options in a `CONAN_BUILD` CMake cache variable. Some examples:

* `-DCONAN_BUILD=never`: use binary packages or fail if a binary package is not found
* `-DCONAN_BUILD=fmt;zlib`: build the `fmt` and `zlib` packages from source

## Development, contributors

There are some tests, you can run in python, with pytest, for example:
Expand Down
19 changes: 16 additions & 3 deletions conan_provider.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,17 @@ macro(construct_profile_argument argument_variable profile_list)
endmacro()


macro(construct_build_flag_argument argument_variable build_flag_list)
set(${argument_variable} "")
set(_arg_flag "--build=")
set(_build_flag_list "${${build_flag_list}}")
list(TRANSFORM _build_flag_list PREPEND ${_arg_flag})
set(${argument_variable} ${_build_flag_list})
unset(_arg_flag)
unset(_build_flag_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)
Expand All @@ -500,6 +511,7 @@ macro(conan_provide_dependency method package_name)
endif()
construct_profile_argument(_host_profile_flags CONAN_HOST_PROFILE)
construct_profile_argument(_build_profile_flags CONAN_BUILD_PROFILE)
construct_build_flag_argument(_build_flags CONAN_BUILD)
if(EXISTS "${CMAKE_SOURCE_DIR}/conanfile.py")
file(READ "${CMAKE_SOURCE_DIR}/conanfile.py" outfile)
if(NOT "${outfile}" MATCHES ".*CMakeDeps.*")
Expand All @@ -517,11 +529,11 @@ macro(conan_provide_dependency method package_name)
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} --build=missing ${generator})
conan_install(${_host_profile_flags} ${_build_profile_flags} ${_build_flags} ${generator})
else()
message(STATUS "CMake-Conan: Installing both Debug and Release")
conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Release --build=missing ${generator})
conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Debug --build=missing ${generator})
conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Release ${_build_flags} ${generator})
conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Debug ${_build_flags} ${generator})
endif()
unset(_host_profile_flags)
unset(_build_profile_flags)
Expand Down Expand Up @@ -594,3 +606,4 @@ cmake_language(DEFER DIRECTORY "${CMAKE_SOURCE_DIR}" CALL conan_provide_dependen
# 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_BUILD "missing" CACHE STRING "List of values for 'conan install' --build flag")
17 changes: 17 additions & 0 deletions tests/test_smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,23 @@ def test_profile_pass_path(self, capfd, basic_cmake_project):
assert "ERROR: Invalid setting 'JuliusOS' is not a valid 'settings.os' value." in err


class TestBuildFlagCustomization:
def test_build_flag_default(self, capfd, basic_cmake_project):
"""Test the default --build flag"""
source_dir, binary_dir = basic_cmake_project
run(f"cmake -S {source_dir} -B {binary_dir} -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES={conan_provider} -DCMAKE_BUILD_TYPE=Release", check=True)
out, _ = capfd.readouterr()
assert "--build=missing" in out

def test_build_flag_list(self, capfd, basic_cmake_project):
"""Test passing a list of --build flags"""
source_dir, binary_dir = basic_cmake_project
run(f'cmake -S {source_dir} -B {binary_dir} -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES={conan_provider} -DCMAKE_BUILD_TYPE=Release -DCONAN_BUILD="fmt;zlib"', check=True)
out, _ = capfd.readouterr()
assert "--build=fmt" in out
assert "--build=zlib" in out


class TestSubdir:
@pytest.fixture(scope="class", autouse=True)
def subdir_setup(self, tmp_path_factory):
Expand Down

0 comments on commit c89a554

Please sign in to comment.