如何在库中以前缀开头找到所有C函数
对于一个小的测试框架,我想进行自动测试发现。目前,我的计划是所有测试都有一个前缀,基本上可以像这样实现
#define TEST(name) void TEST_##name(void)
,并且可以像这样(在不同的C文件中)使用
TEST(one_eq_one) { assert(1 == 1); }
,丑陋的部分是您需要再次在MAIM中列出所有测试名称功能。
我不想这样做,而是想在库中收集所有测试(例如lib-my-unit-tests.so),并自动生成主函数,然后只将生成的主函数链接到库中。所有这些内部动作都可以通过CMAKE很好地隐藏。
因此,我需要一个可以做的脚本:
1. Write "int main(void) {"
2. For all functions $f starting with 'TEST_' in lib-my-unit-tests.so do
a) write "extern void $f(void);"
b) write "$f();
3. Write "}"
该脚本的大多数部分都很容易,但是我不确定如何可靠地获取从前缀开始的所有功能的列表。 在POSIX系统上,我可以尝试解析nm
的输出。但是在这里,我不确定名称是否总是相同的(在我的MacBook上,所有名称以附加的“ _”开头)。对我来说,看起来可能是OS/Architecture依赖于二进制文件的名称。对于Windows,我尚不对如何做到这一点有任何想法。
因此,我的问题是:
- 有没有更好的方法在C中实施测试局面? (也许类似
dlsym
) - 我如何可靠地获取所有功能名称的列表,以MACOS/Linux/Windows上的某个前缀开头,
解决问题的部分解决方案是解析nm
nm < /code>带有正则表达式:
for line in $(nm $1) ; do
# Finds all functions starting with "TEST_" or "_TEST_"
if [[ $line =~ ^_?(TEST_.*)$ ]] ; then
echo "${BASH_REMATCH[1]}"
fi
done
然后第二个脚本会消耗此输出来生成调用这些功能的AC文件。然后,Cmake调用第二个脚本来创建测试可执行文件,
add_executable(test-executable generated_source.c)
target_link_libraries(test-executable PRIVATE library_with_test_functions)
add_custom_command(
OUTPUT generated_source.c
COMMAND second_script.sh library_with_test_functions.so > generated_source.c
DEPENDS second_script.sh library_with_test_functions)
我认为这在POSIX Systems上有效,但我不知道如何为Windows解决它
For a small test framework, I want to do automatic test discovery. Right now, my plan is that all tests just have a prefix, which could basically be implemented like this
#define TEST(name) void TEST_##name(void)
And be used like this (in different c files)
TEST(one_eq_one) { assert(1 == 1); }
The ugly part is that you would need to list all test-names again in the main function.
Instead of doing that, I want to collect all tests in a library (say lib-my-unit-tests.so) and generate the main function automatically, and then just link the generated main function against the library. All of this internal action can be hidden nicely with cmake.
So, I need a script that does:
1. Write "int main(void) {"
2. For all functions $f starting with 'TEST_' in lib-my-unit-tests.so do
a) write "extern void $f(void);"
b) write "$f();
3. Write "}"
Most parts of that script are easy, but I am unsure how to reliably get a list of all functions starting with the prefix.
On POSIX systems, I can try to parse the output of nm
. But here, I am not sure if the names will always be the same (on my MacBook, all names start with an additional '_'). To me, it looks like it might be OS/architecture-dependent which names will be generated for the binary. For windows, I do not yet have an idea on how to do that.
So, my questions are:
- Is there a better way to implement test-discovery in C? (maybe something like
dlsym
) - How do I reliably get a list of all function-names starting with a certain prefix on a MacOS/Linux/Windows
A partial solution for the problem is parsing nm
with a regex:
for line in $(nm $1) ; do
# Finds all functions starting with "TEST_" or "_TEST_"
if [[ $line =~ ^_?(TEST_.*)$ ]] ; then
echo "${BASH_REMATCH[1]}"
fi
done
And then a second script consumes this output to generate a c file that calls these functions. Then, cmake calls the second script to create the test executable
add_executable(test-executable generated_source.c)
target_link_libraries(test-executable PRIVATE library_with_test_functions)
add_custom_command(
OUTPUT generated_source.c
COMMAND second_script.sh library_with_test_functions.so > generated_source.c
DEPENDS second_script.sh library_with_test_functions)
I think this works on POSIX systems, but I don't know how to solve it for Windows
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用
nm
或objdump
实用程序来编写shell脚本,以列出符号,通过awk
选择适当的名称并输出所需的所需名称源线。You can write a shell script using the
nm
orobjdump
utilities to list the symbols, pipe throughawk
to select the appropriate name and output the desired source lines.