目录
  • 静态库和动态库的区别
  • 构建示例
  • ADD_LIBRARY
  • 同时构建静态和动态库
    • SET_TARGET_PROPERTIES
  • 动态库的版本号
    • 安装共享库和头文件
      • 使用外部共享库和头文件
        • 解决 :make后头文件找不到的问题
          • 解决:找到引用的函数问题
            • 特殊的环境变量CMAKE_INCLUDE_PATH和CMAKE_LIBRARY_PATH
              • 总结

                静态库和动态库的区别

                1、静态库的扩展名一般为".a"或者".lib";动态库的扩展名一般为".so"或者".dll"。

                2、静态库在编译时会直接整合到目标程序中,编译成功的可执行文件可以独立运行

                3、动态库在编译时不会放到连接的目标程序中,即可执行文件无法单独运行。

                构建示例

                创建新项目cmake02,包含目录如下

                C++ Cmake的构建静态库和动态库详解

                ​hello.h中的内容

                #ifndef HELLO_H
                #define HELLO_H
                 
                void HelloFunc();
                 
                #endif

                 hello.cpp中的内容

                #include "hello.h"
                #include <iostream>
                using namespace std;
                 
                void HelloFunc()
                {
                    cout<<"Hello World"<<endl;
                }

                项目中CMakeLists.txt内容

                PROJECT(HELLO)
                ADD_SUBDIRECTORY(lib bin)

                lib中CMakeLists.txt内容

                SET(LIBHELLO_SRC hello.cpp)
                ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

                ADD_LIBRARY

                ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

                hello:就是正常的库名,生成的名字前面会加上lib,最终产生的文件是libhello.so

                SHARED,动态库STATIC,静态库

                ${LIBHELLO_SRC}:源文件

                C++ Cmake的构建静态库和动态库详解

                C++ Cmake的构建静态库和动态库详解

                同时构建静态和动态库

                //如果用这种方式,只会构建一个动态库,不会构建出静态库,虽然静态库的后缀是.a

                ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

                ADD_LIBRARY(hello STATIC ${LIBHELLO_SRC})

                //修改静态库的名字,这样是可以的,但是我们往往希望他们的名字是相同的,只是后缀不同而已

                ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

                ADD_LIBRARY(hello_static STATIC ${LIBHELLO_SRC})

                SET_TARGET_PROPERTIES

                这条指令可以用来设置输出的名称,对于动态库,还可以用来指定动态库版本和API版本

                同时构建静态和动态库示例

                SET(LIBHELLO_SRC hello.cpp)
                 
                ADD_LIBRARY(hello_static STATIC	${LIBHELLO_SRC})
                 
                SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
                 
                SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT$
                 
                ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})
                 
                SET_TARGET_PROPERTIES(hello PROPERTIES OUTPUT_NAME "hello")
                SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)

                C++ Cmake的构建静态库和动态库详解

                C++ Cmake的构建静态库和动态库详解

                动态库的版本号

                一般动态库都会有一个版本号的关联

                libhello.so.1.2

                libhello.so->libhello.so.1

                libhello.so.1->libhello.so.1.2

                CMakeList.txt插入如下

                SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)

                 VERSION指代动态库版本,SOVERSION指代API版本

                安装共享库和头文件

                本例中我们将hello的共享库安装到<prefix>/lib目录

                将hello.h安装到<prefix>/include/hello目录

                //文件放到该目录下
                INSTALL(FILES hello.h DESTINATION include/hello)
                 
                //二进制,静态库,动态库安装都是用TARGETS
                //ARCHIVE特指静态库,LIBRATY特指动态库,RUNTIME特指可执行目标二进制
                INSTALL(TARGETS hello hello_static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib)

                C++ Cmake的构建静态库和动态库详解

                注意:安装的时候,指定一下路径,放到系统下

                cmake -DCMAKE_INSTALL_PERFIX=/usr ..

                C++ Cmake的构建静态库和动态库详解

                C++ Cmake的构建静态库和动态库详解

                使用外部共享库和头文件

                新建cmake03目录来使用外部共享库和头文件

                C++ Cmake的构建静态库和动态库详解

                main.cpp内容

                #include <hello.h>
                 
                int main()
                {
                    HelloFunc();
                }

                解决 :make后头文件找不到的问题

                C++ Cmake的构建静态库和动态库详解

                 PS:include 这样是可以的

                关键字:INCLUDE_DIRECTORIES 这条指令可以用来向工程添加多个特定的头文件搜索路径,路径之间用空格分割

                在CMakeLists.txt中加入头文件搜索路径

                INCLUDE_DIRECTORIES(/usr/local/include/hello)

                解决:找到引用的函数问题

                C++ Cmake的构建静态库和动态库详解

                关键字:LINK_DIRCTORIES 添加非标准的共享库搜索路径

                指定第三方库锁在路径,LINK_DIRECTORIES(/home/myproject/libs)

                关键字TARGET_LINK_LIBRARIES 添加需要链接的共享库

                TARGET_LINK_LIBRARIES的时候,只需要给出动态链接库的名字就行了。

                CMakeLists.txt中插入连接共享库,主要要插在executable的后面

                TARGET_LINK_LIBRARIES(hello libhello.so)

                C++ Cmake的构建静态库和动态库详解

                 cmake后make

                C++ Cmake的构建静态库和动态库详解

                执行bin目录下的./hello报错

                C++ Cmake的构建静态库和动态库详解

                解决:mv /usr/local/lib/libhello.so /usr/lib64/

                C++ Cmake的构建静态库和动态库详解

                 查看main的链接情况

                C++ Cmake的构建静态库和动态库详解

                链接静态库

                TARGET_LINK_LIBRARIES(hello libhello.a) 

                特殊的环境变量CMAKE_INCLUDE_PATH和CMAKE_LIBRARY_PATH

                注意:这两个是环境变量而不是cmake变量,可以在linux的bash中进行设置

                在上面例子中使用了绝对路径INCLUDE_DIRECTORIES(/usr/include/hello)来指明include路径的位置

                我们还可以使用环境变量export CMAKE_INCLUDE_PATH=/usr/local/include/hello

                生产debug版本的方法:

                cmake .. -DCMAKE_BUILD_TYPE=debug

                总结

                本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注的更多内容!  

                声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。