Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[POC][APR] Support for cross-building using configuration variables #24329

Merged
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 60 additions & 4 deletions recipes/apr/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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"

Expand Down Expand Up @@ -69,7 +70,12 @@

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")
# 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):
Expand All @@ -83,6 +89,56 @@
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:
franramirez688 marked this conversation as resolved.
Show resolved Hide resolved

./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.")
# Let's try this hack (tested on Linux ARM and Intel)
franramirez688 marked this conversation as resolved.
Show resolved Hide resolved
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",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For ` "ac_cv_file__dev_zero=yes", "ac_cv_mmap__dev_zero=yes":

  • Linux should have /dev/zero and it should be mmap'able, and but fairly certain mmap also supports zeroing with with the MAP_ANONYMOUS flag - so on Linux I think these two checks are yes almost universally.

"ac_cv_define_PTHREAD_PROCESS_SHARED=yes",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surprised this check needs any runtime anything, fairly certain it just checks that the PTHREAD_PROCESS_SHARED macro is defined in pthread.h - this seems part of Posix and I can't find examples of this not being defined on Linux. Very much not the case on windows though

"apr_cv_process_shared_works=yes",
"apr_cv_tcp_nodelay_with_cork=yes"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tcpcork is available on Linux since kernel 2.2 released in 1999
https://linux.die.net/man/7/tcp

So I think we can also assume that this is available - the check is more useful keeping in mind that apr is quite old and aims to support things like solaris, sunOS, etc

elif self.settings.os == "Windows":
configure_args.extend(["apr_cv_mutex_robust_shared=no"
franramirez688 marked this conversation as resolved.
Show resolved Hide resolved
"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)
Expand All @@ -95,7 +151,7 @@
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):
Expand Down Expand Up @@ -131,12 +187,12 @@
fix_apple_shared_install_name(self)

apr_rules_mk = os.path.join(self.package_folder, "res", "build-1", "apr_rules.mk")
apr_rules_cnt = open(apr_rules_mk).read()

Check warning on line 190 in recipes/apr/all/conanfile.py

View workflow job for this annotation

GitHub Actions / Lint changed conanfile.py (v2 migration)

Using open without explicitly specifying an encoding
for key in ("apr_builddir", "apr_builders", "top_builddir"):
apr_rules_cnt, nb = re.subn(f"^{key}=[^\n]*\n", f"{key}=$(_APR_BUILDDIR)\n", apr_rules_cnt, flags=re.MULTILINE)
if nb == 0:
raise ConanException(f"Could not find/replace {key} in {apr_rules_mk}")
open(apr_rules_mk, "w").write(apr_rules_cnt)

Check warning on line 195 in recipes/apr/all/conanfile.py

View workflow job for this annotation

GitHub Actions / Lint changed conanfile.py (v2 migration)

Using open without explicitly specifying an encoding

def package_info(self):
self.cpp_info.set_property("pkg_config_name", "apr-1")
Expand All @@ -152,4 +208,4 @@

# TODO: to remove in conan v2
self.env_info.APR_ROOT = self.package_folder
self.env_info._APR_BUILDDIR = os.path.join(self.package_folder, "res", "build-1")

Check warning on line 211 in recipes/apr/all/conanfile.py

View workflow job for this annotation

GitHub Actions / Lint changed conanfile.py (v2 migration)

Access to a protected member _APR_BUILDDIR of a client class
Loading