-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
I am observing an issue with clang-cl
and how it resolves include paths. It appears the front end is ignoring values passed in to the compiler via -I
IF that path is also part of the INCLUDE
environment variable.
This causes a problem as the value passed in via -I
should be considered a higher precedence regardless of whether it occurs in the INCLUDE
environment variable or not. The MSVC cl
compiler front end does not treat the value special and respects the ordering defined below.
The MSVC cl
documentation notes (https://learn.microsoft.com/en-us/cpp/build/reference/i-additional-include-directories)
The compiler searches directories in the following order:
- If the #include directive is specified using double-quote form, it first searches local directories. The search begins in the same directory as the file that contains the #include directive. If it fails to find the file, it searches next in the directories of the currently opened include files, in the reverse order in which they were opened. The search begins in the directory of the parent include file and continues upward through the directories of any grandparent include files.
- If the #include directive is specified in angle-bracket form, or if the local directory search has failed, it searches directories specified by using the /I option, in the order they're specified on the command line.
- Directories specified in the INCLUDE environment variable.
C:\Workspace\tmp\t42>dir /s /b /a-d
C:\Workspace\tmp\t42\main.cpp
C:\Workspace\tmp\t42\env\foo.h
C:\Workspace\tmp\t42\include\foo.h
C:\Workspace\tmp\t42\env>set INCLUDE=%CD%;%INCLUDE%
C:\Workspace\tmp\t42\env>cd ..
C:\Workspace\tmp\t42>clang-cl main.cpp && main.exe
C:\Workspace\tmp\t42\env\foo.h
C:\Workspace\tmp\t42>clang-cl -Iinclude main.cpp && main.exe
include\foo.h
C:\Workspace\tmp\t42>set INCLUDE=%INCLUDE%;C:\Workspace\tmp\t42\include
C:\Workspace\tmp\t42>clang-cl -Iinclude main.cpp && main.exe
C:\Workspace\tmp\t42\env\foo.h
C:\Workspace\tmp\t42>
The files foo.h
are identical (just in different locations to illustrate the behavior):
foo.h
#include <cstdio>
void foo()
{
std::printf("%s\n", __FILE__);
}
main.cpp
#include <foo.h>
int main(void)
{
foo();
return 0;
}