我试图了解 Linux 的工作原理以及如何构建模块。
到目前为止,我看到 Linux 标头存储在 中,/usr/include
并且这些接口的编译实现位于/usr/lib/x86_64-linux-gnu
.我有几个问题:
Linux 或任何 C 程序如何知道在哪里查找头文件和 .so 文件?有没有定义这个的文件?如果我想添加另一个默认源或标题文件夹(只是为了闲逛),是否可以修改这些引用?
如何避免冲突?例如,在 中
libprocps-dev
有一个/usr/include/proc/numa.h
定义为 的头文件void numa_uninit (void);
。该文件的实现位于/usr/lib/x86_64-linux-gnu/libprocps.so
.如果有人还编译了另一个具有相同函数定义但具有另一个实现(或代码)的 .so 文件并将其添加到 ,该怎么办/usr/lib/x86_64-linux-gnu
?链接器如何知道哪个是必须链接到该标头定义的正确 .so 文件?
谢谢。
答案1
我试图了解 Linux 的工作原理以及如何构建模块。
构建内核模块不涉及“标准”C 编译器目录;相反,请参阅/lib/modules/$(uname -r)/build
.
C程式不知道去哪里寻找头文件和库; C 预处理器和编译器执行此操作。您可以使用以下命令查看标准包含目录
gcc -xc -E -v - < /dev/null
(对于 C++ 替换
-xc
为-xc++
),以及使用库搜索目录gcc -print-search-dirs
编译器并不能避免冲突;由运行编译器的任何人或任何人来确保搜索路径不包含冲突的标头。库不会自动链接,您必须将库添加到链接器命令行(
-lprocps
在您的示例中);任何其他库都会被忽略。在这两种情况下,当出现冲突时,编译和/或链接会因错误而停止。