mattn / p5-Devel-CheckLib

check that a library is available
http://search.cpan.org/dist/Devel-CheckLib/
13 stars 22 forks source link

Provide a way to supply linker flags from the environment #31

Open fazalmajid opened 4 years ago

fazalmajid commented 4 years ago

My automated scripted builds of DBD::mysql failed because they added assert_lib to their Makefile.PL in 4.050 or thereabouts:

assert_lib(
  LIBS => ($opt->{'embedded'} ? $opt->{'embedded'} : $opt->{libs}),
);

and assert_lib neither honors LDFLAGS nor does it accept -L or -Wl,-R in LIBS to supply custom locations for the libraries and force their RPATH.

My work-around was to strip the assert_lib calls from DBD::mysql's Makefile.PL using a sed script, but you really need to provide a way, preferably through environment variables, to control or override flags in the build process.

ryandesign commented 3 years ago

Yes please. It is customary for CFLAGS and LDFLAGS to be set as environment variables. You should honor them. Here is a bug report from a MacPorts user who was unable to build DBD::mysql because of this problem. In macOS 10.14 and 10.15, the flags needed to build (specifically, the path to the directory that contains the OS headers (the "SDK")) changed in each major version of Xcode (annually). Now in macOS 11, the flags needed change in each minor version Xcode (every few months), so we need to be able to supply those flags to the build. It cannot be assumed that the flags that were used to build perl some time ago are the same flags that should be used to build anything now.

hakonhagland commented 3 years ago

assert_lib neither honors LDFLAGS nor does it accept -L or -Wl,-R in LIBS to supply custom locations for the libraries and force their RPATH

Here is some more information regarding this issue. I am on macOS (x86_64) Big Sur 11.2.3. I downloaded MySQL Community Server from here and then installed it into the custom location /usr/local/mysql-8.0.19-macos10.15-x86_64. I added /usr/local/mysql-8.0.19-macos10.15-x86_64/bin to the PATH environment variable such that mysql_config could be found.

I downloaded the Perl module DBD::mysql. This module uses Devel::CheckLib when I run perl Makefile.PL it finds the library paths by using mysql_config --libs but in order to run the binary generated by Devel::CheckLib::assert_lib() I need to set the environment variable

 DYLD_LIBRARY_PATH=/usr/local/mysql-8.0.19-macos10.15-x86_64/lib

since the library is not located in a standard location for the dynamic loader. However using DYLD_LIBRARY_PATH runs into this issue, which makes the make test fail as explained here. So my feeling is that instead of using DYLD_LIBRARY_PATH one should incorporate the path in the loaded binary using RPATH. That is: one should provide the linker flag -Wl,-rpath,/usr/local/mysql-8.0.19-macos10.15-x86_64/lib..

ryandesign commented 3 years ago

If /usr/local/mysql-8.0.19-macos10.15-x86_64/lib is the standard location where the MySQL installer installs its files, you should not need to set DYLD_LIBRARY_PATH to use them, and if you do, then that is a bug in the files that the MySQL installer is installing that you should report to MySQL. On the other hand, if the MySQL installer installed the files elsewhere and you moved them into /usr/local/mysql-8.0.19-macos10.15-x86_64/lib, then it's on you to fix each library's install_name and the cross references between the binaries and libraries using the install_name_tool program and then you don't need to use DYLD_LIBRARY_PATH either.

hakonhagland commented 3 years ago

@ryandesign Thanks for the comments.

and you moved them

I don't think I moved them. Still if I did, wouldn't it be easier for the user if he only had to update the PATH to include /usr/local/mysql-8.0.19-macos10.15-x86_64/bin (so Makefile.PL can find mysql_config).

then it's on you to fix each library's install_name and the cross references between the binaries and libraries using the install_name_tool program and then you don't need to use DYLD_LIBRARY_PATH either.

Maybe, but I was hoping for a simpler solution. There are two issues as I see it:

So my point is that the two steps above could maybe be avoided.

mohawk2 commented 2 years ago

@hakonhagland Does #35 (which is merged and now released, albeit the Changes file doesn't reflect) fix at least your aspect of this problem?

@fazalmajid How about you?

fazalmajid commented 2 years ago

No, I am still getting the error:

gtar zxf lang/perl/DBD-mysql-4.050.tar.gz
(cd DBD-mysql-4.050; env PATH=/usr/local/mysql/bin:$PATH  env OTHERLDFLAGS="-L/usr/local/lib -Wl,-R/usr/local/lib -L/usr/local/ssl/lib -Wl,-R/usr/local/ssl/lib -L/usr/local/mariadb/lib -Wl,-R/usr/local/mariadb/lib" /usr/local/bin/perl Makefile.PL --libs "-L/usr/local/lib -Wl,-R/usr/local/lib -L/usr/local/ssl/lib -Wl,-R/usr/local/ssl/lib -L/usr/local/mariadb/lib -Wl,-R/usr/local/mariadb/lib -lmariadb -lz -lssl -lcrypto -liconv")

PLEASE NOTE:

For 'make test' to run properly, you must ensure that the
database user 'majid' can connect to your MySQL server
and has the proper privileges that these tests require such
as 'drop table', 'create table', 'drop procedure', 'create procedure'
as well as others.

mysql> grant all privileges on test.* to 'majid'@'localhost' identified by 's3kr1t';

You can also optionally set the user to run 'make test' with:

perl Makefile.PL --testuser=username

I will use the following settings for compiling and testing:

  cflags        (mysql_config ) = -I/usr/local/mariadb/include/mysql -I/usr/local/mariadb/include/mysql/mysql
  embedded      (mysql_config ) = 
  libs          (User's choice) = -L/usr/local/lib -Wl,-R/usr/local/lib -L/usr/local/ssl/lib -Wl,-R/usr/local/ssl/lib -L/usr/local/mariadb/lib -Wl,-R/usr/local/mariadb/lib -lmariadb -lz -lssl -lcrypto -liconv
  mysql_config  (guessed      ) = mysql_config
  nocatchstderr (default      ) = 0
  nofoundrows   (default      ) = 0
  nossl         (default      ) = 0
  testdb        (default      ) = test
  testhost      (default      ) = 
  testpassword  (default      ) = 
  testport      (default      ) = 
  testsocket    (default      ) = 
  testuser      (guessed      ) = majid

To change these settings, see 'perl Makefile.PL --help' and
'perldoc DBD::mysql::INSTALL'.

Checking if libs are available for compiling...
LIBS argument badly-formed: -Wl,-R/usr/local/lib
mohawk2 commented 2 years ago

It looks like this snippet is doing its own validation of supplied args:https://github.com/mattn/p5-Devel-CheckLib/blob/a1db7f6568b3b903505505c255c7a72a7d5f8cae/lib/Devel/CheckLib.pm#L353-L364

I think what's needed is either for it to mimic ExtUtils::Liblist more closely, to directly use that (much better), or to stop doing such validation entirely (let the linker decide). Or at least to allow -W.