mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
support static linking against libc
This commit is contained in:
parent
ea3bd58563
commit
430d0dfcb2
@ -70,13 +70,14 @@ compromises backward compatibility.
|
|||||||
|
|
||||||
### Debug / Development Build
|
### Debug / Development Build
|
||||||
|
|
||||||
If you have gcc or clang installed, you can find out what `ZIG_LIBC_LIB_DIR` should
|
If you have gcc or clang installed, you can find out what `ZIG_LIBC_LIB_DIR`
|
||||||
be set to (example below). `ZIG_LIBC_INCLUDE_DIR` likely can be set to `/usr/include`.
|
and `ZIG_LIBC_STATIC_LIB_DIR` should be set to (example below).
|
||||||
|
`ZIG_LIBC_INCLUDE_DIR` likely can be set to `/usr/include`.
|
||||||
|
|
||||||
```
|
```
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DCMAKE_INSTALL_PREFIX=$(pwd) -DZIG_LIBC_LIB_DIR=$(dirname $(cc -print-file-name=crt1.o)) -DZIG_LIBC_INCLUDE_DIR=/usr/include
|
cmake .. -DCMAKE_INSTALL_PREFIX=$(pwd) -DZIG_LIBC_LIB_DIR=$(dirname $(cc -print-file-name=crt1.o)) -DZIG_LIBC_INCLUDE_DIR=/usr/include -DZIG_LIBC_STATIC_LIB_DIR=$(dirname $(cc -print-file-name=crtbeginT.o))
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
./run_tests
|
./run_tests
|
||||||
@ -90,7 +91,7 @@ by the `--libc-lib-dir` and `--libc-include-dir` parameters to the zig binary.
|
|||||||
```
|
```
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DZIG_LIBC_LIB_DIR=/some/path -DZIG_LIBC_INCLUDE_DIR=/some/path
|
cmake .. -DCMAKE_BUILD_TYPE=Release -DZIG_LIBC_LIB_DIR=/some/path -DZIG_LIBC_INCLUDE_DIR=/some/path -DZIG_LIBC_STATIC_INCLUDE_DIR=/some/path
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
```
|
```
|
||||||
|
|||||||
@ -1104,6 +1104,7 @@ struct CodeGen {
|
|||||||
bool have_exported_main;
|
bool have_exported_main;
|
||||||
bool link_libc;
|
bool link_libc;
|
||||||
Buf *libc_lib_dir;
|
Buf *libc_lib_dir;
|
||||||
|
Buf *libc_static_lib_dir;
|
||||||
Buf *libc_include_dir;
|
Buf *libc_include_dir;
|
||||||
bool is_release_build;
|
bool is_release_build;
|
||||||
bool is_test_build;
|
bool is_test_build;
|
||||||
|
|||||||
@ -5852,6 +5852,9 @@ void find_libc_path(CodeGen *g) {
|
|||||||
if (!g->libc_lib_dir || buf_len(g->libc_lib_dir) == 0) {
|
if (!g->libc_lib_dir || buf_len(g->libc_lib_dir) == 0) {
|
||||||
zig_panic("Unable to determine libc lib path. probably need to reconfigure");
|
zig_panic("Unable to determine libc lib path. probably need to reconfigure");
|
||||||
}
|
}
|
||||||
|
if (!g->libc_static_lib_dir || buf_len(g->libc_static_lib_dir) == 0) {
|
||||||
|
zig_panic("Unable to determine libc static lib path. probably need to reconfigure");
|
||||||
|
}
|
||||||
if (!g->libc_include_dir || buf_len(g->libc_include_dir) == 0) {
|
if (!g->libc_include_dir || buf_len(g->libc_include_dir) == 0) {
|
||||||
zig_panic("Unable to determine libc include path. probably need to reconfigure");
|
zig_panic("Unable to determine libc include path. probably need to reconfigure");
|
||||||
}
|
}
|
||||||
|
|||||||
127
src/codegen.cpp
127
src/codegen.cpp
@ -35,6 +35,7 @@ CodeGen *codegen_create(Buf *root_source_dir) {
|
|||||||
g->error_value_count = 1;
|
g->error_value_count = 1;
|
||||||
|
|
||||||
g->libc_lib_dir = buf_create_from_str(ZIG_LIBC_LIB_DIR);
|
g->libc_lib_dir = buf_create_from_str(ZIG_LIBC_LIB_DIR);
|
||||||
|
g->libc_static_lib_dir = buf_create_from_str(ZIG_LIBC_STATIC_LIB_DIR);
|
||||||
g->libc_include_dir = buf_create_from_str(ZIG_LIBC_INCLUDE_DIR);
|
g->libc_include_dir = buf_create_from_str(ZIG_LIBC_INCLUDE_DIR);
|
||||||
|
|
||||||
return g;
|
return g;
|
||||||
@ -81,6 +82,10 @@ void codegen_set_libc_lib_dir(CodeGen *g, Buf *libc_lib_dir) {
|
|||||||
g->libc_lib_dir = libc_lib_dir;
|
g->libc_lib_dir = libc_lib_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void codegen_set_libc_static_lib_dir(CodeGen *g, Buf *libc_static_lib_dir) {
|
||||||
|
g->libc_static_lib_dir = libc_static_lib_dir;
|
||||||
|
}
|
||||||
|
|
||||||
void codegen_set_libc_include_dir(CodeGen *g, Buf *libc_include_dir) {
|
void codegen_set_libc_include_dir(CodeGen *g, Buf *libc_include_dir) {
|
||||||
g->libc_include_dir = libc_include_dir;
|
g->libc_include_dir = libc_include_dir;
|
||||||
}
|
}
|
||||||
@ -4010,6 +4015,12 @@ static const char *get_libc_file(CodeGen *g, const char *file) {
|
|||||||
return buf_ptr(out_buf);
|
return buf_ptr(out_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *get_libc_static_file(CodeGen *g, const char *file) {
|
||||||
|
Buf *out_buf = buf_alloc();
|
||||||
|
os_path_join(g->libc_static_lib_dir, buf_create_from_str(file), out_buf);
|
||||||
|
return buf_ptr(out_buf);
|
||||||
|
}
|
||||||
|
|
||||||
static Buf *build_o(CodeGen *parent_gen, const char *oname) {
|
static Buf *build_o(CodeGen *parent_gen, const char *oname) {
|
||||||
Buf *source_basename = buf_sprintf("%s.zig", oname);
|
Buf *source_basename = buf_sprintf("%s.zig", oname);
|
||||||
Buf *std_dir_path = buf_create_from_str(ZIG_STD_DIR);
|
Buf *std_dir_path = buf_create_from_str(ZIG_STD_DIR);
|
||||||
@ -4096,27 +4107,63 @@ void codegen_link(CodeGen *g, const char *out_file) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool link_in_crt = (g->link_libc && g->out_type == OutTypeExe);
|
||||||
|
if (link_in_crt) {
|
||||||
|
find_libc_path(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// invoke `ld`
|
// invoke `ld`
|
||||||
ZigList<const char *> args = {0};
|
ZigList<const char *> args = {0};
|
||||||
const char *crt1o;
|
|
||||||
|
// TODO make this target dependent
|
||||||
|
args.append("-m");
|
||||||
|
args.append("elf_x86_64");
|
||||||
|
|
||||||
if (g->is_static) {
|
if (g->is_static) {
|
||||||
args.append("-static");
|
args.append("-static");
|
||||||
crt1o = "crt1.o";
|
}
|
||||||
} else {
|
|
||||||
crt1o = "Scrt1.o";
|
args.append("-o");
|
||||||
|
args.append(out_file);
|
||||||
|
|
||||||
|
if (link_in_crt) {
|
||||||
|
const char *crt1o;
|
||||||
|
const char *crtbegino;
|
||||||
|
if (g->is_static) {
|
||||||
|
crt1o = "crt1.o";
|
||||||
|
crtbegino = "crtbeginT.o";
|
||||||
|
} else {
|
||||||
|
crt1o = "Scrt1.o";
|
||||||
|
crtbegino = "crtbegin.o";
|
||||||
|
}
|
||||||
|
args.append(get_libc_file(g, crt1o));
|
||||||
|
args.append(get_libc_file(g, "crti.o"));
|
||||||
|
args.append(get_libc_static_file(g, crtbegino));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < g->lib_dirs.length; i += 1) {
|
||||||
|
const char *lib_dir = g->lib_dirs.at(i);
|
||||||
|
args.append("-L");
|
||||||
|
args.append(lib_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g->link_libc) {
|
||||||
|
args.append("-L");
|
||||||
|
args.append(buf_ptr(g->libc_lib_dir));
|
||||||
|
|
||||||
|
args.append("-L");
|
||||||
|
args.append(buf_ptr(g->libc_static_lib_dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO don't pass this parameter unless linking with libc
|
// TODO don't pass this parameter unless linking with libc
|
||||||
char *ZIG_NATIVE_DYNAMIC_LINKER = getenv("ZIG_NATIVE_DYNAMIC_LINKER");
|
if (ZIG_DYNAMIC_LINKER[0] == 0) {
|
||||||
if (g->is_native_target && ZIG_NATIVE_DYNAMIC_LINKER) {
|
|
||||||
if (ZIG_NATIVE_DYNAMIC_LINKER[0] != 0) {
|
|
||||||
args.append("-dynamic-linker");
|
|
||||||
args.append(ZIG_NATIVE_DYNAMIC_LINKER);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
args.append("-dynamic-linker");
|
args.append("-dynamic-linker");
|
||||||
args.append(buf_ptr(get_dynamic_linker(g->target_machine)));
|
args.append(buf_ptr(get_dynamic_linker(g->target_machine)));
|
||||||
|
} else {
|
||||||
|
args.append("-dynamic-linker");
|
||||||
|
args.append(ZIG_DYNAMIC_LINKER);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g->out_type == OutTypeLib) {
|
if (g->out_type == OutTypeLib) {
|
||||||
@ -4129,24 +4176,9 @@ void codegen_link(CodeGen *g, const char *out_file) {
|
|||||||
out_file = buf_ptr(out_lib_so);
|
out_file = buf_ptr(out_lib_so);
|
||||||
}
|
}
|
||||||
|
|
||||||
args.append("-o");
|
// .o files
|
||||||
args.append(out_file);
|
|
||||||
|
|
||||||
bool link_in_crt = (g->link_libc && g->out_type == OutTypeExe);
|
|
||||||
|
|
||||||
if (link_in_crt) {
|
|
||||||
find_libc_path(g);
|
|
||||||
|
|
||||||
args.append(get_libc_file(g, crt1o));
|
|
||||||
args.append(get_libc_file(g, "crti.o"));
|
|
||||||
}
|
|
||||||
|
|
||||||
args.append((const char *)buf_ptr(&out_file_o));
|
args.append((const char *)buf_ptr(&out_file_o));
|
||||||
|
|
||||||
if (link_in_crt) {
|
|
||||||
args.append(get_libc_file(g, "crtn.o"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g->is_test_build) {
|
if (g->is_test_build) {
|
||||||
const char *test_runner_name = g->link_libc ? "test_runner_libc" : "test_runner_nolibc";
|
const char *test_runner_name = g->link_libc ? "test_runner_libc" : "test_runner_nolibc";
|
||||||
Buf *test_runner_o_path = build_o(g, test_runner_name);
|
Buf *test_runner_o_path = build_o(g, test_runner_name);
|
||||||
@ -4158,20 +4190,45 @@ void codegen_link(CodeGen *g, const char *out_file) {
|
|||||||
args.append(buf_ptr(builtin_o_path));
|
args.append(buf_ptr(builtin_o_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < g->lib_dirs.length; i += 1) {
|
|
||||||
const char *lib_dir = g->lib_dirs.at(i);
|
|
||||||
args.append("-L");
|
|
||||||
args.append(lib_dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto it = g->link_table.entry_iterator();
|
auto it = g->link_table.entry_iterator();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
auto *entry = it.next();
|
auto *entry = it.next();
|
||||||
if (!entry)
|
if (!entry)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Buf *arg = buf_sprintf("-l%s", buf_ptr(entry->key));
|
// we handle libc explicitly, don't do it here
|
||||||
args.append(buf_ptr(arg));
|
if (!buf_eql_str(entry->key, "c")) {
|
||||||
|
Buf *arg = buf_sprintf("-l%s", buf_ptr(entry->key));
|
||||||
|
args.append(buf_ptr(arg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// libc dep
|
||||||
|
if (g->link_libc) {
|
||||||
|
if (g->is_static) {
|
||||||
|
args.append("--start-group");
|
||||||
|
args.append("-lgcc");
|
||||||
|
args.append("-lgcc_eh");
|
||||||
|
args.append("-lc");
|
||||||
|
args.append("--end-group");
|
||||||
|
} else {
|
||||||
|
args.append("-lgcc");
|
||||||
|
args.append("--as-needed");
|
||||||
|
args.append("-lgcc_s");
|
||||||
|
args.append("--no-as-needed");
|
||||||
|
args.append("-lc");
|
||||||
|
args.append("-lgcc");
|
||||||
|
args.append("--as-needed");
|
||||||
|
args.append("-lgcc_s");
|
||||||
|
args.append("--no-as-needed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// crt end
|
||||||
|
if (link_in_crt) {
|
||||||
|
args.append(get_libc_static_file(g, "crtend.o"));
|
||||||
|
args.append(get_libc_file(g, "crtn.o"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g->verbose) {
|
if (g->verbose) {
|
||||||
|
|||||||
@ -26,6 +26,7 @@ void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);
|
|||||||
void codegen_set_out_type(CodeGen *codegen, OutType out_type);
|
void codegen_set_out_type(CodeGen *codegen, OutType out_type);
|
||||||
void codegen_set_out_name(CodeGen *codegen, Buf *out_name);
|
void codegen_set_out_name(CodeGen *codegen, Buf *out_name);
|
||||||
void codegen_set_libc_lib_dir(CodeGen *codegen, Buf *libc_lib_dir);
|
void codegen_set_libc_lib_dir(CodeGen *codegen, Buf *libc_lib_dir);
|
||||||
|
void codegen_set_libc_static_lib_dir(CodeGen *g, Buf *libc_static_lib_dir);
|
||||||
void codegen_set_libc_include_dir(CodeGen *codegen, Buf *libc_include_dir);
|
void codegen_set_libc_include_dir(CodeGen *codegen, Buf *libc_include_dir);
|
||||||
void codegen_add_lib_dir(CodeGen *codegen, const char *dir);
|
void codegen_add_lib_dir(CodeGen *codegen, const char *dir);
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,8 @@
|
|||||||
#define ZIG_STD_DIR "@CMAKE_INSTALL_PREFIX@/@ZIG_STD_DEST@"
|
#define ZIG_STD_DIR "@CMAKE_INSTALL_PREFIX@/@ZIG_STD_DEST@"
|
||||||
#define ZIG_LIBC_INCLUDE_DIR "@ZIG_LIBC_INCLUDE_DIR@"
|
#define ZIG_LIBC_INCLUDE_DIR "@ZIG_LIBC_INCLUDE_DIR@"
|
||||||
#define ZIG_LIBC_LIB_DIR "@ZIG_LIBC_LIB_DIR@"
|
#define ZIG_LIBC_LIB_DIR "@ZIG_LIBC_LIB_DIR@"
|
||||||
|
#define ZIG_LIBC_STATIC_LIB_DIR "@ZIG_LIBC_STATIC_LIB_DIR@"
|
||||||
|
#define ZIG_DYNAMIC_LINKER "@ZIG_DYNAMIC_LINKER@"
|
||||||
|
|
||||||
#cmakedefine ZIG_LLVM_OLD_CXX_ABI
|
#cmakedefine ZIG_LLVM_OLD_CXX_ABI
|
||||||
|
|
||||||
|
|||||||
40
src/main.cpp
40
src/main.cpp
@ -16,24 +16,25 @@
|
|||||||
static int usage(const char *arg0) {
|
static int usage(const char *arg0) {
|
||||||
fprintf(stderr, "Usage: %s [command] [options]\n"
|
fprintf(stderr, "Usage: %s [command] [options]\n"
|
||||||
"Commands:\n"
|
"Commands:\n"
|
||||||
" build create executable, object, or library from target\n"
|
" build create executable, object, or library from target\n"
|
||||||
" test create and run a test build\n"
|
" test create and run a test build\n"
|
||||||
" version print version number and exit\n"
|
" version print version number and exit\n"
|
||||||
" parseh convert a c header file to zig extern declarations\n"
|
" parseh convert a c header file to zig extern declarations\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
" --release build with optimizations on and debug protection off\n"
|
" --release build with optimizations on and debug protection off\n"
|
||||||
" --static output will be statically linked\n"
|
" --static output will be statically linked\n"
|
||||||
" --strip exclude debug symbols\n"
|
" --strip exclude debug symbols\n"
|
||||||
" --export [exe|lib|obj] override output type\n"
|
" --export [exe|lib|obj] override output type\n"
|
||||||
" --name [name] override output name\n"
|
" --name [name] override output name\n"
|
||||||
" --output [file] override destination path\n"
|
" --output [file] override destination path\n"
|
||||||
" --verbose turn on compiler debug output\n"
|
" --verbose turn on compiler debug output\n"
|
||||||
" --color [auto|off|on] enable or disable colored error messages\n"
|
" --color [auto|off|on] enable or disable colored error messages\n"
|
||||||
" --libc-lib-dir [path] set the C compiler data path\n"
|
" --libc-lib-dir [path] set the C compiler data path\n"
|
||||||
" --libc-include-dir [path] set the C compiler data path\n"
|
" --libc-static-lib-dir [path] set the C compiler data path\n"
|
||||||
" -isystem [dir] add additional search path for other .h files\n"
|
" --libc-include-dir [path] set the C compiler data path\n"
|
||||||
" -dirafter [dir] same as -isystem but do it last\n"
|
" -isystem [dir] add additional search path for other .h files\n"
|
||||||
" --library-path [dir] add a directory to the library search path\n"
|
" -dirafter [dir] same as -isystem but do it last\n"
|
||||||
|
" --library-path [dir] add a directory to the library search path\n"
|
||||||
, arg0);
|
, arg0);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@ -59,6 +60,7 @@ int main(int argc, char **argv) {
|
|||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
ErrColor color = ErrColorAuto;
|
ErrColor color = ErrColorAuto;
|
||||||
const char *libc_lib_dir = nullptr;
|
const char *libc_lib_dir = nullptr;
|
||||||
|
const char *libc_static_lib_dir = nullptr;
|
||||||
const char *libc_include_dir = nullptr;
|
const char *libc_include_dir = nullptr;
|
||||||
ZigList<const char *> clang_argv = {0};
|
ZigList<const char *> clang_argv = {0};
|
||||||
ZigList<const char *> lib_dirs = {0};
|
ZigList<const char *> lib_dirs = {0};
|
||||||
@ -108,6 +110,8 @@ int main(int argc, char **argv) {
|
|||||||
out_name = argv[i];
|
out_name = argv[i];
|
||||||
} else if (strcmp(arg, "--libc-lib-dir") == 0) {
|
} else if (strcmp(arg, "--libc-lib-dir") == 0) {
|
||||||
libc_lib_dir = argv[i];
|
libc_lib_dir = argv[i];
|
||||||
|
} else if (strcmp(arg, "--libc-static-lib-dir") == 0) {
|
||||||
|
libc_static_lib_dir = argv[i];
|
||||||
} else if (strcmp(arg, "--libc-include-dir") == 0) {
|
} else if (strcmp(arg, "--libc-include-dir") == 0) {
|
||||||
libc_include_dir = argv[i];
|
libc_include_dir = argv[i];
|
||||||
} else if (strcmp(arg, "-isystem") == 0) {
|
} else if (strcmp(arg, "-isystem") == 0) {
|
||||||
@ -202,6 +206,8 @@ int main(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
if (libc_lib_dir)
|
if (libc_lib_dir)
|
||||||
codegen_set_libc_lib_dir(g, buf_create_from_str(libc_lib_dir));
|
codegen_set_libc_lib_dir(g, buf_create_from_str(libc_lib_dir));
|
||||||
|
if (libc_static_lib_dir)
|
||||||
|
codegen_set_libc_static_lib_dir(g, buf_create_from_str(libc_static_lib_dir));
|
||||||
if (libc_include_dir)
|
if (libc_include_dir)
|
||||||
codegen_set_libc_include_dir(g, buf_create_from_str(libc_include_dir));
|
codegen_set_libc_include_dir(g, buf_create_from_str(libc_include_dir));
|
||||||
codegen_set_verbose(g, verbose);
|
codegen_set_verbose(g, verbose);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user