Federico Mena Quintero
2018-02-07 00:38:01 UTC
Hi, everyone,
I'm trying to figure out why librsvg's build setup is broken for static
libraries. The automake/libtool machinery works fine to build
librsvg.la, but the resulting librsvg.a is broken.
Librsvg gets built from a bunch of .o files from C, and a
librsvg_internals.a library built by Rust/Cargo. Rust properly
compiles this internals library with PIC.
After the .o files and the librsvg_internals.a are built, we use
libtool in the usual fashion:
RUST_LIB=@abs_top_builddir@/rust/target/@RUST_TARGET_SUBDIR@/librsvg_internals.a
***@RSVG_API_MAJOR_VERSION@_la_LIBADD = \
$(LIBRSVG_LIBS) \
$(LIBM) \
$(RUST_LIB)
That is, LIBADD contains the librsvg_internals.a.
The resulting librsvg.la is built just fine. However, the static
librsvg.a is broken. For example, this is the output of "ar -t":
$ cd ~/src/librsvg
$ ar -t .libs/librsvg-2.a
librsvg_internals.a <- this is the Rust sub-library
librsvg_2_la-librsvg-enum-types.o
librsvg_2_la-librsvg-features.o
librsvg_2_la-rsvg-base-file-util.o
[... a bunch of other .o files here ...]
While I don't know all the details of how .a files are made from
libtool, it sounds like that librsvg_internals.a should really be
exploded into the individual .o files, and *those* put into the final
librsvg.a library.
Indeed if I have a tiny program foo.c:
#include <librsvg/rsvg.h>
int main(){
RsvgHandle *svg = rsvg_handle_new_from_data (NULL, 0, NULL);
}
and build it like this:
$ gcc -o foo foo.c `pkg-config --cflags librsvg-2.0` librsvg-2.a `pkg-
config --libs cairo-fc gobject-2.0 gio-2.0 libxml-2.0` -lm
it doesn't work; it gives me this output:
librsvg-2.a(librsvg_2_la-rsvg-base.o): In function `add_node_to_handle':
/home/federico/src/librsvg-latest/rsvg-base.c:207: undefined reference to `rsvg_node_ref'
librsvg-2.a(librsvg_2_la-rsvg-base.o): In function `node_set_atts':
/home/federico/src/librsvg-latest/rsvg-base.c:396: undefined reference to `rsvg_node_set_atts'
/home/federico/src/librsvg-latest/rsvg-base.c:402: undefined reference to `rsvg_node_get_type'
[... tons more of undefined symbols ...]
Those symbols are indeed in the librsvg_internals.a sub-library.
How can I make libtool create the toplevel librsvg.a correctly, out of
a bunch of .o files and a librsvg_internals.a library that is already
PIC-compiled?
(This also breaks --disable-shared for the configure script.)
Any suggestions are appreciated.
(For reference, this is mentioned in both
https://gitlab.gnome.org/GNOME/librsvg/issues/159 (Linux) and
https://github.com/Homebrew/homebrew-core/issues/23772 (MacOS)).
Thanks,
Federico
I'm trying to figure out why librsvg's build setup is broken for static
libraries. The automake/libtool machinery works fine to build
librsvg.la, but the resulting librsvg.a is broken.
Librsvg gets built from a bunch of .o files from C, and a
librsvg_internals.a library built by Rust/Cargo. Rust properly
compiles this internals library with PIC.
After the .o files and the librsvg_internals.a are built, we use
libtool in the usual fashion:
RUST_LIB=@abs_top_builddir@/rust/target/@RUST_TARGET_SUBDIR@/librsvg_internals.a
***@RSVG_API_MAJOR_VERSION@_la_LIBADD = \
$(LIBRSVG_LIBS) \
$(LIBM) \
$(RUST_LIB)
That is, LIBADD contains the librsvg_internals.a.
The resulting librsvg.la is built just fine. However, the static
librsvg.a is broken. For example, this is the output of "ar -t":
$ cd ~/src/librsvg
$ ar -t .libs/librsvg-2.a
librsvg_internals.a <- this is the Rust sub-library
librsvg_2_la-librsvg-enum-types.o
librsvg_2_la-librsvg-features.o
librsvg_2_la-rsvg-base-file-util.o
[... a bunch of other .o files here ...]
While I don't know all the details of how .a files are made from
libtool, it sounds like that librsvg_internals.a should really be
exploded into the individual .o files, and *those* put into the final
librsvg.a library.
Indeed if I have a tiny program foo.c:
#include <librsvg/rsvg.h>
int main(){
RsvgHandle *svg = rsvg_handle_new_from_data (NULL, 0, NULL);
}
and build it like this:
$ gcc -o foo foo.c `pkg-config --cflags librsvg-2.0` librsvg-2.a `pkg-
config --libs cairo-fc gobject-2.0 gio-2.0 libxml-2.0` -lm
it doesn't work; it gives me this output:
librsvg-2.a(librsvg_2_la-rsvg-base.o): In function `add_node_to_handle':
/home/federico/src/librsvg-latest/rsvg-base.c:207: undefined reference to `rsvg_node_ref'
librsvg-2.a(librsvg_2_la-rsvg-base.o): In function `node_set_atts':
/home/federico/src/librsvg-latest/rsvg-base.c:396: undefined reference to `rsvg_node_set_atts'
/home/federico/src/librsvg-latest/rsvg-base.c:402: undefined reference to `rsvg_node_get_type'
[... tons more of undefined symbols ...]
Those symbols are indeed in the librsvg_internals.a sub-library.
How can I make libtool create the toplevel librsvg.a correctly, out of
a bunch of .o files and a librsvg_internals.a library that is already
PIC-compiled?
(This also breaks --disable-shared for the configure script.)
Any suggestions are appreciated.
(For reference, this is mentioned in both
https://gitlab.gnome.org/GNOME/librsvg/issues/159 (Linux) and
https://github.com/Homebrew/homebrew-core/issues/23772 (MacOS)).
Thanks,
Federico