xmake-io / xmake

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

set_kind("object") interfers with before_buildcmd_file resulting in undefined references #5426

Closed chriku closed 1 month ago

chriku commented 1 month ago

Xmake Version

2.9.4

Operating System Version and Architecture

Debian GNU/Linux trixie/sid, Windows 11 Home

Describe Bug

using a rule with before_buildcmd_file inside a target with set_kind("object") that has another target with set_kind("object") as dependency, as well as using the rule in the main target results in the generated object file not being linked.

I have confirmed that this affects (as used in my example) protobuf and capnproto, but did not test any other code generators

Expected Behavior

The object file should be added to the internal lists of object files in before_buildcmd_file, but instead before_buildcmd_file is executed after the object files have already been collected

Project Configuration

In the attached zip, the xmake.lua has a line add_deps("empty") -- Comment out this line. Commenting out this line results in successful compilation, not commenting out this line results in missing symbols

For demonstration purposes I have used the builtin protobuf module, but the same happens with capnproto. I have not tested it with completely custom rules

add_rules("mode.debug", "mode.release")
add_requires("protobuf-cpp")
set_languages("c++latest")

target("empty")
    set_kind("object")

target("a")
    set_kind("object")
    add_deps("empty") -- Comment out this line for successful compilation
    add_packages("protobuf-cpp")
    add_rules("protobuf.cpp")
    add_files("src/a.cpp")
    add_files("src/a.proto", {proto_rootdir = "src"})

target("b")
    set_kind("binary")
    add_deps("a")
    add_packages("protobuf-cpp")
    add_rules("protobuf.cpp")
    add_files("src/b.cpp")
    add_files("src/b.proto", {proto_rootdir = "src"})

Of course this happens also if empty has source files, but they aren't necessary for this issue to occur

Additional Information and Error Logs

xmake -vD does not contain anything related to this issue

I have tested it as well on a freshly installed windows 11 instance, but the appended zip should reproduce the error on all platforms

This may have connections to #2476, but seems different as this only appears with dependencies of kind "object".

waruqi commented 1 month ago

try this patch again. https://github.com/xmake-io/xmake/pull/5437

xmake update -s github:xmake-io/xmake#protobuf
chriku commented 1 month ago

The patch fixes it for protobuf and after porting it my larger project with capnproto also works (using my other capnproto WIP changes I have not opened a PR for yet). Thank you! But a quick search suggests that the identical pattern of table.insert(target:objectfiles(), objectfile) in *_buildcmd_file also appears in the rules for asn1c, qt/qrc, lex_yacc, qt/moc, ispc, capnproto, verilator, vala, cppfront and qt/qmltyperegistrar and most importantly the example in the docs. (this does not include the rules I don't understand).

waruqi commented 1 month ago

The patch fixes it for protobuf and after porting it my larger project with capnproto also works (using my other capnproto WIP changes I have not opened a PR for yet). Thank you! But a quick search suggests that the identical pattern of in also appears in the rules for , , , , , , , , and and most importantly the example in the docs. (this does not include the rules I don't understand).table.insert(target:objectfiles(), objectfile)``*_buildcmd_file``asn1c``qt/qrc``lex_yacc``qt/moc``ispc``capnproto``verilator``vala``cppfront``qt/qmltyperegistrar

Yes, but each change requires more testing, so I don't consider to modify them all for now because I can't guarantee that they will work well.