【问题标题】:Xcode 4 build succeeds, command line build fails?Xcode 4 构建成功,命令行构建失败?
【发布时间】:2011-10-02 22:47:47
【问题描述】:

我在 Xcode 4(最新的非 beta 版本)中有一个项目,在 Xcode 本身构建时构建良好。具体来说,Ld 命令正确使用了派生数据目录(其中放置了构建产品,包括依赖的静态库)。

但是,当我从命令行构建同一个项目时,Ld 命令失败,因为它试图使用项目中的 /build 文件夹,而该文件夹没有被填充。

我已经尝试在父项目和从属项目中调整我所知道的每个构建设置。

关于从哪里开始调试的任何想法?我可以根据需要提供更多信息。

编辑 1: 完整的 Xcode 构建命令:

xcodebuild -project AppName.xcodeproj -target AppName -configuration "Config Name"

其中AppNameConfig Name 都是构建的正确值。

编辑 2: 链接 (Ld) 命令。

在 Xcode 中构建时(这有效):

Ld /Users/james/Library/Developer/Xcode/DerivedData/AppName-apkmkuhwuccsbpblulxcsafyxkwa/Build/Products/Debug-iphonesimulator/AppName.app/AppName normal i386
cd /Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName
setenv MACOSX_DEPLOYMENT_TARGET 10.6
setenv PATH "/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/opt/local/bin:/usr/local/git/bin"
/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-gcc-4.2 -arch i386 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk -L/Users/james/Library/Developer/Xcode/DerivedData/AppName-apkmkuhwuccsbpblulxcsafyxkwa/Build/Products/Debug-iphonesimulator -L/Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName -F/Users/james/Library/Developer/Xcode/DerivedData/AppName-apkmkuhwuccsbpblulxcsafyxkwa/Build/Products/Debug-iphonesimulator -filelist /Users/james/Library/Developer/Xcode/DerivedData/AppName-apkmkuhwuccsbpblulxcsafyxkwa/Build/Intermediates/AppName.build/Debug-iphonesimulator/AppName.build/Objects-normal/i386/AppName.LinkFileList -mmacosx-version-min=10.6 -lxml2 -all_load -ObjC -licucore -Xlinker -objc_abi_version -Xlinker 2 -lMyClientLibrary -lxml2 -lsqlite3.0 -framework Security -framework MessageUI -framework QuartzCore -framework MediaPlayer -framework MapKit -framework CoreLocation -framework AudioToolbox -lz.1.2.3 -framework MobileCoreServices -framework SystemConfiguration -framework CFNetwork -framework UIKit -framework Foundation -framework CoreGraphics -o /Users/james/Library/Developer/Xcode/DerivedData/AppName-apkmkuhwuccsbpblulxcsafyxkwa/Build/Products/Debug-iphonesimulator/AppName.app/AppName

当使用上面的构建命令从命令行构建时(失败):

Ld "build/AppName.build/Prod Ad Hoc-iphoneos/AppName.build/Objects-normal/armv6/AppName" normal armv6
cd /Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName
setenv IPHONEOS_DEPLOYMENT_TARGET 4.0
setenv PATH "/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Developer/usr/bin:/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/git/bin:/usr/X11/bin:/opt/local/bin"
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 -arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk "-L/Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName/build/Prod Ad Hoc-iphoneos" -L/Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName "-F/Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName/build/Prod Ad Hoc-iphoneos" -filelist "/Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName/build/AppName.build/Prod Ad Hoc-iphoneos/AppName.build/Objects-normal/armv6/AppName.LinkFileList" -dead_strip -lxml2 -all_load -ObjC -licucore -miphoneos-version-min=4.0 -lMyClientLibrary -lxml2 -lsqlite3.0 -framework Security -framework MessageUI -framework QuartzCore -framework MediaPlayer -framework MapKit -framework CoreLocation -framework AudioToolbox -lz.1.2.3 -framework MobileCoreServices -framework SystemConfiguration -framework CFNetwork -framework UIKit -framework Foundation -framework CoreGraphics -o "/Users/james/Code/ClientName-Depot/NameOfProject/trunk/AppName/build/AppName.build/Prod Ad Hoc-iphoneos/AppName.build/Objects-normal/armv6/AppName"

返回:

ld: library not found for -lMyClientLibrary
collect2: ld returned 1 exit status
Command /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 failed with exit code 1

【问题讨论】:

  • 首先给出完整的 xcodebuild 命令
  • 完成,以及链接器命令。不确定“问题”是否是一个构建使用构建目录而另一个使用派生数据目录,或者客户端库的 .a 没有被复制到正确的位置。
  • 我没有答案。可能是一个错误,但你会认为它会很快被发现。你问过 Apple 的 Xcode 用户列表吗?

标签: ios xcode xcode4 xcodebuild


【解决方案1】:

好的,近 6 小时(可计费)之后,我已经让构建在 Xcode 和命令行(以及构建服务器上,本练习的重点)上正常工作。

在此过程中,我会修复一个问题,只是为了导致另一个问题 - 我显然会修复链接器/Ld 问题,只是导致编译出现问题(“未声明的某类(在此函数中首次使用)”或“SomeHeader.h:没有这样的文件或目录”错误很常见)。

在那个时候,我几乎调整了我能找到的所有设置,所以很难说到底是哪里出了问题,又是什么修复了它。

我认为可能有帮助的事情如下:

  • 将构建转换为使用 Xcode 工作区和方案(而不是项目和目标)
  • 重新排列工作区,将应用项目和静态库作为同级(而不是父/子)
  • 更改了 Xcode 和工作区设置以使用目标中指定的构建位置
  • 更改应用程序和库的构建产品路径以使用 ../build(两个项目文件都包含在主目录的同级子文件夹中,因此将它们构建到同一文件夹中解决了原始链接器/Ld 命令问题,我 想想)
  • 编辑 App 方案以显式构建 Library 目标,并在 App 目标之前构建它
  • 在 App 目标的构建阶段中,在“Link Binary With Libraries”下明确添加库
  • 将库的 .a 文件引用的位置类型更改为“相对于构建产品”
  • 向库项目添加了“复制标题”构建阶段,向公共部分添加了适当的标题
  • 将 Library 项目的 Public Headers 文件夹路径更改为“/include”
  • 将库的安装目录更改为$(BUILT_PRODUCTS_DIR)
  • 将 App 目标的 Library Search Paths 和 User Header Search Paths 更改为 $(BUILT_PRODUCTS_DIR)(递归)
  • 在我的 Jenkins 构建服务器上构建之前添加了一个 Clean 命令
  • 在构建命令中添加了明确的 SDK 和 Arch 参数
  • 从构建配置名称中删除了空格

最终的构建命令如下所示:

xcodebuild -workspace ClientName.xcworkspace -scheme AppName -configuration "ProdAdHoc" -sdk iphoneos -arch "armv6 armv7"

我在调试此问题时使用的一些有用资源:

无论如何,我希望我已经在上面添加了足够多的关键字,以便将来遇到任何类似构建问题的人偶然发现它并发现它很有用。我不知道当我迁移到 Xcode 4 时,我在 Xcode 3.x 中多次执行的工作流程会变得如此混乱,希望 Apple 能够在未来的版本中解决这个问题。

这对我来说是一次非常棒的学习经历,经历所有这些似乎确实解决了我之前遇到的自动完成问题。我会说情况可能会更糟。我仍然可以为 SharePoint 进行开发。

【讨论】:

  • 为了将来参考,确保共享了正确的方案,并切换 xcodebuild 命令行工具以使用适合我的工作区和方案。
  • 也感谢计费客户。
  • 已确认。使用 -scheme X 而不是 -project Y -target Z 对我有用。 (我不必创建任何新方案。)
  • 我正在使用 -scheme 但我收到此错误“Ld /Users/confiz/Library/Developer/Xcode/DerivedData/CloudMessage-afevkkqtjcnmoddycvosdhbgoraa/Build/Intermediates/ArchiveIntermediates/LTDMessaging/IntermediateBuildFilesPath/ CloudMessage.build/Release-iphoneos/LTDMessaging.build/Objects-normal/arm64/LTD\ Messaging normal arm64" 我已清除驱动数据并已完成您上面要求的所有操作,但没有成功。
【解决方案2】:

我昨天遇到了同样的问题并且能够解决。为了缩小对詹姆斯有用的范围,我将指出我必须做的事情。我必须添加一个工作区并切换到使用工作区/方案而不是项目/目标运行 xcodebuild。

使用工作空间/方案强制 xcodebuild 使用 DerivedData 文件夹,而不是主项目下的构建输出文件夹。这允许链接器找到相关的静态库。

这篇博文很有帮助:

http://blog.carbonfive.com/2011/05/04/automated-ad-hoc-builds-using-xcode-4/

【讨论】:

  • 这篇文章为我指明了正确的方向。您至少需要一个方案,并且必须在命令行中指定它。
【解决方案3】:

我在试验文件时遇到此错误,我将@implementation 添加到 .h 文件并将 .m 文件留空。我不相信这是你的错误,但如果其他人得到它,可能会检查你没有这样做。

【讨论】:

    【解决方案4】:

    检查您是否没有在头文件中导入 .m 文件!将 .m 更改为 .h 为我解决了这个问题!

    【讨论】:

      【解决方案5】:

      我不知道这是否对你有用,但就我而言,我有不止一个 main.m 文件。我所要做的就是从目标中分离main.m 之一,它就起作用了。确保您的项目中没有超过一个 main.m

      【讨论】:

        【解决方案6】:

        如果您查看构建日志,要求查看所有消息,您应该会看到一条简洁的行,上面写着“链接...”,几乎没有详细信息。但是,如果您右键单击该行并选择“expand all tr​​anscripts”,您会得到一个非常详细的行,告诉您从 XCode 中发出了什么命令。

        这应该可以帮助您调试问题。

        戴夫

        【讨论】:

        • 看了一下,用 Xcode 和命令行构建的 Ld 命令编辑了我的原始帖子。命令行仍然无法链接。
        【解决方案7】:

        我遇到了类似的异常, 事实证明我在 project.pbxproj 中有一些(空)引用 在我清理了 project.pbxproj 中的那些空引用之后,命令行构建就像之前的 xcode 一样成功。 看看Xcode 4 project: utility to clean up pbxproj file? 实用程序清理-pbxproj-文件

        更多参考

        【讨论】:

          【解决方案8】:

          突然间我在清理之后遇到了同样的问题,起初我看到我惊慌失措:

          linker command failed with exit code 1 (use -v to see invocation)

          ...但它变得非常容易修复,不需要命令行!

          我在导航器中单击了我的项目的根(顶部带有带有“A”的蓝图图标的那个),然后单击了项目部分(您也可以单击目标部分),然后单击按钮在底部中间称为“验证设置”。

          XCode 本身验证了项目文件并告诉我问题是重复的目标定义,并提出修复它......瞧,问题消失了!

          祝你好运!

          【讨论】:

          • 你知道@RacZo这样的回答真的可以用截图
          • 我认为,问题是“从命令行构建应用程序时构建失败”而不是来自 XCode GUI 应用程序......
          【解决方案9】:

          我通过转到“库搜索路径”来解决问题,并确保所有条目都正确。

          【讨论】:

            【解决方案10】:

            就个人而言,我在开发static library 时遇到了这个问题。我有一个包含所有生产代码的static library 目标,以及一个将MyStaticLib.a 文件作为框架拉入的测试目标。

            测试在 Xcode 中运行得很好,但在使用 xcodebuild 的终端中却不行。问题最终是static library 目标正在为Standard architectures 编译,而测试目标想要为Standard architectures (including 64-bit) 编译。将测试目标切换到 Standard architectures 修复了所有问题。

            【讨论】: