compile error for import outside package path

closes #2024

there's a new cli option `--main-pkg-path` which you can use to choose
a different root package directory besides the one inferred from the
root source file

and a corresponding build.zig API:
foo.setMainPkgPath(path)
This commit is contained in:
Andrew Kelley 2019-03-02 10:38:27 -05:00
parent 764205ac13
commit 67b4de33d2
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
16 changed files with 99 additions and 26 deletions

View File

@ -606,7 +606,6 @@ set(ZIG_STD_FILES
"os/windows/ntdll.zig"
"os/windows/ole32.zig"
"os/windows/shell32.zig"
"os/windows/tls.zig"
"os/windows/util.zig"
"os/zen.zig"
"pdb.zig"
@ -617,6 +616,7 @@ set(ZIG_STD_FILES
"sort.zig"
"special/bootstrap.zig"
"special/bootstrap_lib.zig"
"special/bootstrap_windows_tls.zig"
"special/build_runner.zig"
"special/builtin.zig"
"special/compiler_rt/addXf3.zig"

View File

@ -4502,6 +4502,9 @@ ZigType *add_source_file(CodeGen *g, ZigPackage *package, Buf *resolved_path, Bu
Buf *pkg_root_src_dir = &package->root_src_dir;
Buf resolved_root_src_dir = os_path_resolve(&pkg_root_src_dir, 1);
assert(buf_starts_with_buf(resolved_path, &resolved_root_src_dir));
Buf namespace_name = BUF_INIT;
buf_init_from_buf(&namespace_name, &package->pkg_path);
if (source_kind == SourceKindNonRoot) {

View File

@ -88,8 +88,8 @@ static const char *symbols_that_llvm_depends_on[] = {
// TODO probably all of compiler-rt needs to go here
};
CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode,
Buf *zig_lib_dir, Buf *override_std_dir, ZigLibCInstallation *libc)
CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
OutType out_type, BuildMode build_mode, Buf *zig_lib_dir, Buf *override_std_dir, ZigLibCInstallation *libc)
{
CodeGen *g = allocate<CodeGen>(1);
@ -133,16 +133,35 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
}
if (root_src_path) {
Buf *src_basename = buf_alloc();
Buf *src_dir = buf_alloc();
os_path_split(root_src_path, src_dir, src_basename);
Buf *root_pkg_path;
Buf *rel_root_src_path;
if (main_pkg_path == nullptr) {
Buf *src_basename = buf_alloc();
Buf *src_dir = buf_alloc();
os_path_split(root_src_path, src_dir, src_basename);
if (buf_len(src_basename) == 0) {
fprintf(stderr, "Invalid root source path: %s\n", buf_ptr(root_src_path));
exit(1);
if (buf_len(src_basename) == 0) {
fprintf(stderr, "Invalid root source path: %s\n", buf_ptr(root_src_path));
exit(1);
}
root_pkg_path = src_dir;
rel_root_src_path = src_basename;
} else {
Buf resolved_root_src_path = os_path_resolve(&root_src_path, 1);
Buf resolved_main_pkg_path = os_path_resolve(&main_pkg_path, 1);
if (!buf_starts_with_buf(&resolved_root_src_path, &resolved_main_pkg_path)) {
fprintf(stderr, "Root source path '%s' outside main package path '%s'",
buf_ptr(root_src_path), buf_ptr(main_pkg_path));
exit(1);
}
root_pkg_path = main_pkg_path;
rel_root_src_path = buf_create_from_mem(
buf_ptr(&resolved_root_src_path) + buf_len(&resolved_main_pkg_path) + 1,
buf_len(&resolved_root_src_path) - buf_len(&resolved_main_pkg_path) - 1);
}
g->root_package = new_package(buf_ptr(src_dir), buf_ptr(src_basename), "");
g->root_package = new_package(buf_ptr(root_pkg_path), buf_ptr(rel_root_src_path), "");
g->std_package = new_package(buf_ptr(g->zig_std_dir), "index.zig", "std");
g->root_package->package_table.put(buf_create_from_str("std"), g->std_package);
} else {

View File

@ -15,8 +15,8 @@
#include <stdio.h>
CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out_type, BuildMode build_mode,
Buf *zig_lib_dir, Buf *override_std_dir, ZigLibCInstallation *libc);
CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
OutType out_type, BuildMode build_mode, Buf *zig_lib_dir, Buf *override_std_dir, ZigLibCInstallation *libc);
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

@ -17026,6 +17026,18 @@ static IrInstruction *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructio
return ir_const_type(ira, &import_instruction->base, import_entry->value);
}
if (source_kind == SourceKindNonRoot) {
ZigPackage *cur_scope_pkg = scope_package(import_instruction->base.scope);
Buf *pkg_root_src_dir = &cur_scope_pkg->root_src_dir;
Buf resolved_root_src_dir = os_path_resolve(&pkg_root_src_dir, 1);
if (!buf_starts_with_buf(resolved_path, &resolved_root_src_dir)) {
ir_add_error_node(ira, source_node,
buf_sprintf("import of file outside package path: '%s'",
buf_ptr(import_target_path)));
return ira->codegen->invalid_instruction;
}
}
if ((err = file_fetch(ira->codegen, resolved_path, import_code))) {
if (err == ErrorFileNotFound) {
ir_add_error_node(ira, source_node,

View File

@ -41,7 +41,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path)
child_out_type = OutTypeObj;
}
CodeGen *child_gen = codegen_create(full_path, parent_gen->zig_target, child_out_type,
CodeGen *child_gen = codegen_create(nullptr, full_path, parent_gen->zig_target, child_out_type,
parent_gen->build_mode, parent_gen->zig_lib_dir, parent_gen->zig_std_dir,
parent_gen->libc);

View File

@ -63,6 +63,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
" --output-lib [file] override import library path\n"
" --pkg-begin [name] [path] make pkg available to import and push current pkg\n"
" --pkg-end pop current pkg\n"
" --main-pkg-path set the directory of the root package\n"
" --release-fast build with optimizations on and safety off\n"
" --release-safe build with optimizations on and safety on\n"
" --release-small build with size optimizations on and safety off\n"
@ -438,6 +439,7 @@ int main(int argc, char **argv) {
TargetSubsystem subsystem = TargetSubsystemAuto;
bool is_single_threaded = false;
Buf *override_std_dir = nullptr;
Buf *main_pkg_path = nullptr;
ValgrindSupport valgrind_support = ValgrindSupportAuto;
if (argc >= 2 && strcmp(argv[1], "build") == 0) {
@ -476,8 +478,8 @@ int main(int argc, char **argv) {
ZigTarget target;
get_native_target(&target);
CodeGen *g = codegen_create(build_runner_path, &target, OutTypeExe, BuildModeDebug, get_zig_lib_dir(),
override_std_dir, nullptr);
CodeGen *g = codegen_create(main_pkg_path, build_runner_path, &target, OutTypeExe,
BuildModeDebug, get_zig_lib_dir(), override_std_dir, nullptr);
g->valgrind_support = valgrind_support;
g->enable_time_report = timing_info;
buf_init_from_str(&g->cache_dir, cache_dir ? cache_dir : default_zig_cache_name);
@ -567,8 +569,8 @@ int main(int argc, char **argv) {
get_native_target(&target);
Buf *fmt_runner_path = buf_alloc();
os_path_join(get_zig_special_dir(), buf_create_from_str("fmt_runner.zig"), fmt_runner_path);
CodeGen *g = codegen_create(fmt_runner_path, &target, OutTypeExe, BuildModeDebug, get_zig_lib_dir(),
nullptr, nullptr);
CodeGen *g = codegen_create(main_pkg_path, fmt_runner_path, &target, OutTypeExe,
BuildModeDebug, get_zig_lib_dir(), nullptr, nullptr);
buf_init_from_str(&g->cache_dir, cache_dir ? cache_dir : default_zig_cache_name);
g->valgrind_support = valgrind_support;
g->is_single_threaded = true;
@ -729,6 +731,8 @@ int main(int argc, char **argv) {
llvm_argv.append(argv[i]);
} else if (strcmp(arg, "--override-std-dir") == 0) {
override_std_dir = buf_create_from_str(argv[i]);
} else if (strcmp(arg, "--main-pkg-path") == 0) {
main_pkg_path = buf_create_from_str(argv[i]);
} else if (strcmp(arg, "--library-path") == 0 || strcmp(arg, "-L") == 0) {
lib_dirs.append(argv[i]);
} else if (strcmp(arg, "--library") == 0) {
@ -908,8 +912,8 @@ int main(int argc, char **argv) {
return EXIT_SUCCESS;
}
case CmdBuiltin: {
CodeGen *g = codegen_create(nullptr, &target, out_type, build_mode, get_zig_lib_dir(), override_std_dir,
nullptr);
CodeGen *g = codegen_create(main_pkg_path, nullptr, &target,
out_type, build_mode, get_zig_lib_dir(), override_std_dir, nullptr);
g->valgrind_support = valgrind_support;
g->is_single_threaded = is_single_threaded;
Buf *builtin_source = codegen_generate_builtin_source(g);
@ -1012,8 +1016,8 @@ int main(int argc, char **argv) {
return EXIT_FAILURE;
}
}
CodeGen *g = codegen_create(zig_root_source_file, &target, out_type, build_mode, get_zig_lib_dir(),
override_std_dir, libc);
CodeGen *g = codegen_create(main_pkg_path, zig_root_source_file, &target, out_type, build_mode,
get_zig_lib_dir(), override_std_dir, libc);
g->valgrind_support = valgrind_support;
g->subsystem = subsystem;
@ -1096,7 +1100,6 @@ int main(int argc, char **argv) {
if (out_file_lib != nullptr && out_type == OutTypeLib && !is_static)
codegen_set_output_lib_path(g, buf_create_from_str(out_file_lib));
add_package(g, cur_pkg, g->root_package);
if (cmd == CmdBuild || cmd == CmdRun || cmd == CmdTest) {

View File

@ -859,6 +859,7 @@ pub const LibExeObjStep = struct {
verbose_cc: bool,
c_std: Builder.CStd,
override_std_dir: ?[]const u8,
main_pkg_path: ?[]const u8,
exec_cmd_args: ?[]const ?[]const u8,
name_prefix: []const u8,
filter: ?[]const u8,
@ -950,6 +951,7 @@ pub const LibExeObjStep = struct {
.c_std = Builder.CStd.C99,
.system_linker_hack = false,
.override_std_dir = null,
.main_pkg_path = null,
.exec_cmd_args = null,
.name_prefix = "",
.filter = null,
@ -1098,6 +1100,10 @@ pub const LibExeObjStep = struct {
self.override_std_dir = dir_path;
}
pub fn setMainPkgPath(self: *LibExeObjStep, dir_path: []const u8) void {
self.main_pkg_path = dir_path;
}
pub fn setOutputPath(self: *LibExeObjStep, file_path: []const u8) void {
self.output_path = file_path;
@ -1424,6 +1430,11 @@ pub const LibExeObjStep = struct {
try zig_args.append(builder.pathFromRoot(dir));
}
if (self.main_pkg_path) |dir| {
try zig_args.append("--main-pkg-path");
try zig_args.append(builder.pathFromRoot(dir));
}
try builder.spawnChild(zig_args.toSliceConst());
if (self.kind == Kind.Lib and !self.static and self.target.wantSharedLibSymLinks()) {

View File

@ -46,7 +46,7 @@ nakedcc fn _start() noreturn {
extern fn WinMainCRTStartup() noreturn {
@setAlignStack(16);
if (!builtin.single_threaded) {
_ = @import("../os/windows/tls.zig");
_ = @import("bootstrap_windows_tls.zig");
}
std.os.windows.ExitProcess(callMain());
}

View File

@ -1,4 +1,4 @@
const std = @import("../../index.zig");
const std = @import("std");
export var _tls_index: u32 = std.os.windows.TLS_OUT_OF_INDEXES;
export var _tls_start: u8 linksection(".tls") = 0;
@ -26,7 +26,7 @@ pub const IMAGE_TLS_DIRECTORY = extern struct {
SizeOfZeroFill: u32,
Characteristics: u32,
};
export const _tls_used linksection(".rdata$T") = IMAGE_TLS_DIRECTORY {
export const _tls_used linksection(".rdata$T") = IMAGE_TLS_DIRECTORY{
.StartAddressOfRawData = &_tls_start,
.EndAddressOfRawData = &_tls_end,
.AddressOfIndex = &_tls_index,

View File

@ -134,7 +134,7 @@ nakedcc fn clone() void {
}
}
const math = @import("../math/index.zig");
const math = std.math;
export fn fmodf(x: f32, y: f32) f32 {
return generic_fmod(f32, x, y);

View File

@ -7,6 +7,7 @@ pub fn addCases(cases: *tests.BuildExamplesContext) void {
cases.addC("example/hello_world/hello_libc.zig");
cases.add("example/cat/main.zig");
cases.add("example/guess_number/main.zig");
cases.addBuildFile("test/standalone/main_pkg_path/build.zig");
cases.addBuildFile("example/shared_library/build.zig");
cases.addBuildFile("example/mix_o_files/build.zig");
if (builtin.os != builtin.Os.macosx) {

View File

@ -2,6 +2,15 @@ const tests = @import("tests.zig");
const builtin = @import("builtin");
pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"import outside package path",
\\comptime{
\\ _ = @import("../a.zig");
\\}
,
"tmp.zig:2:9: error: import of file outside package path: '../a.zig'",
);
cases.add(
"bogus compile var",
\\const x = @import("builtin").bogus;

View File

@ -0,0 +1,5 @@
const b = @import("../b.zig");
test "main pkg path" {
b.foo();
}

View File

@ -0,0 +1 @@
pub fn foo() void {}

View File

@ -0,0 +1,9 @@
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const test_exe = b.addTest("a/test.zig");
test_exe.setMainPkgPath(".");
const test_step = b.step("test", "Test the program");
test_step.dependOn(&test_exe.step);
}