ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.03k stars 2.49k forks source link

Broken .dll exported functions when libCpp is linked #19746

Open tuket opened 5 months ago

tuket commented 5 months ago

Zig Version

0.13.0-dev.30+6fd09f8d2

Steps to Reproduce and Observed Behavior

Please find attached a .zip with a minimum reproducible example. test.zip

I'm testing this in Windows 10.

In this project you will find a build.zig, and 3 different source files (root.zig, root.c, root.cpp).

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const lib = b.addSharedLibrary(.{
        .name = "test",
        //.root_source_file = b.path("src/root.zig"),
        .target = target,
        .optimize = optimize,
        .strip = true,
    });

    //if (false) {
    lib.addCSourceFile(.{
        .file = .{ .path = "src/root.c" },
        .flags = &.{"-std=c99"},
    });
    //} else {
    lib.addCSourceFile(.{
        .file = .{ .path = "src/root.cpp" },
        .flags = &.{"-std=c++11"},
    });
    //}

    lib.linkLibC();
    lib.linkLibCpp();

    b.installArtifact(lib);
}

If you compile the project as is (zig build cmd), and inspect the exported functions of the .dll, you will see the functions of the .c and .cpp source files correctly exported. I use DLL Export Viewer for this:

image

Now, if you un-comment line 9 of build.zig,

    const lib = b.addSharedLibrary(.{
        .name = "test",
        .root_source_file = b.path("src/root.zig"), // uncomment this
        .target = target,
        .optimize = optimize,
        .strip = true,
    });

Now all the C/C++ functions are not exported anymore. Only the .zig one is exported.

dllexp_XXMqzSznaR

I'm not sure if this intended behavior or not, I though I would just point it out beause it seems weird. But it's not the main issue I want to report.

Comment back line 9.

In root.cpp un-comment line 10

int foo(Data d)
{
    delete[] (char*)d.p; // un-comment this
    return 5;
}

This seems to force the use of libCpp and thus links it (the .dll becomes way bigger). As a result, all the C exported functions from our source files seem to disappear!

dllexp_yV2UOmWhq4

Expected Behavior

The functions of our C/C++ source files should be exported, regardless whether we are linking libCpp or not.

Shabinder commented 1 month ago

+1, facing same.

Shabinder commented 1 month ago

This is a blocker to compile c++ files against windows target, is there a known workaround ? Since as soon as I enable linkLibCpp and include C++ source files, I get a broken dll with no exports from C++ and even my C code, but keeping it disabled does build and export C only in dll correctly

serby2000 commented 3 weeks ago

On zig 0.13.0 cf90dfd

I added:

Now I can export functions from zig, c, and cpp at the same time. I also can configure ordinals.

image

I'm very new to zig (my 5th day) so if you are interested in a PR with this solution you will have to work the details with me first

serby2000 commented 3 weeks ago

It works also with master

Most of the needed code was already there.

https://github.com/ziglang/zig/compare/3929cac...serby2000:zig:b940bcb