【cmake】CMakeList添加库|添加头文件|添加路径|add_executable、add_library、target_link_libraries|添加编译选项|宏开关

开胃菜例子

CMakeLists生成和添加依赖库

原文;

cmake之生成动态库:https://www.cnblogs.com/pandamohist/p/13408455.html

https://blog.csdn.net/bandaoyu/article/details/115165199

整体原文链接:https://blog.csdn.net/michaelhan3/article/details/69568362

 

1、目录结构

│ CMakeLists.txt
│ index.txt

├─build
├─include
│ hello.h
│ hi.h

└─src
hello.cxx
hi.cxx
2、CMakeLists.txt

cmake_minimum_required(VERSION 3.1)

#项目名
project(libhello)

# 1、指定库的目录变量
set(libhello_src src/hello.cxx)
# 指定头文件搜索路径
include_directories("${PROJECT_SOURCE_DIR}/include")

 

# 2、添加库(对应的两个项目)
add_library( hello_shared SHARED ${libhello_src})
add_library( hello_static STATIC ${libhello_src})
# 按照一般的习惯,静态库名字跟动态库名字应该是一致的,只是扩展名不同;
# 即:静态库名为 libhello.a; 动态库名为libhello.so ;
# 所以,希望 "hello_static" 在输出时,不是"hello_static",而是以"hello"的名字显示,故设置如下
# SET_TARGET_PROPERTIES (hello_static PROPERTIES OUTPUT_NAME "hello")


# 3、cmake在构建一个新的target时,会尝试清理掉其他使用这个名字的库,
# 因此,在构建libhello.a时,就会清理掉libhello.so.
# 为了回避这个问题,比如再次使用SET_TARGET_PROPERTIES定义 CLEAN_DIRECT_OUTPUT属性。
SET_TARGET_PROPERTIES (hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
SET_TARGET_PROPERTIES (hello_shared PROPERTIES CLEAN_DIRECT_OUTPUT 1)


# 4、按照规则,动态库是应该包含一个版本号的,
# VERSION指代动态库版本,SOVERSION指代API版本。
SET_TARGET_PROPERTIES (hello_static PROPERTIES VERSION 1.1 SOVERSION 1)
SET_TARGET_PROPERTIES (hello_shared PROPERTIES VERSION 1.1 SOVERSION 1)


# 5、若将libhello.a, libhello.so.x以及hello.h安装到系统目录,才能真正让其他人开发使用,
# 本例中,将hello的共享库安装到<prefix>/lib目录;
# 将hello.h安装<prefix>/include/hello目录。
#INSTALL (TARGETS hello hello_shared LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
#INSTALL (TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)
#INSTALL (FILES hello.h DESTINATION include/hello)
3、configure and generate

xxx/to/path

cd build
cmake ..

4、其他设置

若需要指定输出路径,尝试下面的示例指令:

# 设置VS会自动新建Debug和Release文件夹
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Bin)

# 设置分别设置Debug和Release输出目录
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/Lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../../build/Debug)

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/Lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/Bin)

 

CMakeLists更多小例子

 

生成.so共享库文件


下面是我的几个文件:

1hello.cpp

//hello.cpp
 int Calculate_sum_Of_Two_Number(int x,int y)
{
   int z=0;
   z=x+y;
   return (z);
}

3 main.cpp

//main.cpp
#include "hello.hpp"
#include <stdio.h>
int main(void)
{
   int a=0,b=0,c=0;
   printf("please input two parameter:");
   scanf("%d",&a);
   scanf("%d",&b);
   c=Calculate_sum_Of_Two_Number(a,b);
   printf("the sum is : %d",c);
   return 0;
}

4 CMakeLists.txt

#要求的Cmake最低版本
CMAKE_MINIMUM_REQUIRED( VERSION 2.8)
 
#工程名称
PROJECT(main)
 
#设置编译器编译模式:
set( CMAKE_BUILD_TYPE "Debug" )
 
#生成共享库
#get the shared package
#here needs no .hpp
add_library(calculate_shared SHARED  hello.cpp)
 
#生成可以执行的文件
add_executable(main main.cpp)
 
#连接共享库
target_link_libraries(main calculate_shared)

 

上面CmakeLists.txt里面, 共享库的名称是calculate_shared,这个是我们可以自己更改的。生成的可执行文件是main, 这个名称也是可以更改的。

不过需要注意的是,hello.cpp里面不用在包含hello.hpp 了。(汗,因为这个导致出错,提示说是重复定义函数了);

编译生成:

mkdir build
cd build
cmake ..
make
我们就可以看到build生成了 如下的文件:

CMakeCache.txt cmake_install.cmake main
CMakeFiles libcalculate_shared.so Makefile

libcalculate_shared.so就是生成的共享库文件。

他们的路径是:/home/fan/dev/cmake/4-exer/

下面有build文件夹,以及main.cpp, hello.cpp, hello.hpp,

build文件夹下面有共享库 libcalculate_shared.so.so

 

调用共享库文件

所有的外部依赖库都是这样的,比如opencv ,openni, eigen等等,原理是一样的,只不过他们已经安装在系统里面了,可以查找,而这个则是需要我们自己去配置。

即我上面生成的共享库文件本质上和opencv的库是相同的。只不过这个共享库需要自己手动配置。

比如我又新建了一个工程,需要调用上面的共享库 libcalculate_shared.so。

main.cpp如下:

//main.cpp
#include <stdio.h>
#include <iostream>
#include "hello.hpp"
using namespace std;
int main(void)
{
   int x=2,y=3;
   int z=0;
   z=Calculate_sum_Of_Two_Number(x,y);
   cout<<"the result is:"<<z<<endl;
   return 0;
}

那么在CMakeLists.txt里面,我需要告诉CMake, 这个头文件可以在哪里找到,头文件所定义的函数又可以在哪里找到。

上面hello.hpp的路径是:/home/fan/dev/cmake/4-exer/hello.hpp

libcalculate_shared.so的路径是/home/fan/dev/cmake/4-exer/build/libcalculate_shared.so

则CMakeLists.txt如下:

CMAKE_MINIMUM_REQUIRED( VERSION 2.8)
 
PROJECT(main)
#设置编译器编译模式:
SET( CMAKE_BUILD_TYPE "Debug" )
 
SET(HELLO_INCLUE 
    /home/fan/dev/cmake/4-exer/)
 
SET(HELLO_SO 
    /home/fan/dev/cmake/4-exer/build/libcalculate_shared.so)
 
INCLUDE_DIRECTORIES(${HELLO_INCLUE})
 
add_executable(main main.cpp)
 
target_link_libraries(main ${HELLO_SO})

这里要注意一些细节(对于我这个渣渣来说的)

1、${ }这种形式代表一个变量,比如上面的,HELLO_INCLUE ,就是我自己定义的一个变量。

2、头文件包含到头文件所在的文件夹,即 /home/fan/dev/cmake/4-exer/

3、共享库要指明具体的共享库 ,精确到.so

其实主要的就是指明这个调用这个共享库的时候,使用的头文件,以及共享库本身所在的位置,然后包含链接就可以了。

安装过的共享库(例如opencv)就不用这么麻烦了,因为它的地址都放在了变量里面。

Opencv的依赖添加
比如Opencv, 它的头文件和.so文件都已经放在了系统变量里面,不用向上面自己定义了(上面例子里面的头文件和共享库文件的地址都是我自己设置的)

它的CMakeLists.txt如下:

find_package(OpenCV REQUIRED)

include_directories(${OPENCV_INCLUDE_DIRS})

target_link_libraries(MAIN ${OpenCV_LIBS})

只需要查找就可以了,OpenCV_LIBS 和 OPENCV_INCLUDE_DIRS 都是系统帮我们已经定义好的,所以比较容易

参考博客:

1、如何写自己的CmakeLists.txt https://www.cnblogs.com/chaofn/p/10160555.html

2、 【OpenCV】使用CMake链接自己路径下面的OpenCV库 https://blog.csdn.net/twt520ly/article/details/81981473

原文链接:https://blog.csdn.net/qq_37761077/article/details/88750711

生成一个可执行程序的 CMakeList

#添加包含文件的的目录
include_directories(${cppzmq_INCLUDE_DIR})             
 
#用${SOURCE_FILES}指定的文件,生成可执行文件sample_project 
add_executable(sample_project ${SOURCE_FILES}) 
 
#生成可执行文件sample_project 需要连接 ${CMAKE_THREAD_LIBS_INIT}指定的库
target_link_libraries (sample_project  ${CMAKE_THREAD_LIBS_INIT}) 
 

生成一个.so动态库的 CMakeList 

#用${SRC_LISTS}指定的所有的源文件生成一个库,名字叫libsugan
add_library(libsugan ${SRC_LISTS})   
 
#生成libsugan库需要链接 ${OpenCV_LIBS}、 ${PROJECT_SOURCE_DIR}/lib/libCommonUtilities.so、${PROJECT_SOURCE_DIR}/lib/libInuStreams.so
target_link_libraries(libsugan                 
    ${OpenCV_LIBS}
    ${PROJECT_SOURCE_DIR}/lib/libCommonUtilities.so
    ${PROJECT_SOURCE_DIR}/lib/libInuStreams.so
)

原文链接:https://blog.csdn.net/bandaoyu/article/details/115165199

grep -nR "common" ./ --include=*.txt|grep -vE "src_bak|boost|erasure-code|doc|link.txt"

add_library(生成库),target_link_libraries(生成目标连接的库),set_target_properties
生成静态库:

add_library(libsugan ${SRC_LISTS}) #用${SRC_LISTS}生成静态库libsugan

ADD_LIBRARY(static_lib STATIC ${DIR_SUB_SRCS})

生成动态库(加SHARED ):
add_library(libsugan SHARED ${SRC_LISTS}) #用${SRC_LISTS}生成动态库libsugan

target_link_libraries(libsugan #生成静态库libsugan还需链接依赖库${OpenCV_LIBS}…
${OpenCV_LIBS}
${PROJECT_SOURCE_DIR}/lib/libCommonUtilities.so
${PROJECT_SOURCE_DIR}/lib/libInuStreams.so
)

#上面的配置生成名字为libsugan的静态库,但Linux下对库的存储格式是lib+name.a,所以库libsugan存储出来的结果就是liblibsugan.a,看着很别扭。用下面这句,保证了存储出来的静态库叫做libsugan.a:

set_target_properties(libsugan PROPERTIES OUTPUT_NAME "sugan")

#但是请千万注意,在整个CmakeLists.txt里

#如果想链接生成的这个库必须使用 “add_library(libsugan ${SRC_LISTS})”指明的名字。
set_target_properties(libsugan PROPERTIES OUTPUT_NAME "sugan")

add_executable(demo ./src/main.cpp)
target_link_libraries(demo libsugan)

连接库:

target_link_libraries(demo libsugan)

target_link_libraries(app libsort.a) #生成app 链入 libsort.a静态库

TARGET_LINK_LIBRARIES(app libsort.a)

原例子:

add_library,target_link_libraries,set_target_properties,target_link_libraries使用联系:https://blog.csdn.net/michaelhan3/article/details/69568362

#工程名字
project(Camera_sugan)                  
 
#编译最低cmake版本
cmake_minimum_required(VERSION 2.6)    
 
#设置c++编译器
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )  
 
#在整个电脑上找opencv包
find_package(OpenCV REQUIRED)    
 
#包含头文件路径
include_directories(             
    ./include/inudev/
    ./src/
)
 
#将所有的源文件列为一个集合,集合名字叫做SRC_LISTS
set(SRC_LISTS                   
    ./src/inuitive.cpp
    ./src/runCamera_Qfeeltech.cpp
)
 
#将集合里的所有的源文件生成一个静态库,该静态库的名字libsugan,
注意,在整个CmakeLists里都要用libsugan这个
add_library(libsugan ${SRC_LISTS})   
 
#名字来代替之前那个集合生成的库。
target_link_libraries(libsugan    #链接静态库需要的依赖库
    ${OpenCV_LIBS}
    ${PROJECT_SOURCE_DIR}/lib/libCommonUtilities.so
    ${PROJECT_SOURCE_DIR}/lib/libInuStreams.so
)

原文链接:https://blog.csdn.net/michaelhan3/article/details/69568362

posted @ 2023-02-09 08:41  小小仓鼠  阅读(3402)  评论(0编辑  收藏  举报