现在我们来看看怎么为你的工程添加一个库。这个库中包含我们自己实现的用于计算一个数值的平方根的功能。程序可以使用这个库,而不是去使用编译器提供的标准函数。在这次教程中,我们将这个库放入名为“MathFunctions”的文件夹。其中包含两个文件,内容如下:
// MathFunctions.h
double mysqrt(double x);
// mysqrt.cxx
include "MathFunctions.h"
#include <cstdio>
// a hack square root calculation using simple operations
double mysqrt(double x)
{
if (x <= 0) {
return 0;
}
double result;
double delta;
result = x;
// do ten iterations
int i;
for (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;
}
现在我们需要在MathFunctions目录下建立一个CMakeLists.txt文件,向其中添加一行:
add_library (MathFunctions mysqrt.cxx)
在源文件mysqrt.cxx中有一个名为mysqrt的函数,用来实现与sqrt()相似的功能。为了能够在之前的tutorial.cxx中使用该库,我们需要修改tutorial.cxx所在目录中的CMakeLists.txt文件。使用 add_subdirectory 将MathFunctions目录添加进去,并且还需要添加头文件目录,用以找到函数原型。修改后的内容如下:
# Minimum version required
cmake_minimum_required(VERSION 3.0.0)
PROJECT(Tutorial)
# The version number
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)
# configure a header file to pass some of the Cmake settings
# to the source code
configure_file(
"${PROJECT_SOURCE_DIR}/TutorialConfig.h.in"
"${PROJECT_BINARY_DIR}/TutorialConfig.h"
)
# add the binary tree to the search path for include file
# so that we will find TestConfig.h
include_directories("${PROJECT_BINARY_DIR}")
include_directories("${PROJECT_SOURCE_DIR}/MathFunctions")
add_subdirectory(MathFunctions)
# add the executable
ADD_EXECUTABLE(Tutorial tutorial.cpp)
target_link_libraries(Tutorial MathFunctions)
现在我们再来添加一个optional用以控制是否要使用这个库,虽然这在这个示例中显得有点多余,但是对于那些大型库或者依赖于第三方库的话,你可能就要这么做了,不然会显得是否麻烦。现在我们来添加这个optional到CMakeLists.txt文件中:
# should we use our math function
option(USE_MYMATH "Use tutorial provided math implementation" ON)
这条语句定义的USE_MYMATH会显示在CMake GUI上,默认值为ON,用户可以根据自己的需要更改。这个设定会保存在缓存中,所以用户不必重复设置它当你在这个工程上使用CMake时。接下来我们来添加一些判断语句,用以决定对库的使用,语法很简单,如下:
# 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 executable
add_executable (Tutorial tutorial.cxx)
target_link_libraries (Tutorial ${EXTRA_LIBS})
我们通过USE_MYMATH的值来判断是否需要使用并编译MathFunctions。注意,这里使用了变量EXTAR_LIBS,用来表示需要编译和链接的库(可以是一个库,也可以是多个),避免以后修改的麻烦,提高代码重用性。
现在我们来修改tutorial.cxx文件,非常简单:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include "TutorialConfig.h"
// #define USE_MYMATH
#ifdef USE_MYMATH
#include "MathFunctions.h"
#endif
using namespace std;
int main(int argc, char *argv[])
{
if (argc < 2) {
fprintf(stdout, "%s Version %d.%d\n",
argv[0],
Tutorial_VERSION_MAJOR,
Tutorial_VERSION_MINOR
);
fprintf(stdout, "usage: %s number\n", argv[0]);
return 1;
}
double inputValue = atof(argv[1]);
#ifdef USE_MYMATH
double outputValue = mysqrt(inputValue);
cout << "1" << endl;
#else
double outputValue = sqrt(inputValue);
cout << "2" << endl;
#endif
fprintf(stdout, "The square root of %g is %g\n",
inputValue, outputValue
);
return 0;
}