diff --git a/test/standalone.zig b/test/standalone.zig index 14a9865c6c..43c68c3686 100644 --- a/test/standalone.zig +++ b/test/standalone.zig @@ -30,4 +30,5 @@ pub fn addCases(cases: *tests.StandaloneContext) void { if (std.Target.current.cpu.arch == .x86_64) { // TODO add C ABI support for other architectures cases.addBuildFile("test/stage1/c_abi/build.zig", .{}); } + cases.addBuildFile("test/standalone/c_compiler/build.zig", .{ .build_modes = true, .cross_targets = true }); } diff --git a/test/standalone/c_compiler/build.zig b/test/standalone/c_compiler/build.zig new file mode 100644 index 0000000000..1026f2ca50 --- /dev/null +++ b/test/standalone/c_compiler/build.zig @@ -0,0 +1,53 @@ +const std = @import("std"); +const Builder = std.build.Builder; +const CrossTarget = std.zig.CrossTarget; + +fn isRunnableTarget(t: CrossTarget) bool { + if (t.isNative()) return true; + + return (t.getOsTag() == std.Target.current.os.tag and + t.getCpuArch() == std.Target.current.cpu.arch); +} + +pub fn build(b: *Builder) void { + const mode = b.standardReleaseOptions(); + const target = b.standardTargetOptions(.{}); + + const test_step = b.step("test", "Test the program"); + + const exe_c = b.addExecutable("test_c", null); + b.default_step.dependOn(&exe_c.step); + exe_c.addCSourceFile("test.c", &[0][]const u8{}); + exe_c.setBuildMode(mode); + exe_c.setTarget(target); + exe_c.linkLibC(); + + const exe_cpp = b.addExecutable("test_cpp", null); + b.default_step.dependOn(&exe_cpp.step); + exe_cpp.addCSourceFile("test.cpp", &[0][]const u8{}); + exe_cpp.setBuildMode(mode); + exe_cpp.setTarget(target); + exe_cpp.linkSystemLibrary("c++"); + + // disable broken LTO links: + switch(target.getOsTag()) { + .windows => { + exe_cpp.want_lto = false; + }, + .macos => { + exe_cpp.want_lto = false; + exe_c.want_lto = false; + }, + else => {}, + } + + if (isRunnableTarget(target)) { + const run_c_cmd = exe_c.run(); + test_step.dependOn(&run_c_cmd.step); + const run_cpp_cmd = exe_cpp.run(); + test_step.dependOn(&run_cpp_cmd.step); + } else { + test_step.dependOn(&exe_c.step); + test_step.dependOn(&exe_cpp.step); + } +} diff --git a/test/standalone/c_compiler/test.c b/test/standalone/c_compiler/test.c new file mode 100644 index 0000000000..842a63fc67 --- /dev/null +++ b/test/standalone/c_compiler/test.c @@ -0,0 +1,25 @@ +#include +#include + +typedef struct { + int val; +} STest; + +int getVal(STest* data) { return data->val; } + +int main (int argc, char *argv[]) +{ + STest* data = (STest*)malloc(sizeof(STest)); + data->val = 123; + + assert(getVal(data) != 456); + int ok = (getVal(data) == 123); + + if (argc>1) fprintf(stdout, "val=%d\n", data->val); + + free(data); + + if (!ok) abort(); + + return 0; +} diff --git a/test/standalone/c_compiler/test.cpp b/test/standalone/c_compiler/test.cpp new file mode 100644 index 0000000000..f10a9e0c00 --- /dev/null +++ b/test/standalone/c_compiler/test.cpp @@ -0,0 +1,26 @@ +#include +#include + +class CTest { +public: + CTest(int val) : m_val(val) {}; + virtual ~CTest() {} + + virtual int getVal() const { return m_val; } + virtual void printVal() { std::cout << "val=" << m_val << std::endl; } +private: + int m_val; +}; + +int main (int argc, char *argv[]) +{ + auto* t = new CTest(123); + assert(t->getVal()!=456); + if (argc>1) t->printVal(); + bool ok = t->getVal() == 123; + delete t; + + if (!ok) abort(); + + return 0; +}