implement standard library path search

closes #463
See #302
master
Andrew Kelley 2017-10-01 18:29:50 -04:00
parent 9636603a3b
commit 1962c8588f
10 changed files with 147 additions and 32 deletions

View File

@ -327,8 +327,9 @@ set(ZIG_SOURCES
"${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp"
)
set(C_HEADERS_DEST "lib/zig/include")
set(ZIG_STD_DEST "lib/zig/std")
set(ZIG_LIB_DIR "lib/zig")
set(C_HEADERS_DEST "${ZIG_LIB_DIR}/include")
set(ZIG_STD_DEST "${ZIG_LIB_DIR}/std")
set(CONFIGURE_OUT_FILE "${CMAKE_BINARY_DIR}/config.h")
configure_file (
"${CMAKE_SOURCE_DIR}/src/config.h.in"

View File

@ -1456,7 +1456,9 @@ struct CodeGen {
Buf *libc_lib_dir;
Buf *libc_static_lib_dir;
Buf *libc_include_dir;
Buf *zig_lib_dir;
Buf *zig_std_dir;
Buf *zig_c_headers_dir;
Buf *zig_std_special_dir;
Buf *dynamic_linker;
Buf *ar_path;

View File

@ -56,13 +56,20 @@ static PackageTableEntry *new_package(const char *root_src_dir, const char *root
}
CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode,
Buf *zig_std_dir)
Buf *zig_lib_dir)
{
CodeGen *g = allocate<CodeGen>(1);
codegen_add_time_event(g, "Initialize");
g->zig_std_dir = zig_std_dir;
g->zig_lib_dir = zig_lib_dir;
g->zig_std_dir = buf_alloc();
os_path_join(zig_lib_dir, buf_create_from_str("std"), g->zig_std_dir);
g->zig_c_headers_dir = buf_alloc();
os_path_join(zig_lib_dir, buf_create_from_str("include"), g->zig_c_headers_dir);
g->build_mode = build_mode;
g->out_type = out_type;
g->import_table.init(32);

View File

@ -15,7 +15,7 @@
#include <stdio.h>
CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode,
Buf *zig_std_dir);
Buf *zig_lib_dir);
void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len);

View File

@ -13,8 +13,7 @@
#define ZIG_VERSION_PATCH @ZIG_VERSION_PATCH@
#define ZIG_VERSION_STRING "@ZIG_VERSION@"
#define ZIG_HEADERS_DIR "@CMAKE_INSTALL_PREFIX@/@C_HEADERS_DEST@"
#define ZIG_STD_DIR "@CMAKE_INSTALL_PREFIX@/@ZIG_STD_DEST@"
#define ZIG_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@"
#define ZIG_LIBC_INCLUDE_DIR "@ZIG_LIBC_INCLUDE_DIR_ESCAPED@"
#define ZIG_LIBC_LIB_DIR "@ZIG_LIBC_LIB_DIR_ESCAPED@"
#define ZIG_LIBC_STATIC_LIB_DIR "@ZIG_LIBC_STATIC_LIB_DIR_ESCAPED@"

View File

@ -34,7 +34,7 @@ static const char *get_libc_static_file(CodeGen *g, const char *file) {
static Buf *build_o_raw(CodeGen *parent_gen, const char *oname, Buf *full_path) {
ZigTarget *child_target = parent_gen->is_native_target ? nullptr : &parent_gen->zig_target;
CodeGen *child_gen = codegen_create(full_path, child_target, OutTypeObj, parent_gen->build_mode,
parent_gen->zig_std_dir);
parent_gen->zig_lib_dir);
child_gen->want_h_file = false;
child_gen->verbose_link = parent_gen->verbose_link;

View File

@ -49,7 +49,7 @@ static int usage(const char *arg0) {
" --verbose turn on compiler debug output\n"
" --verbose-link turn on compiler debug output for linking only\n"
" --verbose-ir turn on compiler debug output for IR only\n"
" --zig-std-dir [path] directory where zig standard library resides\n"
" --zig-install-prefix [path] override directory where zig thinks it is installed\n"
" -dirafter [dir] same as -isystem but do it last\n"
" -isystem [dir] add additional search path for other .h files\n"
" -mllvm [arg] additional arguments to forward to LLVM's option processing\n"
@ -131,6 +131,93 @@ static int print_target_list(FILE *f) {
return EXIT_SUCCESS;
}
static bool test_zig_install_prefix(Buf *test_path, Buf *out_zig_lib_dir) {
Buf lib_buf = BUF_INIT;
buf_init_from_str(&lib_buf, "lib");
Buf zig_buf = BUF_INIT;
buf_init_from_str(&zig_buf, "zig");
Buf std_buf = BUF_INIT;
buf_init_from_str(&std_buf, "std");
Buf index_zig_buf = BUF_INIT;
buf_init_from_str(&index_zig_buf, "index.zig");
Buf test_lib_dir = BUF_INIT;
Buf test_zig_dir = BUF_INIT;
Buf test_std_dir = BUF_INIT;
Buf test_index_file = BUF_INIT;
os_path_join(test_path, &lib_buf, &test_lib_dir);
os_path_join(&test_lib_dir, &zig_buf, &test_zig_dir);
os_path_join(&test_zig_dir, &std_buf, &test_std_dir);
os_path_join(&test_std_dir, &index_zig_buf, &test_index_file);
int err;
bool exists;
if ((err = os_file_exists(&test_index_file, &exists))) {
exists = false;
}
if (exists) {
buf_init_from_buf(out_zig_lib_dir, &test_zig_dir);
return true;
}
return false;
}
static int find_zig_lib_dir(Buf *out_path) {
int err;
Buf self_exe_path = BUF_INIT;
if (!(err = os_self_exe_path(&self_exe_path))) {
Buf *cur_path = &self_exe_path;
for (;;) {
Buf *test_dir = buf_alloc();
os_path_dirname(cur_path, test_dir);
if (buf_eql_buf(test_dir, cur_path)) {
break;
}
if (test_zig_install_prefix(test_dir, out_path)) {
return 0;
}
cur_path = test_dir;
}
}
if (ZIG_INSTALL_PREFIX != nullptr) {
if (test_zig_install_prefix(buf_create_from_str(ZIG_INSTALL_PREFIX), out_path)) {
return 0;
}
}
return ErrorFileNotFound;
}
static Buf *resolve_zig_lib_dir(const char *zig_install_prefix_arg) {
int err;
Buf *result = buf_alloc();
if (zig_install_prefix_arg == nullptr) {
if ((err = find_zig_lib_dir(result))) {
fprintf(stderr, "Unable to find zig lib directory. Reinstall Zig or use --zig-install-prefix.\n");
exit(EXIT_FAILURE);
}
return result;
}
Buf *zig_lib_dir_buf = buf_create_from_str(zig_install_prefix_arg);
if (test_zig_install_prefix(zig_lib_dir_buf, result)) {
return result;
}
fprintf(stderr, "No Zig installation found at prefix: %s\n", zig_install_prefix_arg);
exit(EXIT_FAILURE);
}
enum Cmd {
CmdInvalid,
CmdBuild,
@ -192,7 +279,7 @@ int main(int argc, char **argv) {
const char *libc_lib_dir = nullptr;
const char *libc_static_lib_dir = nullptr;
const char *libc_include_dir = nullptr;
const char *zig_std_dir = nullptr;
const char *zig_install_prefix = nullptr;
const char *dynamic_linker = nullptr;
ZigList<const char *> clang_argv = {0};
ZigList<const char *> llvm_argv = {0};
@ -248,29 +335,26 @@ int main(int argc, char **argv) {
} else if (i + 1 < argc && strcmp(argv[i], "--cache-dir") == 0) {
cache_dir = argv[i + 1];
i += 1;
} else if (i + 1 < argc && strcmp(argv[i], "--zig-std-dir") == 0) {
} else if (i + 1 < argc && strcmp(argv[i], "--zig-install-prefix") == 0) {
args.append(argv[i]);
i += 1;
zig_std_dir = argv[i];
args.append(zig_std_dir);
zig_install_prefix = argv[i];
args.append(zig_install_prefix);
} else {
args.append(argv[i]);
}
}
if (zig_std_dir == nullptr) {
zig_std_dir = ZIG_STD_DIR;
}
Buf *zig_std_dir_buf = buf_create_from_str(zig_std_dir);
Buf *zig_lib_dir_buf = resolve_zig_lib_dir(zig_install_prefix);
Buf *special_dir = buf_alloc();
os_path_join(zig_std_dir_buf, buf_sprintf("special"), special_dir);
os_path_join(zig_lib_dir_buf, buf_sprintf("special"), special_dir);
Buf *build_runner_path = buf_alloc();
os_path_join(special_dir, buf_create_from_str("build_runner.zig"), build_runner_path);
CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, zig_std_dir_buf);
CodeGen *g = codegen_create(build_runner_path, nullptr, OutTypeExe, BuildModeDebug, zig_lib_dir_buf);
codegen_set_out_name(g, buf_create_from_str("build"));
codegen_set_verbose(g, verbose);
@ -430,8 +514,8 @@ int main(int argc, char **argv) {
libc_static_lib_dir = argv[i];
} else if (strcmp(arg, "--libc-include-dir") == 0) {
libc_include_dir = argv[i];
} else if (strcmp(arg, "--zig-std-dir") == 0) {
zig_std_dir = argv[i];
} else if (strcmp(arg, "--zig-install-prefix") == 0) {
zig_install_prefix = argv[i];
} else if (strcmp(arg, "--dynamic-linker") == 0) {
dynamic_linker = argv[i];
} else if (strcmp(arg, "-isystem") == 0) {
@ -619,12 +703,9 @@ int main(int argc, char **argv) {
buf_create_from_str((cache_dir == nullptr) ? default_zig_cache_name : cache_dir),
full_cache_dir);
if (zig_std_dir == nullptr) {
zig_std_dir = ZIG_STD_DIR;
}
Buf *zig_lib_dir_buf = resolve_zig_lib_dir(zig_install_prefix);
CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode,
buf_create_from_str(zig_std_dir));
CodeGen *g = codegen_create(zig_root_source_file, target, out_type, build_mode, zig_lib_dir_buf);
codegen_set_out_name(g, buf_out_name);
codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);
codegen_set_is_test(g, cmd == CmdTest);

View File

@ -312,11 +312,12 @@ int os_fetch_file(FILE *f, Buf *out_buf) {
}
int os_file_exists(Buf *full_path, bool *result) {
#if defined(ZIG_OS_POSIX)
*result = access(buf_ptr(full_path), F_OK) != -1;
#if defined(ZIG_OS_WINDOWS)
*result = GetFileAttributes(buf_ptr(full_path)) != INVALID_FILE_ATTRIBUTES;
return 0;
#else
return GetFileAttributes(buf_ptr(full_path)) != INVALID_FILE_ATTRIBUTES;
*result = access(buf_ptr(full_path), F_OK) != -1;
return 0;
#endif
}
@ -835,3 +836,26 @@ int os_init(void) {
#endif
return 0;
}
int os_self_exe_path(Buf *out_path) {
#if defined(ZIG_OS_WINDOWS)
buf_resize(out_path, 256);
for (;;) {
DWORD copied_amt = GetModuleFileName(nullptr, buf_ptr(out_path), buf_len(out_path));
if (copied_amt <= 0) {
return ErrorFileNotFound;
}
if (copied_amt < buf_len(out_path)) {
buf_resize(out_path, copied_amt);
return 0;
}
buf_resize(out_path, buf_len(out_path) * 2);
}
#elif defined(ZIG_OS_DARWIN)
return ErrorFileNotFound;
#elif defined(ZIG_OS_LINUX)
return ErrorFileNotFound;
#endif
return ErrorFileNotFound;
}

View File

@ -64,6 +64,8 @@ double os_get_time(void);
bool os_is_sep(uint8_t c);
int os_self_exe_path(Buf *out_path);
#if defined(__APPLE__)
#define ZIG_OS_DARWIN
#elif defined(_WIN32)

View File

@ -8,7 +8,6 @@
#include "all_types.hpp"
#include "analyze.hpp"
#include "c_tokenizer.hpp"
#include "config.h"
#include "error.hpp"
#include "ir.hpp"
#include "os.hpp"
@ -3206,7 +3205,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
}
clang_argv.append("-isystem");
clang_argv.append(ZIG_HEADERS_DIR);
clang_argv.append(buf_ptr(codegen->zig_c_headers_dir));
clang_argv.append("-isystem");
clang_argv.append(buf_ptr(codegen->libc_include_dir));
@ -3244,7 +3243,7 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
bool allow_pch_with_compiler_errors = false;
bool single_file_parse = false;
bool for_serialization = false;
const char *resources_path = ZIG_HEADERS_DIR;
const char *resources_path = buf_ptr(codegen->zig_c_headers_dir);
std::unique_ptr<ASTUnit> err_unit;
std::unique_ptr<ASTUnit> ast_unit(ASTUnit::LoadFromCommandLine(
&clang_argv.at(0), &clang_argv.last(),