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

configure: strip -L/usr/lib and similar from netCDF, MySQL, GEOS and SFCGAL lib path #2395

Merged
merged 30 commits into from Apr 20, 2020

Conversation

eleaver
Copy link
Contributor

@eleaver eleaver commented Apr 9, 2020

Addresses bug #2357: In gdal/configure geos and netcdf library paths shadow local --with-proj. This PR changes configure.ac to strip explicit leading -L/usr/lib or -L/usr/lib64 from GEOS_LIBS and NETCDF_LIBS. Reran "autoconf configure.ac > configure" to update "configure" as well. BUT PLEASE NOTE my autoconf is version 2.69, NOT 2.70, therefore the new --runstatedir option introduced with autoconf-2.70 does not appear in the present configure. If this is an issue, either reject this PR, re-run autoconf-2.70 on the merged result if autoconf-2.70 is available, or otherwise make sure git merge retained the --runstatedir option in the merged result.

What does this PR do? (see above)

What are related issues/pull requests? bug #2357

Tasklist

I wished to use Gdal-3.0.4 and later on Fedora30, whose system proj package is 5.2.0 whereas gdal-3.x.y needs proj 6. So I compile and install /usr/local/proj-6.3.1 on both Fedora30 AND Fedora32 (beta), whose system proj is also 6.3.1, and verified that gdal autotests give identical results on Fedora32 when gdal is configured with either the system proj-6.3.1 or with the /usr/local/proj-6.3.1. So that part looks good.

Unfortunately, the autotest results on Fedora30 are not identical with those on Fedora32:

============================= test session starts ==============================
Fedora30 (up-to-date)
platform linux -- Python 3.7.6, pytest-3.10.1, py-1.7.0, pluggy-0.8.1
rootdir: /home/leaver/project/Grass/Requisites/gdal/git/GDAL/autotest, inifile: pytest.ini
plugins: sugar-0.9.2, env-0.6.2
collected 7064 items
71 failed, 5689 passed, 1302 skipped, 2 xfailed, 39 warnings in 1864.04 seconds
============================= test session starts ==============================
Fedora 32 (beta 1.2 up-to-date)
platform linux -- Python 3.8.2, pytest-4.6.9, py-1.8.0, pluggy-0.13.0
rootdir: /home/leaver/project/Grass/Requisites/gdal/git/GDAL/autotest, inifile: pytest.ini, testpaths: ogr, gcore, gdrivers, osr, alg, gnm, utilities, pyscripts
plugins: sugar-0.9.2, env-0.6.2
collected 7064 items
= 56 failed, 5636 passed, 1370 skipped, 2 xfailed, 22 warnings in 1390.74 seconds =
==========================================================================

Fedora32 fails fifteen fewer than Fedora30. It is not clear to me why. Any insight will be welcome. Thanks!

  • ADD YOUR TASKS HERE
  • Add test case(s)
  • Review
  • Adjust for comments
  • All CI builds and checks have passed

Environment

Provide environment details, if relevant:

  • OS: Fedora 30 and 32 on i2500K with Nvidia GTX960. Gdal configured --with-opencl and python3. (I can post my ConfigureGDAL.sh script if desired.)
  • Compilers: gcc-9.3.1 (fc30) and gcc-10.0.1 (beta fc32)

@rouault rouault changed the title Eleaver dev1 Stripped "-L/usr/lib64" from GEOS_LIBS and NETCDF_LIBS Apr 9, 2020
@rouault
Copy link
Member

rouault commented Apr 10, 2020

This might be insufficient for other OS. For example on Ubuntu

$ geos-config --libs
-L/usr/lib/x86_64-linux-gnu -lgeos-3.5.0

@eleaver
Copy link
Contributor Author

eleaver commented Apr 10, 2020 via email

@rouault
Copy link
Member

rouault commented Apr 10, 2020

Alternatively, one might wildly strip all -L/usr/lib64, -L/usr/lib64/* -L/usr/lib, -L/usr/lib/*

That seams reasonable to me

…sing and removal into new AC_DEFUN([STRIP_SYSTEM_LIBRARY_PATHS]) macro.

2. Added Ubuntu's /usr/lib/x86_64-linux-gnu to the list of system library paths removed.
3. If the XXX_LIBS being tested is NOT a system library path, the new STRIP_SYSTEM_LIBRARY_PATHS macro wraps its libdir portion in -Wl,-rpath=$libdir and prepends that to the output variable.
4. Added STRIP_SYSTEM_LIBRARY_PATHS($MYSQL_LIBS) so that path is cleaned up as well.
5. Separately test the proj installation directory, and prepend  -Wl,-rpath=$with_proj/lib (or lib64) if $with_proj is not / or /usr.

MYSQL_LIBS
…ervening whitespace between a system library path and any following non-system library path. Any whitespace left in this location would be included in the subsequent -Wl,-rpath=<path> insertion, leaving an invalid rpath directive.
@@ -1295,6 +1317,8 @@ else
fi
if test "$PROJ_FOUND" = "no"; then
AC_MSG_ERROR([PROJ 6 symbols not found])
elif test x$with_proj != x/usr -a x$with_proj != x/ ; then
Copy link
Member

Choose a reason for hiding this comment

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

At least for consistence with the rest of the code:

Suggested change
elif test x$with_proj != x/usr -a x$with_proj != x/ ; then
elif test "x$with_proj" != "x/usr" -a "x$with_proj" != "x/" ; then

@@ -1243,6 +1261,7 @@ else
fi
else
ORIG_LIBS="$LIBS"
proj_libdir=$with_proj/lib
Copy link
Member

Choose a reason for hiding this comment

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

At least for consistence with similar practice in that file

Suggested change
proj_libdir=$with_proj/lib
proj_libdir="$with_proj/lib"

(to adapt in similar cases)

@@ -10,6 +10,10 @@
*
*/

// For uselocale
Copy link
Member

@rouault rouault Apr 15, 2020

Choose a reason for hiding this comment

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

is this change really needed for this pull request ? I don't see the connection. I'd prefer to see it go through another one if possible
In ogr/ogrsf_frmts/geojson/libjson/GNUmakefile, we already have:

# -D_XOPEN_SOURCE=500 to enable strdup() definition in C11 mode
CPPFLAGS := -D_XOPEN_SOURCE=500 $(CPPFLAGS)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

At this point I believe it is necessary. But I don't know why. Last night I was seeing a "strdup undefined" error on OSX, with ld suggesting we #include <string.h>. But json_object.c does #include <string.h>. The problem appears to be that string.h on OSX defines strdup() only if _XOPEN_SOURCE >= 700L. And by default autoconf sets _XOPEN_SOURCE = 500L. So OSX strdup is undefined. Two obvious questions:

  1. Why did it fail last night, and not before? Did my (seemingly) unrelated changes to configure.ac trigger an _XOPEN_SOURCE change? git should know; I'll have to ask.
  2. If _XOPEN_SOURCE = 700L is indeed required, would it not be better to set it once in configure.ac, rather than in json_object.c, json_tokener.c etc.?
    Ref: https://lists.gnupg.org/pipermail/gnupg-devel/2017-February/032550.html

Is there a way to tag this PR a WIP (Work In Progress)? I'm still working on my new STRIP_SYSTEM_LIBRARY_PATHS macro, and it's likely it might pass all COIN build tests before we're both satisfied with it, and I wouldn't want to see it prematurely merged. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay. So configure sets #define _XOPEN_SOURCE 700; and ogr/ogrsf_frmts/geojson/libjson/GNUmakefile sets CPPFLAGS := -D_XOPEN_SOURCE=500 $(CPPFLAGS)

If you would like, I can try removing this line from this GNUmakefile, and the _XOPEN_SOURCE #definitions from json_object.c, json_tokener,c and see how it goes.

I agree it should be a separate issue and PR, but we need to get the present #2395 resolved as well, and the OSX strdup() appears to block it. I might be able to create another branch for the _XOPEN_SOURCE issue, fix it and test locally, and push to you before continuing with the present #2395. Depends on how easily I can subvert the proj shadow problem. I've recently installed Fedora-32 beta, and it's system proj is 6.3.1; I could work from there (later).

@rouault
Copy link
Member

rouault commented Apr 15, 2020

OSX seems to be unhappy with rpath: https://travis-ci.com/github/OSGeo/gdal/jobs/319537702 "ld: unknown option: -rpath=-L/usr/local/Cellar/geos/3.8.0/lib"

@eleaver
Copy link
Contributor Author

eleaver commented Apr 15, 2020

Thanks, I saw that geos rpath problem. I'll push a fix, but again please don't merge it yet should it pass.

@rouault rouault changed the title Stripped "-L/usr/lib64" from GEOS_LIBS and NETCDF_LIBS WIP/DO_NOT_MERGE: Stripped "-L/usr/lib64" from GEOS_LIBS and NETCDF_LIBS Apr 15, 2020
…_LIBRARY_PATHS macro, and applied the macro to SFCGAL_LIBS.
may be done by setting LDFLAGS in user's ConfigureGDA.sh script
2. Bumped -D_XOPEN_SOURCE=500 to -D_XOPEN_SOURCE=700 in
ogr/ogrsf_frmts/geojson/libjson/GNUmakefile to better please OSX
requirement for defining strdup().
3. Added #if ! defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 700 test in
json_tokener.c before #define _XOPEN_SOURCE 700
@rouault
Copy link
Member

rouault commented Apr 19, 2020

The failures on Travis-CI are unrelated to your changes, but to a temporary breakage on master. They should be solved by merging latest master into your branch

@eleaver
Copy link
Contributor Author

eleaver commented Apr 20, 2020

I've now removed the -Wl,-rpath[,=]$proj_libdir I had previously added to configure.ac. I did this because I can achieve the same or similar effect in my ConfigureGDAL.sh script by including

proj_libdir=/usr/local/proj-6.3.1/lib
export LDFLAGS+=" -Wl,-rpath=$proj_libdir -L$proj_libdir -lproj "

I do the same for GEOS, but still need to export LD_LIBRARY_PATH+=:/usr/local/geos-3.8.2/lib:
otherwise even with LDFLAGS+=" -Wl,-rpath -Wl,$geos_libdir, my Ubuntu_1804 ld won't find libgeos.so.3.8.2. I might re-visit rpath later, but for now what we've got fixes the original #2395 shadowing issue with minimal code changes, and with your approval should be good to merge.

There remains the _XOPEN_SOURCE=700 issue in ogr/ogrsf_frmts/geojson/libjson/. In GNUmakefile I simply changed the previous 500 value to 700, the wrapped the #define _XOPEN_SOURCE 700 with a #if ! defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 700 check in json_tokener.c, where it could likely just be removed.

On the one hand, I'd like to revert these changes and see if my builds again fail on OSX, or whether they succeed like everyone else's. And maybe just remove these _XOPEN_SOURCE settings -- both in GNUmakefile and json_tokener.c -- altogether and see if the build succeeds anyway. One might think it should. On the other, someone added that X_OPEN_SOURCE=500 assignment to GNUmakefile for a reason, and if we remove it completely we risk the build breaking for some customer somewhere on some obsolete system that is nonetheless still useful for them, even if the builds succeed on gdal's own Travis CI server.

My current thinking is that if _XOPEN_SOURCE needs to be set at all, it should be done in configure.ac after an AC_CHECK_FUNCS(strdup), similar to the current AC_CHECK_FUNCS(strtof). Under another issue number. By someone who actually has a Mac.

I think this PR is good to merge, but please review and let me know your thoughts. If you approve, we might avoid a bit of noise in the git log if I resubmit just the final result under a new PR from a new local dev branch, you review and merge that, then reject this one.

@rouault rouault merged commit bb87efe into OSGeo:master Apr 20, 2020
@rouault
Copy link
Member

rouault commented Apr 20, 2020

I've squashed down to a single commit and merged. Thanks

@rouault rouault changed the title WIP/DO_NOT_MERGE: Stripped "-L/usr/lib64" from GEOS_LIBS and NETCDF_LIBS configure: strip -L/usr/lib and similar from netCDF, MySQL, GEOS and SFCGAL lib path Apr 20, 2020
@eleaver
Copy link
Contributor Author

eleaver commented Apr 20, 2020

Thank you Even, and thanks for your patience with this.

@rouault
Copy link
Member

rouault commented Apr 28, 2020

@eleaver This seems to cause the issue reported to me by someone building the following Docker image based on quay.io/pypa/manylinux1_x86_64 : https://github.com/DanielFEvans/gdalmanylinux/blob/gdal_3.1.0/Dockerfile.wheels . The symptom is that GDAL linking line completely lacks the -lgeos_c

The relevant excerpt of the build log is:

checking for geos-config... /usr/local/bin/geos-config
checking for GEOS version >= 3.1.0... yes
checking for GEOSversion in -lgeos_c... yes
configure: Using C API from GEOS 3.8.1
sed: invalid option -- E
Usage: sed [OPTION]... {script-only-if-no-other-script} [input-file]...

  -n, --quiet, --silent
                 suppress automatic printing of pattern space
  -e script, --expression=script
                 add the script to the commands to be executed
  -f script-file, --file=script-file
                 add the contents of script-file to the commands to be executed
  -i[SUFFIX], --in-place[=SUFFIX]
                 edit files in place (makes backup if extension supplied)
  -c, --copy
                 use copy instead of rename when shuffling files in -i mode
		 (avoids change of input file ownership)
  -l N, --line-length=N
                 specify the desired line-wrap length for the `l' command
  --posix
                 disable all GNU extensions.
  -r, --regexp-extended
                 use extended regular expressions in the script.
  -s, --separate
                 consider files as separate rather than as a single continuous
                 long stream.
  -u, --unbuffered
                 load minimal amounts of data from the input files and flush
                 the output buffers more often
      --help     display this help and exit
      --version  output version information and exit

If no -e, --expression, -f, or --file option is given, then the first
non-option argument is taken as the sed script to interpret.  All
remaining arguments are names of input files; if no input files are
specified, then the standard input is read.

E-mail bug reports to: bonzini@gnu.org .
Be sure to include the word ``sed'' somewhere in the ``Subject:'' field.

Even my man page on Ubuntu 16.04 doesn't include -E . So either we can find a portable replacement for the regular expression, or we'll have to back it out

@rcoup
Copy link
Member

rcoup commented Apr 28, 2020

http://blog.dmitryleskov.com/small-hacks/mysterious-gnu-sed-option-e/

Fast forward a few minutes, and I have the answer: it is simply equivalent to “-r“!
/* Undocumented, for compatibility with BSD sed. */

@rouault
Copy link
Member

rouault commented Apr 28, 2020

Fast forward a few minutes, and I have the answer: it is simply equivalent to “-r“!

yep. Indeed a GNU vs BSD difference with recent versions of both understanding both possibilities, but not older ones (apparently quite recent Mac BSD sed still doesn't understand -r, whereas this older manylinux1 doesn't understand -E). Proposed PR fixing this in #2452

@DanielFEvans
Copy link
Contributor

Quick note to say that I've been able to compile RC2 successfully in that docker image - thanks.

(From what I've read, it's intentionally a very old environment to allow maximum cross-distro compatibility when generating Python packages)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants