flavorjones / mini_portile

mini_portile and mini_portile2 - Simple autoconf and cmake builder for developers
MIT License
114 stars 51 forks source link

improve mkmf config #134

Closed flavorjones closed 1 year ago

flavorjones commented 1 year ago

the problem being addressed

v2.8.5.rc1 didn't work perfectly for Nokogiri (see https://github.com/sparklemotion/nokogiri/pull/2974). Specifically: if a system library like libxml2.so is installed in a default search path (e.g., this is the case for some system installations of ruby), then the linker dynamically links against the system library rather than statically linking against the packaged static archive.

the implementation

This PR is an attempt to fix that by asking the developer to pass in the name of the static archive when choosing to statically link. For example:

libxml2_recipe.mkmf_config(pkg: "libxml-2.0", static: "xml2")

In this case, MiniPortile will now:

This PR also makes sure to prepend to $libs instead of appending to it. (Since it now contains archive file paths, this seems like a sensible thing to do.) Finally, this also conditionally adds --static to the pkg-config flags only when a static build is requested with the static: kwarg to mkmf_config.

a note on the new parameter

It may be worth noting why we ask the developer to pass in the name of the static archive root (e.g., xml2 above). While it seems possible to infer the name of this file from the output of pkg-config, there's so much freedom in how packages can describe themselves in a pkg-config file that my confidence is low that we could handle all possible edge cases.

Just as an example, here's the libxml2 config file for a vanilla x86-64 linux system:

prefix=/home/flavorjones/code/oss/nokogiri/ports/x86_64-linux/libxml2/2.11.5
exec_prefix=${prefix}
libdir=/home/flavorjones/code/oss/nokogiri/ports/x86_64-linux/libxml2/2.11.5/lib
includedir=${prefix}/include
modules=1

Name: libXML
Version: 2.11.5
Description: libXML library version2.
Requires:
Libs: -L${libdir} -lxml2
Libs.private: -lz -llzma    -lm  
Cflags: -I${includedir}/libxml2 

A couple of notable things from this example:

The only place we can see the string we want, "xml2", is in the Libs section, however it's possible for multiple -l options to appear on this line, and pkg-config will emit dependencies' libraries as well when asking for --libs-only-l.

It seems best for the developer to just tell us that the libflag is -lxml2 and the static archive is libxml2.a by passing in static: "xml2".