【问题标题】:iOS static library does not link XCODE 5 iOS 7iOS 静态库不链接 XCODE 5 iOS 7
【发布时间】:2013-10-29 13:16:42
【问题描述】:

我在 OSX 10.9 上使用 XCode 5.0.1,我正在链接 libc++(LLVM C++ 标准库)和有效架构 armv7; armv7s 和两者。

1º 我使用 Cmake 创建了一个使用 OpenCV2.framework + foo 的项目,使用 foo.a 创建了一个 XCode 项目。我的可执行链接 OpenCV2.framework + foo.a 并完美运行,编译和链接。

2º 我使用 Ogre 的模板创建了另一个项目。这个项目完美运行。

3º 然后,我尝试将 foo.a 添加到新项目中,以制作与我的可执行文件在步骤 1 中使用的相同的东西。

  • 添加头搜索路径的包含路径。
  • 将库路径添加到库搜索路径。
  • -ObjC -all_load -lfoo 作为Thisthis 添加到其他链接器路径
  • 添加项目所需的代码源。
  • 当我使用对 foo 函数的调用时 --> 链接问题:架构 armv7 到 foo::functionname() 的未定义符号。

  • 信息:
  • 该调用与第一个项目完全一样,可以正常工作。
  • 使用 otool -hv foo.a --> 我看到所有 lib.o 的 cputype 都是 ARV V7
  • 使用 lipo -info foo.a --> 当我使用该拱门时,我看到 foo.a 是 armv7 或 armv7s。
  • 使用 nm foo.a | grep functionname --> 在编译两个arch时,我看到该函数位于armv7和armv7s的库中。

那么,如果库在另一个项目中工作,并且函数在里面,为什么会出现链接问题?


  • 信息 2:
  • 将 foo 目标添加到 ogre 的项目中,同样的问题。关注THIS 方法。
  • 添加目标依赖项也不起作用。

我编译这个示例的 CmakeList 是:

 # /////////////////////////////////////////////////////////
 # //SAMPLE 
 # /////////////////////////////////////////////////////////

 # 3rdParty (OGRE LOCATION)
set(OGRE_SDK_ROOT /Users/vgoni/Librerias/ogre1.9-pre/OgreSDK/ CACHE PATH "Ogre SDK ROOT")
set(OGRE_DEPENDENCIES_DIR ${OGRE_SDK_ROOT}/iOSDependencies CACHE PATH "Ogre SDK DEP")

 # Set up project
SET(PROJ_NAME ogreIOS)

PROJECT( ${PROJ_NAME} )
SET(PRODUCT_NAME ${PROJ_NAME})
SET(EXECUTABLE_NAME ${PROJ_NAME}Executable)

 # Add variable to generate iphone project in ADD_EXECUTABLE
SET(APP_TYPE MACOSX_BUNDLE)

 # Headers
SET(${PROJ_NAME}_HEADERS
    include/OgreStaticPluginLoader.h
    include/OgreDemoApp.h
    include/OgreFramework.h
    include/AppDelegate.h
    )

 # Source
SET(${PROJ_NAME}_SRC
    src/OgreFramework.cpp
    src/OgreDemoApp.cpp
    src/main.mm
)

 # Add there files to Resources package into XCODE
SET_SOURCE_FILES_PROPERTIES(
    resources/ogre.cfg
    resources/plugins.cfg
    resources/resources.cfg
    resources/ogreiosSample-Info.plist
    resources/ogreiosSample-Prefix.pch
    resources/en.lproj/InfoPlist.strings
    PROPERTIES
    MACOSX_PACKAGE_LOCATION Resources
)
 # Include self directories
INCLUDE_DIRECTORIES( include )

 # Include OGRE headers needed
INCLUDE_DIRECTORIES( ${OGRE_SDK_ROOT}/include )
INCLUDE_DIRECTORIES( ${OGRE_SDK_ROOT}/include/OIS )
INCLUDE_DIRECTORIES( ${OGRE_SDK_ROOT}/include/OGRE )
INCLUDE_DIRECTORIES( ${OGRE_SDK_ROOT}/include/OGRE/Overlay )
INCLUDE_DIRECTORIES( ${OGRE_SDK_ROOT}/include/OGRE/iOS )
INCLUDE_DIRECTORIES( ${OGRE_SDK_ROOT}/include/OGRE/RTShaderSystem )
INCLUDE_DIRECTORIES( ${OGRE_SDK_ROOT}/include/OGRE/RenderSystems/GLES2 )
INCLUDE_DIRECTORIES( ${OGRE_SDK_ROOT}/iOSDependencies/include )

 # Link Directories where libraries needed are
LINK_DIRECTORIES( ${OGRE_SDK_ROOT}/lib/Release )
LINK_DIRECTORIES( ${OGRE_SDK_ROOT}/iOSDependencies/lib )
LINK_DIRECTORIES( ${OGRE_SDK_ROOT}/iOSDependencies/lib/Release )

 # Add ogre & boots libraries flags
SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lmesaglsl2 -lboost_system -lboost_chrono -lboost_date_time -lboost_thread -lFreeType -lFreeImage -lzzip -lz -lc++ -lforce_load -lfoo")
 # foo is my library, force to load all to avoid fail in linking

 # 3rdParty ogre libraries
SET(OGRE_LIBS OIS OgreMainStatic RenderSystem_GLES2Static OgreRTShaderSystemStatic ) 

 # Link the libraries needed
 #TARGET_LINK_LIBRARIES (${PROJ_NAME} ${OGRE_LIBS})

 # Create executable for iOS
ADD_EXECUTABLE(
    ${EXECUTABLE_NAME}
        ${APP_TYPE}
        ${${PROJ_NAME}_HEADERS}
        ${${PROJ_NAME}_SRC}
)

 # Adding info to XCode project
 #set_target_properties(${EXECUTABLE_NAME}  PROPERTIES 
    #MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/resources/Info.plist)

 # Change name to make work Macros
SET(PROJ_NAME ogreIOSExecutable) 

 # Macro to add frameworks to Sample Executable
link_ios_framework(AssetsLibrary    ${EXECUTABLE_NAME})
link_ios_framework(AVFoundation     ${EXECUTABLE_NAME})
link_ios_framework(CoreMedia        ${EXECUTABLE_NAME})
link_ios_framework(CoreGraphics     ${EXECUTABLE_NAME})
link_ios_framework(CoreVideo        ${EXECUTABLE_NAME})
link_ios_framework(ImageIO          ${EXECUTABLE_NAME})
link_ios_framework(Foundation       ${EXECUTABLE_NAME})
link_ios_framework(OpenGLES         ${EXECUTABLE_NAME})
link_ios_framework(QuartzCore       ${EXECUTABLE_NAME})
link_ios_framework(UIKit            ${EXECUTABLE_NAME})

 # Needed dependencies
link_ios_sdk(libc++.1.dylib ${EXECUTABLE_NAME})
link_ios_sdk(libz.dylib ${EXECUTABLE_NAME})

 #Add OpenCV Libraries to link
TARGET_LINK_LIBRARIES (${PROJ_NAME} ${OpenCV_LIBS})

LINK_DIRECTORIES(
    ${LIBRARY_OUTPUT_PATH}
)

【问题讨论】:

  • 您在分类方面遇到问题吗?
  • 创建 foo.a 时,“仅构建活动架构”标志设置为是还是否?我用那个标志修复了我的未定义符号错误,也许它有帮助
  • 我已经尝试了这两个值。但我总是拒绝允许在 ARMV7 和 ARMV7s 中执行,因为我在不同的 ipad 版本中进行测试
  • 我也面临 iOS 64 位的此类问题。我已经尝试过那些链接器标志,但我仍然没有希望。
  • 函数名是公开的吗?

标签: ios xcode cmake static-libraries


【解决方案1】:

您必须为每个要添加所有函数链接的库添加一次标志 -ObjC 和 -force_load,避免因未添加函数而导致失败。

例如,您必须更改添加到 lib boost_system 的 cpp 标志,因为这会导致链接器问题:

SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lmesaglsl2 -force_load -lboost_system -lboost_chrono -lboost_date_time -lboost_thread -lFreeType -lFreeImage -lzzip -lz -lc++ -lforce_load -lfoo")

并为您需要的每个库应用此标志。

【讨论】:

  • 我目前面临着类似的问题。你介意解释一下在哪里添加这个吗?谢谢。
【解决方案2】:

Clang 的链接器对库的链接顺序有点严格,您可以尝试在您的项目中交换链接顺序,看看是否是这个原因?

您能在此处生成链接步骤命令行吗?你只需要点击那里的按钮:

另外,也许尝试从您的其他链接器选项中删除-lfoo,因为将.a 添加到您的项目中就足够了。

【讨论】:

  • 我尝试更改顺序,尝试了几种组合,但没有成功。我认为正确的顺序是 OGRE、OPENCV,然后是我的库,比如发布的 CmakeLists.txt。
【解决方案3】:

基本问题,您是否已将 foo.a 添加到链接库中?对于好的目标(打开右侧面板并检查库是否与所需的所有目标链接)?

【讨论】:

  • 是的,我已经添加了它们。问题是该项目没有找到一些功能。这些函数在库中,因为我可以使用 otool 看到它们,而使用其他函数在 ARMV7s 中可以找到,但其中一些没有。
猜你喜欢
  • 2013-01-20
  • 2013-09-29
  • 2017-01-31
  • 1970-01-01
  • 1970-01-01
  • 2011-09-01
  • 2012-06-19
  • 2018-12-06
  • 1970-01-01
相关资源
最近更新 更多