如何在库中以前缀开头找到所有C函数

发布于 2025-02-07 20:10:47 字数 1663 浏览 2 评论 0原文

对于一个小的测试框架,我想进行自动测试发现。目前,我的计划是所有测试都有一个前缀,基本上可以像这样实现

#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,我尚不对如何做到这一点有任何想法。

因此,我的问题是:

  1. 有没有更好的方法在C中实施测试局面? (也许类似dlsym
  2. 我如何可靠地获取所有功能名称的列表,以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:

  1. Is there a better way to implement test-discovery in C? (maybe something like dlsym)
  2. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

月下凄凉 2025-02-14 20:10:47

您可以使用nmobjdump实用程序来编写shell脚本,以列出符号,通过awk选择适当的名称并输出所需的所需名称源线。

You can write a shell script using the nm or objdump utilities to list the symbols, pipe through awk to select the appropriate name and output the desired source lines.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文