buck2 icon indicating copy to clipboard operation
buck2 copied to clipboard

cxx_library not respecting compiling .c/.h files in C mode

Open benbrittain opened this issue 2 years ago • 8 comments

buck2 build :bin

cxx_binary(                                                                                                                                      
    name = "bin",                                                                                                                                
    srcs = [                                                                                                                                     
        "lua.c",                                                                                                                                 
    ],                                                                                                                                           
    deps = [                                                                                                                                     
        ":lua",                                                                                                                                  
    ],                                                                                                                                           
)                                                                                                                                                
                                                                                                                                                 
cxx_library(                                                                                                                                     
    name = "lua",                                                                                                                                
    srcs = [                                                                                                                                     
        "lapi.c",                                                                                                                                
        "lapi.h",                                                                                                                                
        "lcode.c",                                                                                                                               
        "lcode.h",                                                                                                                               
        "lctype.c",                                                                                                                              
        "lctype.h",                                                                                                                              
        "ldebug.c",                                                                                                                              
        "ldebug.h",                                                                                                                              
        "ldo.c",                                                                                                                                 
        "ldo.h",                                                                                                                                 
        "ldump.c",                                                                                                                               
        "lfunc.c",                                                                                                                               
        "lfunc.h",                                                                                                                               
        "lgc.c",                                                                                                                                 
        "lgc.h",             
        ...

Errors: error: invalid argument '-std=c++17' not allowed with 'C'

Which is correct, but I don't see way to force cxx_library to use C and I'm also not quite sure why it's not being autodetected as a c target.

benbrittain avatar Apr 13 '23 20:04 benbrittain

-std=c++17 is passed as a cxx_flag to CxxCompilerInfo . CCompilerInfo has no flags passed to it.

benbrittain avatar Apr 13 '23 20:04 benbrittain

I figured out what it was. The autodetection fails without warning if you add a .h file to the srcs list. I think that should be an allowable extension to be passed for C targets.

benbrittain avatar Apr 13 '23 20:04 benbrittain

Ah, you should be putting the headers in a separate headers argument. You don't compile headers, so it makes sense to differentiate them. I'll see if we can make srcs of .h an error, since no one should want that.

ndmitchell avatar Apr 13 '23 20:04 ndmitchell

I'm tweaking converting a priorly bazel project right now, which handles this situation pretty differently than buck2 does. It makes sense but it was not what I was expecting :)

benbrittain avatar Apr 13 '23 20:04 benbrittain

Yeah, I'm testing a change internally to make it say Not allowed to have header files in the `srcs` attribute - put them in `headers` which hopefully fixes it for good. Might take a while to ship, as I imagine there are a few cases where it relies on that, but with time.

ndmitchell avatar Apr 13 '23 20:04 ndmitchell

I appreciate the timely support!

benbrittain avatar Apr 13 '23 20:04 benbrittain

The reason we have to support headers is because of https://github.com/facebook/buck2/blob/da5373151c7f4f4d6d08666c37a2d23a3aef83dc/prelude/cxx/compile.bzl#L187-L190. While it doesn't say, that is there to support compilation databases, so if a target has no C++ files, we can generate a compilation database by pretending the headers are really C++ files. Not convinced that is a good idea. Following up internally.

ndmitchell avatar Apr 13 '23 21:04 ndmitchell

Plan is to slightly more tightly scope the compilation database fix, and then it will error if you put a header in srcs, with a good error message.

ndmitchell avatar Apr 13 '23 21:04 ndmitchell

Why do headers need a compilation database if they're not compiled? Can't the headers have their database appear in the target that depends on the headers?

calebkiage avatar Apr 20 '23 05:04 calebkiage

For info, I have a diff ready internally that makes the headers in srcs an error.

As to @calebkiage's question, imagine you are writing an IDE, and someone opens a .c file. The best way to generate intelligent suggestions etc is to find the BUCK file that contains the .c file (easy, must be the closest one above it) ask that BUCK file what targets it has and their sources (easy, call buck2 targets) and then generate the compilation database for the .c file (easy, call buck2 build thetarget[compilation_database]). For headers, you need to find something that compiles it. If there is a .c in the same target, that probably includes the header, and will be sufficient. If it is header only, you need to search for a target that depends on the header-only target - which might be anywhere in a multi-million file repo. Or you can do a little bit of a cheat, pretend the header files are .c files, and compile them locally. That means the process looks much the same as for .c files.

ndmitchell avatar Apr 20 '23 07:04 ndmitchell

Thanks for the response @ndmitchell. I have a question about this technique though. How does it work with different compilation options? For example, if the same header is included in a .cpp file that's compiled with C++11 and in another file that is compiled with C++20, the suggestions have to differ when showing suggestions, no? It isn't possible to know which suggestions to show if the header file is a source file on its own since the build system has to pick one standard. Unless I'm missing some context?

calebkiage avatar Apr 24 '23 13:04 calebkiage

@calebkiage - Normally things won't differ too much between C++11 and C++20 (or based on define or similar), so its close enough to have value. Given a single large repo that compiles some things one way, some things another, without knowing the project you are working on its impossible to give a perfect answer.

ndmitchell avatar Apr 24 '23 14:04 ndmitchell

Since 67bdf15d699955498b953d82d3606c862c1ac49a it is an error to put a .h in the srcs field, so hopefully whoever runs into this next will have a good error message and know how to fix it.

ndmitchell avatar Apr 27 '23 19:04 ndmitchell