我的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)
答案 0 :(得分:9)
这里提出了类似的问题: g++ searches /lib/../lib/, then /lib/
这些可怕的搜索路径至少部分地在编译器本身构建时确定,例如在配置阶段。很明显,它超出了环境变量,因为它可能安装了多个GCC副本,并且每个副本都为gcc --print-search-dirs
提供了不同的结果。还注意到g++ --print-search-dirs
和gcc --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.
包含路径:,用于以下格式的命令行:
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手册中的某处解释过。