为什么g ++看起来在LIBRARY_PATH /../ lib64中,这在哪里记录?

时间:2012-09-14 06:42:23

标签: c++ linux gcc g++

我的LIBRARY_PATH环境变量中包含自定义目录:/cs/public/lib/pkg/opencv/lib

但是,当我使用g++ --print-search-dirs时,我会改为:

libraries: =
/cs/public/lib/pkg/opencv/lib/x86_64-suse-linux/4.6/:
/cs/public/lib/pkg/opencv/lib/../lib64/:
/usr/lib64/gcc/x86_64-suse-linux/4.6/:
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../x86_64-suse-linux/lib/x86_64-suse-linux/4.6/:
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../x86_64-suse-linux/lib/../lib64/:
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../x86_64-suse-linux/4.6/:
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../lib64/:
/lib/x86_64-suse-linux/4.6/:
/lib/../lib64/:
/usr/lib/x86_64-suse-linux/4.6/:
/usr/lib/../lib64/:
/cs/public/lib/pkg/opencv/lib/:
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../../x86_64-suse-linux/lib/:
/usr/lib64/gcc/x86_64-suse-linux/4.6/../../../:
/lib/:
/usr/lib/

为什么g ++会在LIBRARY_PATH变量中明确指出的之前查看这些替代方案和一大堆其他系统位置,并记录在哪里?

我会理解是否在LIBRARY_PATH和LIBRARY_PATH /../ lib64等之前搜索了系统默认值,但是g ++将LIBRARY_PATH /../ lib64,然后是系统路径,然后是LIBRARY_PATH。这个订单记录在哪里?

我的g ++版本是g++ (SUSE Linux) 4.6.2

我的操作系统是openSUSE 12.1 (x86_64)

7 个答案:

答案 0 :(得分:9)

这里提出了类似的问题: g++ searches /lib/../lib/, then /lib/

这些可怕的搜索路径至少部分地在编译器本身构建时确定,例如在配置阶段。很明显,它超出了环境变量,因为它可能安装了多个GCC副本,并且每个副本都为gcc --print-search-dirs提供了不同的结果。还注意到g++ --print-search-dirsgcc --print-search-dirs给出了不同的结果,指出g ++包装器也影响搜索路径。除了配置/构建时间差异,GCC肯定知道它自己的可执行文件所在的路径,并将搜索该路径的子目录。很多这种炼金术可以在GCC文件中找到:
http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Directory-Options.html#Directory-Options
http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Environment-Variables.html#Environment-Variables

据我所知,如果不编译自己的GCC副本,最有力的事情就是使用-L选项指定自定义库。我这样说的原因是因为在例如之前搜索-L LIBRARY_PATH(请参阅上面的环境变量链接)。为了使其更容易忍受,您可以在.bashrc文件中添加g ++的别名,包括-L选项。

如果您想要一个明确的答案,那么下载GCC源代码的副本是一种方法。例如,在gcc.c中,出现以下高度暗示的评论:

/* Build a list of search directories from PATHS.
   PREFIX is a string to prepend to the list.
   If CHECK_DIR_P is true we ensure the directory exists.
   If DO_MULTI is true, multilib paths are output first, then
   non-multilib paths.
   This is used mostly by putenv_from_prefixes so we use `collect_obstack'.
   It is also used by the --print-search-dirs flag.  */

然而,评论后面的功能不是很明显。

答案 1 :(得分:7)

这是multilib工作 - 一种机制,允许在一台机器上拥有多个体系结构的库(以及整个编译和构建工具链)。 This Wiki声明“multilib后缀附加到GCC搜索库的所有目录,并通过-L选项传递给链接器。链接器本身没有任何关于multilibs的特定知识,并将继续查询其默认值如果在-L路径中找不到库,则搜索目录。如果在单个编译中使用多个正交ABI更改选项,则可以串联使用多个multilib后缀。“

因此,根据以上描述,架构标记串或其不同变体被附加到编译器接收的每个库搜索路径,因为它不区分默认路径和自定义路径。您的自定义路径在行中排在第一位,但它经历了与其他路径相同的“扩展”过程。

由于需要处理i386兼容性,现在似乎默认在大多数x64发行版上使用multilib机制,这实际上意味着大多数安装都在那里。

答案 2 :(得分:1)

我有完全相同的问题:

Fedora 17, gcc 4.7 and gcc 4.3
CentOS 6.3, gcc 4.4
Unubuntu 12, gcc 4.6

所以看起来这是大多数gcc版本的问题。可能这种奇怪的行为最初出现在gcc 4.2中,至少根据this

我尝试重复规格并与它们一起玩。看起来*multilib规范用于根据平台追加特定字符串。例如,我的原始空格看起来像:

*multilib:
. !m64 !m32;64:../lib64 m64 !m32;32:../lib !m64 m32;

当我将64:../lib64更改为64:../lib时,而不是../lib64 gcc附加../lib。但我无法完全解读*multilib或任何其他规格的含义。

答案 3 :(得分:0)

此答案试图总结GCC和Clang的搜索路径行为。

海湾合作委员会

包含路径:,用于以下格式的命令行:

CPLUS_INCLUDE_PATH=EDIR g++ -IIDIR -isystemSDIR

以下目录列表用作#include <...>的搜索路径:

IDIR                                           # '-I' directories.
SDIR                                           # '-isystem' directories.
EDIR                                           # *_INCLUDE_PATH directories.
GCCDIR/include/c++/GCCVER                      # libstdc++ directory (C++).
GCCDIR/include/c++/GCCVER/GCCARCH              # libstdc++ directory (C++).
GCCDIR/include/c++/GCCVER/backward             # libstdc++ directory (C++).
GCCDIR/lib/gcc/GCCARCH/GCCVER/include          # GCC arch-specific directory.
/usr/local/include/GCCARCH                     # Local arch-specific include directory.
/usr/local/include                             # Local include directory.
GCCDIR/include                                 # GCC include directory.
GCCDIR/lib/gcc/GCCARCH/GCCVER/include-fixed    # GCC include-fixed directory.
/usr/include/GCCARCH                           # System include arch-specific directory.
/usr/include                                   # System include directory.

库路径::以下格式的命令行:

LIBRARY_PATH=EDIR gcc -BBDIR -LLDIR

以下参数传递给链接器:

-LLDIR                                         # '-L' directories.
-LBDIR                                         # '-B' directories.
-LEDIR/../libXX                                # Multilib directories from LIBRARY_PATH.
-LGCCDIR/lib/gcc/GCCARCH/GCCVER                # GCC arch-specific library directory.
-LGCCDIR/libXX                                 # GCC multilib library directory.
-L/libXX                                       # System multilib library directory.
-L/usr/libXX                                   # System multilib library directory. 
-LEDIR                                         # LIBRARY_PATH directories.
-LGCCDIR/lib                                   # Other GCC libraries.

C

包含路径:,用于以下格式的命令行:

CPLUS_INCLUDE_PATH=EDIR clang++ --gcc-toolchain=GCCDIR -BBDIR -IIDIR -isystemSDIR

以下目录列表用作#include <...>的搜索路径:

IDIR                                           # '-I' directories.
SDIR                                           # '-isystem' directories.
EDIR                                           # *_INCLUDE_PATH directories.
 # If -stdlib=libstdc++ is used:
   GCCDIR/include/c++/GCCVER                   # libstdc++ directory from the selected GCC toolchain (C++).
   GCCDIR/include/c++/GCCVER/GCCARCH           # libstdc++ directory from the selected GCC toolchain (C++).
   GCCDIR/include/c++/GCCVER/backward          # libstdc++ directory from the selected GCC toolchain (C++).
 # If -stdlib=libc++ is used:
   CLANGDIR/include/c++/v1                     # libc++ directory (C++).
/usr/local/include                             # Local include directory.
CLANGDIR/lib/clang/CLANGVER/include            # Clang include directory.
/include                                       # System include directory.
/usr/include                                   # System include directory.

库路径::以下格式的命令行:

LIBRARY_PATH=EDIR clang --gcc-toolchain=GCCDIR -BBDIR -LLDIR    

以下参数传递给链接器:

-LLDIR                                         # '-L' directories.
-LGCCDIR/lib/gcc/GCCARCH/GCCVER                # GCC arch-specific library directory.
-LGCCDIR/libXX                                 # GCC multilib library directory.
-L/libXX                                       # System multilib library directory.
-L/usr/libXX                                   # System multilib library directory.
-LGCCDIR/lib                                   # Other GCC libraries.
-LCLANGDIR/lib                                 # Clang libraries.
-L/lib                                         # System library directory.
-L/usr/lib                                     # System library directory.
-LEDIR                                         # LIBRARY_PATH directories.

摘要

在GCC和Clang中,includes的搜索路径几乎相同。如果在两种情况下都使用C前端,则省略C ++特定的路径。 GCC和Clang之间的库搜索路径大不相同,尤其是-B目录的存在和GCC前端中LIBRARY_PATH的奇怪处理。

C和C ++前端的库搜索路径相同。其他库搜索路径由链接器本身引入。以下摘录来自GNU Binutils的香草链接器脚本:

# Multilib library directories.
SEARCH_DIR("BINUTILSDIR/BINUTILSARCH/libXX");
SEARCH_DIR("BINUTILSDIR/libXX");
SEARCH_DIR("/usr/local/libXX");
SEARCH_DIR("/libXX");
SEARCH_DIR("/usr/libXX");
# Traditional library directories.
SEARCH_DIR("BINUTILSDIR/BINUTILSARCH/lib");
SEARCH_DIR("BINUTILSDIR/lib");
SEARCH_DIR("/usr/local/lib");
SEARCH_DIR("/lib");
SEARCH_DIR("/usr/lib");

还必须注意,在上面列出的目录中没有 搜索库依赖项。它们仅依靠传递给链接器的-rpath-rpath-link选项,否则它们将从默认的系统库路径中解析。因此,同时产生-L-rpath-link参数以确保链接了正确的库可能很有用。

最后,仅在-B目录中搜索特殊文件(例如CRT对象)。在Clang中,还将在选定的GCC工具链中搜索特殊文件。其他因素(规格文件,特定于发行版的配置)可能会更改上述部分或全部内容。

答案 4 :(得分:-1)

看起来需要进行交叉编译。来自ChangeLog:

  Wed Mar 29 14:53:23 1995  Jim Wilson  <wilson@cygnus.com>

          * gcc.c (process_command): Delete code modifying gcc_exec_prefix.
          (main): Put it here after last use of gcc_exec_prefix.  For cross
          compiler, set startfile_prefixes if gcc_exec_prefix is set and
          standard_startfile_prefix is a relative path.

startfile_prefixes是用search-dirs标志打印出来的。来自gcc/gcc.c

    if (print_search_dirs)
      {
        printf (_("install: %s%s\n"), standard_exec_prefix, machine_suffix);
        printf (_("programs: %s\n"), build_search_list (&exec_prefixes, "", 0));
        printf (_("libraries: %s\n"), build_search_list (&startfile_prefixes, "", 0));
        return (0);
      }

答案 5 :(得分:-1)

编译器首先会查看默认路径,然后查看其他路径。 如何在打印时对其进行排序我现在没有,但在此处记录了3.19 Environment Variables Affecting GCC

答案 6 :(得分:-1)

路径由内置规范定义。规范定义管道如何处理源代码以获得结果。 GCC只是推动了汇编。

您可以通过-spec=向GCC提供您自己的规范文件,并且可以使用-dumpspecs IIRC获取内置规范。

这可能在GCC手册中的某处解释过。