Page MenuHome GnuPG

--with-libgpg-error-prefix doesn't affect gpgrt-config path detection
Closed, ResolvedPublic

Description

I'm on macOS, cross-compiling for iOS. I have libgpg-error installed to a custom path, and I pass that prefix to --with-libgpg-error-prefix. This machine also happens to have a /usr/local/bin/gpgrt-config (for the system). Awkwardly, the error message that I'm presented with tells me to use --with-libgpg-error-prefix... which I'm already passing ;P.

(FWIW, I believe this to be a new issue--maybe caused by [...]--as I did not have this issue with revision 1a83df98b198902ee6d71549231a3af37088d452, but do have it with cf88dca069915fe5f2945380add43d62cef31d1e. I also would easily believe I'm just misunderstanding something about how I'm expected to set up this configuration.)

checking for gpg-error-config... /Users/runner/work/orchid/orchid/app-ios/out-ios/arm64/usr/bin/gpg-error-config
checking for gpgrt-config... /usr/local/bin/gpgrt-config
configure: Use gpgrt-config with /usr/local/lib as gpg-error-config
checking for GPG Error - version >= 1.27... yes (1.41)
configure: WARNING:
***
*** The config script "/usr/local/bin/gpgrt-config --libdir=/usr/local/lib gpg-error" was
*** built for x86_64-apple-darwin19.6.0 and thus may not match the
*** used host aarch64-apple-darwin.
*** You may want to use the configure option --with-libgpg-error-prefix
*** to specify a matching config script or use $SYSROOT.
***

Event Timeline

saurik created this object in space S1 Public.
gniibe triaged this task as Normal priority.Mar 30 2021, 4:19 AM

We are in transition from old gpg-error-config to new gpgrt-config. <-- This is the cause, while I tried to cover most use cases.

Let me explain current status of libgpg-error and friends.

(Intended) typical use case for cross compilation is (example for MinGW):

configure --prefix=/PATH/TO/TARGET/LIKE/i686-w64-mingw32 --host=i686-w64-mingw32

Another typical use case for cross compilation with multi-arch is (example for ppc64el):

configure --includedir='${prefix}/include/powerpc64le-linux-gnu' --libdir='${exec_prefix}/lib/powerpc64le-linux-gnu' --host=powerpc64le-linux-gnu

That is, for new approach, we don't use target specific gpg-error-config and --with-libgpg-error-prefix any more.
gpgrt-config is common script, which support multi-arch.

IIUC, you can try something like an example of MinGW.

@gniibe The problem is that the check seems to just find gpgrt-config from the path; like, I'm already passing --prefix and --host, but it is deciding to just arbitrarily pick up my system-wide copy of /usr/local/bin/gpgrt-config. Here's my entire configure invocation from that earlier failed build: note that the --prefix is the same as --with-gpg-error-prefix.

cd out-ios/arm64/./vpn/shared/wsk/libgcrypt/ && /Users/runner/work/orchid/orchid/app-ios/vpn/shared/wsk/libgcrypt/configure --host=aarch64-apple-darwin --prefix=/Users/runner/work/orchid/orchid/app-ios/out-ios/arm64/usr CC="clang -miphoneos-version-min=11.0 -isysroot /Applications/Xcode_12.4.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.4.sdk -idirafter /Applications/Xcode_12.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/usr/include -arch arm64" CFLAGS=" -gfull -Os -fdebug-prefix-map=./= -fdebug-prefix-map=/Users/runner/work/orchid/orchid/app-ios=. -DPIC -fPIC -DCHROMIUM_ZLIB_NO_CHROMECONF" CXX="clang++ -miphoneos-version-min=11.0 -isysroot /Applications/Xcode_12.4.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.4.sdk -idirafter /Applications/Xcode_12.4.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk/usr/include -arch arm64" CXXFLAGS=" -gfull -Os -fdebug-prefix-map=./= -fdebug-prefix-map=/Users/runner/work/orchid/orchid/app-ios=. -DPIC -fPIC -DCHROMIUM_ZLIB_NO_CHROMECONF " RANLIB="ranlib" AR="ar" PKG_CONFIG="/Users/runner/work/orchid/orchid/app-ios/env/pkg-config" CPPFLAGS="" LDFLAGS=" " --enable-static --disable-shared  --disable-doc gcry_cv_gcc_aarch64_platform_as_ok=no --disable-asm ac_cv_func_getentropy=no --with-libgpg-error-prefix=/Users/runner/work/orchid/orchid/app-ios/out-ios/arm64/usr

(To be clear, I also know enough about autoconf to not have been like, blocked from upgrading by this: overriding ac_cv_path_GPGRT_CONFIG worked, but I can't believe that's the intended way for someone to ensure they get the correct path for gpgrt-config ;P.)

If it is new, it may be the change of this commit rC8e3cd4c4677c: build: Update gpg-error.m4.

It tries to find the pkg-config directory for the target.

I think that the way it is implemented in gpg-error.m4 doesn't work in your case.
Could you please help me to improve?

IIUC, configure process fails to find correct gpgrt_libdir for the target.

--libdir=/usr/local/lib is wrong, it's for your native compilation.

Currently, it prefers possible_libdir1 to possible_libdir0 but it's not good for your use case.

I wonder if this works in your use case:

diff --git a/m4/gpg-error.m4 b/m4/gpg-error.m4
index d910754e..aeedaf10 100644
--- a/m4/gpg-error.m4
+++ b/m4/gpg-error.m4
@@ -65,7 +65,7 @@ AC_DEFUN([AM_PATH_GPG_ERROR],
   min_gpg_error_version=ifelse([$1], ,1.33,$1)
   ok=no
 
-  AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no)
+  AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no, [$prefix/bin:$PATH])
   if test "$GPGRT_CONFIG" != "no"; then
     # Determine gpgrt_libdir
     #

@gniibe Ah yeah, that was the commit I meant to reference when I said "--maybe caused by --", but then forgot to go back and fill in the commit hash ;P.

So, this has fixed the detection of gpgrt-config, but has caused a new issue:

checking for gpg-error-config... /Users/saurik/orchid/app-ios/out-ios-orc/arm64/usr/bin/gpg-error-config
checking for gpgrt-config... /Users/saurik/orchid/app-ios/out-ios-orc/arm64/usr/bin/gpgrt-config
sed: 1: "/^libraries/{s/librarie ...": bad flag in substitute command: '}'
configure: Use gpgrt-config with /Users/saurik/orchid/app-ios/out-ios-orc/arm64/usr/lib as gpg-error-config

I see the offending command in gpg-error.m4:

sed -n -e "/^libraries/{s/libraries: =//;s/:/\n/gp}"

That should be (both semicolons are necessary):

sed -n -e "/^libraries/{s/libraries: =//;s/:/\n/g;p;}"

FWIW, I'd rather recommend doing this instead:

sed -n -e "/^libraries: =/{s///;p;}"

@gniibe Actually, I just realized that neither of the commands I provided work, as I failed to notice you were trying to also replace :'s with newlines (as I guess libraries from clang can return multiple paths). I'd momentarily edited my comment to just try to add back your colon replacement, before remembering you can't do that either: \n is a GNU sed extension. Hilariously, I'm always in contexts where I can assume I'm using bash (which isn't ok for configure), so I've never bothered to learn a technique that doesn't involve $'\n'... do you have a strategy for doing this replacement? :(

@gniibe OK, so... "worst case": I guess this worked? ;P

sed -n -e "`printf '/^libraries: =/{s///;s/:/\\\\\n/g;p;}'`"

(Six backslashes also works... I'd likely even prefer that.)

Thank you. Sorry for the use of GNU sed extension. It could be just a whitespace, if it's OK not to support path having a space.
sed -n -e "/^libraries/{s/libraries: =//;s/:/ /gp}") should work.

Or, if we keep the code of newline (so that it will eventually support path with a space in future):

diff --git a/m4/gpg-error.m4 b/m4/gpg-error.m4
index d910754e..da5df93c 100644
--- a/m4/gpg-error.m4
+++ b/m4/gpg-error.m4
@@ -65,7 +65,7 @@ AC_DEFUN([AM_PATH_GPG_ERROR],
   min_gpg_error_version=ifelse([$1], ,1.33,$1)
   ok=no
 
-  AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no)
+  AC_PATH_PROG(GPGRT_CONFIG, gpgrt-config, no, [$prefix/bin:$PATH])
   if test "$GPGRT_CONFIG" != "no"; then
     # Determine gpgrt_libdir
     #
@@ -80,7 +80,8 @@ AC_DEFUN([AM_PATH_GPG_ERROR],
     #   Fedora/openSUSE style: /usr/lib, /usr/lib32 or /usr/lib64
     # It is assumed that CC is specified to the one of host on cross build.
     if libdir_candidates=$(${CC:-cc} -print-search-dirs | \
-          sed -n -e "/^libraries/{s/libraries: =//;s/:/\n/gp}"); then
+          sed -n -e "/^libraries/{s/libraries: =//;s/:/\
+/gp}"); then
       # From the output of -print-search-dirs, select valid pkgconfig dirs.
       libdir_candidates=$(for dir in $libdir_candidates; do
         if p=$(cd $dir 2>/dev/null && pwd); then

@gniibe Note that you also need to at least add the semicolons, as BSD sed is trying to parse "gp}" as substitution flags (which, honestly, makes more forward-compatible sense than GNU sed's behavior...).

A PATH with spaces is too Windowish (or macOS). IIRC, we had once checks that the used directories have proper names; we can expect this for build environment. Spaces in file names are horrible from a security POV it is just to easy to get things wrong (hello ssh).

I was wrong in my last comment. Escaping by another \ is needed.

Anyhow, I applied the patch and pushed it to libgpg-error, libgcrypt, and gnupg.

gniibe changed the task status from Open to Testing.Apr 12 2021, 6:13 AM
gniibe added a project: Testing.
gniibe removed a project: Testing.

If it is new, it may be the change of this commit rC8e3cd4c4677c: build: Update gpg-error.m4.

This assumes pkg-config resides on Unix file system in root (/). Not only is this incompatible with Windows, it is also incompatible with any dependency manager that would install the dependencies into a relative folder, just like vcpkg does.

It tries to find the pkg-config directory for the target.

What this should do, first and foremost, is to check in all of the folders defined by the PKG_CONFIG_PATH variable. This is what pkg-config themselves mandate, it is used commonly and it can be expected that any non-standard location of the .pc files will defined by this variable.

Let me clarify the use case of gpg-error.m4.

gpg-error.m4 is for GnuPG and its friends, where we cannot assume availability of pkg-config. Its capability is limited, and we don't pursue 100% compatibility of pkg-config.

We do this way, because GnuPG and its friends are needed in early stage of OS bootstrap, like just after toolchain availability.

For your project in general, when 100% compatibility is needed, you can simply use pkg.m4 and pkg-config to find libgpg-error.

@gnilbe

Let me clarify the use case of gpg-error.m4.

gpg-error.m4 is for GnuPG and its friends, where we cannot assume availability of pkg-config. Its capability is limited, and we don't pursue 100% compatibility of pkg-config.

This is understandable and fair.

For your project in general, when 100% compatibility is needed, you can simply use pkg.m4 and pkg-config to find libgpg-error.

vcpkg is not my personal project where I have a choice of using pkg-config. It is a dependency manager tool, and I am a contributor there who provided libgpg-error, libgcrypt and gpgme ports (think: recipies). It uses vanilla build system to an extent possible – in your case your own autotools scripts, with your bespoke macros, except for Windows, where we currently use ShiftMediaProject forks of your projects for some of them, while others remain unsupported on Windows. We intend to change that.

My point is that, while you do not rely on pkg-config, you attempt to merely wild-guess a location of gpg-error.pc. Again, I understand you do that because pkg-config *may* be unavailable at an early OS bootstrapping phase, but it won't always be the case. It certainly isn't the case with vcpkg, which has a dependency on pkg-config tool. So gpg-error.m4 could, actually, perform a check if pkg-config executable is actually available and use it if so. If it is not, you could then check if PKG_CONFIG_PATH has any explicit paths defined and manually look for gpg-error.pc there. And if that is false, too, then you could proceed with your heuristics of trying to guess its location the way you do now.

Also, and I should maybe have opened with it, the issues vcpkg has with your build system are currently tracked here, while my effort to build gpg-error natively (i.e. without relying on ShiftMediaProject fork) on all platforms is here.