xmake-io / xmake

🔥 A cross-platform build utility based on Lua
https://xmake.io
Apache License 2.0
10.04k stars 785 forks source link

Order of links of library installed via xrepo is wrong #3040

Closed PucklaJ closed 1 year ago

PucklaJ commented 1 year ago

Xmake Version

2.6.8

Operating System Version and Architecture

Garuda Linux

Describe Bug

I am using the library dynareadout in a project and when linking the final executable a lot of unresolved references pop up:

/home/johnny/.xmake/packages/d/dynareadout/0.3/58f01c40deca4fe98f318f76a4a49452/lib/libd3plot_cpp.a(d3plot.cpp.o): in function `dro::D3plot::D3plot(std::filesystem::__cxx11::path const&)':
d3plot.cpp:(.text+0xee): undefined reference to `d3plot_open'
/usr/bin/ld: d3plot.cpp:(.text+0x1db): undefined reference to `d3plot_close'
/usr/bin/ld: /home/johnny/.xmake/packages/d/dynareadout/0.3/58f01c40deca4fe98f318f76a4a49452/lib/libd3plot_cpp.a(d3plot.cpp.o): in function `dro::D3plot::~D3plot()':
d3plot.cpp:(.text+0x245): undefined reference to `d3plot_close'
/usr/bin/ld: /home/johnny/.xmake/packages/d/dynareadout/0.3/58f01c40deca4fe98f318f76a4a49452/lib/libd3plot_cpp.a(d3plot.cpp.o): in function `dro::D3plot::read_node_ids()':
d3plot.cpp:(.text+0x273): undefined reference to `d3plot_read_node_ids'
/usr/bin/ld: /home/johnny/.xmake/packages/d/dynareadout/0.3/58f01c40deca4fe98f318f76a4a49452/lib/libd3plot_cpp.a(d3plot.cpp.o): in function `dro::D3plot::read_solid_element_ids()':
d3plot.cpp:(.text+0x2e3): undefined reference to `d3plot_read_solid_element_ids'
...

This is because the order of the links is wrong:

-lbinout -ld3plot -ld3plot_cpp -lbinout_cpp

It should be:

-ld3plot_cpp -lbinout_cpp -lbinout -ld3plot 

The cpp libraries should be before the other ones because they depend on them. If I build dynareadout directly you can see, when building the tests, that the order is correct:

[ 86%]: linking.debug binout_test
/usr/bin/g++ -o build/linux/x86_64/debug/binout_test build/.objs/binout_test/linux/x86_64/debug/test/binout_test.cpp.o -m64 -Lbuild/linux/x86_64/debug -lbinout_cpp -lbinout
[ 86%]: linking.debug d3plot_test
/usr/bin/g++ -o build/linux/x86_64/debug/d3plot_test build/.objs/d3plot_test/linux/x86_64/debug/test/d3plot_test.cpp.o -m64 -Lbuild/linux/x86_64/debug -ld3plot_cpp -ld3plot

You can also see that the order of the links is wrong when installing the library with xrepo install -v dynareadout during the test:

> checking for c++ links(d3plot, binout, binout_cpp, d3plot_cpp)

Expected Behavior

When a library gets installed using import("package.tools.xmake").install(package, configs) xmake should correctly determine which target depends on which and therefor correctly order the links.

Project Configuration

xmake.lua:

add_requires("dynareadout")

target("link_order")
  set_kind("binary")
  add_packages("dynareadout")
  add_files("link_order.cpp")

link_order.cpp:

#include <binout.hpp>

int main(void) {
  dro::Binout binout_file("binout");
  binout_file.variable_exists("/nodout/metadata/ids");
  return 0;
}

Additional Information and Error Logs

No response

waruqi commented 1 year ago

you can use add_links("xxx", "yy") in package() to fix link order.

like this https://github.com/xmake-io/xmake-repo/blob/3fe2cf293ddf525aa9d43d3f0d759c7b712ce5c9/packages/m/mbedtls/xmake.lua#L14

waruqi commented 1 year ago

https://github.com/xmake-io/xmake-repo/pull/1610

xrepo update-repo
xrepo remove --all -y dynareadout
xmake f -c
xmake