Skip to content

Commit d1a38ef

Browse files
authored
making paths relative in CMakeConfigDeps for deployers (#18197)
* making paths relative in CMakeConfigDeps for deployers * fixing test in Linux * fix test
1 parent e912a66 commit d1a38ef

File tree

4 files changed

+77
-12
lines changed

4 files changed

+77
-12
lines changed

conan/tools/cmake/cmakedeps2/cmakedeps.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,8 @@ def generate(self):
244244
f = self._cmakedeps.get_cmake_filename(dep)
245245
for filename in (f"{f}-config.cmake", f"{f}Config.cmake"):
246246
if os.path.isfile(os.path.join(pkg_folder, filename)):
247-
pkg_paths[pkg_name] = pkg_folder
247+
pkg_paths[pkg_name] = relativize_path(pkg_folder, self._conanfile,
248+
"${CMAKE_CURRENT_LIST_DIR}")
248249
continue
249250

250251
# If CMakeDeps generated, the folder is this one
@@ -292,6 +293,7 @@ def _get_host_runtime_dirs(self):
292293
runtime_dirs = aggregated_cppinfo.bindirs if is_win else aggregated_cppinfo.libdirs
293294
for d in runtime_dirs:
294295
d = d.replace("\\", "/")
296+
d = relativize_path(d, self._conanfile, "${CMAKE_CURRENT_LIST_DIR}")
295297
existing = host_runtime_dirs.setdefault(config, [])
296298
if d not in existing:
297299
existing.append(d)

conan/tools/cmake/cmakedeps2/config.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import jinja2
44
from jinja2 import Template
55

6+
from conan.internal.api.install.generators import relativize_path
7+
68

79
class ConfigTemplate2:
810
"""
@@ -33,6 +35,9 @@ def _context(self):
3335
# FIXME: Proper escaping of paths for CMake and relativization
3436
# FIXME: build_module_paths coming from last config only
3537
build_modules_paths = [f.replace("\\", "/") for f in build_modules_paths]
38+
build_modules_paths = [relativize_path(p, self._cmakedeps._conanfile,
39+
"${CMAKE_CURRENT_LIST_DIR}")
40+
for p in build_modules_paths]
3641
components = self._cmakedeps.get_property("cmake_components", self._conanfile,
3742
check_type=list)
3843
if components is None: # Lets compute the default components names

conan/tools/cmake/cmakedeps2/target_configuration.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from jinja2 import Template
66

77
from conan.errors import ConanException
8+
from conan.internal.api.install.generators import relativize_path
89
from conan.internal.model.pkg_type import PackageType
910
from conan.internal.graph.graph import CONTEXT_BUILD, CONTEXT_HOST
1011

@@ -120,13 +121,17 @@ def _context(self):
120121
include_dirs = definitions = libraries = None
121122
if not self._require.build: # To add global variables for try_compile and legacy
122123
aggregated_cppinfo = cpp_info.aggregated_components()
123-
# FIXME: Proper escaping of paths for CMake and relativization
124-
include_dirs = ";".join(i.replace("\\", "/") for i in aggregated_cppinfo.includedirs)
124+
# FIXME: Proper escaping of paths for CMake
125+
incdirs = [i.replace("\\", "/") for i in aggregated_cppinfo.includedirs]
126+
incdirs = [relativize_path(i, self._cmakedeps._conanfile, "${CMAKE_CURRENT_LIST_DIR}")
127+
for i in incdirs]
128+
include_dirs = ";".join(incdirs)
125129
definitions = ""
126130
root_target_name = self._cmakedeps.get_property("cmake_target_name", self._conanfile)
127131
libraries = root_target_name or f"{pkg_name}::{pkg_name}"
128132

129-
# TODO: Missing find_modes
133+
pkg_folder = relativize_path(pkg_folder, self._cmakedeps._conanfile,
134+
"${CMAKE_CURRENT_LIST_DIR}")
130135
dependencies = self._get_dependencies()
131136
return {"dependencies": dependencies,
132137
"pkg_folder": pkg_folder,

test/integration/toolchains/cmake/cmakedeps2/test_cmakedeps.py

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ class PkgConan(ConanFile):
3030
requires = "lib/1.0"
3131
settings = "os", "arch", "compiler", "build_type"
3232
generators = "CMakeDeps"
33-
def build(self):
34-
cmake = CMake(self)
35-
cmake.configure()
3633
""")
3734
c.save({"conanfile.py": conanfile}, clean_first=True)
3835
c.run(f"install . -c tools.cmake.cmakedeps:new={new_value}")
@@ -76,25 +73,81 @@ def package_info(self):
7673
c.run("create .")
7774
conanfile = textwrap.dedent(f"""
7875
from conan import ConanFile
79-
from conan.tools.cmake import CMake
8076
class PkgConan(ConanFile):
8177
requires = "libb/1.0"
8278
settings = "os", "arch", "compiler", "build_type"
8379
generators = "CMakeDeps"
84-
def build(self):
85-
cmake = CMake(self)
86-
cmake.configure()
8780
""")
8881
c.save({"conanfile.py": conanfile}, clean_first=True)
8982
c.run(f"install . -c tools.cmake.cmakedeps:new={new_value}")
9083
cmake_paths = c.load("conan_cmakedeps_paths.cmake")
91-
cmake_paths.replace("\\", "/")
9284
assert re.search(r"list\(PREPEND CMAKE_PROGRAM_PATH \".*/libb.*/p/binb\"\)", cmake_paths)
9385
assert not re.search(r"list\(PREPEND CMAKE_PROGRAM_PATH /bina\"", cmake_paths)
9486
assert re.search(r"list\(PREPEND CMAKE_LIBRARY_PATH \".*/libb.*/p/libb\" \".*/liba.*/p/liba\"\)", cmake_paths)
9587
assert re.search(r"list\(PREPEND CMAKE_INCLUDE_PATH \".*/libb.*/p/includeb\" \".*/liba.*/p/includea\"\)", cmake_paths)
9688

9789

90+
def test_cmakedeps_deployer_relative_paths():
91+
c = TestClient()
92+
conanfile = textwrap.dedent("""
93+
import os
94+
from conan.tools.files import copy
95+
from conan import ConanFile
96+
class TestConan(ConanFile):
97+
name = "liba"
98+
version = "1.0"
99+
100+
def package_info(self):
101+
self.cpp_info.includedirs = ["includea"]
102+
self.cpp_info.libdirs = ["bina"]
103+
self.cpp_info.bindirs = ["bina"]
104+
crypto_module = os.path.join("share", "cmake", "crypto.cmake")
105+
self.cpp_info.set_property("cmake_build_modules", [crypto_module])
106+
""")
107+
c.save({"conanfile.py": conanfile})
108+
c.run("create .")
109+
110+
conanfile_cmake = textwrap.dedent("""
111+
import os
112+
from conan.tools.files import save
113+
from conan import ConanFile
114+
class TestConan(ConanFile):
115+
name = "libb"
116+
version = "1.0"
117+
118+
def package(self):
119+
save(self, os.path.join(self.package_folder, "libb-config.cmake"), "")
120+
def package_info(self):
121+
self.cpp_info.set_property("cmake_find_mode", "none")
122+
""")
123+
124+
c.save({"conanfile.py": conanfile_cmake})
125+
c.run("create .")
126+
conanfile = textwrap.dedent(f"""
127+
from conan import ConanFile
128+
from conan.tools.cmake import CMake
129+
class PkgConan(ConanFile):
130+
requires = "liba/1.0", "libb/1.0"
131+
settings = "os", "arch", "compiler", "build_type"
132+
generators = "CMakeDeps"
133+
""")
134+
c.save({"conanfile.py": conanfile}, clean_first=True)
135+
136+
# Now with a deployment
137+
c.run(f"install . -c tools.cmake.cmakedeps:new={new_value} --deployer=full_deploy")
138+
cmake_paths = c.load("conan_cmakedeps_paths.cmake")
139+
assert 'set(libb_DIR "${CMAKE_CURRENT_LIST_DIR}/full_deploy/host/libb/1.0")' in cmake_paths
140+
assert ('set(CONAN_RUNTIME_LIB_DIRS "$<$<CONFIG:Release>:${CMAKE_CURRENT_LIST_DIR}'
141+
'/full_deploy/host/liba/1.0/bina>"') in cmake_paths
142+
liba_config = c.load("liba-config.cmake")
143+
assert ('include("${CMAKE_CURRENT_LIST_DIR}/full_deploy/'
144+
'host/liba/1.0/share/cmake/crypto.cmake")') in liba_config
145+
liba_targets = c.load("liba-Targets-release.cmake")
146+
assert ('set(liba_PACKAGE_FOLDER_RELEASE "${CMAKE_CURRENT_LIST_DIR}/full_deploy/'
147+
'host/liba/1.0")') in liba_targets
148+
assert ('set(liba_INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}/full_deploy/'
149+
'host/liba/1.0/includea" )') in liba_targets
150+
98151
def test_cmakeconfigdeps_recipe():
99152
c = TestClient()
100153
conanfile = textwrap.dedent("""

0 commit comments

Comments
 (0)