Skip to content

update CLI to remove --c-source, observe file extensions, and better handle C flags #3508

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
andrewrk opened this issue Oct 23, 2019 · 3 comments
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@andrewrk
Copy link
Member

Currently --c-source is used to pass things to clang, and one positional argument is accepted as the root zig source file. --c-source accepts C flags until the next positional argument, but this fails when there are C flags zig is unaware of that expect a positional argument.

Another related issue is that we have unwanted warnings when compiling assembly files: #2741

It's also more awkward to compile C code than it is with C compilers. I propose that these examples will work:

zig build-exe hello.c -lc
zig build-obj foo.s
zig build-exe foo.c main.zig bar.c

Zig will decide how to handle a positional argument based on whether the extension is .zig or not.

More than 1 zig positional argument will continue to be an error: there can only be 1 root source file.

Now about C flags. Many C flags have the same name in Zig CLI args, such as -I, -L, and -isystem. These flags already properly propagate to compiled C code. When there is a flag such as this, and it's desired to apply to all the C files on the command line, that's the preferred thing to do.

But maybe you want to have 3 c files, one with -std=c11 and two with -std=gnu99. Both want -ftrapv. I propose -cflags and -- for this:

zig build-exe main.zig -cflags -std=c11 -ftrapv -- obj1.c -cflags -std=gnu99 -ftrapv -- obj2.c obj3.c

How it works is that -cflags starts a list of C flags. -- ends the list. From that point on, this list of flags apply to all non-zig positional arguments. Another -cflags argument clears the list and accepts a new list. Clearing all flags would be done like this: -cflags --. These C flags are applied after the flags that zig internally adds to the command line, and so they can be used to override, however this should be done with caution.

The build.zig API for this would be unchanged, and in fact some build scripts that previously would not work due to positional C flags would start working.

See also #3475, it will probably be a good idea to fix the CLI for zig run in the implementation of this issue as well. It's related because of how positional arguments are handled.

@andrewrk andrewrk added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Oct 23, 2019
@andrewrk andrewrk added this to the 0.6.0 milestone Oct 23, 2019
@JesseRMeyer
Copy link

For settings that are often written once, and for alternative workflows, I prefer more verbose names that provide the context of the setting. Here, that would resemble:

-begin_cflags < ... > -end_cflags

Then it's obvious to anyone what is happening.

We could also implicitly end the -cflags once a C file was encountered in the list. Maybe that doesn't work in general due to the issue you open with. In that case, is there much harm in separating the build over multiple zig incantations -- especially if the structure of the build appears to require different stages?

@andrewrk
Copy link
Member Author

-begin_cflags < ... > -end_cflags

Yeah let's do this. It will be --cflags-begin and --cflags-end, to match --pkg-begin and --pkg-end.

We could also implicitly end the -cflags once a C file was encountered in the list. Maybe that doesn't work in general due to the issue you open with.

This would require zig knowing about every C command line flag that takes a positional argument, which it currently does not.

In that case, is there much harm in separating the build over multiple zig incantations -- especially if the structure of the build appears to require different stages?

Yes - this actually gives less information to the compiler. For example, when you use zig build-exe, for some targets and depending on some of the other parameters, zig might be able to make a non-PIC executable. However splitting it up into objects and linking separately makes zig lose information and so it must "play it safe" and emit PIC by default.

The stage1 compiler does not do parallelization, but the self-hosted one will. Giving all the information at once will provided the fastest build. This will be especially true when we end up doing a "fast mode" feature, where the goal is to compile as fast as possible.

@JesseRMeyer
Copy link

However splitting it up into objects and linking separately makes zig lose information

I trust your experience here. I thought all of this information was recoverable at link time, assuming the linker is provided the entire IR from all Zig incantations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

2 participants