All problems in computer science can be solved by another level of indirection.
David Wheeler
你或许听过好几种 Make 工具,例如 GNU Make ,QT 的 qmake ,微软的 MS nmake,BSD Make(pmake),Makepp,等等。这些 Make 工具遵循着不同的规范和标准,所执行的 Makefile 格式也千差万别。这样就带来了一个严峻的问题:如果软件想跨平台,必须要保证能够在不同平台编译。而如果使用上面的 Make 工具,就得为每一种标准写一次 Makefile ,这将是一件让人抓狂的工作。
CMake就是针对上面问题所设计的工具:它首先允许开发者编写一种平台无关的 CMakeList.txt 文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。从而做到“Write once, run everywhere”。显然,CMake 是一个比上述几种 make 更高级的编译配置工具。一些使用 CMake 作为项目架构系统的知名开源项目有 VTK、ITK、KDE、OpenCV、OSG 等[1]。
/** * power - Calculate the power of number. * @param base: Base value. * @param exponent: Exponent value. * * @return base raised to the power exponent. */ doublepower(double base, int exponent) { int result = base; int i;
if (exponent == 0) { return1; } for(i = 1; i < exponent; ++i){ result = result * base; }
return result; }
intmain(int argc, char *argv[]) { if (argc < 3){ printf("Usage: %s base exponent \n", argv[0]); return1; } double base = atof(argv[1]); int exponent = atoi(argv[2]); double result = power(base, exponent); printf("%g ^ %d is %g\n", base, exponent, result); return0; }
[ehome@xman Demo1]$ cmake . -- The C compiler identification is GNU 4.8.2 -- The CXX compiler identification is GNU 4.8.2 -- Check for working C compiler: /usr/sbin/cc -- Check for working C compiler: /usr/sbin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working CXX compiler: /usr/sbin/c++ -- Check for working CXX compiler: /usr/sbin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Configuring done -- Generating done -- Build files have been written to: /home/ehome/Documents/programming/C/power/Demo1 [ehome@xman Demo1]$ make Scanning dependencies of target Demo [100%] Building C object CMakeFiles/Demo.dir/main.cc.o Linking C executable Demo [100%] Built target Demo [ehome@xman Demo1]$ ./Demo 5 4 5 ^ 4 is 625 [ehome@xman Demo1]$ ./Demo 7 3 7 ^ 3 is 343 [ehome@xman Demo1]$ ./Demo 2 10 2 ^ 10 is 1024
intmain(int argc, char *argv[]) { if (argc < 3){ printf("Usage: %s base exponent \n", argv[0]); return1; }
double base = atof(argv[1]); int exponent = atoi(argv[2]);
#ifdef USE_MYMATH printf("Now we use our own Math library. \n"); double result = power(base, exponent); #else printf("Now we use the standard library. \n"); double result = pow(base, exponent); #endif printf("%g ^ %d is %g\n", base, exponent, result); return0; }
CMake 也可以指定安装规则,以及添加测试。这两个功能分别可以通过在产生 Makefile 后使用 make install 和 make test 来执行。在以前的 GNU Makefile 里,你可能需要为此编写 install 和 test 两个伪目标和相应的规则,但在 CMake 里,这样的工作同样只需要简单的调用几条命令。
#ifdef HAVE_POW printf("Now we use the standard library. \n"); double result = pow(base, exponent); #else printf("Now we use our own Math library. \n"); double result = power(base, exponent); #endif
#include<stdio.h> #include<stdlib.h> #include<math.h> #include"config.h" #include"math/MathFunctions.h" intmain(int argc, char *argv[]) { if (argc < 3){ // print version info printf("%s Version %d.%d\n", argv[0], Demo_VERSION_MAJOR, Demo_VERSION_MINOR); printf("Usage: %s base exponent \n", argv[0]); return1; } double base = atof(argv[1]); int exponent = atoi(argv[2]); #if defined (HAVE_POW) printf("Now we use the standard library. \n"); double result = pow(base, exponent); #else printf("Now we use our own Math library. \n"); double result = power(base, exponent); #endif printf("%g ^ %d is %g\n", base, exponent, result); return0; }
# 构建一个 CPack 安装包 include (InstallRequiredSystemLibraries) set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") set (CPACK_PACKAGE_VERSION_MAJOR "${Demo_VERSION_MAJOR}") set (CPACK_PACKAGE_VERSION_MINOR "${Demo_VERSION_MINOR}") include (CPack)
[ehome@xman Demo8]$ sh Demo8-1.0.1-Linux.sh Demo8 Installer Version: 1.0.1, Copyright (c) Humanity This is a self-extracting archive. The archive will be extracted to: /home/ehome/Documents/programming/C/power/Demo8 If you want to stop extracting, please press <ctrl-C>. The MIT License (MIT) Copyright (c) 2013 Joseph Pan(http://hahack.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Do you accept the license? [yN]: y By default the Demo8 will be installed in: "/home/ehome/Documents/programming/C/power/Demo8/Demo8-1.0.1-Linux" Do you want to include the subdirectory Demo8-1.0.1-Linux? Saying no will install in: "/home/ehome/Documents/programming/C/power/Demo8" [Yn]: y Using target directory: /home/ehome/Documents/programming/C/power/Demo8/Demo8-1.0.1-Linux Extracting, please wait... Unpacking finished successfully
完成后提示安装到了 Demo8-1.0.1-Linux 子目录中,我们可以进去执行该程序:
1 2 3
[ehome@xman Demo8]$ ./Demo8-1.0.1-Linux/bin/Demo 5 2 Now we use our own Math library. 5 ^ 2 is 25