zig
zig copied to clipboard
No warnings when using build.zig to compile a pure C project.
Zig Version
0.11.0-dev.3316+ec58b475b
Steps to Reproduce and Observed Behavior
Create the two files and run zig build.
main.c
#include <stdio.h>
int global = 1;
int main() {
int x;
int global = global;
printf("x = %d, and global = %d", x, global);
return 0;
}
build.zig
const std = @import("std");
const Build = std.build;
pub fn build(b: *Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "test",
.optimize = optimize,
.target = target,
});
exe.addCSourceFiles(&.{"main.c"}, &.{
"-std=c17",
"-Wpedantic",
"-Wall",
"-Wextra",
"-Wshadow",
});
exe.linkSystemLibrary("c");
b.installArtifact(exe);
const run = b.addRunArtifact(exe);
run.step.dependOn(b.getInstallStep());
}
Expected Behavior
When compiling with GCC or Clang using the same flags, I get the following warnings:
GCC
main.c: In function ‘main’:
main.c:7:7: warning: declaration of ‘global’ shadows a global declaration [-Wshadow]
7 | int global = global;
| ^~~~~~
main.c:3:5: note: shadowed declaration is here
3 | int global = 1;
| ^~~~~~
main.c:8:3: warning: ‘x’ is used uninitialized [-Wuninitialized]
8 | printf("x = %d, and global = %d", x, global);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:6:7: note: ‘x’ was declared here
6 | int x;
| ^
Clang
main.c:5:9: warning: a function declaration without a prototype is deprecated in all versions of C [-Wstrict-prototypes]
int main() {
^
void
main.c:7:7: warning: declaration shadows a variable in the global scope [-Wshadow]
int global = global;
^
main.c:3:5: note: previous declaration is here
int global = 1;
^
main.c:7:16: warning: variable 'global' is uninitialized when used within its own initialization [-Wuninitialized]
int global = global;
~~~~~~ ^~~~~~
main.c:8:37: warning: variable 'x' is uninitialized when used here [-Wuninitialized]
printf("x = %d, and global = %d", x, global);
^
main.c:6:8: note: initialize the variable 'x' to silence this warning
int x;
^
= 0
4 warnings generated.
I'm expecting zig build to do the same.
Maybe not immediately helpful to you, but two notes:
- The Zig language only has the concept of errors, not warnings - that's probably why warnings aren't currently hooked up. I assume there might not even be a design on how they should work/integrate with the build system yet.
- Clang (internally used by Zig) has a "treat warnings as errors" flag
-Werror. (edit: fixed capitalization, see comment below) If you add this, the warnings should become errors, abort the build and be correctly displayed - if not that's a serious bug!
PSA: that flag seems to be -Werror, not -WError
rohlem commented 2 days ago
- Clang (internally used by Zig) has a "treat warnings as errors" flag
-Werror. (edit: fixed capitalization, see comment below) If you add this, the warnings should become errors, abort the build and be correctly displayed - if not that's a serious bug!
Just tried reproducing this, and it seems you (rohlem) are correct. Here is the output from zig build by adding the -Werror flag to the build file:
λ zig build
zig build-exe test Debug native: error: error(compilation): clang failed with stderr: .../main.c:5:9: error: a function declaration without a prototype is deprecated in all versions of C [-Werror,-Wstrict-prototypes]
.../main.c:7:7: error: declaration shadows a variable in the global scope [-Werror,-Wshadow]
.../main.c:3:5: note: previous declaration is here
.../main.c:10:2: error: no newline at end of file [-Werror,-Wnewline-eof]
.../main.c:7:16: error: variable 'global' is uninitialized when used within its own initialization [-Werror,-Wuninitialized]
.../main.c:8:37: error: variable 'x' is uninitialized when used here [-Werror,-Wuninitialized]
.../main.c:6:8: note: initialize the variable 'x' to silence this warning
zig build-exe test Debug native: error: the following command failed with 1 compilation errors:
.../.zig/zig-macos-aarch64-0.11.0-dev.3312+ab37ab33c/zig build-exe -cflags -std=c17 -Wpedantic -Wall -Wextra -Wshadow -Werror -- .../main.c -lc --cache-dir .../zig-cache --global-cache-dir .../.cache/zig --name test --listen=-
Build Summary: 0/3 steps succeeded; 1 failed (disable with -fno-summary)
install transitive failure
└─ install test transitive failure
└─ zig build-exe test Debug native 1 errors
.../main.c:1:1: error: unable to build C object: clang exited with code 1
Hello,
Yes, @rohlem @Triscuit2311 I do know about the workaround of using -Werror to see warnings when building a C project. However, I, for one, would like to see a proper handling of C warnings as warnings, as I feel that treating warnings as errors can get in the way of some projects.
Let me be clear, I want to get rid of all warnings of my C projects. But there are some situations where it gets in the way to have they treated as error. For instance, I'm working on a GTK3 project and try to migrate it to GTK4. This is already a difficult process when treating warnings as warnings. So treating warnings as errors, because of the complexity of such projects, gets in the way of readability… at least in my humble opinion.
Let me know what you think.
Hello,
Yes, @rohlem @Triscuit2311 I do know about the workaround of using
-Werrorto see warnings when building a C project. However, I, for one, would like to see a proper handling of C warnings as warnings, as I feel that treating warnings as errors can get in the way of some projects.Let me be clear, I want to get rid of all warnings of my C projects. But there are some situations where it gets in the way to have they treated as error. For instance, I'm working on a GTK3 project and try to migrate it to GTK4. This is already a difficult process when treating warnings as warnings. So treating warnings as errors, because of the complexity of such projects, gets in the way of readability… at least in my humble opinion.
Let me know what you think.
I agree with you on this as well, needing the workaround to see warnings does seem out of character for Zig, at least to me. Also, that's an ambitious project and I'm sure there are no shortage of warnings!
This seems related to https://github.com/ziglang/zig/issues/10800#issuecomment-1030611649 and I hope it gets addressed in some form too.
As a workaround until this use case is addressed, I suggest using -Werror only for debug builds.
I have a mixed zig+C project and I have an issue which I think might be related. The project is failing to compile due to some C file, but it doesn't tell me where (file? line?). I suspect it might be a warning that's not being printed but treated as an error?
Just tried reproducing this, and it seems you (rohlem) are correct. Here is the output from
zig buildby adding the-Werrorflag to the build file:
~~How do you add that flag in the build file? Is there any std.build API for adding flags for C?~~
Never mind, found it (second argument of lib.addCSourceFile).
Didn't fix my problem though. I guess mine is a separate issue then.