很多時候我們會在專案中決定使用哪個library, 這裡會舉個範例, 使用自訂的library或是使用系統的library,首先要在最上層的CMakeLists.txt中用option()定義我們的變數USE_MYMATH, on代表用自訂的library, 否則用系統的library, 所以相對應的target_link_libraries()與target_include_directories()也要根據USE_MYMATH稍微做一下調整, 所以我們用EXTRA_LIBS與EXTRA_INCLUDES分別去儲存對應的header file位置與相關的library資訊
# Require a minimum version of cmake. # cmake_minimum_required(VERSION <min>>[...<policy_max>] [FATAL_ERROR]) cmake_minimum_required(VERSION 3.10) # Set the name of the project. # project(<PROJECT-NAME< [<anguage-name>...]) # project(<PROJECT-NAME> # [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]] # [DESCRIPTION <project-description-string>] # [LANGUAGES <language-name>...]) project(Tutorial VERSION 0.1.2.3 DESCRIPTION "This is Brook 1st CMake Lib") # Add an executable to the project using the specified source files. # add_executable(<name> [WIN32] [MACOSX_BUNDLE] # [EXCLUDE_FROM_ALL] # [source1] [source2 ...]) add_executable(Tutorial hello.c) # option(<variable> "<help_text>" [value]) option(USE_MYMATH "Use tutorial provided math implementation" ON) # configure_file(<input> <output> # [NO_SOURCE_PERMISSIONS | USE_SOURCE_PERMISSIONS | # FILE_PERMISSIONS <permissions>...] # [COPYONLY] [ESCAPE_QUOTES] [@ONLY] # [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ]) # configure a header file to pass some of the CMake settings # to the source code configure_file(Config.h.in Config.h) if (USE_MYMATH) # Add a subdirectory to the build. # add_subdirectory(source_dir [binary_dir] # [EXCLUDE_FROM_ALL]) add_subdirectory(mymath01) # list(APPEND <list> [<element> ...]) # Appends elements to the list. # If no variable named <list> exists in the current # scope its value is treated as empty and the elements # are appended to that empty list. list(APPEND EXTRA_LIBS MyMathLib1) list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/mymath01") else() list(APPEND EXTRA_LIBS "m") endif() # Specify libraries or flags to use when linking a given target and/or its dependents. # target_link_libraries(<target> # <PRIVATE|PUBLIC|INTERFACE>- ... # [<PRIVATE|PUBLIC|INTERFACE>
- ...]...) target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS}) # Add include directories to a target. # target_include_directories(&;lt;target> [SYSTEM] [AFTER|BEFORE] # &;lt;INTERFACE|PUBLIC|PRIVATE> [items1...] # [&;lt;INTERFACE|PUBLIC|PRIVATE> [items2...] ...]) target_include_directories(Tutorial PUBLIC "${PROJECT_BINARY_DIR}" ${EXTRA_INCLUDES})
接著會利用Config.h.in的cmakedefine去define USE_MYMATH, hello.c則需要include "Config.h"並且利用#ifdef/#else/#endif做一些對應的修改
[brook@:~/Projects/cmake/02-2]$ tree . `-- src |-- CMakeLists.txt |-- Config.h.in |-- hello.c `-- mymath01 |-- CMakeLists.txt |-- mymath01.c `-- mymath01.h 2 directories, 6 files [brook@:~/Projects/cmake/02-2]$ cat src/Config.h.in #cmakedefine USE_MYMATH [brook@:~/Projects/cmake/02-2]$ cat src/hello.c #include <stdio.h> #include <stdlib.h> #include "Config.h" #ifdef USE_MYMATH #pragma message("use mymath") #include "mymath01.h" #else #pragma message("use system") #include#endif int main(int argc, char *argv[]) { #ifdef USE_MYMATH printf("mymath: %d\n", squar(atoi(argv[1]))); #else printf("system: %d\n", (int)pow(atoi(argv[1]), 2)); #endif return 0; } [brook@:~/Projects/cmake/02-2/build]$ cmake ../src -- The C compiler identification is GNU 7.5.0 -- The CXX compiler identification is GNU 7.5.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: /build/brook/Projects/cmake/02-2/build [brook@:~/Projects/cmake/02-2/build]$ make Scanning dependencies of target MyMathLib1 [ 25%] Building C object mymath01/CMakeFiles/MyMathLib1.dir/mymath01.c.o [ 50%] Linking C static library libMyMathLib1.a [ 50%] Built target MyMathLib1 Scanning dependencies of target Tutorial [ 75%] Building C object CMakeFiles/Tutorial.dir/hello.c.o /build/brook/Projects/cmake/02-2/src/hello.c:6:9: note: #pragma message: use mymath #pragma message("use mymath") ^~~~~~~ [100%] Linking C executable Tutorial [100%] Built target Tutorial [brook@:~/Projects/cmake/02-2/build]$ ./Tutorial 3 mymath: 9 [brook@:~/Projects/cmake/02-2/build]$ cmake ../src/ -DUSE_MYMATH=off -- Configuring done -- Generating done -- Build files have been written to: /build/brook/Projects/cmake/02-2/build [brook@:~/Projects/cmake/02-2/build]$ make Scanning dependencies of target Tutorial [ 50%] Building C object CMakeFiles/Tutorial.dir/hello.c.o /build/brook/Projects/cmake/02-2/src/hello.c:9:9: note: #pragma message: use system #pragma message("use system") ^~~~~~~ [100%] Linking C executable Tutorial [100%] Built target Tutorial [brook@:~/Projects/cmake/02-2/build]$ ./Tutorial 3 system: 9
- 參考資料:
- Step 2: Adding a Library