premake / premake-core

Premake
https://premake.github.io/
BSD 3-Clause "New" or "Revised" License
3.25k stars 620 forks source link

Add support for --include-barrier #2036

Open crazydef opened 1 year ago

crazydef commented 1 year ago

What problem will this solve? Clang, unlike Visual Studio, makes no real distinction between user include paths and system include paths. Basically, user include paths are always searched before system include paths, unlike Visual Studio which searches system include paths followed by user include paths for angle bracket includes, and user paths followed by system paths for double quoted includes.

Because of this, in my particular instance, MacOS system headers are managing to include our header files because they include things like <Path/File.h> while we include "Path/File.h".

What might be a solution? Clang does support the command line argument --include-barrier which restricts all include paths specified prior to it on the command line to double quoted include directives.

Assuming Premake doesn't reorder include paths given to it, having a special string that inserts this command line option instead of an include path would probably be the easiest way to implement this:

includedirs {
  "Some/Include/Path",
  "Some/Other/Path",
  "PREMAKE_INCLUDE_BARRIER",
  "Another/Path",
  ...
}
nickclark2016 commented 1 year ago

Does this solve your issue? https://premake.github.io/docs/externalincludedirs/

crazydef commented 1 year ago

I don't think so. (I'm not sure.)

The problem is the include path we're adding to our project is an internal path which is being picked up by a #include directive from a platform header file.

Specifically, in our project we're including <Cocoa/Cocoa.h> which, in turn, is including <Foundation/Foundation.h>. We have an "internal" search path that we use to include our own "Foundation/Foundation.h" header file, and because of the way clang always searches user paths first, it's our header file that is being picked up. (With the kinds of hilarious consequences that would make Fawlty Towers look like a funeral.)

Being able to explicitly tell clang to ignore (some of*) our paths for #includes that use angle brackets would, I think, solve the issue.

nickclark2016 commented 1 year ago

I would expect if Cocoa is marked as a external include (which translates to -isystem) that clang wouldn't try to resolve includes in the -isystem list of directories to things just specified in -i. That said, I'm not 100% sure a magic variable is the solution, though it's probably the simplest to implement, as premake currently stands.

crazydef commented 1 year ago

Yeah, the correct solution would be an internalincludedirs list which is passed before --include-barrier on the command line.

I don't think clang treats external include paths differently. My understanding is -I and -isystem just determines where they are placed in the list. (User directories are always searched first, followed by system directories.) I'm guessing the --include-barrier and other such command line options are just hacks to workaround issues that have arisen due to copying GCC's behaviour that arose from the many bone-headed decisions that were made decades ago.

crazydef commented 1 year ago

That said, clang also appears to support -iquote=<dir> which, if I understand it correctly, maintains a list of search paths which are only searched for includes using double quotes. Does premake support this at all?

nickclark2016 commented 1 year ago

Not explicitly, though you may be able to use buildoptions: https://premake.github.io/docs/buildoptions/

crazydef commented 1 year ago

Yeah, that could be an option. I suppose, technically speaking, buildoptions could be used for everything if you know your platform and compiler. Although the order of command line arguments might be an issue depending on when they're emitted by Premake.

As of right now though, this is not a priority for me anymore. (I just renamed our file.) So I leave it up to you to decide if you want to just close this, or leave it open as a reminder to extend paths support in Premake at some point in the future. :)

Jarod42 commented 1 year ago

There is (pending) https://github.com/premake/premake-core/pull/2028 which add idirafter.

Not checked clang documentation, but when adding test for that PR in my testing repo, I wrote that doc.

And so that PR should allow to solve the issue (with the caveat that those header are threaten as system/external include from warning point of view.