xmake-io / xmake

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

Xmake links against static library in MSVC when add_deps() is used to add a shared library #2234

Closed adamchristiansen closed 2 years ago

adamchristiansen commented 2 years ago

Xmake Version

2.6.4+202203070649

Operating System Version and Architecture

Windows Server 2022 x64

Describe Bug

I have a project which has two targets: a shared library and a binary. The binary links to the shared library and is added using add_deps(). Below is the relevant output for when the linker runs when running xmake build -v and the compiler/linker are MSVC:

[ 75%]: linking.debug my-bin.exe
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Tools\\MSVC\\14.31.31103\\bin\\HostX64\\x64\\link.exe" -nologo -dynamicbase -nxcompat -machine:x64 -libpath:build\windows\x64\debug -debug -pdb:build\windows\x64\debug\my-bin.pdb my-library.lib -debug:fastlink -incremental:no -out:build\windows\x64\debug\my-bin.exe build\.objs\my-bin\windows\x64\debug\src\bin\main.c.obj
error: LINK : fatal error LNK1181: cannot open input file 'my-library.lib'

The linker is trying to link my-library.lib, which is a static library. However, the xmake.lua specifies that a shared library should be used, so the link command should link against my-library.dll. A shared library is built, as the output of the previous build step produces a DLL:

[ 50%]: linking.debug my-library.dll
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Tools\\MSVC\\14.31.31103\\bin\\HostX64\\x64\\link.exe" -dll -nologo -machine:x64 -debug -pdb:build\windows\x64\debug\my-library.pdb -out:build\windows\x64\debug\my-library.dll build\.objs\my-library\windows\x64\debug\src\lib\library.c.obj

Expected Behavior

It is expected that xmake would execute a link command against my-library.dll rather than my-library.lib when my-library is a shared library.

This does work as expected on macOS and Ubuntu when the compiler is XCode/Clang and GCC, respectively.

Project Configuration

A minimal reproducible example can be found at: xmake-shared-test.zip. Since it is small the contents are shown below:

xmake.lua:

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

set_languages("c11")
set_warnings("all")

if is_plat("windows") then
    add_ldflags("-debug:fastlink")
    add_ldflags("-incremental:no")
end

target("my-library")
    set_kind("shared")
    add_files("src/lib/**.c")

target("my-bin")
    set_kind("binary")
    add_deps("my-library")
    add_files("src/bin/**.c")

src/lib/library.c

int add(int x, int y) {
    return x + y;
}

src/bin/main.c

#include <stdio.h>

int add(int x, int y);

int main(void) {
    int x = 5;
    int y = 7;
    printf("%d + %d = %d\n", x, y, add(x, y));
}

Additional Information and Error Logs

xmake config -vD --mode=debug

checking for platform ... windows
checking for architecture ... x64
checking for vswhere.exe ... C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe
checking for cl.exe ... C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.31.31103\bin\HostX64\x64\cl.exe
checking for Microsoft Visual Studio (x64) version ... 2022
checkinfo: cannot runv(dmd.exe --version), No such file or directory
checking for dmd ... no
checkinfo: cannot runv(ldc2.exe --version), No such file or directory
checking for ldc2 ... no
checkinfo: cannot runv(gdc.exe --version), No such file or directory
checking for gdc ... no
checkinfo: cannot runv(zig.exe version), No such file or directory
checking for zig ... no
checkinfo: cannot runv(zig.exe version), No such file or directory
checking for zig ... no
checking for link.exe ... C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.31.31103\bin\HostX64\x64\link.exe
checking for the shared library linker (sh) ... link.exe
checking for link.exe ... C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.31.31103\bin\HostX64\x64\link.exe
checking for the linker (ld) ... link.exe
configure
{
    vs = 2022
    arch = x64
    buildir = build
    kind = static
    ccache = true
    mode = debug
    host = windows
    plat = windows
    ndk_stdcxx = true
}

xmake build -vD

checking for cl.exe ... C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.31.31103\bin\HostX64\x64\cl.exe
checking for the c compiler (cc) ... cl.exe
checking for the c compiler (cc) ... cl.exe
checking for C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.31.31103\bin\HostX64\x64\cl.exe ... ok
checking for flags (-FS -Fd) ... ok
> cl.exe "-FS" "-FdC:\Users\RUNNER~1\AppData\Local\Temp\.xmake\220401\_9BB4C3234B9D4070886BBE0DD6F9A770.pdb" "-nologo"
checking for flags (-Od) ... ok
> cl.exe "-Od"
checking for flags (-std:c11) ... ok
> cl.exe "-std:c11" "-nologo"
checkinfo: cannot runv(ccache.exe --version), No such file or directory
checking for ccache ... no
[ 25%]: compiling.debug src\lib\library.c
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Tools\\MSVC\\14.31.31103\\bin\\HostX64\\x64\\cl.exe" -c -nologo -Zi -FS -Fdbuild\windows\x64\debug\compile.my-library.pdb -W3 -Od -std:c11 -Fobuild\.objs\my-library\windows\x64\debug\src\lib\library.c.obj src\lib\library.c
[ 25%]: compiling.debug src\bin\main.c
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Tools\\MSVC\\14.31.31103\\bin\\HostX64\\x64\\cl.exe" -c -nologo -Zi -FS -Fdbuild\windows\x64\debug\compile.my-bin.pdb -W3 -Od -std:c11 -Fobuild\.objs\my-bin\windows\x64\debug\src\bin\main.c.obj src\bin\main.c
checking for flags (cl_sourceDependencies) ... ok
> cl.exe "/sourceDependencies" "C:\Users\RUNNER~1\AppData\Local\Temp\.xmake\220401\_0988FA0B20724510818E0654C34FBC70.json" "-nologo"
[ 50%]: linking.debug my-library.dll
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Tools\\MSVC\\14.31.31103\\bin\\HostX64\\x64\\link.exe" -dll -nologo -machine:x64 -debug -pdb:build\windows\x64\debug\my-library.pdb -out:build\windows\x64\debug\my-library.dll build\.objs\my-library\windows\x64\debug\src\lib\library.c.obj
checking for C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.31.31103\bin\HostX64\x64\link.exe ... ok
checking for flags (-debug:fastlink) ... ok
> link.exe "-debug:fastlink" "-nologo" "-dynamicbase" "-nxcompat" "-machine:x64"
checking for flags (-incremental:no) ... ok
> link.exe "-incremental:no" "-nologo" "-dynamicbase" "-nxcompat" "-machine:x64"
[ 75%]: linking.debug my-bin.exe
"C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Tools\\MSVC\\14.31.31103\\bin\\HostX64\\x64\\link.exe" -nologo -dynamicbase -nxcompat -machine:x64 -libpath:build\windows\x64\debug -debug -pdb:build\windows\x64\debug\my-bin.pdb my-library.lib -debug:fastlink -incremental:no -out:build\windows\x64\debug\my-bin.exe build\.objs\my-bin\windows\x64\debug\src\bin\main.c.obj
error: @programdir\modules\private\async\runjobs.lua:232: @programdir\actions\build\kinds\binary.lua:74: @programdir\modules\core\tools\link.lua:159: LINK : fatal error LNK1181: cannot open input file 'my-library.lib'
waruqi commented 2 years ago

your shared lib need export symbols, otherwise .lib will not be generated automatically by msvc.

adamchristiansen commented 2 years ago

@waruqi Thank you, this solved the issue.