sysroot简介
1. 概述
在本教程中,我们将讨论 sysroot 以及在调用编译器时调整它的方法。
2. sysroot
除了我们自己的代码文件,编译器还使用许多其他文件来生成它们的输出。例如,为了生成程序、目标文件和其他类型的输出,C 和 C++ 编译器会搜索头文件和库。
默认情况下,编译器会在标准位置搜索这些文件。但是,**我们可能希望使用替代目录。**例如,当交叉编译针对其他平台的二进制文件或使用非标准标头和/或库准备实验性构建时。
*sysroot 目录用作标头和库的根目录。因此,让我们考虑默认情况下分别在/usr/include/和/usr/lib/下搜索标头和库。通过将sysroot定义为/home/dir ,编译器现在将分别在/home/dir/usr/include/和/home/dir/usr/lib/*下查找头文件和库。
3. 设置sysroot
下面讨论的选项指的是gcc 编译器。但是, sysroot 的概念并不排斥gcc。它甚至不排除一般的 C/C++ 编译器:还有其他语言的编译器也使用 sysroot 的概念并提供更改它的方法。
3.1. –sysroot和*-isysroot*选项
–sysroot = dir选项告诉编译器在头文件和库默认目录前加上 dir。此选项也会影响链接器,因为它还会更改库的搜索位置。然后,链接器也必须支持这个选项。GNU 链接器(ld 程序)从 2.16 版开始支持 sysroot。对于其他链接器,我们必须查看它们各自的文档。 在下面的示例中,gcc将使用*/home/blogdemo*作为搜索头文件和库文件的根目录:
$ gcc hello.c --sysroot=/home/blogdemo
** -isysroot dir选项的作用类似于*–sysroot*,但它仅影响头文件的根目录。**
以下示例说明了*-isysroot选项。在此调用中,gcc将使用/home/blogdemo*作为搜索头文件的根目录,但仍将在标准目录中搜索库:
$ gcc hello.c -isysroot /home/blogdemo
请注意,-isysroot是单虚线。然后,它遵循不同于*–sysroot* 的约定:选项的名称及其值之间没有等号 (=)。
允许同时定义*–sysroot和-isysroot* 。在这种情况下,-isysroot将影响标题搜索目录,而*–sysroot*将影响库目录。
3.2. 使用 = 和*$SYSROOT*占位符
** -I 、-iquote、-isystem和*-idirafter选项还提供引用 sysroot 的方法**。在为这些选项设置搜索目录时,我们只需要在它们的参数前加上“=”或“$SYSROOT”* 。这样,它们将充当 sysroot 的占位符。
让我们采用以下 C 文件:
#include <stdio.h>
#include "blogdemo.h"
int main(int argc, char* argv[]) {
printf("Hello world!\n");
return 0;
}
以及以下命令:
$ gcc hello.c -isysroot /home/blogdemo -iquote '$SYSROOT/quoted/'
现在,让我们剖析上面的命令:
- -isysroot /home/blogdemo将*/home/blogdemo*设置为用于头文件搜索的 sysroot
- -iquote选项为包含在*#include指令的引号形式中的头文件设置备用路径*。我们的示例 C 文件中的文件blogdemo.h已使用引用形式引用。然后,它将受此选项的影响
- ‘$SYSROOT/quoted/’ 将扩展为*/home/blogdemo/quoted/*
*请注意,我们在’$SYSROOT/quoted/’周围使用了单引号。**如果我们使用双引号,$SYSROOT*将被 shell 处理为环境变量。
也可用作 sysroot 的占位符的等号 (=) 不会遇到该问题。以下命令执行与上述示例相同的功能:
$ gcc hello.c -isysroot /home/blogdemo -iquote "=/quoted/"