c - 如何确保静态库和应用程序编译相同?

标签 c gcc static-libraries

我正在努力将第 3 方项目集成到我的应用程序中(准确地说是 LittleFS)。我试图将项目编译为静态库,然后将其链接到我的应用程序中。我在链接和获取正确的包含路径方面没有问题,我的问题在于如何处理编译时配置。

例如,该项目的标题中有如下一行:

struct lfs_config {
    ...
    #ifdef LFS_THREADSAFE
    int (*lock)(const struct lfs_config *c);
    int (*unlock)(const struct lfs_config *c);
    #endif
    ...
};

我将使用以下标志编译第 3 方项目/静态库以启用此功能:

gcc ... -DLFS_THREADSAFE

但是,当我将此库链接到我的应用程序时,要使其正常工作,我需要确保我的应用程序具有-DLFS_THREADSAFE 标志设置。

这意味着我必须跟踪在两个不同的地方设置了哪些定义,这似乎会在一段时间后变得有点容易出错和麻烦。

我的问题是,如何确保静态库和应用程序共享相同的配置?

最佳答案

没有确定且可移植的方法来执行此操作。事实上,我使用过的大多数编码标准都不允许任何基于宏定义不同的结构,尤其是当该结构用作 API 的一部分时。如果接口(interface)结构定义不一致,这将被视为 API 设计缺陷。

与其让结构内容根据编译时配置实际改变,不如保持一致,而是简单地将值设置为表明它们未被使用的值。也就是说,在您的示例中,无条件地保留函数指针,没有任何“ifdef”:

struct lfs_config {
    ...
    int (*lock)(const struct lfs_config *c);
    int (*unlock)(const struct lfs_config *c);
    ...
};

如果 LFS_THREADSAFE 未定义,这些指针可以设置为 NULL。假设您使用 c99 样式的初始值设定项,这就可以工作,即

const struct lfs_config MY_CONFIG = {
    .other_option_1 = <value>
#ifdef LFS_THREADSAFE
    .lock = my_lock
    .unlock = my_unlock
#endif
    .other_option_2 = <value>
};

在这种情况下,如果定义了LFS_THREADSAFE,则lockunlock 项将被相应地设置。但是如果 LFS_THREADSAFE 未定义,这些初始化器将被省略,并且根据 C99 标准,未指定的成员将被分配值 0(NULL,在指针的情况下)。在库内部,如果函数指针值为 NULL,则可以简单地跳过锁定/解锁调用。

或者,也可以始终将指针设置为有效函数,但如果 LFS_THREADSAFE 未定义,则将其设为空操作。即:

int my_lock(struct lfs_config *c)
{
#ifdef LFS_THREADSAFE
    <do_something>
#endif
    return 0;
}

和解锁类似。

总而言之,保持 API 结构尽可能一致,而不是让它们依赖于宏总是明智的。希望这有帮助!!

关于c - 如何确保静态库和应用程序编译相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73749905/

相关文章:

valgrind 可以从单独目录中的 C 可执行文件中使用我使用的静态库中的内存泄漏吗?

c - 链接两个具有相同函数签名的 lib 文件?

无法使用 Visual C++ 编译器包含某些头文件

c - 在 phpinfo() 输出中公开扩展版本

linux - 'all' 需要 Makefile 错误 : No rule to make target, 。停止

c - 为什么 GCC 会针对错误的 printf 格式说明符显示重复警告?

c++ - 静态库。导入和导出内联函数

c - 使用 c Token-Pasting 访问结构中的字段

c - 我的程序(获取函数)有什么问题?

c++ - 是否可以使用 GCC 编译具有特定编译器标志的代码文件的一部分?