Target
1.1. INTERFACE_INCLUDE_DIRECTORIES
若此Target為Library,則此Property代表public include directories的List
Target B若link到此Target A,則Target B會自動includeTarget AProperty中INTERFACE_INCLUDE_DIRECTORIES所指向的directories, 因此不必再特別設定include_directories可以透過
set_target_properties設定
set_target_properties(${TargetName}
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}/inc
)
- 若
target_include_directories()指令中,值被設定為PUBLIC或是INTERFACE,則target_include_directories()內的設定值會自動加入INTERFACE_INCLUDE_DIRECTORIES
2.1. 說明
target_include_directories(<target> [SYSTEM] [BEFORE]
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
- 為Target添加
include directories PUBLIC,PRIVATEandINTERFACE此3個為Keyword
PUBLIC:
會將target_include_directories()的值發佈到INCLUDE_DIRECTORIES與INTERFACE_INCLUDE_DIRECTORIES
PRIVATE:
會將target_include_directories()的值發佈到INCLUDE_DIRECTORIES
INTERFACE:
會將target_include_directories()的值發佈到INTERFACE_INCLUDE_DIRECTORIES
2.2. Directory
├── CMakeLists.txt
├── foo
│ ├── CMakeLists.txt
│ ├── src
│ │ └── foo.c
│ └── inc
│ └── foo.h
└── bar
├── CMakeLists.txt
└── src
└── bar.c
2.3. Root
cmake_minimum_required(VERSION 2.8)
add_subdirectory(foo)
add_subdirectory(bar)2.4. Foo
cmake_minimum_required(VERSION 2.8)
project(Foo)
add_library(foo SHARED src/foo.c)
target_include_directories(foo PUBLIC
${PROJECT_SOURCE_DIR}/inc
)
# target_include_directories(foo PRIVATE
# ${PROJECT_SOURCE_DIR}/inc
# )
# set_target_properties(foo
# PROPERTIES
# INTERFACE_INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}/inc
# )#include "foo/foo.h"
#include <stdio.h>
void foo(void)
{
printf("This is foo version %s\n", "1.0");
}#pragma once
#ifndef FOOBAR_FOO_H
#define FOOBAR_FOO_H
void foo(void);
#endif若將target_include_directories(PUBLIC)
改為以下:
target_include_directories(foo PRIVATE
${PROJECT_SOURCE_DIR}/inc
)
會造成build bar.c失敗 =>
bar/src/bar.c:2:21: fatalerror: foo/foo.h: 沒有此一檔案或目錄
∵沒有設定INTERFACE_INCLUDE_DIRECTORIES
∴Target bar找不到Target foo需要的include directories
若改為以下:
set_target_properties(foo
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}/inc
)
會造成build foo.c失敗 =>
foo/src/foo.c:2:21: fatal error: foo/foo.h: 沒有此一檔案或目錄
∵沒有設定INCLUDE_DIRECTORIES
∴Target foo找不到需要的include directories
在這個範例看不出使用set_target_properties來設置INTERFACE_INCLUDE_DIRECTORIES的好處,
那麼什麼時候會需要用到呢?
等我們講到Importing Targets的時候,set_target_properties就非用不可了。
Importing Targets:
將外部已經build好的library(.a or .so)或是executable file(.exe),
引入到當前CMake的Project中,使其成為一個邏輯上的Target。
由於這類的Target無法使用target_include_directories(),
此時便需要set_target_properties來設置INTERFACE_INCLUDE_DIRECTORIES
add_library( External_lib SHARED IMPORTED GLOBAL )
set_target_properties( External_lib
PROPERTIES
IMPORTED_LOCATION /path/to/libExternal_lib.so
INTERFACE_INCLUDE_DIRECTORIES /path/to/External_lib/include
)
2.5. Bar
cmake_minimum_required(VERSION 2.8)
project(Bar)
add_executable(bar src/bar.c)
target_link_libraries(bar
foo
)#include "foo/foo.h"
int main(int argc, char* argv[])
{
foo();
return 0;
}2.6. Result

