From 17e643bff087dcf4f8d83249a14ff547eb61a500 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Mon, 3 May 2021 14:39:38 +0200 Subject: [PATCH 1/9] boost: fix building with -o boost:shared=True -o boost:without_fiber=True --- recipes/boost/all/conanfile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/boost/all/conanfile.py b/recipes/boost/all/conanfile.py index 80810767aa07b..fabbc762c7ca3 100644 --- a/recipes/boost/all/conanfile.py +++ b/recipes/boost/all/conanfile.py @@ -334,7 +334,7 @@ def validate(self): if self.settings.compiler == "Visual Studio" and self._shared: if "MT" in str(self.settings.compiler.runtime): raise ConanInvalidConfiguration("Boost can not be built as shared library with MT runtime.") - if self.options.numa: + if self.options.get_safe("numa"): raise ConanInvalidConfiguration("Cannot build a shared boost with numa support on Visual Studio") # Check, when a boost module is enabled, whether the boost modules it depends on are enabled as well. @@ -1066,7 +1066,7 @@ def create_library_config(deps_name, name): # Specify here the toolset with the binary if present if don't empty parameter : contents += '\nusing "%s" : %s : ' % (self._toolset, self._toolset_version) - + if self._is_msvc: contents += ' "%s"' % self._cxx.replace("\\", "/") else: From 9f04c0c9c1f273abff7a7033b059b2fac33bd4fa Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Mon, 3 May 2021 14:51:18 +0200 Subject: [PATCH 2/9] boost: it is safe to use self.options.debug_level unconditionally --- recipes/boost/all/conanfile.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/recipes/boost/all/conanfile.py b/recipes/boost/all/conanfile.py index fabbc762c7ca3..cf977992ee1b6 100644 --- a/recipes/boost/all/conanfile.py +++ b/recipes/boost/all/conanfile.py @@ -672,8 +672,7 @@ def _build_bcp(self): with tools.vcvars(self.settings) if self._is_msvc else tools.no_op(): with tools.chdir(folder): command = "%s -j%s --abbreviate-paths toolset=%s" % (self._b2_exe, tools.cpu_count(), self._toolset) - if "debug_level" in self.options: - command += " -d%d" % self.options.debug_level + command += " -d%d" % self.options.debug_level self.output.warn(command) self.run(command, run_environment=True) @@ -963,12 +962,13 @@ def add_defines(library): if self.options.extra_b2_flags: flags.extend(shlex.split(str(self.options.extra_b2_flags))) - flags.extend(["install", - "--prefix=%s" % self.package_folder, - "-j%s" % tools.cpu_count(), - "--abbreviate-paths"]) - if "debug_level" in self.options: - flags.append("-d%d" % self.options.debug_level) + flags.extend([ + "install", + "--prefix=%s" % self.package_folder, + "-j%s" % tools.cpu_count(), + "--abbreviate-paths", + "-d%d" % self.options.debug_level, + ]) return flags @property From 80276e38fbd6fd452394569eef7495a2c932667f Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Mon, 3 May 2021 20:31:23 +0200 Subject: [PATCH 3/9] boost: add addr2line_location option + test --- recipes/boost/all/conanfile.py | 41 +++++++++- recipes/boost/all/test_package/CMakeLists.txt | 24 ++++++ recipes/boost/all/test_package/conanfile.py | 6 ++ recipes/boost/all/test_package/stacktrace.cpp | 76 +++++++++++++++++++ 4 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 recipes/boost/all/test_package/stacktrace.cpp diff --git a/recipes/boost/all/conanfile.py b/recipes/boost/all/conanfile.py index cf977992ee1b6..2a2082921db57 100644 --- a/recipes/boost/all/conanfile.py +++ b/recipes/boost/all/conanfile.py @@ -94,6 +94,7 @@ class BoostConan(ConanFile): "extra_b2_flags": "ANY", # custom b2 flags "i18n_backend": ["iconv", "icu", None], "visibility": ["global", "protected", "hidden"], + "addr2line_location": "ANY", } options.update({"without_{}".format(_name): [True, False] for _name in CONFIGURE_OPTIONS}) @@ -124,6 +125,7 @@ class BoostConan(ConanFile): "extra_b2_flags": "None", "i18n_backend": "iconv", "visibility": "hidden", + "addr2line_location": "/usr/bin/addr2line", } default_options.update({"without_{}".format(_name): False for _name in CONFIGURE_OPTIONS}) default_options.update({"without_{}".format(_name): True for _name in ("graph_parallel", "mpi", "python")}) @@ -297,6 +299,10 @@ def _fPIC(self): def _shared(self): return self.options.get_safe("shared", self.default_options["shared"]) + @property + def _stacktrace_addr2line_available(self): + return not self.options.header_only and not self.options.without_stacktrace and self.settings.compiler != "Visual Studio" + def configure(self): if self.options.header_only: del self.options.shared @@ -315,6 +321,12 @@ def configure(self): self.options.python_version = self._detect_python_version() self.options.python_executable = self._python_executable + if self._stacktrace_addr2line_available: + if os.path.abspath(str(self.options.addr2line_location)) != str(self.options.addr2line_location): + raise ConanInvalidConfiguration("addr2line_location must be an absolute path to addr2line") + else: + del self.options.addr2line_location + if self.options.layout == "b2-default": self.options.layout = "versioned" if self.settings.os == "Windows" else "system" @@ -956,6 +968,9 @@ def add_defines(library): link_flags = 'linkflags="%s"' % " ".join(link_flags) if link_flags else "" flags.append(link_flags) + if self.options.get_safe("addr2line_location"): + cxx_flags.append("-DBOOST_STACKTRACE_ADDR2LINE_LOCATION={}".format(self.options.addr2line_location)) + cxx_flags = 'cxxflags="%s"' % " ".join(cxx_flags) if cxx_flags else "" flags.append(cxx_flags) @@ -1349,7 +1364,7 @@ def filter_transform_module_libraries(names): for name in names: if name in ("boost_stacktrace_windbg", "boost_stacktrace_windbg_cached") and self.settings.os != "Windows": continue - if name in ("boost_stacktrace_addr2line", "boost_stacktrace_basic") and self.settings.compiler == "Visual Studio": + if name in ("boost_stacktrace_basic",) and self.settings.compiler == "Visual Studio": continue if name == "boost_stacktrace_backtrace": if "boost_stacktrace_backtrace" not in all_detected_libraries: @@ -1381,7 +1396,7 @@ def filter_transform_module_libraries(names): for requirement in self._dependencies.get("requirements", {}).get(module, []): if requirement == "backtrace": - # FIXME: backtrace not (yet) available in cci + # FIXME: add backtrace support (libbacktrace is available in cci) continue if self.options.get_safe(requirement, None) == False: continue @@ -1392,6 +1407,7 @@ def filter_transform_module_libraries(names): if requirement != self.options.i18n_backend: continue self.cpp_info.components[module].requires.append("{0}::{0}".format(conan_requirement)) + for incomplete_component in incomplete_components: self.output.warn("Boost component '{0}' is missing libraries. Try building boost with '-o boost:without_{0}'.".format(incomplete_component)) @@ -1403,6 +1419,26 @@ def filter_transform_module_libraries(names): if non_built: raise ConanException("These libraries were expected to be built, but were not built: {}".format(non_built)) + if self.settings.os in ("Linux", "FreeBSD"): + self.cpp_info.components["stacktrace"].system_libs.append("dl") + + if self._stacktrace_addr2line_available: + self.cpp_info.components["stacktrace_addr2line"].defines.extend([ + "BOOST_STACKTRACE_ADDR2LINE_LOCATION=\"{}\"".format(self.options.addr2line_location), + "BOOST_STACKTRACE_USE_ADDR2LINE", + ]) + + # FIXME: add backtrace support + # self.cpp_info.components["stacktrace_backtrace"].defines.extend([ + # "BOOST_STACKTRACE_USE_BACKTRACE", + # ]) + + self.cpp_info.components["stacktrace_noop"].defines.append("BOOST_STACKTRACE_USE_NOOP") + + if self.settings.os == "Windows": + self.cpp_info.components["stacktrace_windb"].defines.append("BOOST_STACKTRACE_USE_WINDBG") + self.cpp_info.components["stacktrace_windb_cached"].defines.append("BOOST_STACKTRACE_USE_WINDBG_CACHED") + if not self.options.without_python: pyversion = tools.Version(self._python_version) self.cpp_info.components["python{}{}".format(pyversion.major, pyversion.minor)].requires = ["python"] @@ -1438,3 +1474,4 @@ def filter_transform_module_libraries(names): self.cpp_info.components["headers"].defines.extend(["BOOST_AC_USE_PTHREADS", "BOOST_SP_USE_PTHREADS"]) else: self.cpp_info.components["headers"].defines.extend(["BOOST_AC_DISABLE_THREADS", "BOOST_SP_DISABLE_THREADS"]) + self.user_info.stacktrace_addr2line_available = self._stacktrace_addr2line_available diff --git a/recipes/boost/all/test_package/CMakeLists.txt b/recipes/boost/all/test_package/CMakeLists.txt index 2cfe002fb0feb..866cefce68d5d 100644 --- a/recipes/boost/all/test_package/CMakeLists.txt +++ b/recipes/boost/all/test_package/CMakeLists.txt @@ -62,6 +62,30 @@ if(NOT HEADER_ONLY) target_link_libraries(locale_exe PRIVATE Boost::locale) endif() + if(WITH_STACKTRACE_ADDR2LINE) + find_package(Boost COMPONENTS stacktrace REQUIRED) + add_executable(stacktrace_addr2line_exe stacktrace.cpp) + target_compile_definitions(stacktrace_addr2line_exe PRIVATE TEST_STACKTRACE_IMPL=1) + target_link_libraries(stacktrace_addr2line_exe PRIVATE Boost::stacktrace_addr2line) + endif() + + if(WITH_STACKTRACE) + find_package(Boost COMPONENTS stacktrace REQUIRED) + add_executable(stacktrace_noop_exe stacktrace.cpp) + target_compile_definitions(stacktrace_noop_exe PRIVATE TEST_STACKTRACE_IMPL=3) + target_link_libraries(stacktrace_noop_exe PRIVATE Boost::stacktrace_noop) + + if(WIN32) + add_executable(stacktrace_windbg_exe stacktrace.cpp) + target_compile_definitions(stacktrace_windbg_exe PRIVATE TEST_STACKTRACE_IMPL=4) + target_link_libraries(stacktrace_windbg_exe PRIVATE Boost::stacktrace_windbg) + + add_executable(stacktrace_windbg_cached_exe stacktrace.cpp) + target_compile_definitions(stacktrace_windbg_cached_exe PRIVATE TEST_STACKTRACE_IMPL=5) + target_link_libraries(stacktrace_windbg_cached_exe PRIVATE Boost::stacktrace_windbg_cached) + endif() + endif() + if(WITH_PYTHON) find_package(Boost COMPONENTS python REQUIRED) add_library(hello_ext MODULE python.cpp) diff --git a/recipes/boost/all/test_package/conanfile.py b/recipes/boost/all/test_package/conanfile.py index a77bbd9e621eb..5322905fcf2bd 100644 --- a/recipes/boost/all/test_package/conanfile.py +++ b/recipes/boost/all/test_package/conanfile.py @@ -34,6 +34,8 @@ def build(self): cmake.definitions["WITH_LOCALE"] = not self.options["boost"].without_locale cmake.definitions["WITH_NOWIDE"] = not self._boost_option("without_nowide", True) cmake.definitions["WITH_JSON"] = not self._boost_option("without_json", True) + cmake.definitions["WITH_STACKTRACE"] = not self.options["boost"].without_stacktrace + cmake.definitions["WITH_STACKTRACE_ADDR2LINE"] = self.deps_user_info["boost"].stacktrace_addr2line_available cmake.configure() cmake.build() @@ -65,3 +67,7 @@ def test(self): with tools.environment_append({"PYTHONPATH": "{}:{}".format("bin", "lib")}): self.run("{} {}".format(self.options["boost"].python_executable, os.path.join(self.source_folder, "python.py")), run_environment=True) self.run(os.path.join("bin", "numpy_exe"), run_environment=True) + if not self.options["boost"].without_stacktrace: + self.run(os.path.join("bin", "stacktrace_noop_exe"), run_environment=True) + if self.deps_user_info["boost"].stacktrace_addr2line_available: + self.run(os.path.join("bin", "stacktrace_addr2line_exe"), run_environment=True) diff --git a/recipes/boost/all/test_package/stacktrace.cpp b/recipes/boost/all/test_package/stacktrace.cpp new file mode 100644 index 0000000000000..015867694e0fc --- /dev/null +++ b/recipes/boost/all/test_package/stacktrace.cpp @@ -0,0 +1,76 @@ +#include + +#include + +void f3() { + std::cout << "==start stacktrace==\n" << boost::stacktrace::stacktrace() << "==end stacktrace==\n"; +} + +void f2() { + f3(); +} + +void f1() { + f2(); +} + +#define TEST_STACKTRACE_ADDR2LINE 1 +#define TEST_STACKTRACE_BACKTRACE 2 +#define TEST_STACKTRACE_NOOP 3 +#define TEST_STACKTRACE_WINDBG 4 +#define TEST_STACKTRACE_WINDBG_CACHED 5 + +static const char *stacktrace_impls[] = { + "addr2line", + "backtrace", + "noop", + "windbg", + "windbg_cached", +}; + +int main() { + int res = 0; + +#if !defined TEST_STACKTRACE_IMPL + std::cerr << "TEST_STACKTRACE_IMPL not defined!\n"; + res = 1; +#else + std::cerr << "Testing " << stacktrace_impls[TEST_STACKTRACE_IMPL-1] << "...\n"; +# if defined(BOOST_STACKTRACE_USE_ADDR2LINE) +# if TEST_STACKTRACE_IMPL != TEST_STACKTRACE_ADDR2LINE + std::cerr << "BOOST_STACKTRACE_USE_ADDR2LINE defined but not testing stacktrace_addr2line\n"; + res = 1; +# endif +# if !defined(BOOST_STACKTRACE_ADDR2LINE_LOCATION) + std::cerr << "error: BOOST_STACKTRACE_ADDR2LINE_LOCATION not defined\n"; + res = 1; +# endif +# endif +# if defined(BOOST_STACKTRACE_USE_BACKTRACE) +# if TEST_STACKTRACE_IMPL != TEST_STACKTRACE_BACKTRACE + std::cerr << "BOOST_STACKTRACE_USE_BACKTRACE defined but not testing stacktrace_backtrace\n"; + res = 1; +# endif +# endif +# if defined(BOOST_STACKTRACE_USE_NOOP) +# if TEST_STACKTRACE_IMPL != TEST_STACKTRACE_NOOP + std::cerr << "BOOST_STACKTRACE_USE_NOOP defined but not testing stacktrace_noop\n"; + res = 1; +# endif +# endif +# if defined(BOOST_STACKTRACE_USE_WINDBG) +# if TEST_STACKTRACE_IMPL != TEST_STACKTRACE_WINDBG + std::cerr << "BOOST_STACKTRACE_USE_WINDBG defined but not testing stacktrace_windbg\n"; + res = 1; +# endif +# endif +# if defined(BOOST_STACKTRACE_USE_WINDBG_CACHED) +# if TEST_STACKTRACE_IMPL != TEST_STACKTRACE_WINDBG_CACHED + std::cerr << "BOOST_STACKTRACE_USE_WINDBG_CACHED defined but not testing stacktrace_windbg_cached\n"; + res = 1; +# endif +# endif +#endif + f1(); + return res; +} From a71780e036db01ebff0c9968879b2a3a5db5fca3 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Mon, 3 May 2021 21:15:59 +0200 Subject: [PATCH 4/9] boost: don't create component for modules that can/should have libraries but don't have --- recipes/boost/all/conanfile.py | 37 +++++++++++-------- recipes/boost/all/test_package/CMakeLists.txt | 11 ++++-- recipes/boost/all/test_package/conanfile.py | 1 + recipes/boost/all/test_package/stacktrace.cpp | 8 ++-- 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/recipes/boost/all/conanfile.py b/recipes/boost/all/conanfile.py index 2a2082921db57..7b7e891d5868a 100644 --- a/recipes/boost/all/conanfile.py +++ b/recipes/boost/all/conanfile.py @@ -1383,6 +1383,11 @@ def filter_transform_module_libraries(names): continue module_libraries = filter_transform_module_libraries(self._dependencies["libs"][module]) + + # Don't create components for modules that should have libraries, but don't have (because of filter) + if self._dependencies["libs"][module] and not module_libraries: + continue + all_expected_libraries = all_expected_libraries.union(module_libraries) if set(module_libraries).difference(all_detected_libraries): incomplete_components.append(module) @@ -1419,25 +1424,27 @@ def filter_transform_module_libraries(names): if non_built: raise ConanException("These libraries were expected to be built, but were not built: {}".format(non_built)) - if self.settings.os in ("Linux", "FreeBSD"): - self.cpp_info.components["stacktrace"].system_libs.append("dl") + if not self.options.without_stacktrace: + if self.settings.os in ("Linux", "FreeBSD"): + self.cpp_info.components["stacktrace_basic"].system_libs.append("dl") + self.cpp_info.components["stacktrace_addr2line"].system_libs.append("dl") - if self._stacktrace_addr2line_available: - self.cpp_info.components["stacktrace_addr2line"].defines.extend([ - "BOOST_STACKTRACE_ADDR2LINE_LOCATION=\"{}\"".format(self.options.addr2line_location), - "BOOST_STACKTRACE_USE_ADDR2LINE", - ]) + if self._stacktrace_addr2line_available: + self.cpp_info.components["stacktrace_addr2line"].defines.extend([ + "BOOST_STACKTRACE_ADDR2LINE_LOCATION=\"{}\"".format(self.options.addr2line_location), + "BOOST_STACKTRACE_USE_ADDR2LINE", + ]) - # FIXME: add backtrace support - # self.cpp_info.components["stacktrace_backtrace"].defines.extend([ - # "BOOST_STACKTRACE_USE_BACKTRACE", - # ]) + # FIXME: add backtrace support + # self.cpp_info.components["stacktrace_backtrace"].defines.extend([ + # "BOOST_STACKTRACE_USE_BACKTRACE", + # ]) - self.cpp_info.components["stacktrace_noop"].defines.append("BOOST_STACKTRACE_USE_NOOP") + self.cpp_info.components["stacktrace_noop"].defines.append("BOOST_STACKTRACE_USE_NOOP") - if self.settings.os == "Windows": - self.cpp_info.components["stacktrace_windb"].defines.append("BOOST_STACKTRACE_USE_WINDBG") - self.cpp_info.components["stacktrace_windb_cached"].defines.append("BOOST_STACKTRACE_USE_WINDBG_CACHED") + if self.settings.os == "Windows": + self.cpp_info.components["stacktrace_windb"].defines.append("BOOST_STACKTRACE_USE_WINDBG") + self.cpp_info.components["stacktrace_windb_cached"].defines.append("BOOST_STACKTRACE_USE_WINDBG_CACHED") if not self.options.without_python: pyversion = tools.Version(self._python_version) diff --git a/recipes/boost/all/test_package/CMakeLists.txt b/recipes/boost/all/test_package/CMakeLists.txt index 866cefce68d5d..5cdc1e1edd9e6 100644 --- a/recipes/boost/all/test_package/CMakeLists.txt +++ b/recipes/boost/all/test_package/CMakeLists.txt @@ -71,17 +71,22 @@ if(NOT HEADER_ONLY) if(WITH_STACKTRACE) find_package(Boost COMPONENTS stacktrace REQUIRED) + add_executable(stacktrace_noop_exe stacktrace.cpp) - target_compile_definitions(stacktrace_noop_exe PRIVATE TEST_STACKTRACE_IMPL=3) + target_compile_definitions(stacktrace_noop_exe PRIVATE TEST_STACKTRACE_IMPL=4) target_link_libraries(stacktrace_noop_exe PRIVATE Boost::stacktrace_noop) + add_executable(stacktrace_basic_exe stacktrace.cpp) + target_compile_definitions(stacktrace_basic_exe PRIVATE TEST_STACKTRACE_IMPL=3) + target_link_libraries(stacktrace_basic_exe PRIVATE Boost::stacktrace_basic) + if(WIN32) add_executable(stacktrace_windbg_exe stacktrace.cpp) - target_compile_definitions(stacktrace_windbg_exe PRIVATE TEST_STACKTRACE_IMPL=4) + target_compile_definitions(stacktrace_windbg_exe PRIVATE TEST_STACKTRACE_IMPL=5) target_link_libraries(stacktrace_windbg_exe PRIVATE Boost::stacktrace_windbg) add_executable(stacktrace_windbg_cached_exe stacktrace.cpp) - target_compile_definitions(stacktrace_windbg_cached_exe PRIVATE TEST_STACKTRACE_IMPL=5) + target_compile_definitions(stacktrace_windbg_cached_exe PRIVATE TEST_STACKTRACE_IMPL=6) target_link_libraries(stacktrace_windbg_cached_exe PRIVATE Boost::stacktrace_windbg_cached) endif() endif() diff --git a/recipes/boost/all/test_package/conanfile.py b/recipes/boost/all/test_package/conanfile.py index 5322905fcf2bd..c019c642a511c 100644 --- a/recipes/boost/all/test_package/conanfile.py +++ b/recipes/boost/all/test_package/conanfile.py @@ -68,6 +68,7 @@ def test(self): self.run("{} {}".format(self.options["boost"].python_executable, os.path.join(self.source_folder, "python.py")), run_environment=True) self.run(os.path.join("bin", "numpy_exe"), run_environment=True) if not self.options["boost"].without_stacktrace: + self.run(os.path.join("bin", "stacktrace_basic_exe"), run_environment=True) self.run(os.path.join("bin", "stacktrace_noop_exe"), run_environment=True) if self.deps_user_info["boost"].stacktrace_addr2line_available: self.run(os.path.join("bin", "stacktrace_addr2line_exe"), run_environment=True) diff --git a/recipes/boost/all/test_package/stacktrace.cpp b/recipes/boost/all/test_package/stacktrace.cpp index 015867694e0fc..fb28adf03f8b6 100644 --- a/recipes/boost/all/test_package/stacktrace.cpp +++ b/recipes/boost/all/test_package/stacktrace.cpp @@ -16,13 +16,15 @@ void f1() { #define TEST_STACKTRACE_ADDR2LINE 1 #define TEST_STACKTRACE_BACKTRACE 2 -#define TEST_STACKTRACE_NOOP 3 -#define TEST_STACKTRACE_WINDBG 4 -#define TEST_STACKTRACE_WINDBG_CACHED 5 +#define TEST_STACKTRACE_BASIC 3 +#define TEST_STACKTRACE_NOOP 4 +#define TEST_STACKTRACE_WINDBG 5 +#define TEST_STACKTRACE_WINDBG_CACHED 6 static const char *stacktrace_impls[] = { "addr2line", "backtrace", + "basic", "noop", "windbg", "windbg_cached", From 97a3b45144a13983e6d85979656d270d181b3524 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 4 May 2021 01:07:05 +0200 Subject: [PATCH 5/9] boost: add stacktrace_backtrace support --- recipes/boost/all/conanfile.py | 65 ++++++++++++------- recipes/boost/all/test_package/CMakeLists.txt | 14 ++-- recipes/boost/all/test_package/conanfile.py | 5 +- 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/recipes/boost/all/conanfile.py b/recipes/boost/all/conanfile.py index 7b7e891d5868a..b7a4466d2bf2d 100644 --- a/recipes/boost/all/conanfile.py +++ b/recipes/boost/all/conanfile.py @@ -95,6 +95,7 @@ class BoostConan(ConanFile): "i18n_backend": ["iconv", "icu", None], "visibility": ["global", "protected", "hidden"], "addr2line_location": "ANY", + "with_stacktrace_backtrace": [True, False], } options.update({"without_{}".format(_name): [True, False] for _name in CONFIGURE_OPTIONS}) @@ -126,6 +127,7 @@ class BoostConan(ConanFile): "i18n_backend": "iconv", "visibility": "hidden", "addr2line_location": "/usr/bin/addr2line", + "with_stacktrace_backtrace": True, } default_options.update({"without_{}".format(_name): False for _name in CONFIGURE_OPTIONS}) default_options.update({"without_{}".format(_name): True for _name in ("graph_parallel", "mpi", "python")}) @@ -327,6 +329,9 @@ def configure(self): else: del self.options.addr2line_location + if self.options.get_safe("without_stacktrace", True): + del self.options.with_stacktrace_backtrace + if self.options.layout == "b2-default": self.options.layout = "versioned" if self.settings.os == "Windows" else "system" @@ -436,6 +441,10 @@ def _with_icu(self): def _with_iconv(self): return not self.options.header_only and self._with_dependency("iconv") and self.options.i18n_backend == "iconv" + @property + def _with_stacktrace_backtrace(self): + return not self.options.header_only and self.options.get_safe("with_stacktrace_backtrace", False) + def requirements(self): if self._with_zlib: self.requires("zlib/1.2.11") @@ -445,6 +454,9 @@ def requirements(self): self.requires("xz_utils/5.2.5") if self._with_zstd: self.requires("zstd/1.4.9") + if self._with_stacktrace_backtrace: + self.requires("libbacktrace/cci.20210118") + self.requires("libunwind/1.5.0") if self._with_icu: self.requires("icu/68.2") @@ -1098,16 +1110,27 @@ def create_library_config(deps_name, name): contents += '"%s" ' % tools.which(self._ar).replace("\\", "/") if self._ranlib: contents += '"%s" ' % tools.which(self._ranlib).replace("\\", "/") - if "CXXFLAGS" in os.environ: - contents += '"%s" ' % os.environ["CXXFLAGS"] - if "CFLAGS" in os.environ: - contents += '"%s" ' % os.environ["CFLAGS"] - if "CPPFLAGS" in os.environ: - contents += '"%s" ' % os.environ["CPPFLAGS"] - if "LDFLAGS" in os.environ: - contents += '"%s" ' % os.environ["LDFLAGS"] - if "ASFLAGS" in os.environ: - contents += '"%s" ' % os.environ["ASFLAGS"] + cxxflags = tools.get_env("CXXFLAGS", " ") + cflags = tools.get_env("CFLAGS", " ") + cppflags = tools.get_env("CPPFLAGS", " ") + ldflags = tools.get_env("LDFLAGS", " ") + asflags = tools.get_env("ASFLAGS", " ") + + if self._with_stacktrace_backtrace: + for l in ("libbacktrace", "libunwind"): + cppflags += " ".join("-I'{}'".format(p) for p in self.deps_cpp_info[l].include_paths) + " " + ldflags += " ".join("-L'{}'".format(p) for p in self.deps_cpp_info[l].lib_paths) + " " + + if cxxflags.strip(): + contents += '"%s" ' % cxxflags + if cflags.strip(): + contents += '"%s" ' % cflags + if cppflags.strip(): + contents += '"%s" ' % cppflags + if ldflags.strip(): + contents += '"%s" ' % ldflags + if asflags.strip(): + contents += '"%s" ' % asflags contents += " ;" @@ -1366,12 +1389,6 @@ def filter_transform_module_libraries(names): continue if name in ("boost_stacktrace_basic",) and self.settings.compiler == "Visual Studio": continue - if name == "boost_stacktrace_backtrace": - if "boost_stacktrace_backtrace" not in all_detected_libraries: - continue - # FIXME: Boost.Build sometimes picks up a system libbacktrace library. - # How to avoid this and force using a conan packaged libbacktrace package. - self.output.warn("Picked up a system libbacktrace library") if not self.options.get_safe("numa") and "_numa" in name: continue libs.append(add_libprefix(name.format(**libformatdata)) + libsuffix) @@ -1400,9 +1417,6 @@ def filter_transform_module_libraries(names): self.cpp_info.components[module].names["pkg_config"] = "boost_{}".format(module) for requirement in self._dependencies.get("requirements", {}).get(module, []): - if requirement == "backtrace": - # FIXME: add backtrace support (libbacktrace is available in cci) - continue if self.options.get_safe(requirement, None) == False: continue conan_requirement = self._option_to_conan_requirement(requirement) @@ -1428,6 +1442,8 @@ def filter_transform_module_libraries(names): if self.settings.os in ("Linux", "FreeBSD"): self.cpp_info.components["stacktrace_basic"].system_libs.append("dl") self.cpp_info.components["stacktrace_addr2line"].system_libs.append("dl") + if self._with_stacktrace_backtrace: + self.cpp_info.components["stacktrace_backtrace"].system_libs.append("dl") if self._stacktrace_addr2line_available: self.cpp_info.components["stacktrace_addr2line"].defines.extend([ @@ -1435,10 +1451,13 @@ def filter_transform_module_libraries(names): "BOOST_STACKTRACE_USE_ADDR2LINE", ]) - # FIXME: add backtrace support - # self.cpp_info.components["stacktrace_backtrace"].defines.extend([ - # "BOOST_STACKTRACE_USE_BACKTRACE", - # ]) + if self._with_stacktrace_backtrace: + self.cpp_info.components["stacktrace_backtrace"].defines.append("BOOST_STACKTRACE_USE_BACKTRACE") + self.cpp_info.components["stacktrace_backtrace"].system_libs.append("dl") + self.cpp_info.components["stacktrace_backtrace"].requires.extend([ + "libunwind::libunwind", + "libbacktrace::libbacktrace", + ]) self.cpp_info.components["stacktrace_noop"].defines.append("BOOST_STACKTRACE_USE_NOOP") diff --git a/recipes/boost/all/test_package/CMakeLists.txt b/recipes/boost/all/test_package/CMakeLists.txt index 5cdc1e1edd9e6..0754909906c80 100644 --- a/recipes/boost/all/test_package/CMakeLists.txt +++ b/recipes/boost/all/test_package/CMakeLists.txt @@ -69,17 +69,23 @@ if(NOT HEADER_ONLY) target_link_libraries(stacktrace_addr2line_exe PRIVATE Boost::stacktrace_addr2line) endif() + if(WITH_STACKTRACE_BACKTRACE) + add_executable(stacktrace_backtrace_exe stacktrace.cpp) + target_compile_definitions(stacktrace_backtrace_exe PRIVATE TEST_STACKTRACE_IMPL=2) + target_link_libraries(stacktrace_backtrace_exe PRIVATE Boost::stacktrace_backtrace) + endif() + if(WITH_STACKTRACE) find_package(Boost COMPONENTS stacktrace REQUIRED) - add_executable(stacktrace_noop_exe stacktrace.cpp) - target_compile_definitions(stacktrace_noop_exe PRIVATE TEST_STACKTRACE_IMPL=4) - target_link_libraries(stacktrace_noop_exe PRIVATE Boost::stacktrace_noop) - add_executable(stacktrace_basic_exe stacktrace.cpp) target_compile_definitions(stacktrace_basic_exe PRIVATE TEST_STACKTRACE_IMPL=3) target_link_libraries(stacktrace_basic_exe PRIVATE Boost::stacktrace_basic) + add_executable(stacktrace_noop_exe stacktrace.cpp) + target_compile_definitions(stacktrace_noop_exe PRIVATE TEST_STACKTRACE_IMPL=4) + target_link_libraries(stacktrace_noop_exe PRIVATE Boost::stacktrace_noop) + if(WIN32) add_executable(stacktrace_windbg_exe stacktrace.cpp) target_compile_definitions(stacktrace_windbg_exe PRIVATE TEST_STACKTRACE_IMPL=5) diff --git a/recipes/boost/all/test_package/conanfile.py b/recipes/boost/all/test_package/conanfile.py index c019c642a511c..7d90149bf12ee 100644 --- a/recipes/boost/all/test_package/conanfile.py +++ b/recipes/boost/all/test_package/conanfile.py @@ -36,6 +36,7 @@ def build(self): cmake.definitions["WITH_JSON"] = not self._boost_option("without_json", True) cmake.definitions["WITH_STACKTRACE"] = not self.options["boost"].without_stacktrace cmake.definitions["WITH_STACKTRACE_ADDR2LINE"] = self.deps_user_info["boost"].stacktrace_addr2line_available + cmake.definitions["WITH_STACKTRACE_BACKTRACE"] = self._boost_option("with_stacktrace_backtrace", False) cmake.configure() cmake.build() @@ -70,5 +71,7 @@ def test(self): if not self.options["boost"].without_stacktrace: self.run(os.path.join("bin", "stacktrace_basic_exe"), run_environment=True) self.run(os.path.join("bin", "stacktrace_noop_exe"), run_environment=True) - if self.deps_user_info["boost"].stacktrace_addr2line_available: + if str(self.deps_user_info["boost"].stacktrace_addr2line_available) == "True": self.run(os.path.join("bin", "stacktrace_addr2line_exe"), run_environment=True) + if self._boost_option("with_stacktrace_backtrace", False): + self.run(os.path.join("bin", "stacktrace_backtrace_exe"), run_environment=True) From 1cf6aab256cce37768cf21ed1f97defbd6fe04a2 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 4 May 2021 01:43:33 +0200 Subject: [PATCH 6/9] boost: fix stacktrace with MSVC --- recipes/boost/all/conanfile.py | 6 +++++- recipes/boost/all/test_package/CMakeLists.txt | 14 ++++++++------ recipes/boost/all/test_package/conanfile.py | 14 +++++++++----- recipes/boost/all/test_package/stacktrace.cpp | 2 +- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/recipes/boost/all/conanfile.py b/recipes/boost/all/conanfile.py index b7a4466d2bf2d..2438573dc0516 100644 --- a/recipes/boost/all/conanfile.py +++ b/recipes/boost/all/conanfile.py @@ -238,6 +238,10 @@ def config_options(self): if "without_{}".format(opt_name) not in self.options: raise ConanException("{} has the configure options {} which is not available in conanfile.py".format(self._dependency_filename, opt_name)) + # libbacktrace cannot be built on Visual Studio + if self.settings.compiler == "Visual Studio": + del self.options.with_stacktrace_backtrace + # nowide requires a c++11-able compiler + movable std::fstream: change default to not build on compiler with too old default c++ standard or too low compiler.cppstd # json requires a c++11-able compiler: change default to not build on compiler with too old default c++ standard or too low compiler.cppstd if self.settings.compiler.cppstd: @@ -1387,7 +1391,7 @@ def filter_transform_module_libraries(names): for name in names: if name in ("boost_stacktrace_windbg", "boost_stacktrace_windbg_cached") and self.settings.os != "Windows": continue - if name in ("boost_stacktrace_basic",) and self.settings.compiler == "Visual Studio": + if name in ("boost_stacktrace_addr2line", "boost_stacktrace_backtrace", "boost_stacktrace_basic",) and self.settings.compiler == "Visual Studio": continue if not self.options.get_safe("numa") and "_numa" in name: continue diff --git a/recipes/boost/all/test_package/CMakeLists.txt b/recipes/boost/all/test_package/CMakeLists.txt index 0754909906c80..5ef223512573f 100644 --- a/recipes/boost/all/test_package/CMakeLists.txt +++ b/recipes/boost/all/test_package/CMakeLists.txt @@ -78,13 +78,15 @@ if(NOT HEADER_ONLY) if(WITH_STACKTRACE) find_package(Boost COMPONENTS stacktrace REQUIRED) - add_executable(stacktrace_basic_exe stacktrace.cpp) - target_compile_definitions(stacktrace_basic_exe PRIVATE TEST_STACKTRACE_IMPL=3) - target_link_libraries(stacktrace_basic_exe PRIVATE Boost::stacktrace_basic) + if(NOT MSVC) + add_executable(stacktrace_basic_exe stacktrace.cpp) + target_compile_definitions(stacktrace_basic_exe PRIVATE TEST_STACKTRACE_IMPL=3) + target_link_libraries(stacktrace_basic_exe PRIVATE Boost::stacktrace_basic) + endif() - add_executable(stacktrace_noop_exe stacktrace.cpp) - target_compile_definitions(stacktrace_noop_exe PRIVATE TEST_STACKTRACE_IMPL=4) - target_link_libraries(stacktrace_noop_exe PRIVATE Boost::stacktrace_noop) + add_executable(stacktrace_noop_exe stacktrace.cpp) + target_compile_definitions(stacktrace_noop_exe PRIVATE TEST_STACKTRACE_IMPL=4) + target_link_libraries(stacktrace_noop_exe PRIVATE Boost::stacktrace_noop) if(WIN32) add_executable(stacktrace_windbg_exe stacktrace.cpp) diff --git a/recipes/boost/all/test_package/conanfile.py b/recipes/boost/all/test_package/conanfile.py index 7d90149bf12ee..e873ebc81d467 100644 --- a/recipes/boost/all/test_package/conanfile.py +++ b/recipes/boost/all/test_package/conanfile.py @@ -69,9 +69,13 @@ def test(self): self.run("{} {}".format(self.options["boost"].python_executable, os.path.join(self.source_folder, "python.py")), run_environment=True) self.run(os.path.join("bin", "numpy_exe"), run_environment=True) if not self.options["boost"].without_stacktrace: - self.run(os.path.join("bin", "stacktrace_basic_exe"), run_environment=True) + if self.settings.compiler != "Visual Studio": + self.run(os.path.join("bin", "stacktrace_basic_exe"), run_environment=True) self.run(os.path.join("bin", "stacktrace_noop_exe"), run_environment=True) - if str(self.deps_user_info["boost"].stacktrace_addr2line_available) == "True": - self.run(os.path.join("bin", "stacktrace_addr2line_exe"), run_environment=True) - if self._boost_option("with_stacktrace_backtrace", False): - self.run(os.path.join("bin", "stacktrace_backtrace_exe"), run_environment=True) + if str(self.deps_user_info["boost"].stacktrace_addr2line_available) == "True": + self.run(os.path.join("bin", "stacktrace_addr2line_exe"), run_environment=True) + if self.settings.os == "Windows": + self.run(os.path.join("bin", "stacktrace_windbg_exe"), run_environment=True) + self.run(os.path.join("bin", "stacktrace_windbg_cached_exe"), run_environment=True) + if self._boost_option("with_stacktrace_backtrace", False): + self.run(os.path.join("bin", "stacktrace_backtrace_exe"), run_environment=True) diff --git a/recipes/boost/all/test_package/stacktrace.cpp b/recipes/boost/all/test_package/stacktrace.cpp index fb28adf03f8b6..d58676489cb60 100644 --- a/recipes/boost/all/test_package/stacktrace.cpp +++ b/recipes/boost/all/test_package/stacktrace.cpp @@ -37,7 +37,7 @@ int main() { std::cerr << "TEST_STACKTRACE_IMPL not defined!\n"; res = 1; #else - std::cerr << "Testing " << stacktrace_impls[TEST_STACKTRACE_IMPL-1] << "...\n"; + std::cerr << "Testing stacktrace_" << stacktrace_impls[TEST_STACKTRACE_IMPL-1] << "...\n"; # if defined(BOOST_STACKTRACE_USE_ADDR2LINE) # if TEST_STACKTRACE_IMPL != TEST_STACKTRACE_ADDR2LINE std::cerr << "BOOST_STACKTRACE_USE_ADDR2LINE defined but not testing stacktrace_addr2line\n"; From 6e449a8bb7313c768de8df0d2c905b6e414e1d8a Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 4 May 2021 04:04:03 +0200 Subject: [PATCH 7/9] boost: fix passing of environment flags + remove thread_local for older clang versions --- recipes/boost/all/conanfile.py | 35 ++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/recipes/boost/all/conanfile.py b/recipes/boost/all/conanfile.py index 2438573dc0516..6ff4e27f8f2b2 100644 --- a/recipes/boost/all/conanfile.py +++ b/recipes/boost/all/conanfile.py @@ -730,6 +730,17 @@ def _run_bcp(self): self.run(command) def build(self): + # Older clang releases require a thread_local variable to be initialized by a constant value + tools.replace_in_file(os.path.join(self.source_folder, self._source_subfolder, "boost", "stacktrace", "detail", "libbacktrace_impls.hpp"), + "/* thread_local */", "thread_local", strict=False) + tools.replace_in_file(os.path.join(self.source_folder, self._source_subfolder, "boost", "stacktrace", "detail", "libbacktrace_impls.hpp"), + "/* static __thread */", "static __thread", strict=False) + if self.settings.compiler == "clang" and tools.Version(self.settings.compiler.version) < 6: + tools.replace_in_file(os.path.join(self.source_folder, self._source_subfolder, "boost", "stacktrace", "detail", "libbacktrace_impls.hpp"), + "thread_local", "/* thread_local */") + tools.replace_in_file(os.path.join(self.source_folder, self._source_subfolder, "boost", "stacktrace", "detail", "libbacktrace_impls.hpp"), + "static __thread", "/* static __thread */") + if self.options.header_only: self.output.warn("Header only package, skipping build") return @@ -1114,27 +1125,27 @@ def create_library_config(deps_name, name): contents += '"%s" ' % tools.which(self._ar).replace("\\", "/") if self._ranlib: contents += '"%s" ' % tools.which(self._ranlib).replace("\\", "/") - cxxflags = tools.get_env("CXXFLAGS", " ") - cflags = tools.get_env("CFLAGS", " ") - cppflags = tools.get_env("CPPFLAGS", " ") - ldflags = tools.get_env("LDFLAGS", " ") - asflags = tools.get_env("ASFLAGS", " ") + cxxflags = tools.get_env("CXXFLAGS", "") + " " + cflags = tools.get_env("CFLAGS", "") + " " + cppflags = tools.get_env("CPPFLAGS", "") + " " + ldflags = tools.get_env("LDFLAGS", "") + " " + asflags = tools.get_env("ASFLAGS", "") + " " if self._with_stacktrace_backtrace: for l in ("libbacktrace", "libunwind"): - cppflags += " ".join("-I'{}'".format(p) for p in self.deps_cpp_info[l].include_paths) + " " - ldflags += " ".join("-L'{}'".format(p) for p in self.deps_cpp_info[l].lib_paths) + " " + cppflags += " ".join("-I{}".format(p) for p in self.deps_cpp_info[l].include_paths) + " " + ldflags += " ".join("-L{}".format(p) for p in self.deps_cpp_info[l].lib_paths) + " " if cxxflags.strip(): - contents += '"%s" ' % cxxflags + contents += '"%s" ' % cxxflags.strip() if cflags.strip(): - contents += '"%s" ' % cflags + contents += '"%s" ' % cflags.strip() if cppflags.strip(): - contents += '"%s" ' % cppflags + contents += '"%s" ' % cppflags.strip() if ldflags.strip(): - contents += '"%s" ' % ldflags + contents += '"%s" ' % ldflags.strip() if asflags.strip(): - contents += '"%s" ' % asflags + contents += '"%s" ' % asflags.strip() contents += " ;" From 0a19a2f836dd24c95e6ff20137b741115f0f0e81 Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Tue, 4 May 2021 23:33:18 +0200 Subject: [PATCH 8/9] boost: don't build the tests in parallel to see where c3i chokes --- recipes/boost/all/test_package/conanfile.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/recipes/boost/all/test_package/conanfile.py b/recipes/boost/all/test_package/conanfile.py index e873ebc81d467..3836803096b48 100644 --- a/recipes/boost/all/test_package/conanfile.py +++ b/recipes/boost/all/test_package/conanfile.py @@ -38,6 +38,8 @@ def build(self): cmake.definitions["WITH_STACKTRACE_ADDR2LINE"] = self.deps_user_info["boost"].stacktrace_addr2line_available cmake.definitions["WITH_STACKTRACE_BACKTRACE"] = self._boost_option("with_stacktrace_backtrace", False) cmake.configure() + # Disable parallel builds because c3i (=conan-center's test/build infrastructure) seems to choke here + cmake.parallel = False cmake.build() def test(self): From 53cb5aecb6c47cbaf062bbbc0975cc62d98525ad Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Fri, 7 May 2021 02:53:21 +0200 Subject: [PATCH 9/9] boost: allow building boost_stacktrace_{addr2line,backtrace} when cross building --- recipes/boost/all/conanfile.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/recipes/boost/all/conanfile.py b/recipes/boost/all/conanfile.py index 6ff4e27f8f2b2..92d9a6e0d377c 100644 --- a/recipes/boost/all/conanfile.py +++ b/recipes/boost/all/conanfile.py @@ -730,6 +730,11 @@ def _run_bcp(self): self.run(command) def build(self): + if tools.cross_building(self.settings, skip_x64_x86=True): + # When cross building, do not attempt to run the test-executable (assume they work) + tools.replace_in_file(os.path.join(self.source_folder, self._source_subfolder, "libs", "stacktrace", "build", "Jamfile.v2"), + "$(>) > $(<)", + "echo \"\" > $(<)", strict=False) # Older clang releases require a thread_local variable to be initialized by a constant value tools.replace_in_file(os.path.join(self.source_folder, self._source_subfolder, "boost", "stacktrace", "detail", "libbacktrace_impls.hpp"), "/* thread_local */", "thread_local", strict=False) @@ -1443,7 +1448,7 @@ def filter_transform_module_libraries(names): self.cpp_info.components[module].requires.append("{0}::{0}".format(conan_requirement)) for incomplete_component in incomplete_components: - self.output.warn("Boost component '{0}' is missing libraries. Try building boost with '-o boost:without_{0}'.".format(incomplete_component)) + self.output.warn("Boost component '{0}' is missing libraries. Try building boost with '-o boost:without_{0}'. (Option is not guaranteed to exist)".format(incomplete_component)) non_used = all_detected_libraries.difference(all_expected_libraries) if non_used: