xmake-io / xmake

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

add deps invalid #5791

Closed star-hengxing closed 1 day ago

star-hengxing commented 1 week ago

Xmake Version

dev

Operating System Version and Architecture

Windows

Describe Bug

git clone https://github.com/lhmouse/mcfgthread.git
# cp xmake.lua
# cp version.h to builddir
xmake f -c -p mingw
xmake
xmake test -v

version.h

#ifndef __MCFGTHREAD_VERSION_
#define __MCFGTHREAD_VERSION_

#define _MCF_ABI_VERSION_MAJOR    1
#define _MCF_ABI_VERSION_MINOR    10
#define _MCF_ABI_VERSION_STRING   "1.10.alpha"

#endif  /* __MCFGTHREAD_VERSION_  */

Expected Behavior

Work.

meson setup builddir
meson compile -C builddir

Project Configuration

test target -> add_rule(test) -> target:add("deps", dep)

set_project("mcfgthread")
set_xmakever("2.9.6")
set_description("Cornerstone library for C++11 threading on mingw-w64")
set_license("LGPL-3.0-or-later WITH GCC-exception-3.1")

set_allowedplats("windows", "mingw", "msys")
set_languages("c99", "c++11")
set_warnings("more")

add_rules("mode.debug", "mode.release")

add_cxflags("-masm=intel")
if is_arch(".*86") then
    add_cxflags("-msse2", "-mfpmath=sse")
    if is_plat("windows") then
        add_defines("__i386__")
    end
elseif is_arch(".*64") then
    add_cxflags("-mcmodel=small")
    if is_plat("windows") then
        add_defines("_AMD64_")
    end
end

add_defines("_WIN32_WINNT=0x0601", "__USE_MINGW_ANSI_STDIO")
add_undefines("_FORTIFY_SOURCE")
add_cxflags(
    "-fno-stack-protector", "-fstrict-aliasing", "-ffast-math", "-fno-ident",
    "-fno-omit-frame-pointer", "-Werror=conversion", "-Werror=sign-compare",
    "-Werror=sign-conversion", "-Werror=write-strings", "-Werror=return-type",
    "-Werror=double-promotion", "-Wmissing-declarations", "-Wswitch-enum",
    "-Wmissing-field-initializers", "-Wsuggest-attribute=noreturn", "-Wshadow",
    "-Wunused-function", "-Wunused-label", "-Wunused-local-typedefs",
    "-Wunused-but-set-variable", "-Wunused-but-set-parameter",
    "-Wunused-const-variable", "-Wno-unused-command-line-argument",
    "-Wno-dll-attribute-on-redeclaration"
)

if is_mode("debug") then
    add_cxflags("__MCF_DEBUG")
end

add_includedirs(os.projectdir())
add_includedirs("builddir")

rule("mcfgthread-build")
    on_config(function (target)
        local src_full = {"gthr.c", "gthr_libobjc.c", "c11.c", "libcxx.c"}

        if target:is_static() then
            target:add("files", "mcfgthread/*.c")
        elseif target:is_object() then
            target:add("files", "mcfgthread/*.c|" .. table.concat(src_full, "|"))
            target:add("defines", "__MCF_BUILDING_DLL")
            target:add("cxflags", "-fPIC")
        elseif target:is_shared() then
            target:add("deps", "mcfgthread-object")
            if not target:name():endswith("minimal") then
                for _, file in ipairs(src_full) do
                    target:add("files", path.join("mcfgthread", file))
                end
            end
        end

        if target:is_plat("windows") then
            target:add("deps", "mcfgthread-crt")
            local src_crt = target:dep("mcfgthread-crt"):get("files")
            target:remove("files", src_crt)
        end

        target:add("cflags", "-ffreestanding", "-fasynchronous-unwind-tables")
        target:set("pcheader", "mcfgthread/xprecompiled.h")
        target:add("syslinks", "kernel32", "ntdll")

        if target:is_shared() then
            target:add("defines", "__MCF_BUILDING_DLL")
            target:add("deps", "mcfgthread-version")
            -- TODO: soname
            target:set("suffixname", "-1")

            if target:has_tool("sh", "gcc", "gxx") then
                target:add("shflags", 
                    "-nostdlib", "-Wl,--entry,__MCF_dll_startup@@Z", "-Wl,--gc-sections",
                    "-Wl,--enable-auto-image-base", "-Wl,--subsystem,windows:6.1",
                    "-Wl,--exclude-all-symbols", "-Wl,--kill-at", {force = true})
            end

            if target:is_plat("windows") then
                -- TODO: msvc linker unsupported `-subsystem:windows,6.1`, use editbin?
                local msvc_link_flags = {"-entry:__MCF_dll_startup@@Z", "-EMITPOGOPHASEINFO"}
                if target:has_tool("sh", "clang", "clangxx") then
                    for i, flag in ipairs(msvc_link_flags) do
                        msvc_link_flags[i] = "-Wl," .. flag
                    end
                end
                target:add("shflags", msvc_link_flags, {force = true})
            end
        end
    end)

target("mcfgthread-version")
    set_kind("object")
    add_files("mcfgthread/*.rc")
    -- add_configfiles("mcfgthread/version.h.in", {pattern = "@(.-)@"})

target("mcfgthread-object")
    set_kind("object")
    add_rules("mcfgthread-build")

if is_plat("windows") then
-- https://github.com/llvm/llvm-project/issues/55329
    target("mcfgthread-crt")
        set_kind("object")
        add_files(
            "mcfgthread/memcpy.c",
            "mcfgthread/memmove.c",
            "mcfgthread/memset.c"
        )

        set_toolchains("msvc")
end

target("mcfgthread-minimal")
    set_kind("shared")
    add_rules("mcfgthread-build")

target("mcfgthread")
    set_kind("shared")
    add_rules("mcfgthread-build")

target("mcfgthread-static")
    set_kind("static")
    add_rules("mcfgthread-build")

for _, file in ipairs(os.files("test/*.c")) do
    target(path.basename(file))
        set_default(false)
        add_rules("test")
        add_files(file)
        add_tests("default")
end

for _, file in ipairs(os.files("test/*.cpp")) do
    if not path.basename(file) == "gthr_cxx98_pedantic" then
        target(path.basename(file) .. "_cpp")
            set_default(false)
            add_rules("test")
            add_files(file)
            add_tests("default")

            add_ldflags("-static-libgcc")
            set_runtimes("stdc++_static")
    end
end

rule("test")
    on_config(function (target)
        target:set("kind", "binary")
        target:add("syslinks", "user32")

        local dep = "mcfgthread"
        local name = target:name()
        for _, i in ipairs({"win8", "win10", "self_oom", "mix", "tls_dtor_static"}) do
            if i == name then
                dep = "mcfgthread-static"
                break
            end
        end

        if name == "memory" then
            dep = "mcfgthread-minimal"
        end

        target:add("deps", dep)

        if name == "gthr_c89_pedantic" then
            target:set("languages", "c89")
            target:add("cxflags", "-Wpedantic", "-Wno-variadic-macros",
                "-Wno-long-long", "-Werror=declaration-after-statement", "-Wno-c99-extensions")
        end

        if name == "gthr_cxx98_pedantic" then
            target:set("languages", "c++98")
            target:add("cxflags", "-Wpedantic", "-Wno-variadic-macros",
                "-Wno-long-long", "-Wno-zero-as-null-pointer-constant", "-Wno-c++11-extensions")
        end

        if name == "c11_c99_pedantic" then
            target:set("languages", "c99")
            target:add("cxflags", "-Wpedantic")
        end

        if name == "cxx11_no_exceptions" then
            target:set("languages", "c++11")
            target:add("cxflags", "-fno-rtti", "-fno-exceptions")
        end

        if name == "cxx11_pedantic" then
            target:set("languages", "c++11")
            target:add("cxflags", "-Wpedantic")
        end

        if name == "cxx14_pedantic" then
            target:set("languages", "c++14")
            target:add("cxflags", "-Wpedantic")
        end

        if name:startswith("shared_mutex_") then
            target:set("languages", "c++17")
        end

        if name:startswith("shared_timed_mutex_") then
            target:set("languages", "c++14")
        end

        if name == "runtime_failure" then
            -- TODO: value?
            -- target:add("runenvs", "_MCF_RUNTIME_FAILURE_TEST_ERROR", "0")
        end
    end)

Additional Information and Error Logs

C:\msys64\mingw64\bin\x86_64-w64-mingw32-g++ -o build\mingw\x86_64\release\tls_dtor_static.exe build\.objs\tls_dtor_static\mingw\x86_64\release\test\tls_dtor_static.c.obj -m64 -s -luser32
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: build\.objs\mix\mingw\x86_64\release\test\mix.c.obj:mix.c:(.text.startup+0x9d): undefined reference to `_MCF_tls_key_new'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: build\.objs\mix\mingw\x86_64\release\test\mix.c.obj:mix.c:(.text.startup+0xa5): undefined reference to `_MCF_thread_self'
C:/msys64/mingw64/biCn/../l:/msysib/gc64c/x86_64-w64-mingw32/14.2.0//m../..ingw64/bin/../lib/../../gcc/x86_64-w64-mingw32/14.2.0/../../../x86_64-w64-ming/..w3/2/bin/x86_64-w64-mingw32ld.exe/bin/ld.e:xe :b uild\.objs\mibx\mingw\xu86_64\releaiseld\.o\test\mbjs\self_oom\minixgw\x86_64\.c.objrele:Camse:/msys64/mingw64/bini\/../txlib/gcc/xest\self86_64-w64-mi_ongw.om.c.objc:3:2(/14s..2elft.0/../../../../x86_64-w64-ext.startup_mingw32/bin/ld.exe+oom.c0x::b(b .)btext.star:utup ui+ndefined reference tl0xd\o `.objs\tls_dtor_static\mingw\x86_64\release\test\tls_dtor_sta_3tic.c.obj_7M:C)Ft_tls_tablls_dtor_e:stati: u(n_xset.defined reference 'text
t+o `0x_1_MCF_crt8_heap)':
 undefined reference to `_MCF_sem_wait'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: build\.objs\tls_dtor_static\mingw\x86_64\release\test\tls_dtor_static.c.obj:tls_dtor_stati:(.text+collect2.exe: error: ld returned 1 exit status
0x1d): undefined reference collect2.exe: error: ld returned 1 exit status
to `_MCF_thread_self'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: build\.objs\tls_dtor_static\mingw\x86_64\release\test\tls_dtor_static.c.obj:tls_dtor_stati:(.text+0x3a): undefined reference to `__MCF_tls_table_xset'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: build\.objs\tls_dtor_static\mingw\x86_64\release\test\tls_dtor_static.c.obj:tls_dtor_stati:(.text.startup+0x34): undefined reference to `_MCF_tls_key_new'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: build\.objs\tls_dtor_static\mingw\x86_64\release\test\tls_dtor_static.c.obj:tls_dtor_stati:(.text.startup+0x4c): undefined reference to `_MCF_thread_new_aligned'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: build\.objs\tls_dtor_static\mingw\x86_64\release\test\tls_dtor_static.c.obj:tls_dtor_stati:(.text.startup+0x9b): undefined reference to `_MCF_sem_signal_some'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/14.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: build\.objs\tls_dtor_static\mingw\x86_64\release\test\tls_dtor_static.c.obj:tls_dtor_stati:(.text.startup+0xa7): undefined reference to `_MCF_thread_wait'
collect2.exe: error: ld returned 1 exit status
error: execv(C:\msys64\mingw64\bin\x86_64-w64-mingw32-g++ -o build\mingw\x86_64\release\mix.exe build\.objs\mix\mingw\x86_64\release\test\mix.c.obj -m64 -s -luser32) failed(1)
star-hengxing commented 5 days ago
$ xmake l cli.bisect -g v2.9.3 -b dev --gitdir=A:/project/xmake/xmake -c "xmake test"
daaf89c5108e92db407532f3002493d071f9e88f is the first bad commit
commit daaf89c5108e92db407532f3002493d071f9e88f
Author: ruki <waruqi@gmail.com>
Date:   Tue Jul 2 22:51:34 2024 +0800

    fix load targets repeatly #5288

 xmake/actions/test/main.lua                                |  3 ---
 xmake/core/sandbox/modules/import/core/project/project.lua | 12 ++++++------
 xmake/plugins/pack/main.lua                                |  3 ---
 3 files changed, 6 insertions(+), 12 deletions(-)
waruqi commented 2 days ago

这边没法复现,给个完整的复现工程

add_rules("mode.debug", "mode.release")

rule("test")
    on_config(function (target)
        target:add("deps", "foo")
    end)

target("foo")
    set_kind("static")
    add_files("src/foo.cpp")

target("test")
    set_kind("binary")
    add_files("src/main.cpp")
    add_tests("default")
    add_rules("test")
ruki-2:test ruki$ xmake test -vD
checking for platform ... macosx
checking for architecture ... x86_64
checking for Xcode directory ... /Applications/Xcode.app
checking for Codesign Identity of Xcode ... Apple Development: waruqi@gmail.com (T3NA4MRVPU)
checking for SDK version of Xcode for macosx (x86_64) ... 14.0
checking for Minimal target version of Xcode for macosx (x86_64) ... 14.0
checkinfo: cannot runv(zig version), No such file or directory
checking for zig ... no
checkinfo: cannot runv(zig version), No such file or directory
checking for zig ... no
checking for nim ... /usr/local/bin/nim
checking for /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/b
in/clang ... ok
checking for the c++ compiler (cxx) ... clang
checking for /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/b
in/clang ... ok
checking for flags (-fPIC) ... ok
> clang "-fPIC" "-Qunused-arguments" "-target" "x86_64-apple-macos14.0" "-isysroot" "/Application
s/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk"
checking for flags (-fvisibility-inlines-hidden) ... ok
> clang "-fvisibility-inlines-hidden" "-Qunused-arguments" "-target" "x86_64-apple-macos14.0" "-i
sysroot" "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/Mac
OSX14.0.sdk"
checking for flags (-O3) ... ok
> clang "-O3" "-Qunused-arguments" "-target" "x86_64-apple-macos14.0" "-isysroot" "/Applications/
Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk"
checking for flags (-DNDEBUG) ... ok
> clang "-DNDEBUG" "-Qunused-arguments" "-target" "x86_64-apple-macos14.0" "-isysroot" "/Applicat
ions/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk"
[ 50%]: cache compiling.release src/foo.cpp
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -c -
Qunused-arguments -target x86_64-apple-macos14.0 -isysroot /Applications/Xcode.app/Contents/Devel
oper/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk -fvisibility=hidden -fvisibility-inl
ines-hidden -O3 -DNDEBUG -o build/.objs/foo/macosx/x86_64/release/src/foo.cpp.o src/foo.cpp
checking for flags (-MMD -MF) ... ok
> clang "-MMD" "-MF" "/dev/null" "-Qunused-arguments" "-target" "x86_64-apple-macos14.0" "-isysro
ot" "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14
.0.sdk"
checking for flags (-fdiagnostics-color=always) ... ok
> clang "-fdiagnostics-color=always" "-Qunused-arguments" "-target" "x86_64-apple-macos14.0" "-is
ysroot" "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacO
SX14.0.sdk"
checking for /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/b
in/ar ... ok
checking for the static library archiver (ar) ... ar
[ 62%]: archiving.release libfoo.a
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar -cr bui
ld/macosx/x86_64/release/libfoo.a build/.objs/foo/macosx/x86_64/release/src/foo.cpp.o
checking for the c++ compiler (cxx) ... clang
[ 75%]: cache compiling.release src/main.cpp
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -c -
Qunused-arguments -target x86_64-apple-macos14.0 -isysroot /Applications/Xcode.app/Contents/Devel
oper/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk -fvisibility=hidden -fvisibility-inl
ines-hidden -O3 -DNDEBUG -o build/.objs/test/macosx/x86_64/release/src/main.cpp.o src/main.cpp
checking for /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/b
in/clang++ ... ok
checking for the linker (ld) ... clang++
checking for /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/b
in/clang++ ... ok
checking for flags (-fPIC) ... ok
> clang++ "-fPIC" "-target" "x86_64-apple-macos14.0" "-isysroot" "/Applications/Xcode.app/Content
s/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.0.sdk" "-lz" "-target" "x86_64-appl
e-macos14.0" "-isysroot" "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/De
veloper/SDKs/MacOSX14.0.sdk" "-lz"
[ 87%]: linking.release test
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -o
 build/macosx/x86_64/release/test build/.objs/test/macosx/x86_64/release/src/main.cpp.o -target x
86_64-apple-macos14.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platf
orm/Developer/SDKs/MacOSX14.0.sdk -lz -Lbuild/macosx/x86_64/release -Wl,-x -Wl,-dead_strip -lfoo

build cache stats:
cache directory: /private/tmp/test/build/.build_cache
cache hit rate: 0%
cache hit: 0
cache hit total time: 0.000s
cache miss: 2
cache miss total time: 0.005s
new cached files: 2
remote cache hit: 0
remote new cached files: 0
preprocess failed: 0
compile fallback count: 0
compile total time: 0.555s

running tests ...
[100%]: running.test test/default

report of tests:
[100%]: test/default .................................... passed 0.012s
stdout: build/.gens/test/macosx/x86_64/release/tests/test/default.stdout.log
100% tests passed, 0 tests failed out of 1, spent 0.012s
star-hengxing commented 1 day ago

大概是因为 target 在 on_config 才添加源文件,导致没有自动添加 c/c++ rule 。 加上 add_rules("c") 后,链接参数有 -lxxx,但没有 syslinks 。

target("test")
    set_kind("static")
    -- add_files("src/lib.c")
    add_rules("c")
    on_config(function (target)
        target:add("files", "src/lib.c")
        target:add("syslinks", "user32")
    end)

target("main")
    set_kind("binary")
    add_files("src/main.c")
    add_deps("test")
[ 37%]: compiling.release src\lib.c
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.41.34120\\bin\\HostX64\\x64\\cl.exe" -c -nologo -O2 -DNDEBUG -Fobuild\.objs\test\windows\x64\release\src\lib.c.obj src\lib.c
[ 50%]: compiling.release src\main.c
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.41.34120\\bin\\HostX64\\x64\\cl.exe" -c -nologo -O2 -DNDEBUG -Fobuild\.objs\main\windows\x64\release\src\main.c.obj src\main.c
[ 62%]: archiving.release test.lib
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.41.34120\\bin\\HostX64\\x64\\link.exe" -lib -nologo -machine:x64 /opt:ref /opt:icf -out:build\windows\x64\release\test.lib build\.objs\test\windows\x64\release\src\lib.c.obj
[ 87%]: linking.release main.exe
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.41.34120\\bin\\HostX64\\x64\\link.exe" -nologo -dynamicbase -nxcompat -machine:x64 -libpath:build\windows\x64\release /opt:ref /opt:icf test.lib -out:build\windows\x64\release\main.exe build\.objs\main\windows\x64\release\src\main.c.obj
error: test.lib(lib.c.obj) : error LNK2019: unresolved external symbol __imp_MessageBoxA referenced in function my_fn
build\windows\x64\release\main.exe : fatal error LNK1120: 1 unresolved externals
waruqi commented 1 day ago

跟 c rule 没啥,关系,是 inherit links 那个 rule 用的也是 on_config,它的执行顺序 跟 用户 rule 的 on_config 平级,谁先执行未定义,这里先执行了内置的 inherit links ,所以这个时候 on_config 里面的 syslinks 还没被添加进去。

这种顺序问题,要想完全解决,只能等 3.0 对 rule 的执行顺序重构,做更灵活的配置支持

Issues-translate-bot commented 1 day ago

Bot detected the issue body's language is not English, translate it automatically.


It has nothing to do with the c rule. It is related to inherit links. That rule also uses on_config. Its execution order is the same as the on_config of the user rule. Whoever executes undefined first, here the built-in inherit links are executed first, so at this time in on_config The syslinks have not been added yet.

waruqi commented 1 day ago

目前只能通过添加 before/after_config 来 workaround 提升配置 config 顺序的灵活性,先这么试试吧 https://github.com/xmake-io/xmake/pull/5813

回头 3.0 可能会重构改进这块,目前也没太多时间大改