【问题标题】:trouble building universal binary with autotools使用自动工具构建通用二进制文件时遇到问题
【发布时间】:2011-05-24 00:58:42
【问题描述】:

我有一个使用自动工具在 OS X 上构建的项目。我想构建一个通用二进制文件,但在OBJCFLAGS 中放置多个-arch 选项与gcc 的-M(automake 用于依赖跟踪)冲突。我可以看到一些解决方法,但没有一个看起来很简单。

有没有办法强制将预处理与编译分开(所以 -M 给CPP,而 -arch 给OBJC)?

我可以看到 automake 支持禁用依赖项跟踪的选项,并在无法完成时启用它作为副作用。即使基于副作用的跟踪可用,是否有办法强制使用旧式跟踪?

我对@9​​87654326@ 没有任何经验。有没有一种很好的方法可以将其与 autotools 工作流程联系起来?

【问题讨论】:

    标签: macos autotools universal-binary


    【解决方案1】:

    这个Apple Technical Note 看起来很有希望,但这是我没有做过的事情。我认为您只需要在准备发布时进行通用构建,所以也许您可以不进行依赖跟踪?

    【讨论】:

    • 技术说明是一个很好的资源,但最终它会告诉我我所知道的(可以使用 lipo 或禁用依赖跟踪)。不过,您提出了一个很好的观点,即专门为发布启用跟踪。
    【解决方案2】:

    这里有一些解决方案;并且很可能是逃避了我的人。

    1. 最简单、最快的方法是将--disable-dependency-tracking 添加到您的./configure 运行中。

      这将告诉它根本不生成依赖项。由于在代码生成期间使用了 -M 依赖选项,所以依赖阶段会杀死你;如果针对多个架构,则无法做到这一点。

      所以如果你在别人的包上做一个干净的构建,这“很好”;或者您不介意在每次构建之前进行“清理”。如果您在源代码上进行黑客攻击,尤其是头文件,那么这并不好,因为 make 可能不知道要重建什么,并且会给您留下陈旧的二进制文件。

    2. 更好,但更危险的是执行以下操作:

      CC=clang CXX=clang++ ./configure

      这将使编译器发出叮当声而不是 gcc。如果你有最近的 Xcode,你就有了叮当声。 Configure 将意识到 clang 满足编译要求,但也会确定它对于自动依赖生成是不安全的。它不会禁用自动依赖生成,而是执行旧式的 2 次生成。

      一个警告:这可能会也可能不会像我描述的那样工作,具体取决于您设置架构标志的方式。如果您有要传递给所有编译器调用的标志(即:-I 用于包含路径),则应设置 CPPFLAGS。对于代码生成,为 C 和 C++ 设置 CFLAGS 和 CXXFLAGS,(我想为 ObjC 设置 COBJFLAGS)。通常,您会在其中添加 $CPPFLAGS。我通常会编写一个类似于以下内容的 shell 脚本:

      #!/bin/bash
      
      export CC=clang
      export CXX=clang
      
      export CPPFLAGS="-isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5 -fvisibility=hidden"
      export CFLAGS="-arch i386 -arch x86_64 -O3 -fomit-frame-pointer -momit-leaf-frame-pointer -ffast-math $CPPFLAGS"
      export CXXFLAGS=$CFLAGS
      
      ./configure
      

      你可能不想要这些确切的标志,但它应该让你明白。

    3. 脂肪。听起来你已经走上了这条路。我发现最好的方法如下:

      一个。制作像.X86_64.i386 这样的顶级目录。注意“。”在前。如果您将构建定位到源目录,它通常需要以点开头,以避免以后搞砸“make clean”。

      b.运行 ./configure 时使用以下内容:--prefix=`pwd`/.i386`,然后设置架构(在本例中为 i386)。

      c。做make,make install,假设一切顺利make clean,并确保这些东西还在.i386中,对每个架构重复。每个阶段结束时的make clean 非常重要,因为重新配置可能会更改要清理的内容,并且您确实希望确保不会用旧的架构文件污染架构。

      d。假设您按照自己想要的方式进行了所有构建,我通常会制作一个外观和感觉类似这样的 shell 脚本,然后在最后运行它会为您解决问题。

      # move the working builds for posterity and debugging
      mv .i386 ./Build/i386
      mv .x86_64 ./Build/x86_64
      
      for path in ./Build/i386/lib/*
      do
          file=${path##*/}
          # only convert 'real' files                                                                                                   
          if [ -f "$file" -a ! -L "$file" ]; then
              partner="./Build/x86_64/Lib/$file"
              if [ -f $partner -a ! -L $partner ]; then
                  target="./Build/Lib/$file"
                  lipo -create "$file" "$partner" -output "$target" || { echo "Lipo failed to get phat"; exit 5; }
                  echo Universal Binary Created: $target
              else
                  echo Skipping: $file, no valid architecture pairing at: $partner
              fi
          else
              # this is a pretty common case, openssl creates symlinks                                                                  
              # echo Skipping: $file, NOT a regular file                                                                                
              true
          fi
      done
      
    4. 我没有想到的是让我使用 gcc 和老式 2-pass dep gen 的魔法。坦率地说,随着我对 clang/llvm 的印象越来越深刻,我每天都越来越不在乎了。

    祝你好运!

    【讨论】:

      猜你喜欢
      • 2012-10-11
      • 2019-01-28
      • 1970-01-01
      • 2015-03-07
      • 2012-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多