cmake的使用--目标的编译附源码
building simple targets
代碼倉庫地址
https://github.com/zzu-andrew/linux-sys/tree/dfew/CMakeExecutables
If an executable is defined with the EXCLUDE_FROM_ALL option, it will not be included in that default ALL target.
add_executable(targetName [WIN32] [MACOSX_BUNDLE][EXCLUDE_FROM_ALL]source1 [source2 ...] )EXCLUDE_FROM_ALL設置之后將不再生成該可執行程序
Defining Libraries
add_library(targetName [STATIC | SHARED | MODULE][EXCLUDE_FROM_ALL]source1 [source2 ...] )STATIC生成靜態庫
SHARED生成動態庫
MODULE windows上的DLL
要是在add_library中省略了動態庫還是靜態庫的選項,可以在調用cmake的時候通過編譯選項指定如
cmake -DBUILD_SHARED_LIBS=YES /path/to/source等價于在CMakeLists.txt中設置
set(BUILD_SHARED_LIBS YES)Linking Targets
CMake captures this richer set of dependency relationships with its target_link_libraries() command, not just the simplistic idea of needing to link. The general form of the command is:
target_link_libraries(targetName<PRIVATE|PUBLIC|INTERFACE> item1 [item2 ...][<PRIVATE|PUBLIC|INTERFACE> item3 [item4 ...]]... )PRIVATE
Private dependencies specify that library A uses library B in its own internal implementation. Anything else that links to library A doesn’t need to know about B because it is an internal implementation detail of A.
PUBLIC
Public dependencies specify that not only does library A use library B internally, it also uses B in its interface. This means that A cannot be used without B, so anything that uses A will also have a direct dependency on B. An example of this would be a function defined in library A which has at least one parameter of a type defined and implemented in library B, so code cannot call the function from A without providing a parameter whose type comes from B.
INTERFACE
Interface dependencies specify that in order to use library A, parts of library B must also be 17used. This differs from a public dependency in that library A doesn’t require B internally, it only uses B in its interface. An example of where this is useful is when working with library targets defined using the INTERFACE form of add_library(), such as when using a target to represent a header-only library’s dependencies
target_link_libraries允許定義一個庫是怎樣依賴其他庫,按照下面的順序定義進行定義
add_library(collector src1.cpp) add_library(algo src2.cpp) add_library(engine src3.cpp) add_library(ui src4.cpp) add_executable(myApp main.cpp) target_link_libraries(collector PUBLIC uiPRIVATE algo engine ) target_link_libraries(myApp PRIVATE collector)In this example, the ui library is linked to the collector library as PUBLIC, so even though myApp only directly links to collector, myApp will also be linked to ui because of that PUBLIC relationship。
the targetName used with target_link_libraries() must have been defined by an add_executable() or add_library() command in the same directory from which target_link_libraries() is being called.
Linking Non-targets
target_link_libraries() command is more flexible than that. In addition to CMake targets, the following things can also be specified as items in a target_link_libraries() command:
Full path to a library file
CMake will add the library file to the linker command. If the library file changes, CMake will detect that change and re-link the target. prior 3.3 version (e.g. replace /usr/lib/libfoo.so with -lfoo)CMake會去查找庫,帶來的問題就是有大量歷史緩存。
Plain library name
If just the name of the library is given with no path, the linker command will search for that library (e.g. foo becomes -lfoo or foo.lib, depending on the platform). This would be common for libraries provided by the system.
Link flag
As a special case, items starting with a hyphen other than -l or -framework will be treated as flags to be added to the linker command. Cmake手冊中禁止這樣使用,因為當是PUBLIC或者INTERFACE連接的時候這些命令可能會傳遞給其他的目標。
TIPS
目標名字和工程名字不必必須一樣,當時通常教程和示例中會通過變量的形式將兩者設置成一樣的。
# Poor practice, but very common set(projectName MyExample) project(${projectName}) add_executable(${projectName} ...)本章源碼:
#This should be the first line of the CMakeLists.txtcmake_minimum_required(VERSION 3.2)# Poor practice, but very common set(projectName MyProject) project(${projectName} VERSION 4.7.2 LANGUAGES C)add_library(collector src1.c) add_library(echo_demo echo_demo.c)#add_executable(targetName [WIN32] [MACOSX_BUNDLE] # [EXCLUDE_FROM_ALL] # source1 [source2 ...] #) # EXCLUDE_FROM_ALL 不對該可執行程序進行編譯 set(executeProcess myExe) # 使用變量 add_executable(${executeProcess} main.c)# PUBLIC 的鏈接方式可以直接在鏈接echo_demo的目標中使用 collector庫中的函數 target_link_libraries(echo_demoPUBLIC collector)target_link_libraries(${executeProcess}PRIVATE echo_demo )echo_demo.c
#include <stdio.h>int echo_demo(void) {printf("echo demo\n");return 0; } #include <stdio.h>int echo_demo(void);int main(int argc, char const *argv[]) {int ret = 0;ret = echo_demo();if(ret != 0){printf("call echo demo failed\n");}return 0; }src1.c
#include <stdio.h>void src1(void) {printf("src1, is Linked.\n");return; }總結
以上是生活随笔為你收集整理的cmake的使用--目标的编译附源码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数博会重磅活动:第二届大数据科学与工程国
- 下一篇: cmake的使用--变量使用超详细详解