分一下几个方面来描述:
1. 每一个LIB要编译成静态库或动态库如何描述,每一个TOOL要编译成可执行文件如何描述?
2. LIB和TOOL可能会依赖于其他LIB,该如何描述?
3. 每个LIB和TOOL都会include很多头文件,相同的头文件如何处理,私有的头文件如何处理?
4. CMake中的一些用法
5. LLVM中用到的技巧
先举一个简单的例子:
//
└─tutorial.c
└─TutorialConfig.h.in
└─CMakeLists.txt
└─include
└─mysqrt.h
└─lib
└─CMakeLists.txt
└─MakeTable.c
└─mysqrt.c
在这个例子中,Top level和lib中会分别定义一个CMakeLists.txt用来指定编译规则。这个例子主要做了以下几件事:
1)用宏USE_MYMATH来控制是否使用自己定义的sqrt()
2) 定义了一个MakeTable.c文件生成sqrt()的一个结果表,在自己定义的sqrt()函数中查表得出简单的结果。
3)或者通过exp和log来计算sqrt的值,但前提是当前库支持exp和log,这些都通过check_function_exists检查是否支持,如果支持相应的宏就会打开。
4)通过CTest,定义相应的测试用例,检查执行结果是否正确。
Top Level中的
Tutorial.c:
// A simple program that computes the square root of a number
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "TutorialConfig.h"
#ifdef USE_MYMATH
#include "mysqrt.h"
#endif
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);
printf ("call local sqrt\n");
#else
double outputValue = sqrt(inputValue);
#endif
fprintf(stdout,"The square root of %g is %g\n",
inputValue, outputValue);
return 0;
}
当cmake为头文件配置”@Tutorial_VERSION_MAJOR@”和
“@Tutorial_VERSION_MINOR@”两个值时,会从CMakeLists.txt中找到相应的值来替换配置文件中对应行。
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
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP
CMakeList.txt定义如下:
cmake_minimum_required (VERSION 2.6)
project (Tutorial)
# The version number.
//"set"用来给对应的变量赋值
set (Tutorial_VERSION_MAJOR 1)
set (Tutorial_VERSION_MINOR 0)
set(include_dir ${CMAKE_CURRENT_SOURCE_DIR}/include)
//"MESSAGE"用来打印信息,包括变量的值
MESSAGE(STATUS "include folder: " ${include_dir})
//"option"用来定义宏,"ON"表示打开,"OFF"表示关闭
option (USE_MYMATH "Use tutorial provided math implementation" ON)
//configure_file: 将一份文件拷贝到另一个位置并修改它的内容。
# 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 in