1

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

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

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

我没有任何经验lipo。有没有一种很好的方法可以将它与 autotools 工作流程联系起来?

4

2 回答 2

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”。

    湾。运行 ./configure 类似:--prefix=`pwd`/.i386`,然后你设置架构(在本例中为 i386)。

    C。做 make, and 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-02-17T19:34:30.767 回答
2

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

于 2011-05-26T12:10:48.447 回答