1
1
import filecmp
2
2
import os
3
3
import shutil
4
+ import fnmatch
4
5
5
6
from conan .internal .cache .home_paths import HomePaths
6
7
from conan .api .output import ConanOutput
@@ -99,6 +100,8 @@ def full_deploy(graph, output_folder):
99
100
def runtime_deploy (graph , output_folder ):
100
101
"""
101
102
Deploy all the shared libraries and the executables of the dependencies in a flat directory.
103
+
104
+ It preserves symlinks in case the configuration tools.deployer:symlinks is True.
102
105
"""
103
106
conanfile = graph .root .conanfile
104
107
output = ConanOutput (scope = "runtime_deploy" )
@@ -125,7 +128,7 @@ def runtime_deploy(graph, output_folder):
125
128
if not os .path .isdir (libdir ):
126
129
output .warning (f"{ dep .ref } { libdir } does not exist" )
127
130
continue
128
- count += _flatten_directory (dep , libdir , output_folder , symlinks , [".dylib" , ".so" ])
131
+ count += _flatten_directory (dep , libdir , output_folder , symlinks , [".dylib* " , ".so* " ])
129
132
130
133
output .info (f"Copied { count } files from { dep .ref } " )
131
134
conanfile .output .success (f"Runtime deployed to folder: { output_folder } " )
@@ -142,11 +145,15 @@ def _flatten_directory(dep, src_dir, output_dir, symlinks, extension_filter=None
142
145
output = ConanOutput (scope = "runtime_deploy" )
143
146
for src_dirpath , _ , src_filenames in os .walk (src_dir , followlinks = symlinks ):
144
147
for src_filename in src_filenames :
145
- if extension_filter and not any (src_filename . endswith ( ext ) for ext in extension_filter ):
148
+ if extension_filter and not any (fnmatch . fnmatch ( src_filename , f'* { ext } ' ) for ext in extension_filter ):
146
149
continue
147
150
148
151
src_filepath = os .path .join (src_dirpath , src_filename )
149
152
dest_filepath = os .path .join (output_dir , src_filename )
153
+
154
+ if not symlinks and os .path .islink (src_filepath ):
155
+ continue
156
+
150
157
if os .path .exists (dest_filepath ):
151
158
if filecmp .cmp (src_filepath , dest_filepath ): # Be efficient, do not copy
152
159
output .verbose (f"{ dest_filepath } exists with same contents, skipping copy" )
@@ -156,7 +163,9 @@ def _flatten_directory(dep, src_dir, output_dir, symlinks, extension_filter=None
156
163
157
164
try :
158
165
file_count += 1
159
- shutil .copy2 (src_filepath , dest_filepath , follow_symlinks = symlinks )
166
+ # INFO: When follow_symlinks is false, and src is a symbolic link, it tries to
167
+ # copy all metadata from the src symbolic link to the newly created dst link
168
+ shutil .copy2 (src_filepath , dest_filepath , follow_symlinks = not symlinks )
160
169
output .verbose (f"Copied { src_filepath } into { output_dir } " )
161
170
except Exception as e :
162
171
if "WinError 1314" in str (e ):
0 commit comments