Skip to content

Instantly share code, notes, and snippets.

@valgur
Last active June 28, 2024 17:06
Show Gist options
  • Save valgur/65b3f3e5570f68f0bb31709697c3c860 to your computer and use it in GitHub Desktop.
Save valgur/65b3f3e5570f68f0bb31709697c3c860 to your computer and use it in GitHub Desktop.
Conan deployer for shared host libraries
# License: public domain / CC0-1.0
import glob
import os
import shutil
from conan.api.output import ConanOutput
from conans.util.files import mkdir
def deploy(graph, output_folder):
"""
Copy all shared libraries of host dependencies into <deploy-folder>.
"""
conanfile = graph.root.conanfile
output = ConanOutput(scope="shared_deploy")
output.info(f"Deploying runtime dependencies to folder: {output_folder}")
mkdir(output_folder)
keep_symlinks = conanfile.conf.get("tools.deployer:symlinks", check_type=bool, default=True)
for _, dep in conanfile.dependencies.host.items():
if dep.package_folder is None:
output.warning(f"{dep.ref} does not have a package folder, skipping")
continue
cpp_info = dep.cpp_info.aggregated_components()
copied_libs = set()
for bindir in cpp_info.bindirs:
if not os.path.isdir(bindir):
continue
for lib in cpp_info.libs:
if _copy_files(dep, "{}.dll".format(lib), bindir, output_folder, keep_symlinks):
copied_libs.add(lib)
for libdir in cpp_info.libdirs:
if not os.path.isdir(libdir):
continue
for lib in cpp_info.libs:
if _copy_files(dep, "lib{}.so*".format(lib), libdir, output_folder, keep_symlinks):
copied_libs.add(lib)
if _copy_files(dep, "lib{}.dylib".format(lib), libdir, output_folder, keep_symlinks):
copied_libs.add(lib)
output.info(f"Copied {len(copied_libs)} shared libraries from {dep.ref}: {', '.join(sorted(copied_libs))}")
not_found = copied_libs - set(cpp_info.libs)
if not_found:
output.error(f"Some {dep.ref} libraries were not found: {', '.join(sorted(not_found))}")
conanfile.output.success(f"Shared libraries deployed to folder: {output_folder}")
def _copy_files(dep, pattern, src_dir, output_dir, keep_symlinks):
file_count = 0
output = ConanOutput(scope="deploy_shared")
for src in glob.glob(os.path.join(src_dir, pattern)):
dst = os.path.join(output_dir, os.path.basename(src))
try:
if os.path.lexists(dst):
os.remove(dst)
shutil.copy2(src, dst, follow_symlinks=not keep_symlinks)
output.verbose(f"Copied {src}")
file_count += 1
except Exception:
output.error(f"Copying of {dep} shared library failed: {src} -> {dst}")
raise
return file_count
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment