【问题标题】:Xcode custom build configuration causes "library/file not found" for static librariesXcode 自定义构建配置导致静态库“找不到库/文件”
【发布时间】:2012-01-21 08:40:27
【问题描述】:

我有一个带有一个项目的工作区,该项目与另一个项目(也在工作区中)中的静态库链接。这是Kobold2D 的问题,虽然我了解原因,但我一直无法解决,我想是similar to this question

项目目标和静态库目标都具有 DebugRelease 构建配置。一切都很好。

现在有人在项目中添加了一个新的构建配置,并将其命名为 Ad-Hoc。现在项目的目标构建了 Ad-Hoc 配置,但是静态库没有这样的配置。显然,他们随后默认构建 Release 配置。

最后,当链接器应该把所有东西放在一起时,它失败了:

ld: library not found for -lbox2d-ios
Command /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang++ failed with exit code 1

对于通过-force_load $(BUILT_PRODUCTS_DIR)/libSomeLib.a 强制加载的库,错误类似,但显示“找不到文件”。我应该注意到库“libbox2d-ios.a”在“链接二进制与库”构建阶段列表中。

显然问题在于链接器假定库位于 BUILT_PRODUCTS_DIR 的 Ad-Hoc-iphoneos 文件夹中,而它们实际上位于 Release-iphoneos 中文件夹,因为它们没有 Ad-Hoc 构建配置。

我怎样才能打链接器的脸并告诉他将库放在它们所在的位置?最好我正在寻找一种适用于这两种情况的解决方案,即库添加了标准方式(将二进制文件与库构建阶段链接)和需要额外 -force_load 才能工作的库。

我希望有办法:

  • 强制将库放置在应用目标的构建配置文件夹中
  • 运行后编译和预链接脚本,将每个库复制到构建配置文件夹中
  • 指定库的相对路径
  • 为 -force_load 使用除 $BUILT_PRODUCTS_DIR 之外的其他宏
  • 像 -WTFmake-all-problems-go-away 这样的链接器标志

对不起,我不得不说……啊! :)

【问题讨论】:

  • ARGH!!! 确实(愤怒的家伙)

标签: xcode4 build linker static-libraries


【解决方案1】:

正如在类似问题iOS Static Library as a Subproject of a Project That Has Custom Build Configurations? 中所说,解决方法是添加这一行

$(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)

到您的目标的Framework Search PathsHeader Search Paths 和/或Library Search Paths

【讨论】:

  • 太棒了!非常适用于 Xcode 7 中的 iOS 导入项目/框架!
  • 我应该添加,将其添加到除发布和调试之外的任何构建配置 - 不要为所有配置添加行。
【解决方案2】:

这里有一些对我有用的东西。

在具有 Adhoc 构建配置的项目中,覆盖“Per-configuration Build Products Path”(CONFIGURATION_BUILD_DIR) 和“Per-configuration Intermediate Build Files Path”(CONFIGURATION_TEMP_DIR) 以使用与 Adhoc 构建配置相同的文件夹发布配置。

Adhoc: CONFIGURATION_BUILD_DIR = $(SYMROOT)/Release$(EFFECTIVE_PLATFORM_NAME)
Adhoc: CONFIGURATION_TEMP_DIR = $(PROJECT_TEMP_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)

现在,当您进行 Adhoc 构建时,Xcode 会将 libFoo.a 和 Bar.app 放在 Release-iphoneos 文件夹中。链接器会很高兴,您可以像往常一样使用 -force_load $(BUILT_PRODUCTS_DIR)/libFoo.a。

或者,您可以将 Release-iphoneos 文件夹添加到临时构建配置的库搜索路径中:

Adhoc: LIBRARY_SEARCH_PATHS = $(inherited) $(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)

但是您必须为每个构建配置设置不同的 -force_load:

Debug: OTHER_LINKER_FLAGS = $(inherited) -force_load $(BUILT_PRODUCTS_DIR)/libFoo.a
Adhoc: OTHER_LINKER_FLAGS = $(inherited) -force_load $(BUILD_DIR)/Release$(EFFECTIVE_PLATFORM_NAME)
Release: OTHER_LINKER_FLAGS = $(inherited) -force_load $(BUILT_PRODUCTS_DIR)/libFoo.a

【讨论】:

  • 关于在 Release 和 Adhoc 之间共享相同的构建目录,这可能会导致问题,因为当您在 Release 和 Adhoc 之间切换时,Xcode 不会重新编译和重新生成正确配置的库。你们不觉得吗?
  • 我认为你是对的,达特先生。很烦人。我只在自动构建工具使用的方案中使用这种技术来解决这个问题,这些工具在每次构建之前执行清理。
  • 第一个建议工作完美。第二个我无法上班。谢谢
【解决方案3】:

我在使用 CocoaPods 并尝试拥有多个 Adhoc(或 Enterprise,或 Beta)配置时遇到了类似的问题。

这似乎可行(假设两个项目都位于同一个 xcworkspace 中):

  • subproject 生成的库添加到mainproject Link Binary with Libraries。

  • 由于subproject 不知道配置Adhoc,Xcode 在构建它时将使用Release 配置作为后备(或者可能是列表的第一个配置)。

  • 链接器会因为找不到库而报错……好的,让我们处理这个。

  • 将运行脚本构建阶段添加到 mainproject,就在 Target Dependencies 阶段之后。输入这个脚本:

if [ "$CONFIGURATION" = "Adhoc" ]; then
    echo "====================================="
    echo "Copying libPods Release into the Adhoc product build dir!"
    echo "====================================="
    cp "$BUILT_PRODUCTS_DIR/../Release-$PLATFORM_NAME/libPods.a" "$BUILT_PRODUCTS_DIR"
else
    echo "No manual lib copy."
fi

这将复制subprojectRelease构建生成的lib(在构建mainproject时会发生)到Adhoc构建目录中,以便链接器找到该lib。我们应该很高兴!对!

【讨论】:

  • 我刚刚在新配置“测试”中遇到了同样的问题,我也可以通过将“测试”添加到 Pods 项目并进行全面清理和重建来解决它。
【解决方案4】:

很遗憾,我还没有找到一种方法来做到这一点。我能找到的最佳解决方法是添加新目标而不是新构建配置。例如,在我的一个项目中,我只有发布和调试配置,但我有额外的目标,称为“MyProject - 应用商店”和“MyProject - ad hoc”。当然,这只有在您可以控制项目文件的情况下才有可能。

重复的目标非常烦人,因为您可以将文件添加到一个目标而忘记将它们添加到其他目标,并且在您尝试构建它之前您不会知道。但它确实构建了,这是一个胜利(无论如何使用 xcode)。

前段时间我问了一个类似的问题:What is the correct way to set build configurations in an ios project using static libraries for creating an archive in xcode 4?

【讨论】:

    【解决方案5】:

    我的框架是使用我的应用项目中的另一个 SDK 项目构建的。首先我有一个“Debug”和“Release”,然后我添加了一个新的 "TestFlight" 配置。我不能用那个新的存档。我最终在 SDK 项目中添加了一个同名的新构建配置。换句话说,我最终将“TestFlight”配置添加到我的应用程序和 SDK 项目中。现在存档工作。

    我不确定这是否是最好的方法。但它现在对我来说看起来足够干净。 :)

    哦,对于Cocoapods,在你复制配置后,如果你立即运行pod install,你会得到这个黄色警告:

    [!] CocoaPods 没有设置您项目的基本配置,因为您的项目已经有一个自定义配置集。为了使 CocoaPods 集成能够正常工作,请设置目标的基本配置...

    你必须进入项目,“信息”选项卡,“配置”部分,选择刚刚创建的新配置,并将所有目标的“Pods.release”设置为“无”第一的。之后,你就可以安全地运行pod install了。

    【讨论】:

    • 谢谢!你很准!您应该创建另一个线程来询问这个问题,然后发布您的答案,这样您就可以获得适当的信用(如果您关心的话)。我想对于嵌入式库,您需要确保它们还具有您的项目具有的所有构建配置选项,即如果您的项目具有调试、测试和发布版本,您拥有的每个嵌入式库项目都必须包含相同的内容。
    • 在我的库项目中创建与我的应用程序项目中名称相同的构建配置是唯一为我做的事情(@ULazdins 回答适用于常规构建,但不适用于存档)。谢谢!
    【解决方案6】:

    您可以在运行 xcodebuild 之前添加 CONFIGURATION_BUILD_DIR=/Some/Shared/Dir。例如:

    cd SOURCE_DIR
    xcodebuild  -workspace YourProject.xcworkspace -scheme YourScheme -configuration AdHoc -sdk iphoneos clean build CONFIGURATION_BUILD_DIR="`pwd`"/build
    

    【讨论】:

      【解决方案7】:

      通常我有一个AppStore 方案(映射到我的AppStore 配置)。

      发生在我身上的一件事是,这个区分大小写的问题使 Cocoapods 在 Release-iphonesimulator(作为后备)而不是 AppStore-iphonesimulator 中为 Pods.build 生成构建文件夹。

      我想当我链接方案和配置时我错过了点击,只有删除它并重新添加才让我明白出了什么问题。检查差异。

      我使用的是 cocoapods 0.38.2,所以这显然是用户错误配置,而不是 Cocoapods issue that was resolved on 0.34

      【讨论】:

        猜你喜欢
        • 2017-08-10
        • 2022-12-18
        • 2011-12-30
        • 2011-10-15
        • 1970-01-01
        • 2013-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多