authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-28 20:54:11-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-28 20:54:11-07:00
log0afb5b2ec6de494efe0605b2270f6a01b95237af
treeb43c1faae430a6a0ac3f5801a278d36a0a13ed04
parente248de93a07fd6a7f48581ce0d9f6f77a69c76de

stage2: add `zig ar` subcommand

The same entrypoint supports the following commands: * ar * ranlib * dlltool * lib For now, our strategy is to bundle the (renamed) `main()` function of llvm-ar, same as our strategy for `zig clang`. However, as Zig matures, a goal will be to replace the dependency on LLVM with our own implementation of this tool, so that it is available in builds of zig that do not have LLVM extensions enabled. This commit also categorizes the subcommands into categories in the --help menu.

3 files changed, 41 insertions(+), 8 deletions(-)

CMakeLists.txt+1
...@@ -319,6 +319,7 @@ set(OPTIMIZED_C_SOURCES...@@ -319,6 +319,7 @@ set(OPTIMIZED_C_SOURCES
319set(ZIG_CPP_SOURCES319set(ZIG_CPP_SOURCES
320 # These are planned to stay even when we are self-hosted.320 # These are planned to stay even when we are self-hosted.
321 "${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp"321 "${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp"
322 "${CMAKE_SOURCE_DIR}/src/zig_llvm-ar.cpp"
322 "${CMAKE_SOURCE_DIR}/src/zig_clang.cpp"323 "${CMAKE_SOURCE_DIR}/src/zig_clang.cpp"
323 "${CMAKE_SOURCE_DIR}/src/zig_clang_driver.cpp"324 "${CMAKE_SOURCE_DIR}/src/zig_clang_driver.cpp"
324 "${CMAKE_SOURCE_DIR}/src/zig_clang_cc1_main.cpp"325 "${CMAKE_SOURCE_DIR}/src/zig_clang_cc1_main.cpp"
src/main.zig+38-7
...@@ -43,22 +43,29 @@ const normal_usage =...@@ -43,22 +43,29 @@ const normal_usage =
43 \\Commands:43 \\Commands:
44 \\44 \\
45 \\ build Build project from build.zig45 \\ build Build project from build.zig
46 \\ init-exe Initialize a `zig build` application in the cwd
47 \\ init-lib Initialize a `zig build` library in the cwd
48 \\
49 \\ ast-check Look for simple compile errors in any set of files
46 \\ build-exe Create executable from source or object files50 \\ build-exe Create executable from source or object files
47 \\ build-lib Create library from source or object files51 \\ build-lib Create library from source or object files
48 \\ build-obj Create object from source or object files52 \\ build-obj Create object from source or object files
53 \\ fmt Reformat Zig source into canonical form
54 \\ run Create executable and run immediately
55 \\ test Create and run a test build
56 \\ translate-c Convert C code to Zig code
57 \\
58 \\ ar Use Zig as a drop-in archiver
49 \\ cc Use Zig as a drop-in C compiler59 \\ cc Use Zig as a drop-in C compiler
50 \\ c++ Use Zig as a drop-in C++ compiler60 \\ c++ Use Zig as a drop-in C++ compiler
61 \\ dlltool Use Zig as a drop-in dlltool.exe
62 \\ lib Use Zig as a drop-in lib.exe
63 \\ ranlib Use Zig as a drop-in ranlib
64 \\
51 \\ env Print lib path, std path, cache directory, and version65 \\ env Print lib path, std path, cache directory, and version
52 \\ fmt Reformat Zig source into canonical form
53 \\ ast-check Look for simple compile errors in any set of files
54 \\ help Print this help and exit66 \\ help Print this help and exit
55 \\ init-exe Initialize a `zig build` application in the cwd
56 \\ init-lib Initialize a `zig build` library in the cwd
57 \\ libc Display native libc paths file or validate one67 \\ libc Display native libc paths file or validate one
58 \\ run Create executable and run immediately
59 \\ translate-c Convert C code to Zig code
60 \\ targets List available compilation targets68 \\ targets List available compilation targets
61 \\ test Create and run a test build
62 \\ version Print version number and exit69 \\ version Print version number and exit
63 \\ zen Print Zen of Zig and exit70 \\ zen Print Zen of Zig and exit
64 \\71 \\
...@@ -201,6 +208,12 @@ pub fn mainArgs(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v...@@ -201,6 +208,12 @@ pub fn mainArgs(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v
201 return buildOutputType(gpa, arena, args, .zig_test);208 return buildOutputType(gpa, arena, args, .zig_test);
202 } else if (mem.eql(u8, cmd, "run")) {209 } else if (mem.eql(u8, cmd, "run")) {
203 return buildOutputType(gpa, arena, args, .run);210 return buildOutputType(gpa, arena, args, .run);
211 } else if (mem.eql(u8, cmd, "dlltool") or
212 mem.eql(u8, cmd, "ranlib") or
213 mem.eql(u8, cmd, "lib") or
214 mem.eql(u8, cmd, "ar"))
215 {
216 return punt_to_llvm_ar(arena, args);
204 } else if (mem.eql(u8, cmd, "cc")) {217 } else if (mem.eql(u8, cmd, "cc")) {
205 return buildOutputType(gpa, arena, args, .cc);218 return buildOutputType(gpa, arena, args, .cc);
206 } else if (mem.eql(u8, cmd, "c++")) {219 } else if (mem.eql(u8, cmd, "c++")) {
...@@ -3197,6 +3210,7 @@ pub const info_zen =...@@ -3197,6 +3210,7 @@ pub const info_zen =
3197;3210;
31983211
3199extern "c" fn ZigClang_main(argc: c_int, argv: [*:null]?[*:0]u8) c_int;3212extern "c" fn ZigClang_main(argc: c_int, argv: [*:null]?[*:0]u8) c_int;
3213extern "c" fn ZigLlvmAr_main(argc: c_int, argv: [*:null]?[*:0]u8) c_int;
32003214
3201/// TODO https://github.com/ziglang/zig/issues/32573215/// TODO https://github.com/ziglang/zig/issues/3257
3202fn punt_to_clang(arena: *Allocator, args: []const []const u8) error{OutOfMemory} {3216fn punt_to_clang(arena: *Allocator, args: []const []const u8) error{OutOfMemory} {
...@@ -3212,6 +3226,23 @@ fn punt_to_clang(arena: *Allocator, args: []const []const u8) error{OutOfMemory}...@@ -3212,6 +3226,23 @@ fn punt_to_clang(arena: *Allocator, args: []const []const u8) error{OutOfMemory}
3212 process.exit(@bitCast(u8, @truncate(i8, exit_code)));3226 process.exit(@bitCast(u8, @truncate(i8, exit_code)));
3213}3227}
32143228
3229/// TODO https://github.com/ziglang/zig/issues/3257
3230fn punt_to_llvm_ar(arena: *Allocator, args: []const []const u8) error{OutOfMemory} {
3231 if (!build_options.have_llvm)
3232 fatal("`zig ar`, `zig dlltool`, `zig ranlib', and `zig lib` unavailable: compiler built without LLVM extensions", .{});
3233
3234 // Convert the args to the format llvm-ar expects.
3235 // We subtract 1 to shave off the zig binary from args[0].
3236 const argv = try arena.allocSentinel(?[*:0]u8, args.len - 1, null);
3237 for (args[1..]) |arg, i| {
3238 // TODO If there was an argsAllocZ we could avoid this allocation.
3239 argv[i] = try arena.dupeZ(u8, arg);
3240 }
3241 const argc = @intCast(c_int, argv.len);
3242 const exit_code = ZigLlvmAr_main(argc, argv.ptr);
3243 process.exit(@bitCast(u8, @truncate(i8, exit_code)));
3244}
3245
3215/// The first argument determines which backend is invoked. The options are:3246/// The first argument determines which backend is invoked. The options are:
3216/// * `ld.lld` - ELF3247/// * `ld.lld` - ELF
3217/// * `ld64.lld` - Mach-O3248/// * `ld64.lld` - Mach-O
src/zig_llvm-ar.cpp+2-1
...@@ -1260,7 +1260,8 @@ static int ranlib_main(int argc, char **argv) {...@@ -1260,7 +1260,8 @@ static int ranlib_main(int argc, char **argv) {
1260 return performOperation(CreateSymTab, nullptr);1260 return performOperation(CreateSymTab, nullptr);
1261}1261}
12621262
1263int main(int argc, char **argv) {1263extern "C" int ZigLlvmAr_main(int argc, char **argv);
1264int ZigLlvmAr_main(int argc, char **argv) {
1264 InitLLVM X(argc, argv);1265 InitLLVM X(argc, argv);
1265 ToolName = argv[0];1266 ToolName = argv[0];
12661267