Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 851732
Collapse All | Expand All

(-)a/CMakeLists.txt (+6 lines)
Lines 159-164 if(APPLE AND ZIG_STATIC) Link Here
159
        /opt/homebrew/opt/ncurses/lib)
159
        /opt/homebrew/opt/ncurses/lib)
160
    list(APPEND LLVM_LIBRARIES "${CURSES}")
160
    list(APPEND LLVM_LIBRARIES "${CURSES}")
161
endif()
161
endif()
162
if (APPLE AND (${LLVM_LINK_MODE} STREQUAL "shared"))
163
    find_library(APPLE_LIBCPP NAMES libc++.tbd NAMES_PER_DIR)
164
    if ("${APPLE_LIBCPP}" STREQUAL "APPLE_LIBCPP-NOTFOUND")
165
        set(APPLE_LIBCPP "")
166
    endif()
167
endif()
162
168
163
set(ZIG_CPP_LIB_DIR "${CMAKE_BINARY_DIR}/zigcpp")
169
set(ZIG_CPP_LIB_DIR "${CMAKE_BINARY_DIR}/zigcpp")
164
170
(-)a/build.zig (-20 / +93 lines)
Lines 252-257 pub fn build(b: *Builder) !void { Link Here
252
    };
252
    };
253
    exe_options.addOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version));
253
    exe_options.addOption([:0]const u8, "version", try b.allocator.dupeZ(u8, version));
254
254
255
    // -Dzig0 makes extra assumptions about the system config/bootstrapping, which we verify here.
256
    if (use_zig0) {
257
        if (!have_stage1) {
258
            std.log.err("-Dzig0 is currently only supported in combination with -Denable-stage1", .{});
259
            std.os.exit(1);
260
        }
261
        if (!static_llvm) {
262
            std.log.err("-Dzig0 is currently only supported with -Dstatic-llvm", .{});
263
            std.os.exit(1);
264
        }
265
    }
266
255
    if (enable_llvm) {
267
    if (enable_llvm) {
256
        const cmake_cfg = if (static_llvm) null else blk: {
268
        const cmake_cfg = if (static_llvm) null else blk: {
257
            if (findConfigH(b, config_h_path_option)) |config_h_path| {
269
            if (findConfigH(b, config_h_path_option)) |config_h_path| {
Lines 286-300 pub fn build(b: *Builder) !void { Link Here
286
                artifact.addIncludePath("deps/SoftFloat-3e/source/include");
298
                artifact.addIncludePath("deps/SoftFloat-3e/source/include");
287
                artifact.addIncludePath("deps/SoftFloat-3e-prebuilt");
299
                artifact.addIncludePath("deps/SoftFloat-3e-prebuilt");
288
300
289
                artifact.defineCMacro("ZIG_LINK_MODE", "Static");
301
                if (cmake_cfg) |cfg| {
302
                    artifact.defineCMacro("ZIG_LINK_MODE", if (cfg.llvm_linkage == .dynamic) "Dynamic" else "Static");
303
                } else {
304
                    artifact.defineCMacro("ZIG_LINK_MODE", "Static");
305
                }
290
306
291
                artifact.addCSourceFiles(&stage1_sources, &exe_cflags);
307
                artifact.addCSourceFiles(&stage1_sources, &exe_cflags);
292
                artifact.addCSourceFiles(&optimized_c_sources, &[_][]const u8{ "-std=c99", "-O3" });
308
                artifact.addCSourceFiles(&optimized_c_sources, &[_][]const u8{ "-std=c99", "-O3" });
293
309
294
                artifact.linkLibrary(softfloat);
310
                artifact.linkLibrary(softfloat);
295
                artifact.linkLibCpp();
296
            }
311
            }
297
312
313
            zig0.linkLibCpp();
298
            try addStaticLlvmOptionsToExe(zig0);
314
            try addStaticLlvmOptionsToExe(zig0);
299
315
300
            const zig1_obj_ext = target.getObjectFormat().fileExt(target.getCpuArch());
316
            const zig1_obj_ext = target.getObjectFormat().fileExt(target.getCpuArch());
Lines 349-354 pub fn build(b: *Builder) !void { Link Here
349
            // is pointless.
365
            // is pointless.
350
            exe.addPackagePath("compiler_rt", "src/empty.zig");
366
            exe.addPackagePath("compiler_rt", "src/empty.zig");
351
        }
367
        }
368
352
        if (cmake_cfg) |cfg| {
369
        if (cmake_cfg) |cfg| {
353
            // Inside this code path, we have to coordinate with system packaged LLVM, Clang, and LLD.
370
            // Inside this code path, we have to coordinate with system packaged LLVM, Clang, and LLD.
354
            // That means we also have to rely on stage1 compiled c++ files. We parse config.h to find
371
            // That means we also have to rely on stage1 compiled c++ files. We parse config.h to find
Lines 567-577 fn addCmakeCfgOptionsToExe( Link Here
567
    exe: *std.build.LibExeObjStep,
584
    exe: *std.build.LibExeObjStep,
568
    use_zig_libcxx: bool,
585
    use_zig_libcxx: bool,
569
) !void {
586
) !void {
570
    exe.addObjectFile(fs.path.join(b.allocator, &[_][]const u8{
587
    // Adds the Zig C++ sources which both stage1 and stage2 need.
571
        cfg.cmake_binary_dir,
588
    //
572
        "zigcpp",
589
    // We need this because otherwise zig_clang_cc1_main.cpp ends up pulling
573
        b.fmt("{s}{s}{s}", .{ exe.target.libPrefix(), "zigcpp", exe.target.staticLibSuffix() }),
590
    // in a dependency on llvm::cfg::Update<llvm::BasicBlock*>::dump() which is
574
    }) catch unreachable);
591
    // unavailable when LLVM is compiled in Release mode.
592
    const zig_cpp_cflags = exe_cflags ++ [_][]const u8{"-DNDEBUG=1"};
593
    exe.addCSourceFiles(&zig_cpp_sources, &zig_cpp_cflags);
594
575
    assert(cfg.lld_include_dir.len != 0);
595
    assert(cfg.lld_include_dir.len != 0);
576
    exe.addIncludePath(cfg.lld_include_dir);
596
    exe.addIncludePath(cfg.lld_include_dir);
577
    exe.addIncludePath(cfg.llvm_include_dir);
597
    exe.addIncludePath(cfg.llvm_include_dir);
Lines 583-589 fn addCmakeCfgOptionsToExe( Link Here
583
    if (use_zig_libcxx) {
603
    if (use_zig_libcxx) {
584
        exe.linkLibCpp();
604
        exe.linkLibCpp();
585
    } else {
605
    } else {
586
        const need_cpp_includes = true;
587
        const lib_suffix = switch (cfg.llvm_linkage) {
606
        const lib_suffix = switch (cfg.llvm_linkage) {
588
            .static => exe.target.staticLibSuffix()[1..],
607
            .static => exe.target.staticLibSuffix()[1..],
589
            .dynamic => exe.target.dynamicLibSuffix()[1..],
608
            .dynamic => exe.target.dynamicLibSuffix()[1..],
Lines 594-614 fn addCmakeCfgOptionsToExe( Link Here
594
        if (exe.target.getOsTag() == .linux) {
613
        if (exe.target.getOsTag() == .linux) {
595
            // First we try to link against gcc libstdc++. If that doesn't work, we fall
614
            // First we try to link against gcc libstdc++. If that doesn't work, we fall
596
            // back to -lc++ and cross our fingers.
615
            // back to -lc++ and cross our fingers.
597
            addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), "", need_cpp_includes) catch |err| switch (err) {
616
            addCxxKnownPath(b, cfg, exe, b.fmt("libstdc++.{s}", .{lib_suffix}), "") catch |err| switch (err) {
598
                error.RequiredLibraryNotFound => {
617
                error.RequiredLibraryNotFound => {
599
                    exe.linkSystemLibrary("c++");
618
                    exe.linkSystemLibrary("c++");
600
                },
619
                },
601
                else => |e| return e,
620
                else => |e| return e,
602
            };
621
            };
622
            try addLibcxxIncludePaths(b, cfg, exe);
603
            exe.linkSystemLibrary("unwind");
623
            exe.linkSystemLibrary("unwind");
604
        } else if (exe.target.isFreeBSD()) {
624
        } else if (exe.target.isFreeBSD()) {
605
            try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null, need_cpp_includes);
625
            try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null);
606
            exe.linkSystemLibrary("pthread");
626
            exe.linkSystemLibrary("pthread");
607
        } else if (exe.target.getOsTag() == .openbsd) {
627
        } else if (exe.target.getOsTag() == .openbsd) {
608
            try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null, need_cpp_includes);
628
            try addCxxKnownPath(b, cfg, exe, b.fmt("libc++.{s}", .{lib_suffix}), null);
609
            try addCxxKnownPath(b, cfg, exe, b.fmt("libc++abi.{s}", .{lib_suffix}), null, need_cpp_includes);
629
            try addCxxKnownPath(b, cfg, exe, b.fmt("libc++abi.{s}", .{lib_suffix}), null);
630
            try addLibcxxIncludePaths(b, cfg, exe);
610
        } else if (exe.target.isDarwin()) {
631
        } else if (exe.target.isDarwin()) {
611
            exe.linkSystemLibrary("c++");
632
            if (cfg.llvm_linkage == .dynamic and cfg.apple_libcpp_path.len > 0) {
633
                exe.addObjectFile(cfg.apple_libcpp_path);
634
                const sysroot = std.fs.path.dirname(std.fs.path.dirname(std.fs.path.dirname(cfg.apple_libcpp_path).?).?).?;
635
                exe.addIncludePath(b.fmt("{s}/usr/include/c++/v1/", .{sysroot}));
636
            } else {
637
                exe.linkSystemLibrary("c++");
638
            }
612
        }
639
        }
613
    }
640
    }
614
641
Lines 651-663 fn addStaticLlvmOptionsToExe(exe: *std.build.LibExeObjStep) !void { Link Here
651
    }
678
    }
652
}
679
}
653
680
681
/// Invoke the system C++ compiler and have it locate `objname`, usually
682
/// a static or shared library file that's included in the stdlib.
654
fn addCxxKnownPath(
683
fn addCxxKnownPath(
655
    b: *Builder,
684
    b: *Builder,
656
    ctx: CMakeConfig,
685
    ctx: CMakeConfig,
657
    exe: *std.build.LibExeObjStep,
686
    exe: *std.build.LibExeObjStep,
658
    objname: []const u8,
687
    objname: []const u8,
659
    errtxt: ?[]const u8,
688
    errtxt: ?[]const u8,
660
    need_cpp_includes: bool,
661
) !void {
689
) !void {
662
    if (!std.process.can_spawn)
690
    if (!std.process.can_spawn)
663
        return error.RequiredLibraryNotFound;
691
        return error.RequiredLibraryNotFound;
Lines 676-689 fn addCxxKnownPath( Link Here
676
        return error.RequiredLibraryNotFound;
704
        return error.RequiredLibraryNotFound;
677
    }
705
    }
678
    exe.addObjectFile(path_unpadded);
706
    exe.addObjectFile(path_unpadded);
707
}
679
708
680
    // TODO a way to integrate with system c++ include files here
709
/// Invoke the system C++ compiler and add to the build any libc++ include
710
/// paths in its system include search list.
711
fn addLibcxxIncludePaths(
712
    b: *Builder,
713
    ctx: CMakeConfig,
714
    exe: *std.build.LibExeObjStep,
715
) !void {
681
    // c++ -E -Wp,-v -xc++ /dev/null
716
    // c++ -E -Wp,-v -xc++ /dev/null
682
    if (need_cpp_includes) {
717
    const max_output_size = 400 * 1024;
683
        // I used these temporarily for testing something but we obviously need a
718
    var child = std.ChildProcess.init(&[_][]const u8{ ctx.cxx_compiler, "-E", "-Wp,-v", "-xc++", "/dev/null" }, b.allocator);
684
        // more general purpose solution here.
719
    child.stdin_behavior = .Ignore;
685
        //exe.addIncludePath("/nix/store/2lr0fc0ak8rwj0k8n3shcyz1hz63wzma-gcc-11.3.0/include/c++/11.3.0");
720
    child.stdout_behavior = .Ignore;
686
        //exe.addIncludePath("/nix/store/2lr0fc0ak8rwj0k8n3shcyz1hz63wzma-gcc-11.3.0/include/c++/11.3.0/x86_64-unknown-linux-gnu");
721
    child.stderr_behavior = .Pipe;
722
    try child.spawn();
723
    const stderr = child.stderr.?.reader().readAllAlloc(b.allocator, max_output_size) catch unreachable;
724
    errdefer b.allocator.free(stderr);
725
726
    const term = try child.wait();
727
    assert(term == .Exited and term.Exited == 0);
728
729
    var it = mem.tokenize(u8, stderr, "\r\n");
730
    while (it.next()) |line| {
731
        if (std.mem.eql(u8, line, "#include <...> search starts here:"))
732
            break;
733
    } else unreachable;
734
735
    paths: while (it.next()) |line| {
736
        if (line[0] != ' ')
737
            break;
738
739
        // Look for a directory name starting with "c++" or "g++" within the last three
740
        // components of the path.
741
        var i: u8 = 0;
742
        var parent_dir = line[1..];
743
        while (i < 3) : (i += 1) {
744
            if (std.mem.startsWith(u8, std.fs.path.basename(parent_dir), "c++") or
745
                std.mem.startsWith(u8, std.fs.path.basename(parent_dir), "g++"))
746
            {
747
748
                // TODO: Use `addSystemIncludePath` once
749
                //       https://github.com/ziglang/zig/issues/13496 is resolved.
750
                exe.addIncludePath(line[1..]);
751
                continue :paths;
752
            } else parent_dir = std.fs.path.dirname(parent_dir) orelse continue :paths;
753
        }
687
    }
754
    }
688
}
755
}
689
756
Lines 700-705 fn addCMakeLibraryList(exe: *std.build.LibExeObjStep, list: []const u8) void { Link Here
700
767
701
const CMakeConfig = struct {
768
const CMakeConfig = struct {
702
    llvm_linkage: std.build.LibExeObjStep.Linkage,
769
    llvm_linkage: std.build.LibExeObjStep.Linkage,
770
    apple_libcpp_path: []const u8,
703
    cmake_binary_dir: []const u8,
771
    cmake_binary_dir: []const u8,
704
    cmake_prefix_path: []const u8,
772
    cmake_prefix_path: []const u8,
705
    cxx_compiler: []const u8,
773
    cxx_compiler: []const u8,
Lines 763-768 fn findConfigH(b: *Builder, config_h_path_option: ?[]const u8) ?[]const u8 { Link Here
763
fn parseConfigH(b: *Builder, config_h_text: []const u8) ?CMakeConfig {
831
fn parseConfigH(b: *Builder, config_h_text: []const u8) ?CMakeConfig {
764
    var ctx: CMakeConfig = .{
832
    var ctx: CMakeConfig = .{
765
        .llvm_linkage = undefined,
833
        .llvm_linkage = undefined,
834
        .apple_libcpp_path = undefined,
766
        .cmake_binary_dir = undefined,
835
        .cmake_binary_dir = undefined,
767
        .cmake_prefix_path = undefined,
836
        .cmake_prefix_path = undefined,
768
        .cxx_compiler = undefined,
837
        .cxx_compiler = undefined,
Lines 816-821 fn parseConfigH(b: *Builder, config_h_text: []const u8) ?CMakeConfig { Link Here
816
            .prefix = "#define ZIG_LLVM_LIB_PATH ",
885
            .prefix = "#define ZIG_LLVM_LIB_PATH ",
817
            .field = "llvm_lib_dir",
886
            .field = "llvm_lib_dir",
818
        },
887
        },
888
        .{
889
            .prefix = "#define ZIG_APPLE_LIBCPP_PATH ",
890
            .field = "apple_libcpp_path",
891
        },
819
        // .prefix = ZIG_LLVM_LINK_MODE parsed manually below
892
        // .prefix = ZIG_LLVM_LINK_MODE parsed manually below
820
    };
893
    };
821
894
(-)a/src/stage1/config.h.in (+1 lines)
Lines 26-30 Link Here
26
#define ZIG_LLVM_LIB_PATH "@LLVM_LIBDIRS@"
26
#define ZIG_LLVM_LIB_PATH "@LLVM_LIBDIRS@"
27
#define ZIG_LLVM_LIBRARIES "@LLVM_LIBRARIES@"
27
#define ZIG_LLVM_LIBRARIES "@LLVM_LIBRARIES@"
28
#define ZIG_DIA_GUIDS_LIB "@ZIG_DIA_GUIDS_LIB_ESCAPED@"
28
#define ZIG_DIA_GUIDS_LIB "@ZIG_DIA_GUIDS_LIB_ESCAPED@"
29
#define ZIG_APPLE_LIBCPP_PATH "@APPLE_LIBCPP@"
29
30
30
#endif
31
#endif

Return to bug 851732