zig icon indicating copy to clipboard operation
zig copied to clipboard

No warnings when using build.zig to compile a pure C project.

Open malespiaut opened this issue 2 years ago • 6 comments

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.

malespiaut avatar May 30 '23 15:05 malespiaut

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!

rohlem avatar May 30 '23 20:05 rohlem

PSA: that flag seems to be -Werror, not -WError

ghost avatar May 31 '23 12:05 ghost

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

Triscuit2311 avatar Jun 02 '23 02:06 Triscuit2311

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.

malespiaut avatar Jun 14 '23 13:06 malespiaut

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.

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!

Triscuit2311 avatar Jun 15 '23 12:06 Triscuit2311

This seems related to https://github.com/ziglang/zig/issues/10800#issuecomment-1030611649 and I hope it gets addressed in some form too.

sagehane avatar Jun 15 '23 22:06 sagehane

As a workaround until this use case is addressed, I suggest using -Werror only for debug builds.

andrewrk avatar Jul 22 '23 04:07 andrewrk

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 build by adding the -Werror flag 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.

tuket avatar Sep 30 '23 10:09 tuket