iOS静态库在XCODE 5 iOS 7下无法链接

4

我正在使用OSX 10.9上的XCode 5.0.1,并且链接了libc++(LLVM C ++标准库)和Valid architectures armv7; armv7s。

第一步,我创建了一个使用Cmake的OpenCV2.framework + foo的项目,并创建了一个使用foo.a的XCode项目。我的可执行文件链接了OpenCV2.framework + foo.a,并且可以完美工作,编译和链接正常。

第二步,我使用Ogre的模板创建了另一个项目,并且这个项目也可以完美工作。

第三步,我尝试将foo.a添加到新项目中,以执行与第一步相同的操作。

  • 将包含路径添加到Header Search Paths中。
  • 将库路径添加到Library Search Paths中。
  • -ObjC -all_load -lfoo添加到其他链接器路径中,如此处此处所述
  • 在项目中添加所需的代码源。
  • 当我使用foo函数调用时 —> 链接问题:architecture armv7的foo :: functionname()未定义符号。

  • INFO:
  • 该调用与第一个工作的项目完全相同。
  • 使用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。

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


  • INFO 2:
  • 将foo目标添加到Ogre的项目中,同样存在问题。按照此方法进行操作。
  • 添加目标依赖项也无法解决问题。

我的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}
)

你是否遇到了分类问题? - Exploring
当您创建foo.a时,“仅构建活动架构”标志设置为是还是否?我使用该标志修复了我的未定义符号错误,也许它有所帮助。 - Mert Buran
我已经尝试了两个值。但是我总是在ARMV7和ARMV7s上不允许执行,因为我在不同的iPad版本中进行测试。 - vgonisanz
我也遇到了iOS 64位的这种问题。我尝试了那些链接器标志,但对我来说仍然没有希望。 - Exploring
函数名是公共的吗? - dcorbatta
3个回答

3

您需要为每个要添加的库添加一次标志-ObjC和-force_load,以便将所有功能链接到其中,从而避免由未添加的功能引起的失败。

例如,您需要更改cpp标志以添加lib boost_system,因为它会导致链接器问题:

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")

并且对于您需要的每个库都应用这个标志。


我目前遇到了类似的问题。您介意解释一下应该在哪里添加吗?谢谢。 - Youssef Moawad

2

Clang的链接器对库的链接顺序有些严格,你可以尝试在项目中交换链接顺序来查看是否是这个原因导致的?

能否在这里生成链接步骤命令行?只需点击那个按钮: enter image description here

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


我尝试过改变顺序,尝试了几种组合,但都没有成功。我认为正确的顺序是OGRE、OPENCV,然后是我的库,就像发布的CmakeLists.txt一样。 - vgonisanz

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

是的,我已经添加了它们。问题在于项目找不到一些函数。这些函数在库中,因为我可以使用otool看到它们,并且使用其他函数可以在ARMV7s中找到,但其中一些函数却没有被找到。 - vgonisanz

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