文章目錄
- 簡介
- 例子
- 源代碼
- 最終調用到的兩個命令
- 如果結果是
- 這里為什么不直接使用rpm查看包呢?
- 需要注意的問題
簡介
https://cmake.org/cmake/help/latest/module/CheckLibraryExists.html
這個方法是在Modules/CheckLibraryExists.cmake文件里定義的一個宏。
最終使用的方法是通過現場編譯一個文件,里面調用所需要的函數,鏈接時,使用-labc鏈接庫,然后確定這個庫有沒有在編譯環境安裝。其實是分成兩步,一個是找相應的.a/.so文件,一個是尋找相應的函數定義。
例子
比如下面這個例子,就是要看“pcre2_match_8” 函數有沒有定義,根據輸出結果來判斷,有沒有:
CHECK_LIBRARY_EXISTS(pcre2-8 pcre2_match_8 “” HAVE_PCRE2)
如果沒有指定目錄,可能會在目錄:/usr/lib/gcc/x86_64-redhat-linux/8/…/…/…/…/lib64/libpcre2-8.so
if(${VARIABLE})if(NOT CMAKE_REQUIRED_QUIET)message(CHECK_PASS "found")endif()set(${VARIABLE} 1 CACHE INTERNAL "Have library ${LIBRARY}")else()if(NOT CMAKE_REQUIRED_QUIET)message(CHECK_FAIL "not found")endif()set(${VARIABLE} "" CACHE INTERNAL "Have library ${LIBRARY}")endif()
源代碼
對應的源文件是 CheckFunctionExists.c
#ifdef CHECK_FUNCTION_EXISTS# ifdef __cplusplus
extern "C"
# endifcharCHECK_FUNCTION_EXISTS(void);
# ifdef __CLASSIC_C__
int main()
{int ac;char* av[];
# else
int main(int ac, char* av[])
{
# endifCHECK_FUNCTION_EXISTS();if (ac > 1000) {return *av[0];}return 0;
}#else /* CHECK_FUNCTION_EXISTS */
# error "CHECK_FUNCTION_EXISTS has to specify the function"
#endif /* CHECK_FUNCTION_EXISTS */
最終調用到的兩個命令
/usr/bin/cc -pie -fPIC -fstack-protector --param=ssp-buffer-size=4 -DCHECK_FUNCTION_EXISTS=pcre2_match_8 -o CMakeFiles/cmTC_554e1.dir/CheckFunctionExists.c.o -c /usr/share/cmake/Modules/CheckFunctionExists.c
/usr/bin/cc -pie -fPIC -fstack-protector --param=ssp-buffer-size=4 -DCHECK_FUNCTION_EXISTS=pcre2_match_8 -export-dynamic CheckFunctionExists.c.o -o cmTC_554e1 -lpcre2-8
如果結果是
/usr/bin/ld: cannot find -lpcre2-8 “根據 這里的 not find”來判斷是否有相關的library。
collect2: error: ld returned 1 exit status
這里為什么不直接使用rpm查看包呢?
因為rpm是專門RHEL提供的命令,其他平臺不適應。
需要注意的問題
這里需要注意,不能直接使用nm,不加任何參數來查看so文件里是否有這個這個符號而應該加上一個參數:–dynamic。
nm --demangle --dynamic --extern-only <lib.so>
這個可以顯示動態庫里的動態符號
[root@qrms6-host01 lib64]# nm -D --defined-only libpcre2-8.so.0.7.1 | grep match
00000000000196c0 T pcre2_dfa_match_8
0000000000043e80 T pcre2_jit_match_8
0000000000044d60 T pcre2_match_8