Repository: conan-io/conan
Pull request #12443 (2022-11-02 10:09:08)

Make build_folder available in generate() for test_package
Changelog: Feature: Define build_folder in test_package
Docs: https://github.com/conan-io/docs/pull/XXXX

Closes: https://github.com/conan-io/conan/issues/12393



Patch:
diff --git a/README.rst b/README.rst
index fb5ea23ce..91b3c398c 100644
--- a/README.rst
+++ b/README.rst
@@ -8,7 +8,7 @@ Decentralized, open-source (MIT), C/C++ package manager.
 - Homepage: https://conan.io/
 - Github: https://github.com/conan-io/conan
 - Docs: https://docs.conan.io/en/latest/
-- Slack: https://cpplang-inviter.cppalliance.org/ (#conan channel)
+- Slack: https://cppalliance.org/slack/ (#conan channel)
 - Twitter: https://twitter.com/conan_io
 
 
diff --git a/conan/tools/apple/apple.py b/conan/tools/apple/apple.py
index 0feb41eec..b2efefd48 100644
--- a/conan/tools/apple/apple.py
+++ b/conan/tools/apple/apple.py
@@ -80,11 +80,18 @@ def apple_sdk_path(conanfile):
 
 class XCRun(object):
 
-    def __init__(self, conanfile, sdk=None):
+    def __init__(self, conanfile, sdk=None, use_settings_target=False):
         """sdk=False will skip the flag
-           sdk=None will try to adjust it automatically"""
-        if sdk is None and conanfile.settings:
-            sdk = apple_sdk_name(conanfile.settings)
+           sdk=None will try to adjust it automatically
+           target_settings=True try to use settings_target in case they exist"""
+
+        # FIXME: 2.0: remove "hasattr()" condition
+        settings = conanfile.settings
+        if use_settings_target and hasattr(conanfile, "settings_target") and conanfile.settings_target is not None:
+            settings = conanfile.settings_target
+
+        if sdk is None and settings:
+            sdk = apple_sdk_name(settings)
         self.sdk = sdk
 
     def _invoke(self, args):
diff --git a/conan/tools/cmake/toolchain/blocks.py b/conan/tools/cmake/toolchain/blocks.py
index 0ad1e0bbd..eda75b0d6 100644
--- a/conan/tools/cmake/toolchain/blocks.py
+++ b/conan/tools/cmake/toolchain/blocks.py
@@ -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 %}
         """)
 
@@ -239,7 +239,7 @@ class CppStdBlock(Block):
 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):
diff --git a/conan/tools/system/package_manager.py b/conan/tools/system/package_manager.py
index ef281980f..927e8ecd1 100644
--- a/conan/tools/system/package_manager.py
+++ b/conan/tools/system/package_manager.py
@@ -1,5 +1,6 @@
 import platform
 
+from conan.tools.build import cross_building
 from conans.client.graph.graph import CONTEXT_BUILD
 from conans.errors import ConanException
 
@@ -57,7 +58,7 @@ class _SystemPackageManagerTool(object):
 
     def get_package_name(self, package):
         # TODO: should we only add the arch if cross-building?
-        if self._arch in self._arch_names:
+        if self._arch in self._arch_names and cross_building(self._conanfile):
             return "{}{}{}".format(package, self._arch_separator,
                                    self._arch_names.get(self._arch))
         return package
diff --git a/conans/client/manager.py b/conans/client/manager.py
index ae53663c7..aae89735e 100644
--- a/conans/client/manager.py
+++ b/conans/client/manager.py
@@ -84,6 +84,7 @@ def deps_install(app, ref_or_path, install_folder, base_folder, graph_info, remo
         conanfile.folders.set_base_imports(install_folder)
         conanfile.folders.set_base_generators(base_folder)
         conanfile.folders.set_base_source(base_folder)
+        conanfile.folders.set_base_build(base_folder)
 
     if hasattr(conanfile, "layout") and test:
         install_folder = conanfile.generators_folder


Test patch:
diff --git a/conans/test/functional/layout/test_editables_layout.py b/conans/test/functional/layout/test_editables_layout.py
index d81dad552..277798608 100644
--- a/conans/test/functional/layout/test_editables_layout.py
+++ b/conans/test/functional/layout/test_editables_layout.py
@@ -253,3 +253,30 @@ def test_cpp_info_components_editable():
     assert "**VAR libs:['hello_var']**" in out
     assert "**VAR cxxflags:['my_cxx_flag_var']**" in out
     assert "**VAR cflags:['my_c_flag_var']**" in out
+
+
+def test_editable_package_folder():
+    """ This test checks the behavior that self.package_folder is NOT defined (i.e = None)
+    for editable packages, so it cannot be used in ``package_info()`` method
+    """
+    c = TestClient()
+    conanfile = textwrap.dedent("""
+        import os
+        from conan import ConanFile
+        from conan.tools.cmake import cmake_layout
+        class Pkg(ConanFile):
+            name = "pkg"
+            version = "0.1"
+            settings = "os", "compiler", "arch", "build_type"
+
+            def package_info(self):
+                self.output.info("PKG FOLDER={}!!!".format(self.package_folder))
+
+            def layout(self):
+                cmake_layout(self)
+        """)
+    c.save({"conanfile.py": conanfile})
+    c.run("create .")
+    c.run("editable add . pkg/0.1")
+    c.run("install pkg/0.1@")
+    assert "pkg/0.1: PKG FOLDER=None!!!"
diff --git a/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py b/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py
index 01453c25b..4e1e9593f 100644
--- a/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py
+++ b/conans/test/functional/toolchains/cmake/test_cmake_toolchain.py
@@ -69,7 +69,8 @@ def test_cmake_toolchain_custom_toolchain():
     assert not os.path.exists(os.path.join(client.current_folder, "conan_toolchain.cmake"))
     presets = load_cmake_presets(client.current_folder)
     assert "mytoolchain.cmake" in presets["configurePresets"][0]["toolchainFile"]
-    assert "binaryDir" not in presets["configurePresets"][0]
+    # Now that we define the build_folder even if not layout() binaryDir is defined
+    assert "binaryDir" in presets["configurePresets"][0]
 
 
 @pytest.mark.skipif(platform.system() != "Darwin",
@@ -1061,3 +1062,71 @@ def test_resdirs_none_cmake_install():
     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
diff --git a/conans/test/functional/tools/system/package_manager_test.py b/conans/test/functional/tools/system/package_manager_test.py
index 210f6434d..89d27e705 100644
--- a/conans/test/functional/tools/system/package_manager_test.py
+++ b/conans/test/functional/tools/system/package_manager_test.py
@@ -50,11 +50,10 @@ def test_apt_install_substitutes():
     client.save({"conanfile.py": conanfile_py.format(installs)})
     client.run("create . test/1.0@ -c tools.system.package_manager:mode=install "
                "-c tools.system.package_manager:sudo=True", assert_error=True)
-
-    assert "dpkg-query: no packages found matching non-existing1:amd64" in client.out
-    assert "dpkg-query: no packages found matching non-existing2:amd64" in client.out
-    assert "dpkg-query: no packages found matching non-existing3:amd64" in client.out
-    assert "dpkg-query: no packages found matching non-existing4:amd64" in client.out
+    assert "dpkg-query: no packages found matching non-existing1" in client.out
+    assert "dpkg-query: no packages found matching non-existing2" in client.out
+    assert "dpkg-query: no packages found matching non-existing3" in client.out
+    assert "dpkg-query: no packages found matching non-existing4" in client.out
     assert "ERROR: while executing system_requirements(): " \
            "None of the installs for the package substitutes succeeded." in client.out
 
@@ -88,8 +87,8 @@ def test_build_require():
             tool_requires = "tool_require/1.0"
         """)})
     client.run("create consumer.py consumer/1.0@ -s:b arch=armv8 -s:h arch=x86 --build=missing")
-    assert "dpkg-query: no packages found matching non-existing1:arm64" in client.out
-    assert "dpkg-query: no packages found matching non-existing2:arm64" in client.out
+    assert "dpkg-query: no packages found matching non-existing1" in client.out
+    assert "dpkg-query: no packages found matching non-existing2" in client.out
     assert "missing: ['non-existing1', 'non-existing2']" in client.out
 
 
diff --git a/conans/test/functional/tools/test_apple_tools.py b/conans/test/functional/tools/test_apple_tools.py
index 15fba0bcf..cfb351a67 100644
--- a/conans/test/functional/tools/test_apple_tools.py
+++ b/conans/test/functional/tools/test_apple_tools.py
@@ -3,6 +3,7 @@ import textwrap
 
 import pytest
 
+from conans.test.assets.genconanfile import GenConanfile
 from conans.test.utils.tools import TestClient
 
 
@@ -24,3 +25,96 @@ def test_xcrun():
     client.save({"conanfile.py": conanfile}, clean_first=True)
     client.run("create .")
     assert "Xcode.app/Contents/Developer/Platforms/MacOSX.platform" in client.out
+
+
+@pytest.mark.skipif(platform.system() != "Darwin", reason="Requires Xcode")
+def test_xcrun_in_tool_requires():
+    # https://github.com/conan-io/conan/issues/12260
+    client = TestClient()
+    tool = textwrap.dedent("""
+        from conan import ConanFile
+        from conan.tools.apple import XCRun
+        class Pkg(ConanFile):
+            settings = "os", "compiler", "build_type", "arch"
+
+            def package_info(self):
+                xcrun = XCRun(self{})
+                self.output.info("sdk: %s" % xcrun.sdk)
+        """)
+    client.save({"br.py": tool.format(", use_settings_target=True")})
+    client.run("export br.py br/0.1@")
+
+    conanfile = textwrap.dedent("""
+        from conan import ConanFile
+        class Pkg(ConanFile):
+            settings = "os", "compiler", "build_type", "arch"
+            tool_requires = "br/0.1"
+        """)
+
+    profile_ios = textwrap.dedent("""
+        include(default)
+        [settings]
+        os=iOS
+        os.version=15.4
+        os.sdk=iphoneos
+        os.sdk_version=15.0
+        arch=armv8
+    """)
+
+    client.save({"conanfile.py": conanfile, "profile_ios": profile_ios})
+    client.run("create . pkg/1.0@ -pr:h=./profile_ios -pr:b=default --build")
+    assert "br/0.1: sdk: iphoneos15.0" in client.out
+    assert "br/0.1: sdk: macosx" not in client.out
+
+    client.save({"br.py": tool.format("")})
+    client.run("export br.py br/0.1@")
+    client.run("create . pkg/1.0@ -pr:h=./profile_ios -pr:b=default --build")
+    assert "br/0.1: sdk: iphoneos15.0" not in client.out
+    assert "br/0.1: sdk: macosx" in client.out
+
+
+@pytest.mark.skipif(platform.system() != "Darwin", reason="Requires Xcode")
+def test_xcrun_in_required_by_tool_requires():
+    """
+    ConanCenter case, most typical, openssl builds with autotools so needs the sysroot
+    and is a require by cmake so in the build context it needs the settings_build, not
+    the settings_target, that's why the use_settings_target default is False
+    """
+    client = TestClient()
+
+    openssl = textwrap.dedent("""
+        from conan import ConanFile
+        from conan.tools.apple import XCRun
+        class Pkg(ConanFile):
+            settings = "os", "compiler", "build_type", "arch"
+            def build(self):
+                xcrun = XCRun(self)
+                self.output.info("sdk for building openssl: %s" % xcrun.sdk)
+        """)
+
+    consumer = textwrap.dedent("""
+        from conan import ConanFile
+        class Pkg(ConanFile):
+            settings = "os", "compiler", "build_type", "arch"
+            tool_requires = "cmake/1.0"
+        """)
+
+    profile_ios = textwrap.dedent("""
+        include(default)
+        [settings]
+        os=iOS
+        os.version=15.4
+        os.sdk=iphoneos
+        os.sdk_version=15.0
+        arch=armv8
+    """)
+
+    client.save({"cmake.py": GenConanfile("cmake", "1.0").with_requires("openssl/1.0"),
+                 "openssl.py": openssl,
+                 "consumer.py": consumer,
+                 "profile_ios": profile_ios})
+
+    client.run("export openssl.py openssl/1.0@")
+    client.run("export cmake.py")
+    client.run("create consumer.py consumer/1.0@ -pr:h=./profile_ios -pr:b=default --build")
+    assert "sdk for building openssl: macosx" in client.out
diff --git a/conans/test/integration/layout/test_layout_generate.py b/conans/test/integration/layout/test_layout_generate.py
index ebe3cf106..7548f0788 100644
--- a/conans/test/integration/layout/test_layout_generate.py
+++ b/conans/test/integration/layout/test_layout_generate.py
@@ -96,3 +96,32 @@ def test_generate_source_folder_test_package():
             "test_package/conanfile.py": conanfile})
     c.run("create .")
     assert "PKG_CONFIG_PATH True!" in c.out
+
+
+def test_generate_build_folder_test_package():
+    c = TestClient()
+    conanfile = textwrap.dedent("""
+        import os
+        from conan import ConanFile
+        from conan.tools.cmake import cmake_layout
+
+        class Pkg(ConanFile):
+            settings = "os", "compiler", "build_type", "arch"
+
+            def requirements(self):
+                self.requires(self.tested_reference_str)
+
+            def layout(self):
+                cmake_layout(self)
+
+            def generate(self):
+                self.output.info(f"build_folder in test_package: {bool(self.build_folder)}")
+
+            def test(self):
+                pass
+        """)
+
+    c.save({"conanfile.py": GenConanfile("pkg", "1.0"),
+            "test_package/conanfile.py": conanfile})
+    c.run("create .")
+    assert f"build_folder in test_package: True" in c.out
diff --git a/conans/test/integration/tools/system/package_manager_test.py b/conans/test/integration/tools/system/package_manager_test.py
index f63da31ec..dbac4cf19 100644
--- a/conans/test/integration/tools/system/package_manager_test.py
+++ b/conans/test/integration/tools/system/package_manager_test.py
@@ -10,7 +10,7 @@ from conan.tools.system.package_manager import Apt, Dnf, Yum, Brew, Pkg, PkgUtil
 from conans import Settings
 from conans.errors import ConanException
 from conans.model.conf import Conf
-from conans.test.utils.mocks import ConanFileMock
+from conans.test.utils.mocks import ConanFileMock, MockSettings
 
 
 @pytest.mark.parametrize("platform, tool", [
@@ -196,26 +196,66 @@ def test_dnf_yum_return_code_100(tool_class, result):
         assert f"Command '{result}' failed" == str(exc_info.value)
 
 
+@pytest.mark.parametrize("tool_class, arch_host, result", [
+    # not cross-compile -> do not add host architecture
+    (Apt, 'x86_64', 'apt-get install -y --no-install-recommends package1 package2'),
+    (Yum, 'x86_64', 'yum install -y package1 package2'),
+    (Dnf, 'x86_64', 'dnf install -y package1 package2'),
+    (Brew, 'x86_64', 'brew install package1 package2'),
+    (Pkg, 'x86_64', 'pkg install -y package1 package2'),
+    (PkgUtil, 'x86_64', 'pkgutil --install --yes package1 package2'),
+    (Chocolatey, 'x86_64', 'choco install --yes package1 package2'),
+    (PacMan, 'x86_64', 'pacman -S --noconfirm package1 package2'),
+    (Zypper, 'x86_64', 'zypper --non-interactive in package1 package2'),
+    # cross-compile -> add host architecture https://github.com/conan-io/conan/issues/12320
+    (Apt, 'x86', 'apt-get install -y --no-install-recommends package1:i386 package2:i386'),
+    (Yum, 'x86', 'yum install -y package1.i?86 package2.i?86'),
+    (Dnf, 'x86', 'dnf install -y package1.i?86 package2.i?86'),
+    (Brew, 'x86', 'brew install package1 package2'),
+    (Pkg, 'x86', 'pkg install -y package1 package2'),
+    (PkgUtil, 'x86', 'pkgutil --install --yes package1 package2'),
+    (Chocolatey, 'x86', 'choco install --yes package1 package2'),
+    (PacMan, 'x86', 'pacman -S --noconfirm package1-lib32 package2-lib32'),
+    (Zypper, 'x86', 'zypper --non-interactive in package1 package2'),
+])
+def test_tools_install_mode_install_different_archs(tool_class, arch_host, result):
+    conanfile = ConanFileMock()
+    conanfile.conf = Conf()
+    conanfile.settings = MockSettings({"arch": f"{arch_host}"})
+    conanfile.settings_build = MockSettings({"arch": "x86_64"})
+    conanfile.conf["tools.system.package_manager:tool"] = tool_class.tool_name
+    conanfile.conf["tools.system.package_manager:mode"] = "install"
+    with mock.patch('conans.ConanFile.context', new_callable=PropertyMock) as context_mock:
+        context_mock.return_value = "host"
+        tool = tool_class(conanfile)
+
+        def fake_check(*args, **kwargs):
+            return ["package1", "package2"]
+        from conan.tools.system.package_manager import _SystemPackageManagerTool
+        with patch.object(_SystemPackageManagerTool, 'check', MagicMock(side_effect=fake_check)):
+            tool.install(["package1", "package2"])
+
+    assert tool._conanfile.command == result
+
+
 @pytest.mark.parametrize("tool_class, result", [
+    # cross-compile but arch_names=None -> do not add host architecture
+    # https://github.com/conan-io/conan/issues/12320 because the package is archless
     (Apt, 'apt-get install -y --no-install-recommends package1 package2'),
     (Yum, 'yum install -y package1 package2'),
     (Dnf, 'dnf install -y package1 package2'),
-    (Brew, 'brew install package1 package2'),
-    (Pkg, 'pkg install -y package1 package2'),
-    (PkgUtil, 'pkgutil --install --yes package1 package2'),
-    (Chocolatey, 'choco --install --yes package1 package2'),
     (PacMan, 'pacman -S --noconfirm package1 package2'),
-    (Zypper, 'zypper --non-interactive in package1 package2'),
 ])
-def test_tools_install_mode_install(tool_class, result):
+def test_tools_install_archless(tool_class, result):
     conanfile = ConanFileMock()
     conanfile.conf = Conf()
-    conanfile.settings = Settings()
+    conanfile.settings = MockSettings({"arch": "x86"})
+    conanfile.settings_build = MockSettings({"arch": "x86_64"})
     conanfile.conf["tools.system.package_manager:tool"] = tool_class.tool_name
     conanfile.conf["tools.system.package_manager:mode"] = "install"
     with mock.patch('conans.ConanFile.context', new_callable=PropertyMock) as context_mock:
         context_mock.return_value = "host"
-        tool = tool_class(conanfile)
+        tool = tool_class(conanfile, arch_names={})
 
         def fake_check(*args, **kwargs):
             return ["package1", "package2"]
@@ -223,6 +263,8 @@ def test_tools_install_mode_install(tool_class, result):
         with patch.object(_SystemPackageManagerTool, 'check', MagicMock(side_effect=fake_check)):
             tool.install(["package1", "package2"])
 
+    assert tool._conanfile.command == result
+
 
 @pytest.mark.parametrize("tool_class, result", [
     (Apt, 'dpkg-query -W -f=\'${Status}\' package | grep -q "ok installed"'),
@@ -244,3 +286,5 @@ def test_tools_check(tool_class, result):
         context_mock.return_value = "host"
         tool = tool_class(conanfile)
         tool.check(["package"])
+
+    assert tool._conanfile.command == result
diff --git a/conans/test/unittests/tools/cmake/test_cmaketoolchain.py b/conans/test/unittests/tools/cmake/test_cmaketoolchain.py
index 2fac1acfd..2d30b9eb1 100644
--- a/conans/test/unittests/tools/cmake/test_cmaketoolchain.py
+++ b/conans/test/unittests/tools/cmake/test_cmaketoolchain.py
@@ -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):