gpt4 book ai didi

c++ - 运行从源代码构建的 clang 时,如何指定 libc++ 的位置,或者,有人向我解释 -stdlib=libc++ 的作用

转载 作者:行者123 更新时间:2023-12-02 03:36:45 39 4
gpt4 key购买 nike

我正在使用 clang 的规定通过插件和 clang 的 LibTooling 开发插件和工具。我能够做以下事情:

  • 从 svn(Linux 和 OSX),通过运行配置脚本(不使用 cmake)按照入门页面编译 llvm
  • 在 Linux(也来自 svn)上编译 libcxx/libc++,我没有理由期望在 OSX 上有任何问题。问题是 libc++ 头文件已经存在于我的 OSX 系统上
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1/

    而 libc++ dylib 位于/usr/lib/。

    编辑 4:按照说明,我能够在 OS X 上很好地编译 libcxx。我现在有一个全新的 libc++.1.0.dylib 坐在这里。
  • 在 OSX 上,使用 clang++ 的 Release+Asserts(和 Debug+Asserts)版本通过附加编译 C++ 源代码
    -I/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/c++/v1/

    并且不使用 -stdlib=libc++ .使用此标志明确指定 libc++ 作为包含目录允许我构建的 clang 来“查看”标准 c++ 头文件。令人惊讶的是,它在编译一个中等基本的源文件时似乎很满意(它仍然在其中练习了大量的 c++11 疯狂)

  • 基于此,您可以看到我正在破解我新构建的 clang version 3.6.0 (trunk 217905)查找 Apple 的 Xcode 打包的 libc++。这目前表面上是有效的,因为 Xcode 附带的 Apple 的 libc++ 仍然与我刚刚从源代码构建的编译器 ABI 兼容。我仍然很好奇的是,我新编译的 clang 是如何找出在哪里可以找到相应的 libc++ dylib 的!这在稍后我实际编译 libc++ 时提出了一个问题,我应该如何告诉我的新 svn 编译的 clang 查找并使用新的 svn 编译的 libc++ dylib?

    所以,基本上,我仍然对正确设置 libc++ 真正应该做的事情感到完全困惑。当你告诉它时,clang 实际上做了什么 -stdlib=libc++ ?

    它是硬编码的包含路径吗?我可能想从 svn 构建 libc++abi 和 libc++,以便与从 svn 构建的 clang 一起使用。这是最有意义的......那我应该如何安装它?不得不放 -I~/libcxx/include/c++/v1/ (或其他任何内容)进入构建配置是不雅的。

    大概我可以设置我的 llvm 构建来构建 clang 以及 libc++abi 和 libc++,方法是还从 svn 中查看 libcxxabi 和 libcxx,我的期望是安装它应该使 -stdlib=libc++神奇地工作。另请注意,Apple 为您提供的 Xcode clang 并不真正要求您使用 -stdlib=libc++ .它只是神奇地知道从哪里获取库文件。

    然而!美中不足,至少到目前为止我知道要寻找的唯一一个:我的机器已经有了 /usr/bin/clang++ :
    $ ls -la $(which clang++)
    -rwxr-xr-x 1 root wheel 14240 Mar 17 2014 /usr/bin/clang++

    这不是我预期的 Xcode.app 内部的符号链接(symbolic link)!我现在真的很担心运行 make install从我的 llvm 构建目录!它可能会破坏我的 Xcode 环境或阻止我的 Mac 启动(因为 libc++ llvm 文档明确指出,如果发生不好的事情 /usr/lib/libc++.1.dylib 就会发生)!

    希望还没有我错过的文档可以回答这些问题,因为我现在真的应该找到它。

    编辑:我在 http://libcxx.llvm.org 上找到的稀疏指令中看到那
    clang++ -std=c++11 -stdlib=libc++ -nostdinc++ -I<path-to-libcxx>/include -L<path-to-libcxx>/lib test.cpp

    现在可能实际上是“正确的方式”。但这失败的原因是解释了 -stdlib=libc++导致 clang 或什么 -nostdinc++导致叮当做。

    编辑 2:感谢@n.m。现在我们知道 -nostdinc++意味着没有搜索标准的 C++ 包含路径。这意味着标准包含路径是一回事。构建 clang 时这条路径是硬编码的吗?我用谷歌搜索并找到了一些引用变量 CLANG_INCLUDEPATH 的东西,这看起来可能是一个 makefile 变量。不幸的是,我正在我的 llvm 源目录上运行完整的文件系统文本搜索,但没有找到与此类字符串的匹配项(因此它不能是 clang 或在构建 clang 过程中使用的配置)。

    编辑 3:借助 --verbose ,我现在可以看到一些有用的输出:

    Xcode的 clang :
    clang -cc1 version 5.1 based upon LLVM 3.4svn default target x86_64-apple-darwin13.4.0
    ignoring nonexistent directory "/usr/include/c++/v1"
    #include "..." search starts here:
    #include <...> search starts here:
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1
    /usr/local/include
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/5.1/include
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
    /usr/include
    /System/Library/Frameworks (framework directory)
    /Library/Frameworks (framework directory)
    End of search list.

    svn 新鲜的 clang :
    clang -cc1 version 3.6.0 based upon LLVM 3.6.0svn default target x86_64-apple-darwin13.4.0
    ignoring nonexistent directory "/Users/username/Documents/llvmbuild/Release+Asserts/bin/../include/c++/v1"
    ignoring nonexistent directory "/usr/include/c++/v1"
    #include "..." search starts here:
    #include <...> search starts here:
    /usr/local/include
    /Users/username/Documents/llvmbuild/Release+Asserts/bin/../lib/clang/3.6.0/include
    /usr/include
    /System/Library/Frameworks (framework directory)
    /Library/Frameworks (framework directory)
    End of search list.

    好的,这是绘制一些存放 libc++ 文件的地方的图片。

    两个“忽略不存在的目录”条目的存在向我表明 Xcode 的 clang 能够在其硬编码 /Apps/Xcode.app/.../c++/v1/ 中找到 libc++。虽然我的 svn clang 没有在它想要查看的地方找到一个(在 Release+Asserts 构建目录中,这看起来很傻,但实际上它可能是 libcxx 将其头文件复制到 llvm 构建系统的位置)。

    没有关于它从哪里获取 libc++ dylib 的提示。甚至在查看 clang 可执行文件中的字符串时,使用 string 也不行。 (无论如何,这是一个长镜头)。

    不完全清楚到底要做什么,但我现在似乎有一些工具可以开始我的项目。现在的主要问题是 libc++.dylib 发生了什么事情.我不知道新构建的 clang 是否经过硬编码才能在 /usr/lib/libc++.1.dylib 找到它。 , 或者是什么。我需要这样做:
  • 不碰/usr/lib/libc++.1.dylib以免破坏我的整个操作系统
  • 点新编译clang++使用 libc++.1.dylib现已建成,位于与 /usr/lib/libc++.1.dylib 不同的位置.我不在乎它现在去哪里,但我不打算运行 make install这可能会覆盖 /usr/lib/libc++.1.dylib .

  • 只是不清楚做什么有意义。是否指定 -stdlib=libc++事业 clang++链接硬编码 /usr/lib/libc++.1.dylib ?如果是这样,我可以放弃它吗, -l<compiled libc++.dylib>明确的?否则,我如何编译 clang 以修改此路径以使其使用正确的路径?

    暂时我会用 -stdlib=libc++ -nostdinc++ (见第一个编辑)并祈祷它实际上意味着叮当听 -I<new libc++ header path> -L<new libc++ dylib path> .我想如果它仍然不起作用并且尽管做出了这些努力,系统文件仍然被使用,只要我的程序继续编译,我仍然会很高兴......

    最佳答案

    我已经足够满意地回答我自己的问题,所以我将在这里总结我的发现。

    这可能不是全貌,但它描绘的足以让我找到我难以找到的信息。

    大约在tools/clang/lib/Driver/ToolChains.cpp的606行附近只是推送 -lc++ 的代码到命令参数。这是在 clang 的工具链实现中(它或多或少是让 clang 模拟 gcc 命令行行为的组件的一部分,以便它与构建目的兼容)。

    这意味着 libc++.dylib/so 使用与所有其他库完全相同的机制加载进来。 C++ 标准库没有特殊处理。这也意味着它是以半硬编码的方式完成的。也许这不太准确,因为我确实希望显式库路径规范( -L )可以优先于默认根路径。

    无论如何,与其尝试修补 -L ,有一个更大的锤子可以使用,--sysroot .通过将 libc++ 安装到与系统 /usr/lib 不同的位置, 我可以用 --sysroot使用 clang 调用强制 clang 甚至不考虑查看 /usr/lib对于 libc++ 或其他任何东西,就此而言。这是一个有用的标志,例如交叉编译作业。

    好的,这些是一些操纵 clang 来执行我们的指令的方法。当然,它们足够强大。现在我需要绝对确定我认为被包含和链接的 libc++ 实际上被包含和链接。

    我追求的是万无一失的东西,而不是简单而聪明的东西。我对 libc++ 本身进行了一些战略性编辑,然后将其安装到备用目录中(不是 /usr/lib——请参阅我的问题,了解为什么我不想弄乱我的系统 libc++):这可能非常随意,我添加

    std::libcxx_custom_version_type::libcxx_custom_version_type() {
    libcxx_custom_version = "slu_libc++_svn_218071";
    }

    到 src/typeinfo.cpp(在 libc++ 中)并相应地
    struct libcxx_custom_version_type {
    char* libcxx_custom_version;
    libcxx_custom_version_type();
    };

    包括/类型信息。这样做的目的(是的,它很糟糕,哦,好吧)是为了让验证我链接的 libc++ 确实是我从源代码编译的 libc++ 变得非常容易。确实我可以找到字符串 slu_libc++_svn_218071通过使用 strings在 libc++.dylib 上。测试 c++ 文件中的少量测试代码现在可以轻松显示链接的 libc++ 是否是我刚刚编译的那个。

    要对实际的 libc++ 头文件进行相同的验证要简单得多,我们只需要定义一个新的宏并在编译期间检查它。

    现在我有所有的工具可以用来回答我的问题。

    嗯,实际上,现在我收到了这个错误,所以我还不能完全构建任何东西。
    Undefined symbols for architecture x86_64:
    "std::terminate()", referenced from:
    ___clang_call_terminate in reflect-16fcd7.o
    ld: symbol(s) not found for architecture x86_64

    一步一步,我猜...

    关于c++ - 运行从源代码构建的 clang 时,如何指定 libc++ 的位置,或者,有人向我解释 -stdlib=libc++ 的作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25920130/

    39 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com