cmake共享库编译及连接

当项目比较大的时候,我们希望将基础的源文件打包成库,静态库或者共享库都可以。

首先看一下我们的项目目录

cmaths是我自己写的一些数学计算包,我希望把它打成包,在多个项目中共享

 

 根目录的CMakeLists.txt在上图没有显示,我把内容贴出来

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(system_program_notes C)

set(CMAKE_C_STANDARD 11)

add_subdirectory(cmaths)
add_subdirectory(cmaths_static_test)
add_subdirectory(cmaths_shared_test)
#cmaths_static_test需要用到静态库,cmaths_shared_test需要依赖共享库,所以在需要在cmaths目录先执行cmake . && make 即可在cmaths/lib子目录生成libfunc_static.a,libfunc_shared.so库文件
#然后再在根目录执行cmake . && make ,cmaths_static_test,cmaths_shared_test即可成功找到库文件

一、共享库源码及配置

func.h

#ifndef SYSTEM_PROGRAM_NOTES_FUNC_H
#define SYSTEM_PROGRAM_NOTES_FUNC_H
int square(int a,int b);
double sqrt(double x);
#endif //SYSTEM_PROGRAM_NOTES_FUNC_H

func.c

#include "func.h"

int square(int a,int b){
    return a*a+b*b;
}

double sqrt(double x){
    if (x <= 0) {
        return 0;
    }

    double result;
    double delta;
    result = x;

    int i;
    for (i = 0; i < 10; ++i) {
        if (result <= 0) {
            result = 0.1;
        }
        delta = x - (result * result);
        result = result + 0.5 * delta / result;
    }
    return result;
}

cmaths/CMakeLists.txt

add_library(func_static STATIC  func.c)
add_library(func_shared SHARED  func.c)
#设置最终生成库的名称,静态库=func_static,共享库=func_shared
set_target_properties (func_static PROPERTIES OUTPUT_NAME "func_static")
set_target_properties (func_shared PROPERTIES OUTPUT_NAME "func_shared")
#实践发现库会生成到当前目录的lib目录下
set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

#首先在当前目录下执行cmake . && make 即可在当前目录的lib子目录生成libfunc_static.a静态库文件和libfunc_shared.so
#然后再在根目录执行cmake . && make ,即可

二、链接静态库

cmaths_static_test模块需要引用静态库func_static

cmaths_static_test/test.c

#include <stdio.h>
#include "func.h"
int main(int argc, char *argv[]){
    printf("%f\n", sqrt(36));
    printf("%d\n", square(2,3));
}

cmaths_static_test/CMakeLists.txt

#指定路径,用于找到cmaths/func.h
include_directories(../cmaths )
#查找静态库,参数分别是:变量名、库名、HINTS、路径
find_library(FUNC_LIB func_static HINTS ${PROJECT_SOURCE_DIR}/cmaths/lib)
#编译目标文件
add_executable(test test.c)
#链接到静态库
target_link_libraries(test PUBLIC ${FUNC_LIB})

三、链接共享库

cmaths_shared_test/test1.c

#include <stdio.h>
#include "func.h"
int main(int argc, char *argv[]){
    printf("%f\n", sqrt(36));
    printf("%d\n", square(2,3));
}

cmaths_shared_test/CMakeLists.txt

#找到func.h
include_directories(../cmaths )
#指定共享库目录
link_directories(${PROJECT_SOURCE_DIR}/cmaths/lib)
#编译目标文件
add_executable(test1 test1.c)
#链接目标和共享库文件
target_link_libraries(test1 PUBLIC libfunc_shared.so)

四、编译构建

在linux系统,首先在cmaths目录下执行cmake . && make 即可在cmaths的lib子目录生成libfunc_static.a静态库文件和libfunc_shared.so共享库文件

然后再在根目录执行cmake . && make ,即可

然后cd到cmaths_static_test即可发现test可执行文件

cmaths_shared_test即可发现test1可执行文件。

执行无误,说明我们的目标文件成功链接到了库文件

五、安装

平常我们在构建源码安装包的时候,一般是先make,然后make install

make可以从一个名为makefile的文件中获得如何构建你所写程序的依赖关系,并执行编译,可以认为是加强版的gcc

make install也是从makefile读取配置,将make生成的目标文件安装到指定目录

坦率的说makefile不太好写,所以cmake横空出世,让我们可以以比较简单的方式生成makefile。

上面的内容,我们已经可以生成可执行文件和各种库文件,下面我们来将这些文件安装到指定目录

对cmaths/func.c略作修改

#include <stdio.h>
#include "func.h"

int square(int a,int b){
    return a*a+b*b;
}

double sqrt(double x){
    if (x <= 0) {
        return 0;
    }

    double result;
    double delta;
    result = x;

    int i;
    for (i = 0; i < 10; ++i) {
        if (result <= 0) {
            result = 0.1;
        }
        delta = x - (result * result);
        result = result + 0.5 * delta / result;
    }
    return result;
}

int main(int argc, char *argv[]){
    printf("%f\n", sqrt(36));
    printf("%d\n", square(2,3));
}

然后修改cmaths/CMakeLists.txt

add_library(func_static STATIC  func.c)
add_library(func_shared SHARED  func.c)
#设置最终生成库的名称,静态库=func_static,共享库=func_shared
set_target_properties (func_static PROPERTIES OUTPUT_NAME "func_static")
set_target_properties (func_shared PROPERTIES OUTPUT_NAME "func_shared")
#实践发现库会生成到当前目录的lib目录下
set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
add_executable(func func.c)
#首先在当前目录下执行cmake . && make 即可在当前目录的lib子目录生成libfunc_static.a静态库文件和libfunc_shared.so

#然后再在根目录执行cmake . && make ,即可

#最后执行make install 可进行安装工作
#install执行日志,共享库默认被安装到了/usr/local/lib目录下,头文件默认被安装到/usr/local/include目录下
#-- Installing: /usr/local/bin/func
#-- Installing: /usr/local/lib/libfunc_shared.so
#-- Installing: /usr/local/lib/libfunc_static.a
#-- Installing: /usr/local/include/func.h
#安装的目标,后面一行指不同的目标类型要被安装到什么目录
install(TARGETS func  func_shared func_static
        RUNTIME DESTINATION bin
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib)
#安装普通文件
install(FILES func.h DESTINATION include)

 

最后是执行指令,在cmaths目录执行cmake . &&make && make install

可以看到库文件默认被安装到了/usr/local/lib目录下,头文件默认被安装到/usr/local/include目录下,可执行文件被安装到了/usr/local/bin目录下

posted @ 2022-04-27 16:58  Mars.wang  阅读(935)  评论(0编辑  收藏  举报