Skip to content

Instantly share code, notes, and snippets.

@solvingj
Last active September 19, 2018 13:00
Show Gist options
  • Save solvingj/8b3fd2c2a508397dfb6be482a9b66fa0 to your computer and use it in GitHub Desktop.
Save solvingj/8b3fd2c2a508397dfb6be482a9b66fa0 to your computer and use it in GitHub Desktop.
base class
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from conans import ConanFile, tools
import os
class BoostBaseConan(ConanFile):
name = "boost_base"
version = "1.67.0"
url = "https://github.com/bincrafters/conan-boost_base"
website = "https://github.com/boostorg"
description = "Shared python code used in other Conan recipes for the Boost libraries"
license = "MIT"
exports = "LICENSE.md"
short_paths = True
build_requires = "boost_generator/1.67.0@bincrafters/testing"
settings = "os", "arch", "compiler", "build_type"
generators = "boost"
def __init__(self, output, runner, user=None, channel=None):
ConanFile.__init__(self, output, runner, user=None, channel=None)
if not hasattr(self, "lib_short_names"):
self.lib_short_names = []
if not hasattr(self, "source_only_deps"):
self.source_only_deps = []
if not hasattr(self, "header_only_libs"):
self.header_only_libs = []
if not hasattr(self, "b2_defines"):
self.b2_defines = []
if not hasattr(self, "b2_options"):
self.b2_options = self.get_b2_options()
if not hasattr(self, "cycle_group"):
self.cycle_group = ""
def get_b2_options(self):
return {}
def is_in_cycle_group(self):
return self.cycle_group != ""
def is_cycle_group(self):
return ("level" in self.name and "group" in self.name)
def lib_name(self):
return self.lib_short_names[0] if not self.is_cycle_group() and self.lib_short_names else ""
def is_header_only(self, lib_name):
return (lib_name in self.header_only_libs)
jam_header_only_content = """\
import project ;
import path ;
import modules ;
ROOT({0}) = [ path.parent [ path.parent [ path.make [ modules.binding $(__name__) ] ] ] ] ;
project /conan/{0} : requirements <include>$(ROOT({0}))/include ;
project.register-id /boost/{0} : $(__name__) ;\
"""
jam_search_content = """\
lib {0} : : <name>{0} <search>. : : $(usage) ;
"""
jam_alias_content = """\
alias boost_{0} : {1} : : : $(usage) ;
"""
def source(self):
if self.is_cycle_group():
self._source_common()
elif self.is_in_cycle_group():
pass
else:
self._source_common()
self.source_additional()
def _source_common(self):
archive_name = "boost-" + self.version
libs_to_get = self.lib_short_names + self.source_only_deps
for lib_short_name in libs_to_get:
tools.get("{0}/{1}/archive/{2}.tar.gz"
.format(self.website, lib_short_name, archive_name))
os.rename(lib_short_name + "-" + archive_name, lib_short_name)
def source_additional(self):
pass
def build(self):
if self.is_cycle_group():
self._build_common()
elif self.is_in_cycle_group():
pass
else:
self._build_common()
self.build_additional()
def _build_common(self):
for lib_short_name in self.lib_short_names:
self.output.info("Begin boost library build: " + lib_short_name)
lib_dir = os.path.join(lib_short_name, "lib")
if self.is_header_only(lib_short_name):
tools.save(
"jamroot.jam",
self.jam_header_only_content.format(lib_short_name),
append=True)
else:
b2_command = [
"b2",
"-j%s" % (tools.cpu_count()),
"-d+%s" % (os.getenv('CONAN_B2_DEBUG', '1')),
"-a", "--hash=yes", "--debug-configuration", "--layout=system",
self.all_b2_args(),
lib_short_name + "-build",
]
self.output.info("%s: %s" % (os.getcwd(), " ".join(b2_command)))
with tools.environment_append({'PATH':[os.getenv('MPI_BIN', '')]}):
self.run(" ".join(b2_command))
libs = self._collect_build_libs(lib_dir)
for lib in libs:
tools.save(
"jamroot.jam",
self.jam_search_content.format(lib),
append=True)
if "boost_" + lib_short_name not in libs:
tools.save(
"jamroot.jam",
self.jam_alias_content.format(lib_short_name, " ".join(libs)),
append=True)
def _collect_build_libs(self, lib_folder):
libs = []
if not os.path.exists(lib_folder):
self.output.warn("Lib folder doesn't exist, can't collect libraries: {0}".format(lib_folder))
else:
files = os.listdir(lib_folder)
for f in files:
name, ext = os.path.splitext(f)
if ext in (".so", ".lib", ".a", ".dylib"):
if ext != ".lib" and name.startswith("lib"):
name = name[3:]
libs.append(name)
return libs
def build_additional(self):
pass
def package(self):
for lib_short_name in self.lib_short_names:
self.copy(pattern="*LICENSE*", dst="license", src=lib_short_name)
for subdir in ["lib", "include"]:
copydir = os.path.join(lib_short_name, subdir)
self.copy(pattern="*", dst=copydir, src=copydir)
self.package_additional()
def package_additional(self):
pass
def package_info(self):
self.user_info.lib_short_names = ",".join(self.lib_short_names)
self.cpp_info.includedirs = []
self.cpp_info.libdirs = []
self.cpp_info.bindirs = []
self.cpp_info.libs = []
if self.is_cycle_group():
# All variables will be advertised from group member packages
pass
elif self.is_in_cycle_group():
group = self.deps_cpp_info[self.cycle_group]
include_dir = os.path.join(group.rootpath, self.lib_name(), "include")
self.cpp_info.includedirs.append(include_dir)
if not self.is_header_only(self.lib_name()):
lib_dir = os.path.join(group.rootpath, self.lib_name(), "lib")
self.cpp_info.libdirs.append(lib_dir)
self.cpp_info.libs.extend(tools.collect_libs(self, lib_dir))
else:
include_dir = os.path.join(self.lib_name(), "include")
self.cpp_info.includedirs.append(include_dir)
if not self.is_header_only(self.lib_name()):
lib_dir = os.path.join(self.lib_name(), "lib")
self.cpp_info.libdirs.append(lib_dir)
self.cpp_info.libs.extend(tools.collect_libs(self, lib_dir))
self.cpp_info.defines.append("BOOST_ALL_NO_LIB=1")
self.cpp_info.bindirs.extend(self.cpp_info.libdirs)
# Avoid duplicate entries in the libs.
self.cpp_info.libs = list(set(self.cpp_info.libs))
self.package_info_additional()
def package_info_additional(self):
pass
def package_id(self):
if self.is_cycle_group():
pass
elif self.is_in_cycle_group():
pass
else:
if self.is_header_only(self.lib_name()):
self.info.header_only()
boost_deps_only = [dep_name for dep_name in self.info.requires.pkg_names if dep_name.startswith("boost_")]
for dep_name in boost_deps_only:
self.info.requires[dep_name].full_version_mode()
self.package_id_additional()
def package_id_additional(self):
pass
def all_b2_args(self):
self.output.info("self.b2_options = " + self.b2_options)
option_str = " " .join([key + "=" + value for key,value in self.b2_options])
include_str = " " .join(["include=" + lib + '/include' for lib in self.source_only_deps])
define_str = " " .join(["define=" + define for define in self.b2_defines])
return option_str + include_str + define_str
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment