From 4cbcbd119857d070ed51d83ae14b1e202c393390 Mon Sep 17 00:00:00 2001 From: Luis Caro Campos <3535649+jcar87@users.noreply.github.com> Date: Wed, 12 Jun 2024 10:57:33 +0100 Subject: [PATCH 1/6] apr: bypass runtime checks when cross-building for Linux --- recipes/apr/all/conanfile.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/recipes/apr/all/conanfile.py b/recipes/apr/all/conanfile.py index 932bac9dcf2ea..c95a31097547e 100644 --- a/recipes/apr/all/conanfile.py +++ b/recipes/apr/all/conanfile.py @@ -68,7 +68,7 @@ def layout(self): basic_layout(self, src_folder="src") def validate_build(self): - if cross_building(self) and not is_msvc(self): + if cross_building(self) and not is_msvc(self) and self.settings.os != "Linux": raise ConanInvalidConfiguration("apr recipe doesn't support cross-build yet due to runtime checks in autoconf") def build_requirements(self): @@ -96,6 +96,13 @@ def generate(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") + if self.settings.os == "Linux": + # the following are known to be true in modern Linux + tc.configure_args.extend(["ac_cv_file__dev_zero=yes", + "ac_cv_mmap__dev_zero=yes", + "ac_cv_define_PTHREAD_PROCESS_SHARED=yes", + "apr_cv_process_shared_works=yes", + "apr_cv_tcp_nodelay_with_cork=yes"]) tc.generate() def _patch_sources(self): From c9573b4db8653755a2b1feec2bd0d27479337bec Mon Sep 17 00:00:00 2001 From: Francisco Ramirez de Anton Date: Fri, 14 Jun 2024 14:42:45 +0200 Subject: [PATCH 2/6] Isolating variables --- recipes/apr/all/conanfile.py | 69 ++++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 10 deletions(-) diff --git a/recipes/apr/all/conanfile.py b/recipes/apr/all/conanfile.py index c95a31097547e..56f7ec8fca10d 100644 --- a/recipes/apr/all/conanfile.py +++ b/recipes/apr/all/conanfile.py @@ -1,4 +1,5 @@ from conan import ConanFile +from conan.api.output import ConanOutput from conan.errors import ConanException, ConanInvalidConfiguration from conan.tools.apple import fix_apple_shared_install_name from conan.tools.build import cross_building @@ -68,8 +69,13 @@ def layout(self): basic_layout(self, src_folder="src") def validate_build(self): - if cross_building(self) and not is_msvc(self) and self.settings.os != "Linux": - raise ConanInvalidConfiguration("apr recipe doesn't support cross-build yet due to runtime checks in autoconf") + if cross_building(self) and not is_msvc(self): + # Conan provide for Windows and Linux a simple "hack" to avoid entering a pre-built cached file + if self.settings.os not in ("Windows", "Linux") and self.conf.get("user.apr:cache_file") is None: + raise ConanInvalidConfiguration("apr recipe doesn't support cross-build for all the platforms" + " due to runtime checks in autoconf. You can provide" + " a cached file via Conan conf: \n" + " [conf]\nuser.apr:cache_file=/path/to/cache_file to try it.") def build_requirements(self): if not is_msvc(self): @@ -83,6 +89,56 @@ 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 APR configure.in script makes extensive (30 instances) use + Check warning on line 73 in recipes/apr/all/conanfile.py + + String statement has no effect of AC_TRY_RUN (to determine system capabilities) and + checks for /dev/zero. These runtime checks only work when run on the host so + the configure script will fail when cross compiling unless the relevant + configuration variables are provided in a cache file or on the command line or in an + environment variable. The configuration variable values are most easily determined by + running the configure script on a host system using: + + ./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 + + ConanOutput().warning("Trying to set some configuration arguments, but it" + " could fail. The best approach is to provide a" + " pre-built cached file.") + # Let's try this hack (tested on Linux ARM and Intel) + if self.settings.os == "Linux": + # The following are known to be true in modern Linux + configure_args.extend(["apr_cv_mutex_robust_shared=yes", + "ac_cv_file__dev_zero=yes", + "ac_cv_mmap__dev_zero=yes", + "ac_cv_define_PTHREAD_PROCESS_SHARED=yes", + "apr_cv_process_shared_works=yes", + "apr_cv_tcp_nodelay_with_cork=yes"]) + elif self.settings.os == "Windows": + configure_args.extend(["apr_cv_mutex_robust_shared=no" + "ac_cv_file__dev_zero=no", + "ac_cv_mmap__dev_zero=no", + "ac_cv_define_PTHREAD_PROCESS_SHARED=yes", + "apr_cv_tcp_nodelay_with_cork=no"]) + return configure_args + def generate(self): if is_msvc(self): tc = CMakeToolchain(self) @@ -95,14 +151,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") - if self.settings.os == "Linux": - # the following are known to be true in modern Linux - tc.configure_args.extend(["ac_cv_file__dev_zero=yes", - "ac_cv_mmap__dev_zero=yes", - "ac_cv_define_PTHREAD_PROCESS_SHARED=yes", - "apr_cv_process_shared_works=yes", - "apr_cv_tcp_nodelay_with_cork=yes"]) + tc.configure_args.extend(self._get_cross_building_configure_args()) tc.generate() def _patch_sources(self): From a3b5e0daa340847de3ff9d8681064b717f7fd79a Mon Sep 17 00:00:00 2001 From: Francisco Ramirez de Anton Date: Fri, 14 Jun 2024 15:30:17 +0200 Subject: [PATCH 3/6] Fixed bad import --- recipes/apr/all/conanfile.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/recipes/apr/all/conanfile.py b/recipes/apr/all/conanfile.py index 56f7ec8fca10d..1bc04b8a72311 100644 --- a/recipes/apr/all/conanfile.py +++ b/recipes/apr/all/conanfile.py @@ -1,5 +1,7 @@ +import os +import re + from conan import ConanFile -from conan.api.output import ConanOutput from conan.errors import ConanException, ConanInvalidConfiguration from conan.tools.apple import fix_apple_shared_install_name from conan.tools.build import cross_building @@ -10,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" @@ -119,9 +119,9 @@ def _get_cross_building_configure_args(self): configure_args.append(f"--cache-file={user_cache_file}") return configure_args - ConanOutput().warning("Trying to set some configuration arguments, but it" - " could fail. The best approach is to provide a" - " pre-built cached file.") + self.output.warning("Trying to set some configuration arguments, but it" + " could fail. The best approach is to provide a" + " pre-built cached file.") # Let's try this hack (tested on Linux ARM and Intel) if self.settings.os == "Linux": # The following are known to be true in modern Linux From cf655e4690c6a505bef8195557c0e3d010d2e1ce Mon Sep 17 00:00:00 2001 From: Francisco Ramirez de Anton Date: Mon, 24 Jun 2024 15:27:34 +0200 Subject: [PATCH 4/6] Removed Windows configuration flags. Applied suggestions --- recipes/apr/all/conanfile.py | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/recipes/apr/all/conanfile.py b/recipes/apr/all/conanfile.py index 1bc04b8a72311..2287bc5316f12 100644 --- a/recipes/apr/all/conanfile.py +++ b/recipes/apr/all/conanfile.py @@ -70,11 +70,11 @@ def layout(self): def validate_build(self): if cross_building(self) and not is_msvc(self): - # Conan provide for Windows and Linux a simple "hack" to avoid entering a pre-built cached file - if self.settings.os not in ("Windows", "Linux") and self.conf.get("user.apr:cache_file") is None: + # Conan provides for 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("apr recipe doesn't support cross-build for all the platforms" " due to runtime checks in autoconf. You can provide" - " a cached file via Conan conf: \n" + " a pre-built cached file via Conan conf: \n" " [conf]\nuser.apr:cache_file=/path/to/cache_file to try it.") def build_requirements(self): @@ -91,15 +91,15 @@ def source(self): def _get_cross_building_configure_args(self): """ - The APR configure.in script makes extensive (30 instances) use - Check warning on line 73 in recipes/apr/all/conanfile.py + 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: - String statement has no effect of AC_TRY_RUN (to determine system capabilities) and - checks for /dev/zero. These runtime checks only work when run on the host so - the configure script will fail when cross compiling unless the relevant - configuration variables are provided in a cache file or on the command line or in an - environment variable. The configuration variable values are most easily determined by - running the configure script on a host system using: + * 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 @@ -122,21 +122,14 @@ def _get_cross_building_configure_args(self): self.output.warning("Trying to set some configuration arguments, but it" " could fail. The best approach is to provide a" " pre-built cached file.") - # Let's try this hack (tested on Linux ARM and Intel) if self.settings.os == "Linux": - # The following are known to be true in modern 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", "ac_cv_mmap__dev_zero=yes", "ac_cv_define_PTHREAD_PROCESS_SHARED=yes", "apr_cv_process_shared_works=yes", "apr_cv_tcp_nodelay_with_cork=yes"]) - elif self.settings.os == "Windows": - configure_args.extend(["apr_cv_mutex_robust_shared=no" - "ac_cv_file__dev_zero=no", - "ac_cv_mmap__dev_zero=no", - "ac_cv_define_PTHREAD_PROCESS_SHARED=yes", - "apr_cv_tcp_nodelay_with_cork=no"]) return configure_args def generate(self): From dec6327df9bc7f5506a5fc73cebecd5337cea17e Mon Sep 17 00:00:00 2001 From: Francisco Ramirez de Anton Date: Mon, 24 Jun 2024 15:37:22 +0200 Subject: [PATCH 5/6] Simplified configuration arguments --- recipes/apr/all/conanfile.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/recipes/apr/all/conanfile.py b/recipes/apr/all/conanfile.py index 2287bc5316f12..10121371a37f6 100644 --- a/recipes/apr/all/conanfile.py +++ b/recipes/apr/all/conanfile.py @@ -126,8 +126,6 @@ def _get_cross_building_configure_args(self): # 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", - "ac_cv_mmap__dev_zero=yes", - "ac_cv_define_PTHREAD_PROCESS_SHARED=yes", "apr_cv_process_shared_works=yes", "apr_cv_tcp_nodelay_with_cork=yes"]) return configure_args From 3b6b1b0c8b8834a4a69597cc9331e5ba92a8f0b6 Mon Sep 17 00:00:00 2001 From: Francisco Ramirez de Anton Date: Mon, 24 Jun 2024 16:14:52 +0200 Subject: [PATCH 6/6] Added new validate_build check --- recipes/apr/all/conanfile.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/recipes/apr/all/conanfile.py b/recipes/apr/all/conanfile.py index 10121371a37f6..2f5b13dc054ed 100644 --- a/recipes/apr/all/conanfile.py +++ b/recipes/apr/all/conanfile.py @@ -70,12 +70,20 @@ def layout(self): def validate_build(self): if cross_building(self) and not is_msvc(self): - # Conan provides for Linux some configuration flags to avoid entering a pre-built cached file + 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("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 via Conan conf: \n" - " [conf]\nuser.apr:cache_file=/path/to/cache_file to try it.") + raise ConanInvalidConfiguration(msg) def build_requirements(self): if not is_msvc(self):