【问题标题】:CMake with iOS Toolchain: Can't Find Threads带有 iOS 工具链的 CMake:找不到线程
【发布时间】:2013-01-05 12:24:14
【问题描述】:

我正在尝试使用ios-cmake 生成针对iOS 的Xcode 项目。但是,它找不到线程。这是一个用于演示的简单 CMake 脚本:

CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
PROJECT (MyCITest)

SET (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules")

########################
# EDIT: I've also tried adding the lines below prior to posting this question, 
# but there doesn't seem to be any effect.
# (http://stackoverflow.com/questions/8386897)

SET (CMAKE_REQUIRED_INCLUDES ${CMAKE_IOS_SDK_ROOT}/usr ${CMAKE_IOS_SDK_ROOT}/usr/include)
SET (CMAKE_CXX_FLAGS "--sysroot=${CMAKE_IOS_SDK_ROOT} ${CMAKE_CXX_FLAGS}")
SET (CMAKE_C_FLAGS "--sysroot=${CMAKE_IOS_SDK_ROOT} ${CMAKE_C_FLAGS}")

########################

FIND_PACKAGE (ZLIB REQUIRED)
FIND_PACKAGE (LibXml2 REQUIRED)
FIND_PACKAGE (Threads REQUIRED)

从终端运行 CMake:

cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/iOS.cmake -GXcode

这是我得到的输出:

-- Toolchain using default iOS SDK: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk
-- Found ZLIB: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/libz.dylib (found version "1.2.5") 
-- Found LibXml2: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/libxml2.dylib (found version "2.7.8") 
-- Looking for include file pthread.h
-- Looking for include file pthread.h - not found
CMake Error at cmake/modules/FindPackageHandleStandardArgs.cmake:97 (MESSAGE):
  Could NOT find Threads (missing: Threads_FOUND)
Call Stack (most recent call first):
  cmake/modules/FindPackageHandleStandardArgs.cmake:288 (_FPHSA_FAILURE_MESSAGE)
  cmake/modules/FindThreads.cmake:166 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
  CMakeLists.txt:8 (FIND_PACKAGE)


-- Configuring incomplete, errors occurred!

我已经三重检查了 pthread.h 是否位于/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/include,此外,它可以毫无问题地找到 ZLib 和 LibXML2,所以我不确定我做错了什么。

> cmake --version
cmake version 2.8.10.2

【问题讨论】:

标签: ios cmake


【解决方案1】:

这些解决方案似乎都不起作用。我发现唯一对我有用的是设置 FindThreads.cmake 设置的变量。换句话说,在您的工具链文件中定义以下内容:

set(CMAKE_THREAD_LIBS_INIT "-lpthread")
set(CMAKE_HAVE_THREADS_LIBRARY 1)
set(CMAKE_USE_WIN32_THREADS_INIT 0)
set(CMAKE_USE_PTHREADS_INIT 1)

【讨论】:

  • 这会起作用,但它基本上会覆盖查找 pthread 的实际过程:这相当于对其进行硬编码,这并不是不准确的,但可能会导致未来的更新和扩展出现问题。
【解决方案2】:

问题确实是由于 FindThreads.cmake 中对 try_compile 的调用失败。但对我来说设置CMAKE_CXX_COMPILER_WORKS 是不够的。相反,我将try_compile 执行的测试类型从尝试构建可执行文件更改为尝试构建静态库,方法是将其放入工具链文件中:

set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

【讨论】:

  • 我认为这应该是公认的答案。真正的问题是try_compile 将微测试编译为 iOS 应用程序,这需要代码签名。静态库没有。我没想到这会奏效,但我很惊喜!
  • 这很 hack,但是 try_compile 的结果应该是一个可执行文件,而不是一个库。在这里使用XCODE_ATTRIBUTE_CODE_SIGNING_REQUIREDNO 更合适。
【解决方案3】:

原来iOS工具链目前不支持TRY_COMPILECheckIncludeFiles.cmake使用,FindThreads.cmake又使用TRY_COMPILE。工具链当前设置为跳过TRY_COMPILE,使用:

set (CMAKE_CXX_COMPILER_WORKS TRUE)
set (CMAKE_C_COMPILER_WORKS TRUE)

参考:http://code.google.com/p/ios-cmake/issues/detail?id=1&can=1

【讨论】:

  • 这个变通办法可行,但是,工具链“不支持”try_compile 这一事实并不十分准确。问题出在 xcode 生成器上,它将尝试对 try_compile 项目进行签名,这将失败,导致查找线程丢失。由于签名问题,我会说更多的是不支持 ios 工具链的 try_compile。
【解决方案4】:

您可以使用工具链中的下一个变量修复try_compile 命令:

# toolchain.cmake    
set(CMAKE_MACOSX_BUNDLE YES)
set(CMAKE_OSX_SYSROOT "iphoneos")
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.example")

和简约的例子:

# CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(Foo)

find_package(Threads REQUIRED)
add_executable(foo foo.cpp)

生成输出:

> cmake -H. -B_builds -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake -GXcode
...    
-- Looking for include file pthread.h
-- Looking for include file pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - found
-- Found Threads: TRUE
...

【讨论】:

  • 仍然对我不起作用......我面临同样的错误......我正在为 Arm7 架构构建 log4cplus 库。
  • 不幸的是,这不适用于 CMake 3.14
【解决方案5】:

[2019 年 9 月] 修复 XCode 11 和 iOS 13

正如here 解释的那样。

需要使用XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED 而不是下面的CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED 来完成这项工作:

set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES "XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED")
set(XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO")

find_package(Threads REQUIRED)

unset(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES)
unset(XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED)

[2019 年 8 月]:来自 CMake 问题跟踪器的信息

here 讨论了该问题,@alcroito 对此进行了解释。它不使用自定义 ios-cmake 工具链,而是使用新的 native iOS toolchain (CMake 3.14+),但问题是一样的。

问题来源

当使用 Xcode 生成器时,它会默认尝试对应用程序进行签名。在寻找 Threads 时,CMake 调用 FindThreads.cmake,这将调用 TRY_COMPILE 测试,Xcode 将尝试签名并失败。

正确的解决方案:

禁用try_compileFindThreads 的签名(见here):

set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES "CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED")
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")

find_package(Threads REQUIRED)

unset(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES)
unset(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED)

本帖中的其他解决方案

  1. try_compile 的二进制文件设为静态,不会被签名(见here)。这不是很好,因为它应该是可执行文件而不是静态库。

  2. 传递正确的信息以便能够签署try_compile 可执行文件(见here)。这实际上对我不起作用。

  3. 跳过try_compile(见here):不太安全,因为您将跳过所有编译器测试。那也不适合我。

  4. 硬编码 Threads 通过覆盖 FindThreads 所做的事情(见 here):相当肮脏的解决方法。

【讨论】:

  • 似乎 check_cxx_source_compiles 如果没有步骤 1 或 2 也无法正常工作
【解决方案6】:

顺便提一下,我在项目中也遇到了同样的问题。我注释掉了find_package(Threads REQUIRED) 行并生成了Xcode proejct。编译的代码没有错误。也许 Xcode 可以自动链接到 posix 线程库。

【讨论】:

    【解决方案7】:

    对我来说,解决方案是结合我面前的 2 个答案。 注释掉禁用try_compile的2行

    # Skip the platform compiler checks for cross compiling
    set (CMAKE_CXX_COMPILER_WORKS TRUE)
    set (CMAKE_C_COMPILER_WORKS TRUE)
    

    然后将此添加到IOS.cmake工具链文件的顶部。

    set(MACOSX_BUNDLE_GUI_IDENTIFIER com.example)
    set(CMAKE_MACOSX_BUNDLE YES)
    set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer")
    

    【讨论】:

      猜你喜欢
      • 2015-11-23
      • 2019-01-28
      • 2017-06-17
      • 1970-01-01
      • 1970-01-01
      • 2013-09-13
      • 2019-06-06
      • 2019-12-29
      • 1970-01-01
      相关资源
      最近更新 更多