Search code examples
ccmakeinclude

CMake CMAKE_SOURCE_DIR and CMAKE_CURRENT_SOURCE_DIR to set same path, but only latter 'works'


I'm using CMake in, so far as I can tell, the same way as I always use it. The problem is that now include_directories($(CMAKE_SOURCE_DIR)/server/include) results in my header files not being found. When instead I use include_directories($(CMAKE_CURRENT_SOURCE_DIR)/server/include) they are found.

i.e. $(CMAKE_CURRENT_SOURCE_DIR) works, and $(CMAKE_SOURCE_DIR) doesn't.

The bizarre thing is that both of:

message(${CMAKE_SOURCE_DIR}/server/include)
message(${CMAKE_CURRENT_SOURCE_DIR}/server/include)

give:

/home/username/projects/repo/server/include

So why does one work while the other doesn't?


Solution

  • $(FOO) is not the correct syntax to refer to the cmake variable FOO. You need to use ${FOO} instead. Neither of the uses of include_directories should work, unless the build system interprets the path $(CMAKE_CURRENT_SOURCE_DIR)/server/include.

    Note that you're using the proper syntax for the message commands.

    The message command

    message($(CMAKE_CURRENT_SOURCE_DIR)/server/include)
    

    prints

    $(CMAKE_CURRENT_SOURCE_DIR)/server/include
    

    demonstrating the issue.

    I recommend using the CMAKE_CURRENT_SOURCE_DIR instead of CMAKE_SOURCE_DIR btw in all cases except for rare exceptions where you know that the toplevel CMakeLists.txt is located in a directory with specific contents. The former version is easier to recombine when used as part of a larger project via add_subdirectory.

    include_directories(${CMAKE_CURRENT_SOURCE_DIR}/server/include)
    #                    ^                        ^
    

    Note that the use of target_include_directories usually is preferrable to the use of include_directories, since the former allows restricts the targets the include directories are applied to to the one specifically mentioned. It also would allow you to make the include directories to targets linking a cmake library target, if desired.