Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake: how to set COMPILE_FLAGS for header files?

I've successfully used CMake to built a shared library, but the size is not so good. I've already tried several compile flags to cut size, etc.

set_source_files_properties(${TARGET_SOURCE_FILES} PROPERTIES COMPILE_FLAGS "-fexceptions")

Code above is used to open exception handling for single file while -fno-exceptions is added to CMAKE_CXX_FLAG. It works fine.

However, I used the same code to an *.hpp to open rtti for it while -fno-rtti is added to CMAKE_CXX_FLAGS. Unfortunately, it didn't work.

So, is there a way to add COMPILE_FLAGS to header files in CMAKE? I've viewd documentary on offical site, but still no clues.

like image 713
Doorag Avatar asked Jan 09 '18 06:01

Doorag


1 Answers

This is not possible and probably a questionable thing to do in the first place.

Mixing different compile flags within the same binary is a dangerous game. Usually you would want all compilation units in a target to share the same compile flags, as it is very easy to mess things up subtly but terribly otherwise. However, CMake still allows you to use source file properties the way you did to do this if you are really sure what you are doing.

With header files though, things are worse. Headers do not get compiled on their own, so what you are asking for is that all source files that pull in that header will inherit the special compilation options associated with that header. But since all calls to the compiler happen based on source files, this would require to re-run CMake on every source change, check all the includes in all the source files, and adapt the compiler options accordingly. Hopefully you can now see why CMake doesn't want to do this.

What you can do though is specify those options on a per-target basis. Move your headers to an interface target and add a corresponding interface property there. Then, all targets that want to use the header will have to pull in that target as a dependency. As a consequence, all depending source files will get the special compile flags, regardless of whether they actually do include the header or not, but that's just how build systems work:

add_library(my_headers INTERFACE)
target_include_directories(my_headers INTERFACE ${PATH_TO_HEADERS})
target_compile_options(my_headers INTERFACE $<$<CXX_COMPILER_ID:GNU>:-fexceptions>)

add_executable(client a.cpp)
target_link_libraries(client PUBLIC my_headers)

In this example, a.cpp (as well as all other sources of client) will now get compiled with the -fexceptions flag.

like image 195
ComicSansMS Avatar answered Oct 29 '22 13:10

ComicSansMS