很多大型軟體開發專案都是使用CMake來進行編譯。例如LLVM也是使用CMake在建置專案編譯的架構。在開發的過程中,我們往往會使用到其他外部函式庫(External Library)。這篇文章主要將介紹如何在CMakeLists.txt檔案中描述要加入的外部函式庫。

target_link_libraries
由於要Link到外部函式庫,最直接的方式就是將要Link的函式庫名稱直接放入target_link_libraries當中。如果是Shared Library,記得要拿掉開頭的lib以及結尾的.so。例如,我想要在我的main.exe中Link libfoo.so以及libmpi.so。可以寫成以下的方式。
target_link_libraries(main.exe
PRIVATE
foo
mpi
)
而假設我的系統裡有多個不同版本的libfoo.so以及libmpi.so,我們也可以直接透過完整路徑去指定要Link的Library。這裡要注意是完整的路徑以及檔案名稱也就是包含了lib開頭的部分以及.so結尾。例如以下方式。
target_link_libraries(main.exe
PRIVATE
/usr/lib/x86_64-linux-gnu/libfoo.so
/usr/lib/x86_64-linux-gnu/libmpi.so
)
如果我們要聯結的是一個靜態函式庫,則我們可使用完整路徑的方式去指名該函式庫的檔名以及路徑。例如假設我們除了libfoo.so以及libmpi.so以外,還要Link libmylib1.a以及libmylib2.a,則我們可以用以下方式來描述。
target_link_libraries(main.exe
PRIVATE
foo
mpi
/usr/lib/x86_64-linux-gnu/libmylib1.a
/usr/lib/x86_64-linux-gnu/libmylib2.a
)
target_link_directories
含有目標函式庫的資料夾位置也需要透過target_link_directories指定讓系統知道要去哪裡找到目標函式庫。例如我們的函式庫如果都放在/usr/lib/x86_64-linux-gnu中,則可用以下方式來寫在CMakeLists.txt中。
target_link_directories(main.exe
PRIVATE
/usr/lib/x86_64-linux-gnu
)
使用list – APPEND語法讓CMakeLists.txt更簡潔
如果要新增的外部函式庫很多且會被使用在很多的Build Target中,那我會建議使用list去把所有函式庫以及目錄放到同一個變數後,再去把這個變數放到target_link_libraries以及target_link_directories中。這在實務上不僅是讓CMakeList.txt更簡潔,也方便在開發過程中的修改。例如我可以先產生一個MY_LIBS變數,再逐一將每個Library透過APPEND放到這個變數的List中。
set(MY_LIBS foo)
list(APPEND MY_LIBS mpi)
list(APPEND MY_LIBS /usr/lib/x86_64-linux-gnu/libmylib1.a)
list(APPEND MY_LIBS /usr/lib/x86_64-linux-gnu/libmylib2.a)
target_link_libraries(main.exe
PRIVATE
${MY_LIBS}
)
使用這個寫法與上面的寫法是同樣的效果。但是如果今天我們有多個target要使用到這些新增的函式庫,我們就只需要在每個Build Target中寫上${MY_LIBS},而不需要把每一個函式庫的目錄及名稱都在各個地方寫一次。這樣的好處就是將來我們想要修改時,也只需要去修改在list的部分即可。