diff --git a/recipes/apr/all/conanfile.py b/recipes/apr/all/conanfile.py index 932bac9dcf2ea..2f5b13dc054ed 100644 --- a/recipes/apr/all/conanfile.py +++ b/recipes/apr/all/conanfile.py @@ -1,3 +1,6 @@ +import os +import re + from conan import ConanFile from conan.errors import ConanException, ConanInvalidConfiguration from conan.tools.apple import fix_apple_shared_install_name @@ -9,8 +12,6 @@ from conan.tools.layout import basic_layout from conan.tools.microsoft import is_msvc from conan.tools.scm import Version -import os -import re required_conan_version = ">=1.54.0" @@ -69,7 +70,20 @@ def layout(self): def validate_build(self): if cross_building(self) and not is_msvc(self): - raise ConanInvalidConfiguration("apr recipe doesn't support cross-build yet due to runtime checks in autoconf") + msg = ("apr recipe doesn't support cross-build for all the platforms" + " due to runtime checks in autoconf. You can provide" + " a pre-built cached file as an user Conan conf variable to try it.\n\n" + "Via host profile:\n" + "[conf]\nuser.apr:cache_file=/path/to/cache_file\n\n" + "Via CLI: \n" + "-c \"user.apr:cache_file='/path/to/cache_file'\"") + # Cross-building for apr < 1.7.4 is not supported without a pre-built cached file + if Version(self.version) < "1.7.4" and self.conf.get("user.apr:cache_file") is None: + raise ConanInvalidConfiguration(msg) + # Conan provides for apr >= 1.7.4 and Linux some configuration flags to avoid + # entering a pre-built cached file + if self.settings.os != "Linux" and self.conf.get("user.apr:cache_file") is None: + raise ConanInvalidConfiguration(msg) def build_requirements(self): if not is_msvc(self): @@ -83,6 +97,47 @@ def build_requirements(self): def source(self): get(self, **self.conan_data["sources"][self.version], strip_root=True) + def _get_cross_building_configure_args(self): + """ + The vast majority of projects that use autotools and make use of the AC_TRY_RUN macro, + do provide a default fallback when cross-compiling, as per the documentation here: + + * https://ftp.gnu.org/old-gnu/Manuals/autoconf-2.53/html_node/Test-Programs.html + + In that regard, APR cannot be cross-compiled by traditional means, and the only fallback + is to use a cache file. Indeed, the only way to cross-compile that is documented by upstream + is by pre-empting the configuration checks with a cache file that needs to be generated on + the target system: + + ./configure --cache-file={gnu_host_triplet}.cache + + The generated cache file can be repeatedly used to cross-compile to the targeted host system + by including it with the recipe data. + + This recipe is reading this custom user conf variable: + + [conf] + user.apr:cache_file=/path/to/{gnu_host_triplet}.cache + + So you can use it to cross-compile on your system. + """ + configure_args = [] + user_cache_file = self.conf.get("user.apr:cache_file", check_type=str) + if user_cache_file: + configure_args.append(f"--cache-file={user_cache_file}") + return configure_args + + self.output.warning("Trying to set some configuration arguments, but it" + " could fail. The best approach is to provide a" + " pre-built cached file.") + if self.settings.os == "Linux": + # Mandatory cross-building configuration flags (tested on Linux ARM and Intel) + configure_args.extend(["apr_cv_mutex_robust_shared=yes", + "ac_cv_file__dev_zero=yes", + "apr_cv_process_shared_works=yes", + "apr_cv_tcp_nodelay_with_cork=yes"]) + return configure_args + def generate(self): if is_msvc(self): tc = CMakeToolchain(self) @@ -95,7 +150,7 @@ def generate(self): tc = AutotoolsToolchain(self) tc.configure_args.append("--with-installbuilddir=${prefix}/res/build-1") if cross_building(self): - tc.configure_args.append("apr_cv_mutex_robust_shared=yes") + tc.configure_args.extend(self._get_cross_building_configure_args()) tc.generate() def _patch_sources(self):