使用自动工具构建通用二进制文件时遇到问题

发布于 2024-11-08 22:56:30 字数 370 浏览 4 评论 0原文

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

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

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

我对lipo没有任何经验。有没有好的方法将其与自动工具工作流程结合起来?

I have a project that I'm building on OS X using autotools. I'd like to build a universal binary, but putting multiple -arch options in OBJCFLAGS conflicts with gcc's -M (which automake uses for dependency tracking). I can see a couple workarounds, but none seems straightforward.

Is there a way to force preprocessing to be separate from compilation (so -M is given to CPP, while -arch is handed to OBJC)?

I can see that automake supports options for disabling dependency tracking, and enabling it when it can't be done as a side-effect. Is there a way to force the use of the older style of tracking even when the side-effect based tracking is available?

I don't have any experience with lipo. Is there a good way to tie it into the autotools work flow?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

感受沵的脚步 2024-11-15 22:56:30

这篇 Apple 技术说明看起来很有希望,但我还没有没做完。我认为您只需要在准备发布时进行通用构建,因此也许您可以不使用依赖项跟踪?

This Apple Technical Note looks promising, but it's something I haven't done. I would think you'd only need to do a universal build when preparing a release, so perhaps you can do without dependency tracking?

镜花水月 2024-11-15 22:56:30

这里有一些解决方案;很可能是我回避的一个。

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

    这将告诉它根本不生成依赖项。依赖阶段会害死你,因为在代码生成期间会使用 -M 依赖选项;如果有多个架构成为目标,则无法完成此操作。

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

  2. 更好,但更危险的是做这样的事情:

    CC=clang CXX=clang++ ./configure

    这将使编译器发出 clang 声而不是 gcc。如果你有最新的 Xcode,你就会听到 clang。配置将认识到 clang 满足编译要求,但也会确定它对于自动依赖项生成不安全。它将执行旧式的 2 遍生成,而不是禁用自动依赖项生成。

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

    <前><代码>#!/bin/bash

    导出 CC=clang
    导出 CXX=clang

    导出 CPPFLAGS="-isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.5 -fvisibility=hidden"
    导出 CFLAGS="-arch i386 -arch x86_64 -O3 -fomit-frame-pointer -momit-leaf-frame-pointer -ffast-math $CPPFLAGS"
    导出 CXXFLAGS=$CFLAGS

    ./配置

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

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

    a.创建顶级目录,例如 .X86_64.i386。注意“.”在前。如果您将构建目标定位到源目录中,则通常需要以点开头,以避免稍后搞砸“make clean”。

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

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

    d.假设您按照自己想要的方式构建了所有构建,我通常会制作一个看起来和感觉类似的 shell 脚本,在最后运行,这将为您做好准备。

    # 移动工作版本以供后代和调试
    MV .i386 ./Build/i386
    MV .x86_64 ./Build/x86_64
    
    对于 ./Build/i386/lib/* 中的路径
    做
        文件=${路径##*/}
        # 只转换“真实”文件                                                                                                   
        if [ -f "$file" -a ! -L“$文件”];然后
            合作伙伴=“./Build/x86_64/Lib/$file”
            如果 [ -f $partner -a ! -L $合作伙伴];然后
                目标=“./Build/Lib/$file”
                lipo -创建“$file”“$partner”-输出“$target”|| { echo "Lipo 未能获得 phat"; 5号出口; }
                echo 通用二进制文件已创建:$target
            别的
                echo 跳过:$file,在 $partner 处没有有效的架构配对
            菲
        别的
            # 这是一个非常常见的情况,openssl 创建符号链接                                                                  
            # echo 跳过:$file,不是常规文件                                                                                
            真的
        菲
    完毕
    
  4. 我没有想到的是让我使用 gcc 和老式 2-pass dep gen 的魔力。坦率地说,随着我对 clang/llvm 的印象越来越深刻,我每天都越来越不关心。

祝你好运!

There's a few solutions here; and likely one that has evaded me.

  1. The easiest and fastest is to add --disable-dependency-tracking to your run of ./configure.

    This will tell it not to generate dependencies at all. The dependency phase is what's killing you because the -M dependency options are being used during code generation; which can't be done if there are multiple architectures being targetted.

    So this is 'fine' if you are doing a clean build on someone else's package; or you don't mind doing a 'make clean' before each build. If you are hacking at the source, especially header files, this is no good as make probably won't know what to rebuild and will leave you with stale binaries.

  2. Better, but more dangerous is to do something like:

    CC=clang CXX=clang++ ./configure

    This will make the compiler clang instead of gcc. You have clang if you have a recent Xcode. Configure will realize that clang meets the compilation requirements, but will also decide that it isn't safe for auto-dependency generation. Instead of disabling auto dependency gen, it will do old-style 2 pass generation.

    One caveat: This may or may not work as I described depending on how you set your architecture flags. If you have flags you want to pass to all compiler invocations (i.e.: -I for include paths), you should set CPPFLAGS. For code generation, set CFLAGS and CXXFLAGS for C and C++, (and I suppose COBJFLAGS for ObjC). Typically you would add $CPPFLAGS to those. I typically whip up a shell script something like:

    #!/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
    

    You probably don't want these exact flags, but it should get you the idea.

  3. lipo. You've been down this road it sounds like. I've found the best way is as follows:

    a. Make top level directories like .X86_64 and .i386. Note the '.' in front. If you target a build into the source directories it usually needs to start with a dot to avoid screwing up 'make clean' later.

    b. Run ./configure with something like: --prefix=`pwd`/.i386` and however you set the architecture (in this case to i386).

    c. Do the make, and make install, and assuming it all went well make clean and make sure the stuff is still in .i386 Repeat for each architecture. The make clean at the end of each phase is pretty important as the reconfig may change what gets cleaned and you really want to make sure you don't pollute an architecture with old architecture files.

    d. Assuming you have all your builds the way you want, I usually make a shell script that looks and feels something like this to run at the end that will lipo things up for you.

    # 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. What I have NOT figured out is the magic that would let me use gcc, and old school 2-pass dep gen. Frankly I care less and less each day as I become more and more impressed with clang/llvm.

Good luck!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文