【问题标题】:How to share code between two Linux modules?如何在两个 Linux 模块之间共享代码?
【发布时间】:2020-05-17 22:17:52
【问题描述】:

我从一个专有的 Linux 驱动程序收到代码,它具有以下结构:

common/common.c
moduleA/Makefile
moduleB/Makefile

问题在于 moduleA 和 moduleB 都包含语句 moduleX-objs += ../common/common.o。这显然很不合时宜,因为在进行多线程编译时,两个线程同时读取/写入文件 common/common.o。

解决这个问题的干净方法是什么?创建一个单独的模块 common.ko?
用内核构建系统做这些事情的标准方法是什么?

【问题讨论】:

    标签: c makefile linux-kernel gnu-make kernel-module


    【解决方案1】:

    模块依赖于 common.o

    一种方法是在构建模块之前构建 common.o,方法是将 common.o 作为模块的先决条件,因为两个模块都会认为 common.o 是最新的,但如果使用 --always-make 构建仍然存在竞争条件因为模块不会检查日期。您可以通过在模块构建期间将 common 设为只读来防止它发生,使 --always-make 的任何尝试失败(假设模块 makefile 不会覆盖权限,这将是一件奇怪的事情)。但是,您确实必须跟踪模块使用的常见内容。简单的解决方案,最佳性能。

    所有模块都依赖于一个模块

    如果你觉得懒惰,你可以在模块之间建立一个虚假的依赖关系,例如所有模块都依赖于模块A。所有模块都将构建多线程,但所有依赖的模块不会与所有其他模块同时构建。确实存在构建性能下降,但我希望在大多数情况下它是微不足道的。为了获得更好的性能,您可以根据构建时间短或内部多线程高效的模块进行试验。最简单的解决方案,良好的性能。不适用于 --always-make,请使用提到的只读策略。

    单独的源代码树

    通过复制模块和通用到单独的(构建)文件夹然后从那里构建,我已经在单独的源代码树中构建了一些成功,但是它使其他事情变得复杂,并且构建性能可能会降低,因为模块包含大量文件。如果您决定这样做,请记住复制为硬链接:cp -lr。最简单的解决方案(我提到过)。值得注意的是,模块可能希望使用不同的构建标志共同构建,在这种情况下,每个模块都需要单独的 .o 文件。如果是这种情况,那么这个解决方案将在其他解决方案无法发挥作用的地方发挥作用。

    以上是我随着时间的推移学到的设计。不要假装它是最先进的或任何东西。

    【讨论】:

    • 在编译过程中如何让一个模块依赖于另一个模块?我搜索了它,但只找到了关于运行时依赖的结果。
    • 在编排所有模块构建的 makefile 中,假设所有模块都以 libmoduleX.a:moduleA/libmoduleA.a moduleB/libmoduleB.a: moduleC/libmoduleC.a 形式生成工件。这使得 A 和 B “依赖”于 C,因此严格在 C 构建成功之后构建。
    • 什么意思?这不是一个通用的 makefile,而是 kbuild 构建系统。我不知道“编排所有模块的构建的makefile”。你的意思是顶级makefile吗?
    • 是的,顶级 makefile :-) 与 $(MAKE) -C moduleA libmoduleA.a 类似的配方
    • 我不确定我们是否在做同样的事情。这些模块集成在 kennel 构建系统中,因此绝对没有顶级 makefile 明确提及 moduleA,moduleA 递归地包含在构建中。无论如何感谢您的帮助。
    猜你喜欢
    • 2016-04-14
    • 1970-01-01
    • 2014-07-05
    • 1970-01-01
    • 1970-01-01
    • 2019-07-03
    • 1970-01-01
    • 2017-09-06
    • 2015-10-08
    相关资源
    最近更新 更多