0

To my understanding, CMake takes all the sources that are specified in add_executable (or add_library), and creates a makefile target to compile and link each one to create the resultant executable (or library). However, I see online that it is allowed, and even somewhat encouraged, to specify headers in add_executable/add_library! This surprises me because my intuition says that, if headers are specified there, they will be compiled and linked just like a regular source file, which would be wrong,...but somehow they are not; why?

Does CMake check the file extension of provided sources and filter out all the .h/.hh/.hpp/etc.? Or does CMake detect and filter out sources which are #include'ed in other sources? Or does CMake have some other way of knowing which sources should or should not be compiled?

For example, how does

add_executable(myprogram myprogram.cpp myprogram.hpp)

not cause

g++ -c myprogram.hpp -o myprogram.hpp.o

?

I found the following related SO discussions that generally suggest that headers may be specified within add_executable/add_library, but they do not answer why the headers are not then compiled:

2 Answers 2

2

why?

They are explicitly ignored. Because there is an if source is a header; then dont compile in cmake sources.

Does CMake check the file extension of provided sources and filter out all the .h/.hh/.hpp/etc.?

Yes

Or does CMake detect and filter out sources which are #include'ed in other sources?

No.

Or does CMake have some other way of knowing which sources should or should not be compiled?

https://github.com/Kitware/CMake/blob/master/Modules/CMakeCCompiler.cmake.in#L47 :

set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m)
set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
Sign up to request clarification or add additional context in comments.

Comments

1

This behavior is documented in HEADER_FILE_ONLY:

A property on a source file that indicates if the source file is a header file with no associated implementation. This is set automatically based on the file extension and is used by CMake to determine if certain dependency information should be computed.

By setting this property to ON, you can disable compilation of the given source file, even if it should be compiled because it is part of the library's/executable's sources.

So yes, CMake automatically disables compilation of header files based on the file extension.

As @KamilCuk's answer points out, the particular set of file extensions used to categorize headers is given by the CMAKE_<LANG>_IGNORE_EXTENSIONS variable.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.