Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add include rule for other directory?

Tags:

build

cmake

I have this directory structure :

- code
  - shared lib 1
    - unit tests
  - shared lib 2
    - unit tests
- extern libs
  - gtest + gmock
  - extern lib

Each directory has one CMakeLists.txt file.

Shared library 2 needs to link shared library 2. This I solved, how to solve the include?

Here are my CMakeList.txt files for shared lib 1 :

SET( LIB_OUTPUT_NAME shlib1 )

FILE (GLOB HEADER_FILES ./*.hpp)
FILE (GLOB SOURCE_FILES ./*.cpp)

ADD_LIBRARY (${LIB_OUTPUT_NAME} SHARED ${SOURCE_FILES} ${HEADER_FILES} )

and for shared lib 2 :

SET( LIB_OUTPUT_NAME shlib2 )

# what to put here? this doesn't work
include_directories(${shlib1})

FILE( GLOB HEADER_FILES ./*.hpp )
FILE( GLOB SOURCE_FILES ./*.cpp )

ADD_LIBRARY( ${LIB_OUTPUT_NAME} SHARED ${SOURCE_FILES} ${HEADER_FILES} )

target_link_libraries( ${LIB_OUTPUT_NAME} shlib1 ) 

PS: I got more libraries - not just 2. That is why I am looking at more generic solution.


I tried to use target_include_directories like this :

target_include_directories( ${LIB_OUTPUT_NAME} PUBLIC ${shlib1} )

but it didn't work.

like image 569
BЈовић Avatar asked Nov 11 '13 23:11

BЈовић


People also ask

How do you add include directories to 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 do I put CMakeLists txt?

CMakeLists. txt is placed at the root of the source tree of any application, library it will work for. If there are multiple modules, and each module can be compiled and built separately, CMakeLists. txt can be inserted into the sub folder.

What is the difference between Include_directories and Target_include_directories?

1, include_directories() is accessible for all the files in the source-tree 2, target_include_directories() is-only accessible for a specific target when compile.

What is Cmake_source_dir?

CMAKE_SOURCE_DIR refers to the top-level source directory that contains a CMakeLists. txt , while PROJECT_SOURCE_DIR refers to the source directory of the most recent project() command. They are often the same, but a common workflow when using CMake is to use add_subdirectory to add libraries.


1 Answers

If you're using CMake v2.8.11 or newer, then target_include_directories is indeed the way to go.

It's not clear from your question which CMakeLists.txt you've added this command to. If you're trying to specify that any target which depends on shlib1 should have "code/shared lib 1" as an include search path, then you should add the command to "code/shared lib 1/CMakeLists.txt".

In your target_include_directories call, you're specifying that the public search path should be ${shlib1}. I expect that this variable is actually empty - you're certainly not setting it anywhere in your example code. What is available however is the variable shlib1 - this is the target created in your add_library call, but it's not too useful here.

So, your command in "code/shared lib 1/CMakeLists.txt" should be something like:

target_include_directories(${LIB_OUTPUT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})


If you don't want to use target_include_directories (or have to cater for older versions of CMake), you would have to use include_directories in "code/shared lib 2/CMakeLists.txt". However, you'd have to pass the path to "code/shared lib 1".

You could just use a relative path but this perhaps isn't the most robust solution:

include_directories("../shared lib 1")

or assuming you have your top-level CMakeLists.txt in "code", you could do:

include_directories("${CMAKE_SOURCE_DIR}/shared lib 1")

but this isn't much better.

A more robust option might be to make each subdirectory a separate project (i.e. have a project call at the top of each subdir's CMakeLists.txt). This makes the variable <projectName>_SOURCE_DIR available to all subsequent CMake files. So, if your first shared lib also had project(sharedlib1), then in "code/shared lib 2/CMakeLists.txt" you could do:

include_directories(${sharedlib1_SOURCE_DIR})

Or another reasonable solution would be to set a cache variable (to make it available everywhere) in every subdir's CMakeLists.txt, specifying that subdir's public search path(s). For example, in "code/shared lib 1/CMakeLists.txt":

set(shlib1_includes "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL
    "Public include path(s) for shlib1")

then in "code/shared lib 2/CMakeLists.txt":

include_directories(${shlib1_includes})
like image 168
Fraser Avatar answered Oct 01 '22 22:10

Fraser