3

I have a file in source tree which name is "time.h", exactly as system "time.h". This cannot be changed. I have encountered a problem with cmake that when I use include_library option it is translated to -I flag which means that my custom "time.h" takes prcedence over system time.h even for <> includes. This is a definiti no-no.

I tried using include_directories (AFTER dir1 dir2) but it still generate -I option instead of expected -idirafter.

1 Answer 1

4

I don't think this is a problem with CMake; I believe gcc will always find your "time.h" before the system one, regardless of whether you use quotes or brackets in the #include and regardless of the various options in include_directories. See the entries for -I and -isystem in the gcc documentation

The AFTER option of CMake's include_directories relates only to the order of the directories as listed in the gcc command, it doesn't relate to gcc's -idirafter flag.

It's not a great plan to have your own files with identical names to system files, but if your hands are tied, you could avoid this issue without renaming time.h by qualifying the path for your own includes more fully, so rather than e.g.

CMakeLists.txt: include_directories(${PROJECT_SOURCE_DIR}/src) header file: #include <time.h> // we want but don't get system one #include "time.h" // we want and get own custom one 

something more like

CMakeLists.txt: include_directories(${PROJECT_SOURCE_DIR}) header file: #include <time.h> // we want and get system one #include "src/time.h" // we want and get own custom one 


An alternative option would be to stick with your current #include setup (using angle brackets for the system time.h and quotes for your own) and not use include_directories at all in the CMakeLists.txt. Instead I think you could replace it with something like:

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -iquote ${PROJECT_SOURCE_DIR}/src") 

Using -iquote is probably a better option than -idirafter since the directory specified by -idirafter is (in this case incorrectly) treated as a system directory, and as such has warnings suppressed, etc.

If you do go for this choice, it's probably worth commenting the CMakeLists.txt to explain why there is no include_directories to avoid future refactoring reverting back to use the more normal include_directories command.

All in all, your best option if at all possible would be to rename your "time.h" file though.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot for the complete answer. The first option is not good for me as the problem is not with my files, but with system files like "sched.h", which mistakenly include my file instead of system one. So probably, I will go with using explicit compiler options instead of using include_directories.
I came to this question because I had inadvertently created an empty local file called "new" in my include search path. This preempted the <new> system header which was used several #include levels away by a library I'm using. I spent hours figuring out why (message was error: ‘nothrow’ is not a member of ‘std’ followed by a compiler crash). It seems like I can use the -iquote mechanism (is there a Visual Studio equivalent?) to ensure files included via angle brackets came only from system headers; it would be nice if that were supported via a CMake command.
Does anyone know if there's something like iquote in Visual Studio (cl.exe flag?)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.