Rust · 5134 bytes Raw Blame History
1 use std::process::ExitCode;
2
3 use afs_ld::{args, diag, dump, LinkError, Linker};
4
5 fn usage() -> &'static str {
6 "\
7 Usage: afs-ld [options] <inputs...>
8
9 Options:
10 -o <path> Write output to <path>
11 -dylib Emit a dylib instead of an executable
12 -e <symbol> Set the entry symbol
13 -arch arm64 Select the arm64 target
14 -map <path> Emit text link map
15 -why_live <symbol> Print a reachability chain for <symbol>
16 -l<name> / -l <name> Search for library
17 -L <dir> Add library search path
18 -framework <name> Link framework
19 -weak_framework <name> Link weak framework
20 -ObjC Objective-C archive loading mode (currently a no-op warning)
21 -syslibroot <path> Prefix SDK search roots
22 -platform_version macos <min> <sdk>
23 Set LC_BUILD_VERSION payload
24 -r Relocatable output (deferred; errors)
25 -bundle Bundle output (deferred; errors)
26 -undefined <error|warning|suppress|dynamic_lookup>
27 Control unresolved-symbol treatment
28 -rpath <path> Add LC_RPATH
29 -install_name <path> Override dylib install name
30 -current_version <v> Override dylib current version
31 -compatibility_version <v> Override dylib compatibility version
32 -exported_symbols_list <file> Export only symbols matching file patterns
33 -unexported_symbols_list <file> Hide symbols matching file patterns
34 -exported_symbol <sym> Export one symbol/pattern
35 -unexported_symbol <sym> Hide one symbol/pattern
36 -x Strip local symbols
37 -S Strip debug symbols (currently a no-op warning)
38 -no_uuid Omit LC_UUID
39 -no_loh Accepted for compatibility (currently warns; no effect)
40 -thunks=<none|safe|all> Configure branch thunks
41 -dead_strip Dead-strip unreferenced code/data
42 -icf=safe | -icf=none | -icf=all
43 Configure identical code folding (`all` currently errors)
44 -fixup_chains | -no_fixup_chains
45 Select chained fixups vs classic dyld info
46 -all_load Force-load every archive member
47 -force_load <archive> Force-load one archive
48 -Wl,<arg,arg,...> Normalize comma-separated driver flags
49 --dump <path> Dump a Mach-O file summary
50 --dump-archive <path> Dump an archive summary
51 --dump-dylib <path> Dump a dylib summary
52 --dump-tbd <path> Dump a TBD summary
53 -t, -trace Print input paths as they are loaded
54 -h, --help Show this help
55 -v, --version Show afs-ld version
56 "
57 }
58
59 fn main() -> ExitCode {
60 let argv: Vec<String> = std::env::args().collect();
61
62 let opts = match args::parse(&argv[1..]) {
63 Ok(opts) => opts,
64 Err(e) => {
65 diag::error(&e.to_string());
66 return ExitCode::from(2);
67 }
68 };
69
70 if opts.show_help {
71 print!("{}", usage());
72 return ExitCode::SUCCESS;
73 }
74
75 if opts.show_version {
76 println!("afs-ld {}", env!("CARGO_PKG_VERSION"));
77 return ExitCode::SUCCESS;
78 }
79
80 if let Some(path) = &opts.dump {
81 return match dump::dump_file(path) {
82 Ok(()) => ExitCode::SUCCESS,
83 Err(e) => {
84 diag::error(&format!("{}: {}", path.display(), e));
85 ExitCode::from(1)
86 }
87 };
88 }
89
90 if let Some(path) = &opts.dump_archive {
91 return match dump::dump_archive_file(path) {
92 Ok(()) => ExitCode::SUCCESS,
93 Err(e) => {
94 diag::error(&format!("{}: {}", path.display(), e));
95 ExitCode::from(1)
96 }
97 };
98 }
99
100 if let Some(path) = &opts.dump_dylib {
101 return match dump::dump_dylib_file(path) {
102 Ok(()) => ExitCode::SUCCESS,
103 Err(e) => {
104 diag::error(&format!("{}: {}", path.display(), e));
105 ExitCode::from(1)
106 }
107 };
108 }
109
110 if let Some(path) = &opts.dump_tbd {
111 return match dump::dump_tbd_file(path) {
112 Ok(()) => ExitCode::SUCCESS,
113 Err(e) => {
114 diag::error(&format!("{}: {}", path.display(), e));
115 ExitCode::from(1)
116 }
117 };
118 }
119
120 match Linker::run(&opts) {
121 Ok(()) => ExitCode::SUCCESS,
122 Err(LinkError::NoInputs) => {
123 diag::error("no input files");
124 ExitCode::from(2)
125 }
126 Err(LinkError::DuplicateSymbols(msg)) | Err(LinkError::UndefinedSymbols(msg)) => {
127 diag::error_verbatim(&msg);
128 ExitCode::from(1)
129 }
130 Err(e) => {
131 diag::error(&e.to_string());
132 ExitCode::from(1)
133 }
134 }
135 }
136