pthread for win32本身没有提供find_package脚本,cmake官方也没有提供,所以如果在cmake中要查找pthread for win32的库,就得自己实现,我参照FindJPEG.cmake自己写了个查找脚本FindPTHREADW32
。
cmake官方提供的FindJPEG.cmake
非常简单,只输出了include文件夹位置和JPEG库文件(JPEG_INCLUDE_DIR
和JPEG_LIBRARIES
),在写FindPTHREADW32
时,为了更方便的引用库,在输出PTHREADW32_INCLUDE_DIR
和PTHREADW32_LIBRARY
变量的基础上,还提供了imported target:pthreadw32
,
有了imported target定义,在cmake脚本中引用库更加方便,示例如下:
if(WIN32)
find_package(PTHREADW32 REQUIRED)
endif(WIN32)
# 为${_target}添加依赖库pthreadw32
if(TARGET pthreadw32)
target_link_libraries(${_target} PUBLIC pthreadw32)
elseif(HAVE_PTHREAD)
target_link_libraries(${_target} PUBLIC -lpthread)
endif()
下面是我参照FindJPEG.cmake写的完整的实现代码
# FindPTHREADW32
# --------
#
# Find Pthread for win32
#
# Find the native pthread for win32 includes and library This module defines
#
# ::
#
# PTHREADW32_INCLUDE_DIR, where to find pthread.h, etc.
# PTHREADW32_LIBRARY, where to find the pthread for win32 library.
# PTHREADW32_FOUND, If false, do not try to use pthread for win32.
# HAVE_PTHREAD, if true, pthread supported by compiler
#
# IMPORTED TARGET: pthreadw32
#=============================================================================
if(NOT WIN32)
return()
endif()
# 检查编译器是否支持pthread如果支持就返回,
# POSIX版本的MinGW原生支持pthread,不需要额外的pthread for win32库
include(CheckLibraryExists)
CHECK_LIBRARY_EXISTS (pthread pthread_rwlock_init "" HAVE_PTHREAD)
if(HAVE_PTHREAD)
message(STATUS "pthread supported")
return()
endif()
# 查找pthread.h 头文件位置
find_path(PTHREADW32_INCLUDE_DIR pthread.h)
set(PTHREADW32_NAME pthread)
if(MSVC)
set(PTHREADW32_NAME pthread.lib pthreadVC2)
elseif(MINGW)
set(PTHREADW32_NAME libpthread.a pthreadGC2)
endif()
if( CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|x64|AMD64|Win64")
set(_arch "x64")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "Win32|x86")
set(_arch "x86")
endif()
# 查找库文件
find_library(PTHREADW32_LIBRARY NAMES ${PTHREADW32_NAME} pthread PATH_SUFFIXES lib/${_arch} )
# handle the QUIETLY and REQUIRED arguments and set PTHREADW32_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PTHREADW32 DEFAULT_MSG PTHREADW32_LIBRARY PTHREADW32_INCLUDE_DIR)
mark_as_advanced(PTHREADW32_LIBRARY PTHREADW32_INCLUDE_DIR )
#message(STATUS PTHREADW32_INCLUDE_DIR=${PTHREADW32_INCLUDE_DIR})
if(PTHREADW32_FOUND)
if(MSVC)
set(_dll_name pthreadVC2.dll)
elseif(MINGW)
set(_dll_name pthreadGC2.dll)
endif()
find_file(PTHREADW32_DLL ${_dll_name} PATH_SUFFIXES dll/${_arch})
#message(STATUS PTHREADW32_DLL=${PTHREADW32_DLL})
# 创建imported target
add_library(pthreadw32 UNKNOWN IMPORTED)
set_target_properties(pthreadw32 PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${PTHREADW32_INCLUDE_DIR}"
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
IMPORTED_LOCATION "${PTHREADW32_LIBRARY}"
)
# 解决 Visual Studio 2015下编译struct timespec重定义问题
if(MSVC)
# 检查是否定义了 struct timespec
include(CheckStructHasMember)
CHECK_STRUCT_HAS_MEMBER("struct timespec" tv_sec time.h HAVE_STRUCT_TIMESPEC LANGUAGE C )
if(HAVE_STRUCT_TIMESPEC)
set_target_properties(pthreadw32 PROPERTIES INTERFACE_COMPILE_DEFINITIONS HAVE_STRUCT_TIMESPEC )
endif()
endif()
endif()
unset(_arch)