• 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目录下

  • 相关阅读:
    进度3
    进度2
    进度1
    库存物资管理系统
    课程管理系统
    文件与流作业
    bzoj4027: [HEOI2015]兔子与樱花
    bzoj2067: [Poi2004]SZN
    bzoj2071:[POI2004]山洞迷宫
    bzoj1063: [Noi2008]道路设计
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/16199684.html
Copyright © 2020-2023  润新知