把笔记分享给大家!
接上篇内容 CMake 学习笔记整理(2)
######################t8
# proj/src
# main.cpp
#include <xyz.h>
int main(){
china tianchao;
tianchao.Foo();
return 0;
}
# NOTE:
# xyz.h 位于 /usr/include/xyz 目录中
# 因为上一次你执行的内容:
install(FILES xyz.h DESTINATION include/xyz)
# 接着上次已经安装好的文件
# /usr/include/xyz/
# xyz.h
# 添加目录
# proj/
# CMakeLists.txt 重新写入
project(tianchao)
SET(CMAKE_CXX_COMPILER "g++")
SET(CMAKE_CXX_FLAGS "-std=c++11")
add_subdirectory(src)
# 添加一个可执行目标
# proj/src
# CMakeLists.txt 重新写入
add_executable(enter main.cpp)
# cmake配置, make编译, 先清除无关和已配置和已编译的文件
# proj/build
cmake ..
make
# result 肯定出错
path/main.cpp:2:17: fatal error: xyz.h: 没有那个文件或目录
#include <xyz.h>
^
# why
# 如果没有指定特定的目录, 那么搜索目录为:
# /usr/include
# 并不是你想象的(这是目录, 包含文件xyz.h)
# /usr/include/xyz
# think
# 这么写行吗, 试试吧
# main.cpp
#include <xyz/xyz.h>
######################t9
##########################要点须知##########################
# 除了直接在头文件中指定外, 还能这样, 批量指定:
INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)
# 这条指令可以用来向工程添加多个特定的头文件搜索路径,路径之间用空格分割,
# 如果路径中包含了空格,可以使用双引号将它括起来,
# 默认的行为是追加到当前的头文件搜索路径的后面,
# 你可以通过两种方式来进行控制搜索路径添加的方式:
# 1: CMAKE_INCLUDE_DIRECTORIES_BEFORE,通过 SET 这个 cmake 变量为 on,可以将添加的头文件搜索路径放在已有路径的前面
# 2: 通过 AFTER 或者 BEFORE 参数,也可以控制是追加还是置前
# 我还需要指定库
# 我们现在需要完成的任务是将目标文件链接到 libhello,这里我们需要引入两个新的指令
LINK_DIRECTORIES 和 TARGET_LINK_LIBRARIES
LINK_DIRECTORIES 的全部语法是:
LINK_DIRECTORIES(directory1 directory2 ...)
##########################要点须知##########################
# proj/
# CMakeLists.txt 重新写入
project(tianchao)
SET(CMAKE_CXX_COMPILER "g++")
SET(CMAKE_CXX_FLAGS "-std=c++11")
add_subdirectory(src)
add_subdirectory(lib)
# NOTE:
# 不要删除之前安装的文件, 如果删除, 先编译和安装lib
# /usr/lib/
# libcba.so.1.2
# libcba.so.1
# libcba.so
# libcba.a
# /usr/include/xyz/
# xyz.h
#proj/lib
# CMakeLists.txt 重新写入
set(libabc_src xyz.cpp xyz.h)
add_library(cba_static STATIC ${libabc_src})
add_library(cba_shared SHARED ${libabc_src})
set_target_properties(cba_static cba_shared
PROPERTIES
OUTPUT_NAME "cba"
OUTPUT_NAME "cba")
set_target_properties(cba_shared PROPERTIES VERSION 1.2 SOVERSION 1)
install(TARGETS
cba_shared
cba_static
LIBRARY DESTINATION
lib
ARCHIVE DESTINATION
lib
)
install(FILES xyz.h DESTINATION include/xyz)
# 简单暴力的添加路径
# cba: 也可以写成libcba.so, 链接到可执行的tianchao
# proj/src
# CMakeLists.txt 重新写入
add_executable(tianchao main.cpp)
include_directories(/usr/include/xyz)
target_link_libraries(tianchao cba)
# proj/src
# main.cpp 重新写入
#include <xyz.h>
int main(){
china tianchao;
tianchao.Foo();
return 0;
}
# cmake配置, make编译, 先清除无关和已配置和已编译的文件
# 记得指定<prefix>
# proj/build
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
make
sudo make install
# result
# proj/build/src
# tianchao
# comment:
# 执行它: tianchao 得到 <china::Foo>, prefect!
# tianchao 的链接情况:
# proj/build
lld src/tianchao
linux-vdso.so.1 => (0x00007ffc5fb21000)
libcba.so.1 => /usr/lib/libcba.so.1 (0x00007f2635f4b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2635b86000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f2635882000)
/lib64/ld-linux-x86-64.so.2 (0x00007f263614d000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f263557c000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f2635366000)
# 链接到了共享库, 想链接到静态库只需把
# proj/src
# CMakeLists.txt 改
target_link_libraries(tianchao libcba.so)
# 为
target_link_libraries(tianchao libcba.a)
# think
# 我重新来一遍, 把/usr 和proj/build 下生成文件者删除
# 当你make 的时候还是err, 你很快意识到还没安装库和.h文件
main.cpp:1:17: fatal error: xyz.h: 没有那个文件或目录
#include <xyz.h>
^
# 但是你要安装的话不是先得执行make ? --!!
######################t10
# 先放下上一个问题, 假设已经能顺利安装和执行tianchao
##########################要点须知##########################
# 环境变量 CMAKE_INCLUDE_PATH 和 CMAKE_LIBRARY_PATH
# 这两个是环境变量而不是 cmake 变量
# 使用方法: CMAKE_INCLUDE_PATH=/home/include cmake ..等方式
# 前面我们直接使用了绝对路径
INCLUDE_DIRECTORIES(/usr/include/xyz)
# 告诉工程这个头文件目录
# 为了将程序更灵活一点,我们可以使用 CMAKE_INCLUDE_PATH 来进行(bash)
##########################要点须知##########################
# 完成安装的情况下
# proj/
# CMakeLists.txt 注释掉
add_subdirectory(lib)
# proj/src
# CMakeLists.txt 注释掉
include_directories(/usr/include/xyz)
# 添加
find_path(myHeader xyz.h)
if(myHeader)
message(STATUS "!!!!!!!!!!")
include_directories(${myHeader})
endif(myHeader)
# cmake配置, make编译, 先清除无关和已配置和已编译的文件
# 设置环境变量
# proj/build
export CMAKE_INCLUDE_PATH=/usr/include/xyz
cmake ..
make
# comment:
# 这种方式我更喜欢 :-D, 不用bash 指定CMAKE_INCLUDE_PATH
find_path(myHeader
NAMES
xyz.h
PATHS
/usr/include
)