Zig Version
0.14.0-dev.1951+857383689
Steps to Reproduce and Observed Behavior
extern fn can succesfully link with function symbols marked with __declspec(dllexport), it matches the behaviour as if __declspec(dllimport) had been used. This works on both -gnu and -msvc.
However, only with the -msvc ABI, extern var cannot link with data symbols marked with __declspec(dllexport).
Given this source and build script:
conststd=@import("std");
pubfnbuild(b: *std.Build) void {
consttarget=b.standardTargetOptions(.{});
constoptimize=b.standardOptimizeOption(.{});
constfoo_shared=b.addSharedLibrary(.{
.name="foo_shared",
.target=target,
.optimize=optimize,
});
foo_shared.defineCMacro("FOO_API", "__declspec(dllexport)");
foo_shared.addCSourceFile(.{ .file=b.path("src/foo.c"), .flags= &.{} });
foo_shared.linkLibC();
b.installArtifact(foo_shared);
constfoo_cpp_shared=b.addSharedLibrary(.{
.name="foo_cpp_shared",
.target=target,
.optimize=optimize,
});
foo_cpp_shared.defineCMacro("FOO_API", "__declspec(dllexport)");
foo_cpp_shared.addCSourceFile(.{ .file=b.path("src/foo.cpp"), .flags= &.{} });
if (target.result.abi==.msvc)
foo_cpp_shared.linkLibC()
elsefoo_cpp_shared.linkLibCpp();
b.installArtifact(foo_cpp_shared);
constexe=b.addExecutable(.{
.name="dllimport",
.root_source_file=b.path("src/main.zig"),
.target=target,
.optimize=optimize,
});
exe.linkLibrary(foo_shared);
exe.linkLibrary(foo_cpp_shared);
b.installArtifact(exe);
}foo.h:
#ifndefFOO_API#defineFOO_API#endifFOO_APIintfoo();
FOO_APIintfoo_data;
FOO_APIvoid* (*foo_function_pointer)(intbar);
#if_MSC_VER#include<windows.h>BOOLWINAPIDllMain(HINSTANCEhinstDLL, DWORDfdwReason, LPVOIDlpvReserved)
{
return TRUE;
}
#endiffoo.c
#include"foo.h"intfoo() {
return7;
};
intfoo_data=8;
void* (*foo_function_pointer)(intbar) =0;foo.hpp:
#ifndefFOO_API#defineFOO_API#endif#ifdef__cplusplusextern"C" {
#endifFOO_APIintfoo_cpp();
FOO_APIexternintfoo_cpp_data;
FOO_APIexternvoid* (*foo_cpp_function_pointer)(intbar);
#if_MSC_VER#include<windows.h>BOOLWINAPIDllMain(HINSTANCEhinstDLL, DWORDfdwReason, LPVOIDlpvReserved)
{
return TRUE;
}
#endif#ifdef__cplusplus
} /* extern "C" */#endiffoo.cpp
#include"foo.hpp"intfoo_cpp() {
return9;
};
intfoo_cpp_data=10;
void* (*foo_cpp_function_pointer)(intbar) =nullptr;Produces this output with -gnu:
> zig build -Dtarget=x86_64-windows-gnu && zig-out\bin\dllimport.exe
foo() says: 7
foo_data is: u32@100000008
foo_function_pointer is: null
foo_cpp() says: 9
foo_cpp_data is: u32@10000000a
foo_cpp_function_pointer is: null
But fails to link with -msvc:
>zig build -Dtarget=x86_64-windows-msvc && zig-out\bin\dllimport.exe
install
└─ install dllimport
└─ zig build-exe dllimport Debug x86_64-windows-msvc 4 errors
error: lld-link: undefined symbol: foo_data
note: referenced by C:\cygwin64\home\kcbanner\temp\dllimport\src\main.zig:14
note: c:\cygwin64\home\kcbanner\temp\dllimport\.zig-cache\o\d0aa5c5dc0e14955cec128eb46501ab6\dllimport.exe.obj:(main.main)
error: lld-link: undefined symbol: foo_function_pointer
note: referenced by C:\cygwin64\home\kcbanner\temp\dllimport\src\main.zig:15
note: c:\cygwin64\home\kcbanner\temp\dllimport\.zig-cache\o\d0aa5c5dc0e14955cec128eb46501ab6\dllimport.exe.obj:(main.main)
error: lld-link: undefined symbol: foo_cpp_data
note: referenced by C:\cygwin64\home\kcbanner\temp\dllimport\src\main.zig:18
note: c:\cygwin64\home\kcbanner\temp\dllimport\.zig-cache\o\d0aa5c5dc0e14955cec128eb46501ab6\dllimport.exe.obj:(main.main)
error: lld-link: undefined symbol: foo_cpp_function_pointer
note: referenced by C:\cygwin64\home\kcbanner\temp\dllimport\src\main.zig:19
note: c:\cygwin64\home\kcbanner\temp\dllimport\.zig-cache\o\d0aa5c5dc0e14955cec128eb46501ab6\dllimport.exe.obj:(main.main)
error: the following command failed with 4 compilation errors:
C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\bin\zig.exe build-exe c:\cygwin64\home\kcbanner\temp\dllimport\.zig-cache\o\89dd1bf28160503a9c8636fb7182d3a2\foo_shared.lib c:\cygwin64\home\kcbanner\temp\dllimport\.zig-cache\o\a55b9a2d906f932dd72ab4d979d22921\foo_cpp_shared.lib -ODebug -target x86_64-windows-msvc -mcpu baseline -I C:\cygwin64\home\kcbanner\temp\dllimport\.zig-cache\o\b4fda69f43e846a2309c0948ef9aabbc -I C:\cygwin64\home\kcbanner\temp\dllimport\.zig-cache\o\b4fda69f43e846a2309c0948ef9aabbc -Mroot=C:\cygwin64\home\kcbanner\temp\dllimport\src\main.zig -lc --cache-dir c:\cygwin64\home\kcbanner\temp\dllimport\.zig-cache --global-cache-dir e:\dev\zig-cache --name dllimport --zig-lib-dir C:\cygwin64\home\kcbanner\kit\zig\build-stage3-release\lib\zig\ --listen=-
Build Summary: 6/9 steps succeeded; 1 failed
Note that only the data symbols are undefined. The functions link as expected.
Expected Behavior
Expected successful linking and matching output to -gnu.
Zig Version
0.14.0-dev.1951+857383689
Steps to Reproduce and Observed Behavior
extern fncan succesfully link with function symbols marked with__declspec(dllexport), it matches the behaviour as if__declspec(dllimport)had been used. This works on both-gnuand-msvc.However, only with the
-msvcABI,extern varcannot link with data symbols marked with__declspec(dllexport).Given this source and build script:
foo.h:
foo.c
foo.hpp:
foo.cpp
Produces this output with -gnu:
But fails to link with -msvc:
Note that only the data symbols are undefined. The functions link as expected.
Expected Behavior
Expected successful linking and matching output to -gnu.