CMake Introduction
编译系统从Makefile,到Autoconf,再到CMake,
1 Makefile
Makefile的语法比较好玩(晦涩),提供了各种各样的弹性扩展。06年写过下面这样的
Makefile Demo,现在基本不会写了,也忘记了 $<, $@, $*
的含义。
################################ # ApFileSubServer Makefile # # yanyg 2006 10 23 # ################################ CXX := g++ CXXFLAGS := -g -c LIB := -Wl,-Bdynamic -lpthread -lgcc_s -lcrypt -lnsl -lrt SRC :=$(wildcard *.cpp) OBJ :=$(SRC:.cpp=.o) all : ApFileMainServer .SUFFIXES : .o .cpp .cpp.o : @${CXX} ${CXXFLAGS} $< -o $@ @echo "Compile " $< "success..." ApFileMainServer : ${OBJ} @echo "Link OBJ to ApFileMainServer ..." @${CXX} ${LIB} ${OBJ} -o ApFileMainServer @echo "Build ApFileMainServer Success!" .PHONY : clean clean: @echo "Delete OBJ(*.o) && ApFileMainServer..." @rm -fr ${OBJ} ApFileMainServery
这个Makefile只是一个Demo,而不是好的示例。一个Makefile要有编译、打包、安装、 测试等。想写好的Makefile不是一件简单的事情,Autoconf从一定程度缓解了这个问题。
2 Autoconf
3 CMake
目前用起来最爽的编译系统了。
3.1 hello world
hello.c
#include <stdio.h> int main(int argc, char *argv[]) { printf("hello world\n"); return 0; }
CMakeLists.txt:
project(hello) add_executable(hello helloc.c)
Compile:
~$yanyg@t430:~/test $ mkdir build yanyg@t430:~/test $ cd build yanyg@t430:~/test/build $ cmake .. -- The C compiler identification is GNU 8.3.0 -- The CXX compiler identification is GNU 8.3.0 -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done -- Configuring done -- Generating done -- Build files have been written to: /home/yanyg/test/build yanyg@t430:~/test/build$ ls CMakeCache.txt CMakeFiles cmake_install.cmake hello Makefile yanyg@t430:~/test/build$ ./hello hello world
3.2 Test
enable_testing() 必须在项目根目录下,否则找不到test case;例如:
Part of platform/CMakeLists.txt:
enable_testing() set(TESTS_SUITE tests) set(CMAKE_CTEST_COMMAND ctest) add_custom_target(${TESTS_SUITE} COMMENT "Building tests suite") add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS ${TESTS_SUITE})
Part of platform/test/CMakeLists.txt:
enable_language(C CXX) find_package(GTest) if (NOT GTEST_FOUND) message(WARNING "Test: GTest not found, ignore") return() endif() include(GoogleTest) include_directories(${GTEST_INCLUDE_DIRS}) link_libraries(${GTEST_BOTH_LIBRARIES}) find_package(Threads REQUIRED) if (CMAKE_USE_PTHREADS_INIT) add_definitions(-DHAVE_PTHREAD) endif (CMAKE_USE_PTHREADS_INIT) link_libraries(pthread) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../src/include) link_libraries(platform) add_subdirectory(base) add_subdirectory(container) add_subdirectory(memory)
Part of platform/test/base/CMakeLists.txt:
set(TEST_SRC test_assert.cc) set(TEST_TARGET test_base) add_executable(${TEST_TARGET} ${TEST_SRC}) add_dependencies(${TESTS_SUITE} ${TEST_TARGET}) gtest_discover_tests(${TEST_TARGET} PROPERTIES TIMEOUT 10)
Run make check:
yanyg@t430:~/platform/build$ make check [ 13%] Built target platform_memory [ 26%] Built target platform_base Scanning dependencies of target platform_container [ 33%] Building C object src/container/CMakeFiles/platform_container.dir/xarray.c.o [ 33%] Built target platform_container [ 40%] Linking C static library libplatform.a [ 40%] Built target platform [ 46%] Linking CXX executable test_memory [ 60%] Built target test_memory [ 66%] Linking CXX executable test_base [ 73%] Built target test_base [ 80%] Linking CXX executable test_container [100%] Built target test_container [100%] Built target tests Test project /home/yanyg/platform/build Start 1: Assert.Assert 1/10 Test #1: Assert.Assert .................... Passed 0.00 sec Start 2: Assert.AssertDebug 2/10 Test #2: Assert.AssertDebug ............... Passed 0.00 sec Start 3: TestBitmap.Malloc 3/10 Test #3: TestBitmap.Malloc ................ Passed 0.14 sec Start 4: TestBitmap.Arena 4/10 Test #4: TestBitmap.Arena ................. Passed 0.14 sec Start 5: XarrayTest.CreateDestroy 5/10 Test #5: XarrayTest.CreateDestroy ......... Passed 0.00 sec Start 6: XarrayTest.StoreLoad 6/10 Test #6: XarrayTest.StoreLoad ............. Passed 0.01 sec Start 7: TestMemCache.Simple 7/10 Test #7: TestMemCache.Simple .............. Passed 0.02 sec Start 8: TestMemCache.Small 8/10 Test #8: TestMemCache.Small ............... Passed 0.03 sec Start 9: TestMemCache.NoReserve 9/10 Test #9: TestMemCache.NoReserve ........... Passed 0.03 sec Start 10: TestArena.Alloc 10/10 Test #10: TestArena.Alloc .................. Passed 0.03 sec 100% tests passed, 0 tests failed out of 10 Total Test time (real) = 0.41 sec [100%] Built target check yanyg@t430:~/platform/build$ ls Testing/Temporary/ CTestCostData.txt LastTest.log LastTestsFailed.log
4 References
- cmake documentation: https://cmake.org/documentation/
- awesome-cmake: https://github.com/onqtam/awesome-cmake
- professional-cmake: https://crascit.com/professional-cmake/
- automake: https://www.gnu.org/software/automake/
- autoconf: https://www.gnu.org/software/autoconf/autoconf.html
- makefile: https://www.gnu.org/software/make/manual/make.html
- Blog: Autoconf简单示例
- Blog: Autoconf简单示例2