在一起,有多少标签太多了?
c - 在 C/C++ 中将测试符号静态收集到一个数组中
问题描述
问题的简短版本
是否可以在编译时将 C 中的特定符号静态地收集到单个列表/数组中到可执行文件中,而不依赖于 crt 初始化(我经常支持嵌入式目标,并且对动态内存的支持有限)。
编辑:我 100% 可以在链接时发生这种情况,也可以不让符号跨越库边界。
编辑 2:如果它是 gcc 或 clang,我也可以接受编译器特定的答案,但如果可能的话,我更喜欢跨平台。
更长的版本,更多的背景
一段时间以来,这一直是我的痛苦。
现在我有一些我喜欢按顺序运行的内置自测。
我对所有函数强制执行相同的调用约定,并手动将所有测试静态收集到一个数组中。
// ThisLibrary_testlist.h
#define DECLARE_TEST(TESTNAME) void TESTNAME##_test(void * test_args)
DECLARE_TEST(test1);
DECLARE_TEST(test2);
DECLARE_TEST(test3);
// ThisLibrary_some_module.c
#include "ThisLibrary_testlist.h"
DECLARE_TEST(test1)
{
// ... do hood stuff here
}
// ThisLibrary_testarray.c
#include "ThisLibrary_testlist.h"
typedef void (*testfunc_t) (void*);
#define LIST_TEST(TESTNAME)
testfunc_t tests[] =
{
&LIST_TEST(test1),
&LIST_TEST(test2)
};
// now it's an array... you know what to do.
到目前为止,这让我保持活力,但如果我想更新测试,我必须基本上修改 3 个不同位置的代码,这有点荒谬。
更不用说条件编译测试带来的绝对 #ifdef 噩梦了。
有没有更好的办法?
解决方案
使用一点脚本魔法,您可以执行以下操作:在编译源文件之后(但在链接之前),您在目标文件中搜索与您的测试名称模式匹配的符号。了解man nm
如何从目标文件中获取符号名称(好吧,在 Unix 上,就是 - 不知道 windows,抱歉)。根据找到的对象名称列表,您自动创建文件ThisLibrary_testarray.c
,放入所有extern
声明,然后放入函数指针表。生成此文件后,您对其进行编译并最终链接所有内容。
这样,您只需将新的测试函数添加到源文件中。无需维护头文件ThisLibrary_testlist.h
,但您必须确保测试函数具有外部链接,遵循命名模式 - 并确保没有其他符号使用命名模式:-)
推荐阅读
- tailwind-css - 如何将 Tailwind CSS 结果导出到 CSS 文件?
- git - git LFS 不允许我上传我跟踪的文件
- html - 为什么狭窄的视口会在我的网格容器的左侧剪辑,在 Chrome
- python-3.x - 如何执行函数以等待该函数具有来自 filechooser.open_file() 的路径?
- html - 何时使用
和 - django - django-channels 中的套接字上的 mqtt
- php - 更改 Laravel Auth 中检查密码的方法
- python - discord.utils.find 和 discord.utils.get 不断返回 None
- c++ - 我必须在 C++ 中创建一个幂函数,但它不起作用
- laravel - 尝试为特定用户 ID 存储和编辑产品