我正在努力将第 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
,则lock
和unlock
项将被相应地设置。但是如果 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/