Skip to content

Commit

Permalink
Set BUILD_SHARED_LIBS and CMAKE_POSITION_INDEPENDENT_CODE as Cache va…
Browse files Browse the repository at this point in the history
…riables in toolchain (#12401)

* Set BUILD_SHARED_LIBS and CMAKE_POSITION_INDEPENDENT_CODE as Cache variables in CMakeToolchain

Co-authored-by: Francisco Ramírez <[email protected]>
  • Loading branch information
jcar87 and franramirez688 authored Nov 2, 2022
1 parent 7fb77fb commit 9e6f7d5
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 3 deletions.
4 changes: 2 additions & 2 deletions conan/tools/cmake/toolchain/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class FPicBlock(Block):
template = textwrap.dedent("""
{% if fpic %}
message(STATUS "Conan toolchain: Setting CMAKE_POSITION_INDEPENDENT_CODE={{ fpic }} (options.fPIC)")
set(CMAKE_POSITION_INDEPENDENT_CODE {{ fpic }})
set(CMAKE_POSITION_INDEPENDENT_CODE {{ fpic }} CACHE BOOL "Position independent code")
{% endif %}
""")

Expand Down Expand Up @@ -239,7 +239,7 @@ def context(self):
class SharedLibBock(Block):
template = textwrap.dedent("""
message(STATUS "Conan toolchain: Setting BUILD_SHARED_LIBS = {{ shared_libs }}")
set(BUILD_SHARED_LIBS {{ shared_libs }})
set(BUILD_SHARED_LIBS {{ shared_libs }} CACHE BOOL "Build shared libraries")
""")

def context(self):
Expand Down
68 changes: 68 additions & 0 deletions conans/test/functional/toolchains/cmake/test_cmake_toolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -1061,3 +1061,71 @@ def package(self):
client.save({"conanfile.py": conanfile, "CMakeLists.txt": cmake, "my_license": "MIT"})
client.run("create .", assert_error=True)
assert "Cannot install stuff" in client.out


def test_cmake_toolchain_vars_when_option_declared():
t = TestClient()

cmakelists = textwrap.dedent("""
cmake_minimum_required(VERSION 2.8) # <---- set this to an old version for old policies
cmake_policy(SET CMP0091 NEW) # <-- Needed on Windows
project(mylib CXX)
message("CMake version: ${CMAKE_VERSION}")
# Set the options AFTER the call to project, that is, after toolchain is loaded
option(BUILD_SHARED_LIBS "" ON)
option(CMAKE_POSITION_INDEPENDENT_CODE "" OFF)
add_library(mylib src/mylib.cpp)
target_include_directories(mylib PUBLIC include)
get_target_property(MYLIB_TARGET_TYPE mylib TYPE)
get_target_property(MYLIB_PIC mylib POSITION_INDEPENDENT_CODE)
message("mylib target type: ${MYLIB_TARGET_TYPE}")
message("MYLIB_PIC value: ${MYLIB_PIC}")
if(MYLIB_PIC)
#Note: the value is "True"/"False" if set by cmake,
# and "ON"/"OFF" if set by Conan
message("mylib position independent code: ON")
else()
message("mylib position independent code: OFF")
endif()
set_target_properties(mylib PROPERTIES PUBLIC_HEADER "include/mylib.h")
install(TARGETS mylib)
""")

t.run("new mylib/1.0 --template cmake_lib")
t.save({"CMakeLists.txt": cmakelists})

# The generated toolchain should set `BUILD_SHARED_LIBS` to `OFF`,
# and `CMAKE_POSITION_INDEPENDENT_CODE` to `ON` and the calls to
# `option()` in the CMakeLists.txt should respect the existing values.
# Note: on *WINDOWS* `fPIC` is not an option for this recipe, so it's invalid
# to pass it to Conan, in which case the value in CMakeLists.txt
# takes precedence.
fpic_option = "-o mylib:fPIC=True" if platform.system() != "Windows" else ""
fpic_cmake_value = "ON" if platform.system() != "Windows" else "OFF"
t.run(f"create . -o mylib:shared=False {fpic_option} --test-folder=None")
assert "mylib target type: STATIC_LIBRARY" in t.out
assert f"mylib position independent code: {fpic_cmake_value}" in t.out

# When building manually, ensure the value passed by the toolchain overrides the ones in
# the CMakeLists
fpic_option = "-o mylib:fPIC=False" if platform.system() != "Windows" else ""
t.run(f"install . -o mylib:shared=False {fpic_option}")
t.run_command("cmake -S . -B build/ -DCMAKE_TOOLCHAIN_FILE=build/generators/conan_toolchain.cmake")
assert "mylib target type: STATIC_LIBRARY" in t.out
assert f"mylib position independent code: OFF" in t.out

# Note: from this point forward, the CMakeCache is already initialised.
# When explicitly overriding `CMAKE_POSITION_INDEPENDENT_CODE` via command line, ensure
# this takes precedence to the value defined by the toolchain
t.run_command("cmake -S . -B build/ -DCMAKE_POSITION_INDEPENDENT_CODE=ON")
assert "mylib target type: STATIC_LIBRARY" in t.out
assert "mylib position independent code: ON" in t.out

t.run_command("cmake -S . -B build/ -DBUILD_SHARED_LIBS=ON")
assert "mylib target type: SHARED_LIBRARY" in t.out
assert "mylib position independent code: ON" in t.out
2 changes: 1 addition & 1 deletion conans/test/unittests/tools/cmake/test_cmaketoolchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ def test_fpic_when_shared_true(conanfile_linux_shared, fPIC):
toolchain = CMakeToolchain(conanfile_linux_shared)
cmake_value = 'ON' if fPIC else 'OFF'
content = toolchain.content
assert 'set(CMAKE_POSITION_INDEPENDENT_CODE {})'.format(cmake_value) in content
assert 'set(CMAKE_POSITION_INDEPENDENT_CODE {} CACHE BOOL'.format(cmake_value) in content


def test_fpic_when_not_shared(conanfile_linux_shared):
Expand Down

0 comments on commit 9e6f7d5

Please sign in to comment.