Is there a way to import directly to the file without adding a constant?

Is there a way to use @import as if I copy-pasted the source to the file?

Let me explain a bit.
If I @import something, then I have to prefix any struct and/or function in it with the name of the constant, right? But what if I wanted to use it as if they were defined in this current file without having to prefix them?

Not without using the very likely to be axed usingnamespace keyword.

Then what other options would I have?

It’s mostly a “skill issue”, but currently I have the following setup:

  • I wrote a library/package/module, let’s call it “tui” on github
  • I have wrote an app/program that uses “tui”

The problem is that part of the “tui” (one file) is originally written in C and the only (?) way I got it all to work was to translate C to zig and build a static library with libC, then link this static library to the rest of the code.

However, somehow all of this does not work when I try to use “tui” as dependency (zig fetch --save git+https://...). It only works if I copy the same zig file that I generated from C and place it in my app/program repo as source file.

I guess I’m not approaching the problem from correct angle, but I’ve ran out of ideas how to fix it.

Never mind, I think I got it work.

I can @import the C → zig file directly… the downside is that now the whole project has libC dependency not just the static library that in theory could be copy-pasted.

But this does lead to followup question:
How do I module/package a static library with libC dependency in a way that I don’t have to link the rest of the code to libC?

If a library you use depends on libc, then generally your executable will need to link libc. Linking libc changes how your executable is built, even in the simple case of a static libc like musl. You’ll probably have to share your project if you want more specific help.

1 Like

Incorrect, it I build a static library that needs libC and target x86_64-linux-musl, then I can use this static library in the rest of the project without any need to link to libC because musl removes dynamic linking. That is a fact.

Here’s the links to the “library” and to the “app”:

simple text ui for zig

game that uses the tui

The tiny example in the “tui” library, for example, are build like this: the C stuff is compiled with libC, it becomes static library, and the rest of the code uses it without the need to link to libC.

Trying to do this is going against the grain of the language.

Every file defines an anonymous struct: the file itself can have fields, you can create an instance of it, and so on.

Structs are container types, meaning that they define a namespace. You can use usingnamespace to add all of the identifiers in a container type to the currently-scoped container (and you should if that’s a good solution to your needs, and post about it in the issue tracking removing it, I happen to think that it would be a mistake to remove it), but that doesn’t add identifiers to your scope directly: they exist in the namespace, but you would have to qualify them anyway to use them:

const MyFile = @This();
usingnamespace @import("foobarbaz.zig");
// Now you can do this:
MyFile.foo();
// But not this:
foo();

What this restriction does, is that when you see an identifier in code, you should be able to find where it comes from. Providing a way to import code as though it were already in the file cuts against this in two ways: the included source wouldn’t be a container, and a bunch of identifiers would show up out of nowhere.

That’s the main case against usingnamespace actually, it makes it more complex to figure out where identifiers in a namespace come from. I think that complexity is well worth it, in order to have an atomic operation “put that namespace inside this one”, leading to a single source of truth, and enabling some very nice metaprogramming patterns which simply cannot be satisfied without it with the same elegance.

But I understand the argument, and taking it to the next level where we can just inject identifiers directly into a namespace without qualifying them is on the other side of that line.

2 Likes

If you mean in the Zig build system, then yes the build system tracks that your library needs libc and therefore it will automatically link your executable with libc and the crt entry point without needing an explicit linkLibC() call. That is not unique to musl though.

1 Like

It appears that you are right about this.

But this in not intuitive. For other things you must explicitly declare what you do, but in this case there is some hidden magic that happens without declaring it.