CMake编译静态库


准备工作

  • 安装cmake
     我的系统是ubuntu16,这一步就不赘述了,apt或者源代码安装都没问题。

  • 源代码
     我是想在系统中学习好linux应用层编程,所以我买了Linux/Uinx系统编程手册
    在学习过程中发现他的代码都依赖于作者所写的几个头文件,所以我产生了将其将其编译成静态库的想法,虽然文件不多,但是姑且也算是学习到了一些东西。需要的可以自行百度搜索下载。
     源代码分布如下:

    zqh@linux:~/system_program$ tree .
    .
    ├── build
    ├── CMakeLists.txt
    ├── lib
    │   ├── alt_functions.c
    │   ├── alt_functions.h
    │   ├── CMakeLists.txt
    │   ├── ename.c.inc
    │   ├── error_functions.c
    │   ├── error_functions.h
    │   ├── get_num.c
    │   ├── get_num.h
    │   └── tlpi_hdr.h
    └── 编译静态库.md
    
    2 directories, 11 files
    
  • 编写CMakeLists

    • lib目录下的CMakeLists
    CMAKE_MINIMUM_REQUIRED(VERSION 2.8)  
    
    SET(LIB_SRC alt_functions.c error_functions.c get_num.c)  #添加源文件
    
    #添加静态库  
    ADD_LIBRARY(tpli_static STATIC ${LIB_SRC})  
    
    #将静态库重新命名为Libtpli
    SET_TARGET_PROPERTIES(tpli_static PROPERTIES OUTPUT_NAME "tpli")
    
    • 当前目录下的CMakeLists
    CMAKE_MINIMUM_REQUIRED(VERSION 2.8)  
    PROJECT(TestLIB)  #工程名
    ADD_SUBDIRECTORY(lib) #添加子目录
    
  • 编译

    cd build/
    cmake ..
    make
    

    查看结果

    zqh@linux:~/system_program/build$ ls
    CMakeCache.txt  CMakeFiles  cmake_install.cmake  lib  Makefile
    zqh@linux:~/system_program/build$ cd lib/
    zqh@linux:~/system_program/build/lib$ ls
    CMakeFiles  cmake_install.cmake  libtpli.a  Makefile
    

    现在生成了静态库libtpli.a。

  • 测试

    • 准备
      新建了一个目录test,将头文件加入其中,内容如下
      zqh@linux:~/system_program/test$ tree
      .
      ├── build
      ├── CMakeLists.txt
      ├── inc
      │   ├── alt_functions.h
      │   ├── ename.c.inc
      │   ├── error_functions.h
      │   ├── get_num.h
      │   └── tlpi_hdr.h
      └── test.c
      
      2 directories, 7 files
      
      test.c(复制文件内容到另一个文件):
          /*************************************************************************\
      *                  Copyright (C) Michael Kerrisk, 2017.                   *
      *                                                                         *
      * This program is free software. You may use, modify, and redistribute it *
      * under the terms of the GNU General Public License as published by the   *
      * Free Software Foundation, either version 3 or (at your option) any      *
      * later version. This program is distributed without any warranty.  See   *
      * the file COPYING.gpl-v3 for details.                                    *
      \*************************************************************************/
      
      /* Listing 4-1 */
      
      /* copy.c
      
      Copy the file named argv[1] to a new file named in argv[2].
      */
      #include <sys/stat.h>
      #include <fcntl.h>
      #include "tlpi_hdr.h"
      
      #ifndef BUF_SIZE        /* Allow "cc -D" to override definition */
      #define BUF_SIZE 1024
      #endif
      
      int
      main(int argc, char *argv[])
      {
          int inputFd, outputFd, openFlags;
          mode_t filePerms;
          ssize_t numRead;
          char buf[BUF_SIZE];
      
          if (argc != 3 || strcmp(argv[1], "--help") == 0)
              usageErr("%s old-file new-file\n", argv[0]);
      
          /* Open input and output files */
      
          inputFd = open(argv[1], O_RDONLY);
          if (inputFd == -1)
              errExit("opening file %s", argv[1]);
      
          openFlags = O_CREAT | O_WRONLY | O_TRUNC;
          filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
                      S_IROTH | S_IWOTH;      /* rw-rw-rw- */
          outputFd = open(argv[2], openFlags, filePerms);
          if (outputFd == -1)
              errExit("opening file %s", argv[2]);
      
          /* Transfer data until we encounter end of input or an error */
      
          while ((numRead = read(inputFd, buf, BUF_SIZE)) > 0)
              if (write(outputFd, buf, numRead) != numRead)
                  fatal("couldn't write whole buffer");
          if (numRead == -1)
              errExit("read");
      
          if (close(inputFd) == -1)
              errExit("close input");
          if (close(outputFd) == -1)
              errExit("close output");
      
          exit(EXIT_SUCCESS);
      }
      
      CMakeLists.txt:
      CMAKE_MINIMUM_REQUIRED(VERSION 2.8)  
      project (Tutorial)  #工程名
      
      # 添加头文件目录
      include_directories(${PROJECT_SOURCE_DIR}/inc )
      
      
      link_libraries(/home/zqh/system_program/build/lib/libtpli.a)#添加静态库
      
      add_executable (Tutorial test.c) #创建可执行文件
      
      target_link_libraries(Tutorial /home/zqh/system_program/build/lib/libtpli.a)# 连接静态库库
      
    • 编译
      cd build/
      cmake ..
      make
      
    • 运行
      ./Tutorial
      Usage: ./Tutorial old-file new-file
      cat 1.txt
      编译静态库成功
      ./Tutorial 1.txt 2.txt
      cat 2.txt
      编译静态库成功