CMake3:添加一个库

来源:互联网 发布:多层嵌套 知乎 编辑:程序博客网 时间:2024/05/22 06:56

1.添加库

现在可以考虑为我们的项目添加一个库,这个库的功能是计算一个数的平方根。可应用程序将应用这个库,而不是之前由编译器提供的平方根函数计算平方根。本篇博客,我们将把这个库放在一个叫‘MathFunction’的子目录中。并在CMake中使用下述代码进行连接:
add_library(MathFunctions mysqrt.cxx)
源文件mysqrt.c提供了与编译器中具有相似功能的平方根函数,mysqrt()。为了充分利用这个新库,我们在顶层CMakeLists.txt中添加一个Add_subdirectory调用,组建这个库。我们也添加了另外一个包含目录,所以MathFunctions库/MathFunctions.h头文件能够在函数原型中找到。最后一个改变就是将这个新库添加到可执行程序中。
在CMake2的CMakeLists.txt基础上最后几行代码变为:
include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")add_subdirectory (MathFunctions)  # add the executableadd_executable (Tutorial tutorial.c)target_link_libraries (Tutorial MathFunctions)
下面考虑制作MathFunctions库
可能这个环节看起来一点都没有必要。但是,在实际的大项目中我们经常依赖第三方较大型的库。所以首先要考虑的就是如何将库选项添加到顶层文件CMakeLists.txt中
# should we use our own math functions?option (USE_MYMATH         "Use tutorial provided math implementation" ON) 
这条代码的作用是:CMake GUI将会出现一个默认值为‘ON’的选项,用户可以根据实际情况进行选择。这个设置存储在缓存中,所以对于这个项目,用户不需要每次运行CMake时重新设置。
下一个改变就是有条件地组建和连接MathFunctions库。完成这个功能,我们需要在CMakeLists.txt中做一下的更改:
# add the MathFunctions library?#if (USE_MYMATH)  include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")  add_subdirectory (MathFunctions)  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)endif (USE_MYMATH) # add the executableadd_executable (Tutorial tutorial.cxx)target_link_libraries (Tutorial  ${EXTRA_LIBS})
上面代码的含义是:
我们使用 USE_MYMATH 决定 MathFunctions 是否被编译和使用。
注意:我们使用变量‘EXTRA_LIBS’收集所有可供选择的库文件,进而将他们链接到可执行文件中
这种方法对于一个拥有很多可选组建的大型程序而言是很常见的。
变量 USE_MYMATH 在源文件中也会被用到,所以需要的头文件中进行宏定义:
This is provided from CMake to the source code through the TutorialConfig.h.inconfigured file by adding the following line to it:
#cmakedefine USE_MYMATH   //CMakeConfig.h.in
===============================================================================
文件结构如下:
  • ~/MathFunctions/ CMakeLists.txt 
add_library(MathFunctions mysqrt.c)
  • ~/MathFunctions/ MathFunctions.h
double mysqrt(double x);
  • ~/MathFunctions/ MathFunctions.c
#include "MathFunctions.h"#include <stdio.h>// a hack square root calculation using simple operationsdouble mysqrt(double x){  double result;  double delta;  result = x;  for (int i = 0; i < 10; ++i) {    if (result <= 0) {      result = 0.1;    }    delta = x - (result * result);    result = result + 0.5 * delta / result;    fprintf(stdout, "Computing sqrt of %g to be %g\n", x, result);  }  return result;}
  • ~/CMakeLists.txt
cmake_minimum_required (VERSION 2.8)project (Tutorial)# The version number.set (Tutorial_VERSION_MAJOR 1)set (Tutorial_VERSION_MINOR 0)# should we use our own math functionsoption(USE_MYMATH "Use tutorial provided math implementation" ON)# configure a header file to pass some of the CMake settings# to the source codeconfigure_file (  "${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"  "${PROJECT_BINARY_DIR}/TutorialConfig.h"  )# add the binary tree to the search path for include files# so that we will find TutorialConfig.hinclude_directories ("${PROJECT_BINARY_DIR}")# add the MathFunctions library?if (USE_MYMATH)  include_directories ("${PROJECT_SOURCE_DIR}/MathFunctions")  add_subdirectory (MathFunctions)  set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)endif ()# add the executableadd_executable (Tutorial tutorial.c)target_link_libraries (Tutorial  ${EXTRA_LIBS})
  • ~/Tutorial.c
// A simple program that computes the square root of a number#include "TutorialConfig.h"#include <math.h>#include <stdio.h>#include <stdlib.h>#ifdef USE_MYMATH#include "MathFunctions.h"#endifint main(int argc, char* argv[]){  double inputValue = 4;  double outputValue = 0;  if (inputValue >= 0) {#ifdef USE_MYMATH    outputValue = mysqrt(inputValue);#else    outputValue = sqrt(inputValue);#endif  }  fprintf(stdout, "The square root of %g is %g\n", inputValue, outputValue);  fprintf(stdout, "%s Version %d.%d\n", argv[0], Tutorial_VERSION_MAJOR,          Tutorial_VERSION_MINOR);  return 0;}
  • ~/TutorialConfig.h.in
// the configured options and settings for Tutorial#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@#cmakedefine USE_MYMATH