php / php-src

The PHP Interpreter
https://www.php.net
Other
38.01k stars 7.73k forks source link

configure does not detect GNU libiconv correctly #12213

Open eppesuig opened 1 year ago

eppesuig commented 1 year ago

Description

The following code:

I am running configure for compiling php 8.2.8 and, when checking if libiconv is available, I get this error message:

checking for mhash support... no
checking size of long... (cached) 8
checking if we're at 64-bit platform... yes
checking for iconv support... yes
checking for iconv... yes
checking if iconv is glibc's... no
checking if using GNU libiconv... no
checking if iconv is Konstantin Chuguev's... no
checking if using IBM iconv... no
checking if iconv supports errno... no
configure: error: iconv does not support errno

The final error message, about errno, is not really correct, since it is derived from all iconv preceeding lines failing. It seems that my iconv is not glibc, nor GNU, nor Chuguev, nor IBM. But my iconv installation is the GNU one, as shown here:

~ $ iconv --version
iconv (GNU libiconv 1.17)
Copyright (C) 2000-2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Bruno Haible.

So, since no iconv is detected, the linker does not add -liconv parameter, and the next conftest, the one about errno, fails because of link error:

configure:44279: checking if iconv supports errno
configure:44309: cc -o conftest  -I/data/data/com.termux/files/home/.termux-build/php/host-build/ext/date/lib -I/data/data/com.termux/files/home/.termux-build/php/src/ext/date/lib -g -O2 -fvisibility=hidden  -D_GNU_SOURCE   conftes
t.c -lrt -lm  >&5
ld.lld: error: undefined symbol: libiconv_open
>>> referenced by conftest.c:230
>>>               /data/data/com.termux/files/usr/tmp/conftest-a89be2.o:(main)

ld.lld: error: undefined symbol: libiconv_close
>>> referenced by conftest.c:238
>>>               /data/data/com.termux/files/usr/tmp/conftest-a89be2.o:(main)
clang-16: error: linker command failed with exit code 1 (use -v to see invocation)
configure:44309: $? = 1
configure: program exited with status 1
configure: failed program was:
[...]
| #define HAVE_UTIMES 1
| #define HAVE_STRNDUP 1
| #define SIZEOF_LONG 8
| #define HAVE_ICONV 1
| /* end confdefs.h.  */
| 
| #include <iconv.h>
| #include <errno.h>
| 
| int main() {
|   iconv_t cd;
|   cd = iconv_open( "*blahblah*", "*blahblahblah*" );
|   if (cd == (iconv_t)(-1)) {
|     if (errno == EINVAL) {
|       return 0;
|   } else {
|       return 1;
|     }
|   }
|   iconv_close( cd );
|   return 2;
| }
| 
configure:44317: result: no

Please note that there are no issues when looking for the iconv.h include file.

If I call the compiler manually, with same parameters plus -liconv then build and link are fine.

Resulted in this output:

checking for mhash support... no
checking size of long... (cached) 8
checking if we're at 64-bit platform... yes
checking for iconv support... yes
checking for iconv... yes
checking if iconv is glibc's... no
checking if using GNU libiconv... no
checking if iconv is Konstantin Chuguev's... no
checking if using IBM iconv... no
checking if iconv supports errno... no
configure: error: iconv does not support errno

But I expected this output instead:

Well, I suppose that GNU libiconv test should not fail, at very lest.

checking for mhash support... no
checking size of long... (cached) 8
checking if we're at 64-bit platform... yes
checking for iconv support... yes
checking for iconv... yes
checking if iconv is glibc's... no
checking if using GNU libiconv... yes
checking if iconv is Konstantin Chuguev's... no
checking if using IBM iconv... no
checking if iconv supports errno... no

PHP Version

8.2.8

Operating System

termux 0.118.0

eppesuig commented 1 year ago

Hello, I just added the LIBS variable definition before calling configure, and this made the iconv detection work:

env LIBS=-liconv ./configure ....
[...]
checking size of long... (cached) 8
checking if we're at 64-bit platform... yes
checking for iconv support... yes
checking for iconv... yes
checking if iconv is glibc's... no
checking if using GNU libiconv... 273yes
checking if iconv supports errno... yes
checking if iconv supports //IGNORE... yes
checking for IMAP support... no
checking for IMAP Kerberos support... no

Of course, this is not a patch, but it shows the problem.

Thank you, Giuseppe

devnexen commented 1 year ago

Maybe its config.m4 part needs to replace instances of AC_RUN_IFELSE by AC_COMPILE_IFELSE. @petk what do you think ?

eppesuig commented 1 year ago

Just for completeness, when adding the LIBS=-liconv variable to configure's environment, the build still fails when compiling: (output reformatted for readability)

/bin/sh /data/data/com.termux/files/home/.termux-build/php/host-build/libtool --silent \
  --preserve-dup-deps --tag CC --mode=compile cc -Iext/iconv/ \
  -I/data/data/com.termux/files/home/.termux-build/php/src/ext/iconv/ \
  -I/data/data/com.termux/files/home/.termux-build/php/host-build/include \
  -I/data/data/com.termux/files/home/.termux-build/php/host-build/main \
  -I/data/data/com.termux/files/home/.termux-build/php/src \
  -I/data/data/com.termux/files/home/.termux-build/php/host-build/ext/date/lib \
  -I/data/data/com.termux/files/home/.termux-build/php/src/ext/date/lib \
  -I/data/data/com.termux/files/home/.termux-build/php/host-build/TSRM \
  -I/data/data/com.termux/files/home/.termux-build/php/host-build/Zend \
  -I/data/data/com.termux/files/home/.termux-build/php/src/main \
  -I/data/data/com.termux/files/home/.termux-build/php/src/Zend \
  -I/data/data/com.termux/files/home/.termux-build/php/src/TSRM \
  -I/data/data/com.termux/files/home/.termux-build/php/host-build/ \
  -D_GNU_SOURCE  -fno-common -Wstrict-prototypes -Wall -Wextra -Wno-strict-aliasing \
  -Wno-unused-parameter -Wno-sign-compare -g -O2 -fvisibility=hidden -DZEND_SIGNALS  \
  -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 \
  -c /data/data/com.termux/files/home/.termux-build/php/src/ext/iconv/iconv.c \
  -o ext/iconv/iconv.lo  -MMD -MF ext/iconv/iconv.dep -MT ext/iconv/iconv.lo

/data/data/com.termux/files/home/.termux-build/php/src/ext/iconv/iconv.c:363:8: error: call to undeclared function 'iconv'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
                        if (iconv(cd, (char **)&in_p, &in_left, (char **) &out_p, &out_left) == (size_t)-1) {
                            ^
/data/data/com.termux/files/home/.termux-build/php/src/ext/iconv/iconv.c:388:8: error: call to undeclared function 'iconv'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
                        if (iconv(cd, NULL, NULL, (char **) &out_p, &out_left) == (size_t)0) {
[...]
romanovj commented 1 year ago

/data/data/com.termux/files/home/.termux-build/php/src/ext/iconv/iconv.c

#ifdef HAVE_LIBICONV
#undef iconv
#endif
eppesuig commented 1 year ago

Hello @romanovj , I saw this strange line of code, but I think HAVE_LIBICONV isn't defined, so I did not worry about it. In fact, in the compiler command line shown above, there are no defined symbols. The compiler is not called will any iconv defines, so the correct include is missed, and the compilation fails.

romanovj commented 1 year ago

@eppesuig LIBS=-liconv is what leads to HAVE_LIBICONV=1

eppesuig commented 1 year ago

@romanovj But there is no -DHAVE_LIBICONV in the command line of the compiler. Where does the compiler get it from ? The error message is emitted while compiling, not while linking.

romanovj commented 1 year ago

in configure file

/data/data/com.termux/files/home/.termux-build/php/src/configure

printf "%s\n" "#define HAVE_LIBICONV 1" >>confdefs.h

eppesuig commented 1 year ago

I still do not understand, sorry. The line you are referring to is related to the configuration stage, when conftest.c little programs are created and executed. But the error message from the compiler is shown after the configuration stage. The src/ext/iconv/iconv.c source file does not uses conftest.h.

romanovj commented 1 year ago

@eppesuig iconv.c ...

include "php.h"

...

php.h ...

include "php_compat.h"

...

php_compat.h ...

include

...

php_config.h /data/data/com.termux/files/home/.termux-build/php/host-build/main/php_config.h ...

... Generated from php_config.h.in by configure. */

... / Whether libiconv is used /

define HAVE_LIBICONV 1

...


just delete these three lines and you will see next error

#ifdef HAVE_LIBICONV
#undef iconv
#endif

/data/data/com.termux/files/home/.termux-build/php/src/ext/standard/dns.c:419:6: error: call to undeclared function 'res_ninit'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] if (res_ninit(handle)) {

devnexen commented 1 year ago

@eppesuig how do you set your configure step ? Is it something approaching like the termux's php package ? note that the package has a list of patches (not for iconv tough) also editing the config afterwards.

eppesuig commented 1 year ago

@devnexen I am referring to the standard php package in termux, without any change. The shipped package has a problem since it does not load PHP extensions when run in apache2. One possible solution would be to rebuild the same package with the device toolchain instead of the crossbuilder one. When building the php package on the device, I get the error shown here since the device iconv is GNU one, while the crosscompiler iconv is libc one.

For some more details have a look at termux bug report, here.

Thank you

petk commented 1 year ago

Hello, yes, the libiconv does cause issues on many systems. Confirming. The library needs to be set for the check before that GNU libiconv check. Somewhere along the changes they got dropped (LDFLAGS="-liconv $LDFLAGS") in favor of the other sets. @devnexen, yes, it seems the compilation could be enough. I'll check...

petk commented 10 months ago

I've rechecked this a bit and the main issue here is that when using the --with-iconv it will detect the iconv built into the C library on the system. When using the --with-iconv=/usr or the --with-iconv=$TERMUX_PREFIX like in the build package, the GNU library will be detected (or the implementation that is installed at that place). Which is kind of ok.

# build/php.m4
dnl Check libc first if no path is provided in --with-iconv.

On Alpine Linux similar adjustment is done here and there and --with-iconv=/usr is used to use the gnu-libiconv package instead of the C library.

petk commented 6 months ago

Sorry for bumping the issue with on-the-first-glance unrelated info but I've noticed another issue with the iconv extension and package installation on FreeBSD, for example. There are two iconv.h header files. One in /usr/include/iconv.h (libc) and one in /usr/local/include/iconv.h (libiconv). On many systems (BSD-based systems and macOS) then the iconv errno sanity check fails. I'm still not sure yet how to fix this properly without rewriting quite a bit of the PHP_SETUP_ICONV part and flags handling.