Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check in cmake whether a given header file is available for C++ project

Tags:

c++

c

include

cmake

I am using cmake to manage compilation of my project and it is my first time to use cmake. This tool is very convenient, as there is plethora of scripts and functions which allows to check if all necessary libraries are installed on a given computer. Sometimes, however, these generic sripts does not cover some specific case or they are not available at all for a given library. My question is then as follows:

What is the right cmake-style way of veryfying whether a given header file (hpp or h) is available in the include path?

Justification:

Most straigforward way is probably to use CHECK_INCLUDE_FILE macros. For example, if I would like to use UnitTest++ library, I could write

CHECK_INCLUDE_FILE_CXX("UnitTest++.h" HAVE_UNITTESTXX)
IF(NOT HAVE_UNITTESTXX)
  message( FATAL_ERROR "UnitTest++ is not found" )
ENDIF()

Unfortunately If it is done this way, the variable HAVE_UNITTESTXX is stored in the cache. If I install the UnitTest++ library in my system, cmake will still complain about UnitTest++.h not being installed. I can remove cache manually, but standard find package functions does not require that. I can also upgrade the code like this

CHECK_INCLUDE_FILE_CXX("UnitTest++.h" HAVE_UNITTESTXX)
IF(NOT HAVE_UNITTESTXX)
  UNSET(HAVE_UNITTESTXX CACHE)
  message( FATAL_ERROR "UnitTest++ is not found" )
ENDIF()

This solution works, but it does not look nice. I would like to know a cmake way to do this task.

Best regards!

like image 411
wpfnoop Avatar asked May 10 '13 15:05

wpfnoop


People also ask

How do I include a .h file in CMake?

To include headers in CMake targets, use the command target_include_directories(...) . Depending on the purpose of the included directories, you will need to define the scope specifier – either PUBLIC , PRIVATE or INTERFACE .

Where does CMake look CMakeLists txt?

When CMake processes a project source tree, the entry point is a source file called CMakeLists. txt in the top-level source directory. This file may contain the entire build specification or use the add_subdirectory() command to add subdirectories to the build.

How do I add to CMake?

To add a library in CMake, use the add_library() command and specify which source files should make up the library. Rather than placing all of the source files in one directory, we can organize our project with one or more subdirectories. In this case, we will create a subdirectory specifically for our library.


1 Answers

The answer you are looking for is already on the CMake Wiki. They clearly tell to remove the file CMakeCache.txt or the cache line that bothers you by hand.

Unfortunately, there is no cleaner way to do this. Yours is already as good as it could be. I think that CMake tries to be convenient when everything is alright, hence the cache, and tries to force you to delete and regenerate it when you fail.

On the other hand, you could write a CHECK_INCLUDE_FILE_CXX_ERROR macro (or any cleaner name) to wrap your fatal error message so that you don't have to repeat the same code every time:

macro(CHECK_INCLUDE_FILE_CXX_ERROR INCLUDE_FILE HAVE_FILE)
    CHECK_INCLUDE_FILE_CXX(${INCLUDE_FILE} ${HAVE_FILE})
    IF(NOT ${HAVE_FILE})
        UNSET(HAVE_UNITTESTXX CACHE)
        message( FATAL_ERROR "${INCLUDE_FILE} is not found" )
    ENDIF()
endmacro()

And then use it like this:

CHECK_INCLUDE_FILE_CXX_ERROR("UnitTest++.h" HAVE_UNITTESTXX)
like image 134
Morwenn Avatar answered Oct 27 '22 19:10

Morwenn