简体   繁体   English

CMake 未定义符号:pthread_create 编译动态库

[英]CMake undefined symbol: pthread_create compiling dynamic library

My project was working fine before but I changed it to be compiled as a dynamic library in order to have it perform self-update, like so:我的项目之前运行良好,但我将其更改为编译为动态库,以便让它执行自我更新,如下所示:

  • Launcher -> Executable启动器 -> 可执行文件
  • Server -> Library (Core project, multi-threaded with std::thread)服务器 -> 库(核心项目,带 std::thread 的多线程)
  • Updater -> Library更新程序 -> 库

Now, on Linux (Debian Bullseye), I get a runtime error undefined symbol: pthread_create when the launcher tries to dlopen the Server library.现在,在 Linux (Debian Bullseye) 上,当启动器尝试 dlopen 服务器库时,我得到一个运行时错误undefined symbol: pthread_create Windows equivalent works fine. Windows 等效工作正常。

I've tried splitting my big CMakeLists in several subprojects, thinking it could be a CMake bug, but that was of course not the problem.我尝试将我的大 CMakeLists 拆分为几个子项目,认为这可能是 CMake 错误,但这当然不是问题。

I've included below a simplified version of the parent CMakeLists and the subproject CMakeLists for the Server and the launcher.我在下面包含了服务器和启动器的父 CMakeLists 和子项目 CMakeLists 的简化版本。

Parent:家长:

################################
# Project settings
################################
cmake_minimum_required (VERSION 3.8)

set(TARGET_NAME "Server")
set(SERVER_VERSION "1.0.0")

set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
project(${TARGET_NAME} VERSION ${SERVER_VERSION} DESCRIPTION "My Server")

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

################################
# Sources
################################
configure_file(
    ${CMAKE_SOURCE_DIR}/src/Resource.h
    ${CMAKE_CURRENT_BINARY_DIR}/src/Resource.h
    COPYONLY)
configure_file(
    ${CMAKE_SOURCE_DIR}/src/Resource.rc.in
    ${CMAKE_CURRENT_BINARY_DIR}/src/Resource.rc
    @ONLY)
set_source_files_properties("../Server.ico" PROPERTIES LANGUAGE RC)

include_directories("includes")

################################
# Subprojects
################################
add_subdirectory("src/Server")
add_subdirectory("src/Launcher")
add_subdirectory("src/Updater")

Server lib Subproject:服务器库子项目:

################################
# Project settings
################################
cmake_minimum_required (VERSION 3.8)

set(TARGET_NAME "Server-Core")
if (LIB)
    set(EXE_NAME "ServerCore")
else ()
    set(EXE_NAME "Server")
endif ()

project(${TARGET_NAME} VERSION ${SERVER_VERSION} DESCRIPTION "My Server")

################################
# Sources
################################
configure_file(
    Server.hh.in
    Server.hh
    @ONLY)

include_directories(. "${CMAKE_BINARY_DIR}/src/Server/")

file(GLOB_RECURSE SRC "*.hh" "*.hpp" "*.cpp" "${CMAKE_BINARY_DIR}/src/*.hh")
if (LIB)
    add_library(${TARGET_NAME} SHARED ${SRC})
elseif (WIN32)
    add_executable(${TARGET_NAME} ${SRC} ${CMAKE_BINARY_DIR}/src/Resource.rc)
else ()
    add_executable(${TARGET_NAME} ${SRC})
endif ()

################################
# Libs
################################
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(${TARGET_NAME} Threads::Threads)

if(WIN32)
    target_link_libraries(${TARGET_NAME} wsock32 ws2_32)
    target_link_libraries(${TARGET_NAME} Crypt32)
    target_link_libraries(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/libs/libssl.lib)
    target_link_libraries(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/libs/libcrypto.lib)
elseif(UNIX)
    target_link_libraries(${TARGET_NAME} -static-libgcc -static-libstdc++)
    target_link_libraries(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/libs/libssl.a)
    target_link_libraries(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/libs/libcrypto.a)
endif()

################################
# Compiler settings
################################

set_target_properties(${TARGET_NAME} PROPERTIES VERSION ${SERVER_VERSION})
set_target_properties(${TARGET_NAME} PROPERTIES PREFIX "")

set_property(TARGET ${TARGET_NAME} PROPERTY CXX_STANDARD 20)
set_property(TARGET ${TARGET_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
set_property(TARGET ${TARGET_NAME} PROPERTY OUTPUT_NAME ${EXE_NAME})

if(MSVC)
    target_compile_options(${TARGET_NAME} PUBLIC /std:c++latest)
    target_compile_options(${TARGET_NAME} PUBLIC /Zc:__cplusplus)
    set(CMAKE_EXE_LINKER_FLAGS    "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
endif()

Launcher subproject:启动器子项目:

################################
# Project settings
################################
cmake_minimum_required (VERSION 3.8)

set(LAUNCHER_TARGET "Launcher")
set(LAUNCHER_EXE_NAME "Server")
set(LAUNCHER_VERSION "1.0.0")

project(${LAUNCHER_TARGET} VERSION ${LAUNCHER_VERSION} DESCRIPTION "My Server")

################################
# Sources
################################
if (LIB)
    file(GLOB_RECURSE SRC "*.hh" "*.hpp" "*.cpp"
        "../Server/Utils/DynamicLibrary/DynamicLibraryWindows.cpp" "../Server/Utils/DynamicLibrary/DynamicLibraryLinux.cpp"
        "../Server/Utils/DynamicLibrary/IDynamicLibrary.cpp")

    if (WIN32)
        add_executable(${LAUNCHER_TARGET} ${SRC} ${CMAKE_BINARY_DIR}/src/Resource.rc)
    else ()
        add_executable(${LAUNCHER_TARGET} ${SRC})
    endif ()
endif ()

################################
# Libs
################################

if (UNIX)
    if (LIB)
        target_link_libraries(${LAUNCHER_TARGET} ${CMAKE_DL_LIBS})
    endif ()
endif ()

################################
# Compiler settings
################################

set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(${LAUNCHER_TARGET} Threads::Threads)

if (LIB)
    set_target_properties(${LAUNCHER_TARGET} PROPERTIES VERSION ${LAUNCHER_VERSION})

    set_property(TARGET ${LAUNCHER_TARGET} PROPERTY CXX_STANDARD 20)
    set_property(TARGET ${LAUNCHER_TARGET} PROPERTY CXX_STANDARD_REQUIRED ON)
    set_property(TARGET ${LAUNCHER_TARGET} PROPERTY OUTPUT_NAME ${LAUNCHER_EXE_NAME})
endif ()

I'm using CMake 3.16.3 and gcc 9.3.0我正在使用 CMake 3.16.3 和 gcc 9.3.0

What did I do wrong?我做错了什么? I'm still not extremely comfortable with CMake我仍然对 CMake 不太满意

I have been able to fix the problem by adding我已经能够通过添加来解决问题

target_link_libraries(${TARGET} pthread)

after

target_link_libraries(${TARGET} Threads::Threads)

for the Launcher, when compiling for Linux.对于启动器,在编译 Linux 时。

And I need to include <thread> in the launcher and have a piece of code such as我需要在启动器中包含<thread>并有一段代码,例如

std::thread t([](){});
t.join();

This is extremely weird这非常奇怪

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM