使用CMake静态链接pthread库

3

我该如何让CMake在Windows上静态链接pthread库?我使用的是MSYS2 MinGW 32位cmake v3.7。

我想要实现的是像下面这样的编译器调用:

g++ -static-libgcc -static-libstdc++ -std=c++11 -o test test.cpp -Wl,-Bstatic -lpthread

设置

target_link_libraries(test PUBLIC "-Wl,-Bstatic -lpthread")

执行-Wl,-Bdynamic -Wl,-Bstatic -lpthread会产生这样的结果。如果我更改CMAKE_EXE_LINKER_FLAGSpthreads会在我的目标文件之前被包含,因此符号无法解析。


一个澄清:1)当你说你想在Windows上静态链接pthread时,是指生成一个静态库(test将是一个静态库?)还是想链接到pthread静态库? - fedepad
@fedepad 我想要生成一个链接到静态 pthread 的可执行文件(就像更新后的 g++ 调用所产生的)。 - zeeMonkeez
2个回答

1
找到Threads模块:
find_package(Threads REQUIRED)
add_executable(myApp main.cpp)
target_link_libraries(myApp Threads::Threads)

来自文档的注意事项:

对于具有多个线程库的系统,调用者可以设置 CMAKE_THREAD_PREFER_PTHREAD


添加该目标似乎不会改变链接器调用。 pthread 不会出现在命令行上(但是 CMake 根据 CMakeCache.txt 找到它://Have symbol pthread_create CMAKE_HAVE_LIBC_CREATE:INTERNAL=1 //Have include pthread.h CMAKE_HAVE_PTHREAD_H:INTERNAL=1)。 - zeeMonkeez
感谢您的回答。看起来这里真正需要的是 target_link_libraries(ptest2 -static) - zeeMonkeez

1
作为FindThreads.cmake源代码中提到的内容:
# For systems with multiple thread libraries, caller can set
#
# ::
#
#   CMAKE_THREAD_PREFER_PTHREAD
#
# If the use of the -pthread compiler and linker flag is preferred then the
# caller can set
#
# ::
#
#   THREADS_PREFER_PTHREAD_FLAG
#
# Please note that the compiler flag can only be used with the imported
# target. Use of both the imported target as well as this switch is highly
# recommended for new code.

所以除了已经提到的,你可能需要设置额外的标志THREADS_PREFER_PTHREAD_FLAG。在一些系统(如OSX等)中,编译时需要此标志,因为它定义了一些宏,如果只链接-lpthread则会缺少这些宏。

set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
add_library(test test.cpp)
set_property(TARGET test PROPERTY CXX_STANDARD 11)
set_target_properties(test PROPERTIES LINK_SEARCH_START_STATIC 1)
set_target_properties(test PROPERTIES LINK_SEARCH_END_STATIC 1)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
find_package(Threads REQUIRED)  

target_link_libraries(test Threads::Threads)  

它有帮助吗?


1
感谢您抽出时间回答。原来在这个平台上只需要使用target_link_libraries(test -static)就可以了。 - zeeMonkeez
很好,知道了,因为我认为我从未见过在target_link_libraries()内调用-static...的操作。 - fedepad
文档中指出:以 - 开头的项目名称(但不包括 -l 或 -framework)会被视为链接器标志。请注意,这些标志将像其他库链接项一样用于传递依赖项,因此通常可安全地指定为仅作为私有链接项而不传播到依赖项。这就是为什么我的原始尝试没有成功的原因。 - zeeMonkeez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接