| author | |
| committer | |
| log | 525c2eaf5d49f537d4ccd48ab0c5bc1f52cc3204 |
| tree | cf66d3fd2b48f894048dbdfae93e8f5ad1e6e22a |
| parent | e76ce2c1d0d3988359267fd3030a81a52ec99f3f |
9 files changed, 66 insertions(+), 9 deletions(-)
src/all_types.hpp+1| ... | ... | @@ -1743,6 +1743,7 @@ struct CodeGen { |
| 1743 | 1743 | Buf triple_str; |
| 1744 | 1744 | Buf global_asm; |
| 1745 | 1745 | Buf *out_h_path; |
| 1746 | Buf *out_lib_path; | |
| 1746 | 1747 | Buf artifact_dir; |
| 1747 | 1748 | Buf output_file_path; |
| 1748 | 1749 | Buf o_file_output_path; |
src/codegen.cpp+5-1| ... | ... | @@ -175,6 +175,10 @@ void codegen_set_output_h_path(CodeGen *g, Buf *h_path) { |
| 175 | 175 | g->out_h_path = h_path; |
| 176 | 176 | } |
| 177 | 177 | |
| 178 | void codegen_set_output_lib_path(CodeGen *g, Buf *lib_path) { | |
| 179 | g->out_lib_path = lib_path; | |
| 180 | } | |
| 181 | ||
| 178 | 182 | void codegen_set_output_path(CodeGen *g, Buf *path) { |
| 179 | 183 | g->wanted_output_file_path = path; |
| 180 | 184 | } |
| ... | ... | @@ -8201,7 +8205,7 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) { |
| 8201 | 8205 | args.append("-c"); |
| 8202 | 8206 | args.append(buf_ptr(c_source_file)); |
| 8203 | 8207 | |
| 8204 | if (!g->disable_pic) { | |
| 8208 | if (!g->disable_pic && target_supports_fpic(g->zig_target)) { | |
| 8205 | 8209 | args.append("-fPIC"); |
| 8206 | 8210 | } |
| 8207 | 8211 |
src/codegen.hpp+1| ... | ... | @@ -41,6 +41,7 @@ void codegen_set_test_filter(CodeGen *g, Buf *filter); |
| 41 | 41 | void codegen_set_test_name_prefix(CodeGen *g, Buf *prefix); |
| 42 | 42 | void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patch); |
| 43 | 43 | void codegen_set_output_h_path(CodeGen *g, Buf *h_path); |
| 44 | void codegen_set_output_lib_path(CodeGen *g, Buf *lib_path); | |
| 44 | 45 | void codegen_set_output_path(CodeGen *g, Buf *path); |
| 45 | 46 | void codegen_add_time_event(CodeGen *g, const char *name); |
| 46 | 47 | void codegen_print_timing_report(CodeGen *g, FILE *f); |
src/link.cpp+1| ... | ... | @@ -554,6 +554,7 @@ static void construct_linker_job_coff(LinkJob *lj) { |
| 554 | 554 | bool is_library = g->out_type == OutTypeLib; |
| 555 | 555 | switch (g->subsystem) { |
| 556 | 556 | case TargetSubsystemAuto: |
| 557 | add_nt_link_args(lj, is_library); | |
| 557 | 558 | break; |
| 558 | 559 | case TargetSubsystemConsole: |
| 559 | 560 | lj->args.append("/SUBSYSTEM:console"); |
src/main.cpp+6| ... | ... | @@ -60,6 +60,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) { |
| 60 | 60 | " --name [name] override output name\n" |
| 61 | 61 | " --output [file] override destination path\n" |
| 62 | 62 | " --output-h [file] generate header file\n" |
| 63 | " --output-lib [file] override import library path\n" | |
| 63 | 64 | " --pkg-begin [name] [path] make pkg available to import and push current pkg\n" |
| 64 | 65 | " --pkg-end pop current pkg\n" |
| 65 | 66 | " --release-fast build with optimizations on and safety off\n" |
| ... | ... | @@ -375,6 +376,7 @@ int main(int argc, char **argv) { |
| 375 | 376 | const char *in_file = nullptr; |
| 376 | 377 | const char *out_file = nullptr; |
| 377 | 378 | const char *out_file_h = nullptr; |
| 379 | const char *out_file_lib = nullptr; | |
| 378 | 380 | bool strip = false; |
| 379 | 381 | bool is_static = false; |
| 380 | 382 | OutType out_type = OutTypeUnknown; |
| ... | ... | @@ -661,6 +663,8 @@ int main(int argc, char **argv) { |
| 661 | 663 | out_file = argv[i]; |
| 662 | 664 | } else if (strcmp(arg, "--output-h") == 0) { |
| 663 | 665 | out_file_h = argv[i]; |
| 666 | } else if (strcmp(arg, "--output-lib") == 0) { | |
| 667 | out_file_lib = argv[i]; | |
| 664 | 668 | } else if (strcmp(arg, "--color") == 0) { |
| 665 | 669 | if (strcmp(argv[i], "auto") == 0) { |
| 666 | 670 | color = ErrColorAuto; |
| ... | ... | @@ -1094,6 +1098,8 @@ int main(int argc, char **argv) { |
| 1094 | 1098 | codegen_set_output_path(g, buf_create_from_str(out_file)); |
| 1095 | 1099 | if (out_file_h != nullptr && (out_type == OutTypeObj || out_type == OutTypeLib)) |
| 1096 | 1100 | codegen_set_output_h_path(g, buf_create_from_str(out_file_h)); |
| 1101 | if (out_file_lib != nullptr && out_type == OutTypeLib && !is_static) | |
| 1102 | codegen_set_output_lib_path(g, buf_create_from_str(out_file_lib)); | |
| 1097 | 1103 | |
| 1098 | 1104 | |
| 1099 | 1105 | add_package(g, cur_pkg, g->root_package); |
src/target.cpp+6| ... | ... | @@ -1049,3 +1049,9 @@ bool target_requires_libc(const ZigTarget *target) { |
| 1049 | 1049 | // since this is the stable syscall interface. |
| 1050 | 1050 | return (target_is_darwin(target) || target->os == OsFreeBSD || target->os == OsNetBSD); |
| 1051 | 1051 | } |
| 1052 | ||
| 1053 | bool target_supports_fpic(const ZigTarget *target) { | |
| 1054 | // This is not whether the target supports Position Independent Code, but whether the -fPIC | |
| 1055 | // C compiler argument is valid. | |
| 1056 | return target->os != OsWindows; | |
| 1057 | } |
src/target.hpp+1| ... | ... | @@ -141,5 +141,6 @@ bool target_allows_addr_zero(const ZigTarget *target); |
| 141 | 141 | bool target_has_valgrind_support(const ZigTarget *target); |
| 142 | 142 | bool target_is_darwin(const ZigTarget *target); |
| 143 | 143 | bool target_requires_libc(const ZigTarget *target); |
| 144 | bool target_supports_fpic(const ZigTarget *target); | |
| 144 | 145 | |
| 145 | 146 | #endif |
std/build.zig+43-2| ... | ... | @@ -815,6 +815,7 @@ pub const LibExeObjStep = struct { |
| 815 | 815 | linker_script: ?[]const u8, |
| 816 | 816 | out_filename: []const u8, |
| 817 | 817 | output_path: ?[]const u8, |
| 818 | output_lib_path: ?[]const u8, | |
| 818 | 819 | static: bool, |
| 819 | 820 | version: Version, |
| 820 | 821 | object_files: ArrayList([]const u8), |
| ... | ... | @@ -839,6 +840,7 @@ pub const LibExeObjStep = struct { |
| 839 | 840 | root_src: ?[]const u8, |
| 840 | 841 | output_h_path: ?[]const u8, |
| 841 | 842 | out_h_filename: []const u8, |
| 843 | out_lib_filename: []const u8, | |
| 842 | 844 | assembly_files: ArrayList([]const u8), |
| 843 | 845 | packages: ArrayList(Pkg), |
| 844 | 846 | build_options_contents: std.Buffer, |
| ... | ... | @@ -901,10 +903,12 @@ pub const LibExeObjStep = struct { |
| 901 | 903 | .frameworks = BufSet.init(builder.allocator), |
| 902 | 904 | .step = Step.init(name, builder.allocator, make), |
| 903 | 905 | .output_path = null, |
| 906 | .output_lib_path = null, | |
| 904 | 907 | .output_h_path = null, |
| 905 | 908 | .version = ver, |
| 906 | 909 | .out_filename = undefined, |
| 907 | 910 | .out_h_filename = builder.fmt("{}.h", name), |
| 911 | .out_lib_filename = undefined, | |
| 908 | 912 | .major_only_filename = undefined, |
| 909 | 913 | .name_only_filename = undefined, |
| 910 | 914 | .object_files = ArrayList([]const u8).init(builder.allocator), |
| ... | ... | @@ -941,21 +945,32 @@ pub const LibExeObjStep = struct { |
| 941 | 945 | }, |
| 942 | 946 | Kind.Lib => { |
| 943 | 947 | if (self.static) { |
| 944 | self.out_filename = self.builder.fmt("lib{}.a", self.name); | |
| 948 | switch (self.target.getOs()) { | |
| 949 | builtin.Os.windows => { | |
| 950 | self.out_filename = self.builder.fmt("{}.lib", self.name); | |
| 951 | }, | |
| 952 | else => { | |
| 953 | self.out_filename = self.builder.fmt("lib{}.a", self.name); | |
| 954 | }, | |
| 955 | } | |
| 956 | self.out_lib_filename = self.out_filename; | |
| 945 | 957 | } else { |
| 946 | 958 | switch (self.target.getOs()) { |
| 947 | 959 | builtin.Os.ios, builtin.Os.macosx => { |
| 948 | 960 | self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib", self.name, self.version.major, self.version.minor, self.version.patch); |
| 949 | 961 | self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", self.name, self.version.major); |
| 950 | 962 | self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name); |
| 963 | self.out_lib_filename = self.out_filename; | |
| 951 | 964 | }, |
| 952 | 965 | builtin.Os.windows => { |
| 953 | 966 | self.out_filename = self.builder.fmt("{}.dll", self.name); |
| 967 | self.out_lib_filename = self.builder.fmt("{}.lib", self.name); | |
| 954 | 968 | }, |
| 955 | 969 | else => { |
| 956 | 970 | self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}", self.name, self.version.major, self.version.minor, self.version.patch); |
| 957 | 971 | self.major_only_filename = self.builder.fmt("lib{}.so.{d}", self.name, self.version.major); |
| 958 | 972 | self.name_only_filename = self.builder.fmt("lib{}.so", self.name); |
| 973 | self.out_lib_filename = self.out_filename; | |
| 959 | 974 | }, |
| 960 | 975 | } |
| 961 | 976 | } |
| ... | ... | @@ -990,7 +1005,11 @@ pub const LibExeObjStep = struct { |
| 990 | 1005 | |
| 991 | 1006 | self.step.dependOn(&lib.step); |
| 992 | 1007 | |
| 993 | self.full_path_libs.append(lib.getOutputPath()) catch unreachable; | |
| 1008 | if (lib.static or self.target.isWindows()) { | |
| 1009 | self.object_files.append(lib.getOutputLibPath()) catch unreachable; | |
| 1010 | } else { | |
| 1011 | self.full_path_libs.append(lib.getOutputPath()) catch unreachable; | |
| 1012 | } | |
| 994 | 1013 | |
| 995 | 1014 | // TODO should be some kind of isolated directory that only has this header in it |
| 996 | 1015 | self.include_dirs.append(self.builder.cache_root) catch unreachable; |
| ... | ... | @@ -1060,6 +1079,22 @@ pub const LibExeObjStep = struct { |
| 1060 | 1079 | ) catch unreachable; |
| 1061 | 1080 | } |
| 1062 | 1081 | |
| 1082 | pub fn setOutputLibPath(self: *LibExeObjStep, file_path: []const u8) void { | |
| 1083 | assert(self.kind == Kind.Lib); | |
| 1084 | if (self.static) | |
| 1085 | return self.setOutputPath(file_path); | |
| 1086 | ||
| 1087 | self.output_lib_path = file_path; | |
| 1088 | } | |
| 1089 | ||
| 1090 | pub fn getOutputLibPath(self: *LibExeObjStep) []const u8 { | |
| 1091 | assert(self.kind == Kind.Lib); | |
| 1092 | return if (self.output_lib_path) |output_lib_path| output_lib_path else os.path.join( | |
| 1093 | self.builder.allocator, | |
| 1094 | [][]const u8{ self.builder.cache_root, self.out_lib_filename }, | |
| 1095 | ) catch unreachable; | |
| 1096 | } | |
| 1097 | ||
| 1063 | 1098 | pub fn setOutputHPath(self: *LibExeObjStep, file_path: []const u8) void { |
| 1064 | 1099 | self.output_h_path = file_path; |
| 1065 | 1100 | |
| ... | ... | @@ -1225,6 +1260,12 @@ pub const LibExeObjStep = struct { |
| 1225 | 1260 | zig_args.append("--output") catch unreachable; |
| 1226 | 1261 | zig_args.append(output_path) catch unreachable; |
| 1227 | 1262 | |
| 1263 | if (self.kind == Kind.Lib and !self.static) { | |
| 1264 | const output_lib_path = builder.pathFromRoot(self.getOutputLibPath()); | |
| 1265 | zig_args.append("--output-lib") catch unreachable; | |
| 1266 | zig_args.append(output_lib_path) catch unreachable; | |
| 1267 | } | |
| 1268 | ||
| 1228 | 1269 | if (self.kind != Kind.Exe) { |
| 1229 | 1270 | const output_h_path = self.getOutputHPath(); |
| 1230 | 1271 | zig_args.append("--output-h") catch unreachable; |
test/build_examples.zig+2-6| ... | ... | @@ -7,12 +7,8 @@ pub fn addCases(cases: *tests.BuildExamplesContext) void { |
| 7 | 7 | cases.addC("example/hello_world/hello_libc.zig"); |
| 8 | 8 | cases.add("example/cat/main.zig"); |
| 9 | 9 | cases.add("example/guess_number/main.zig"); |
| 10 | if (!is_windows) { | |
| 11 | // TODO get this test passing on windows | |
| 12 | // See https://github.com/ziglang/zig/issues/538 | |
| 13 | cases.addBuildFile("example/shared_library/build.zig"); | |
| 14 | cases.addBuildFile("example/mix_o_files/build.zig"); | |
| 15 | } | |
| 10 | cases.addBuildFile("example/shared_library/build.zig"); | |
| 11 | cases.addBuildFile("example/mix_o_files/build.zig"); | |
| 16 | 12 | if (builtin.os != builtin.Os.macosx) { |
| 17 | 13 | // TODO https://github.com/ziglang/zig/issues/1126 |
| 18 | 14 | cases.addBuildFile("test/standalone/issue_339/build.zig"); |