GCC 插件入门

Posted

技术标签:

【中文标题】GCC 插件入门【英文标题】:Getting started with GCC plugins 【发布时间】:2013-04-03 14:59:36 【问题描述】:

所以在网上搜索了一段时间后,我决定在这里尝试一下,因为它似乎是一个很好的讨论论坛。我试图创建一个简单的 gcc 插件。程序代码附在这封邮件的末尾,但是用简单的英语它注册插件并确保在注册 pragma 时调用 pragma_init 函数。正是在这里,我使用 c_register_pragma 来截取一些 pragma。

我使用http://gcc.gnu.org/onlinedocs/gccint/Plugins-building.html#Plugins-building 中的示例编译它。编译和链接工作正常。但是,当我加载插件时,我得到:

gcc -c -fplugin=plugin.so   test.c -o test.o 

cc1: error: cannot load plugin plugin.so

plugin.so: undefined symbol: warning

我做错了什么?此外,当包含一些头文件(稍后将需要)时,我得到了很多错误。例如,包含“tree.h”会产生(在 50 个其他错误中):

/machmode.h:262:1: error: unknown type name 'class'

 class bit_field_mode_iterator
 ^
/machmode.h:263:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '' token

 
 ^
/plugin/include/tree.h:27:0,
             from conftest.c:63:

/vec.h:220:8: error: field 'register_overhead' declared as a function

有人知道我做错了什么吗?

谢谢

【问题讨论】:

您是否考虑过使用gcc-melt.org 在 MELT(一种扩展 GCC 的特定领域语言)中编写 GCC 扩展而不是痛苦地用 C++ 制作 GCC 插件? gcc -v 的输出是什么? -v的输出(编译然后插件)是:collect2 --eh-frame-hdr -m elf_x86_64 -shared -o plugin.so /lib/../lib64/crti.o /gcc-48/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/crtbeginS.o -L/gcc-48/lib/gcc/x86_64-unknown-linux-gnu/4.8.0 -L/gcc -48/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../../../lib64 -L/lib/../lib64 -L/usr/lib/.. /lib64 -L/gcc-48/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/../../.. plugin.o -lgcc --as-needed -lgcc_s --no-as -needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /gcc-48/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/crtendS.o /lib/../ lib64/crtn.o 我删除了一些路径,因为消息太长了。我更喜欢用 C/C++ 而不是 Melt 编写我的东西。部分是因为我对 Melt 了解不多,但也因为我计划做的一些事情将从插件本身中解析出来。 不,只运行命令gcc -v,不带任何其他参数。 【参考方案1】:

这里有两个问题:

错误:“无法加载插件plugin.so”意味着您应该将存储新共享库插件的目录添加到LD_LIBRARY_PATH。

如果您使用 g++ 而不是 gcc 编译,则包含所有文件的数百个错误在我的计算机中得到解决(不确定为什么会这样想)

【讨论】:

【参考方案2】:

您使用的是哪个版本的 GCC,既要编译您的插件,又要使用该插件?简单运行

 gcc -v

无需任何其他程序参数即可找出!

您是否为 GCC 插件开发安装了适当的软件包(在 Debian 或 Ubuntu 上,它可能是 gcc-4.7-plugin-dev,但将 4.7 版本调整为您的特定 GCC 版本)?

您是否安装了构建 GCC 所需的所有依赖项(在 Debian 或 Ubuntu 上,apt-get build-dep gcc-4.7 gcc-4.7-plugin-dev)?

最新版本的 GCC(尤其是发行版提供的许多 GCC 4.7,以及所有 GCC 4.8)都是由 C++ 编译器而非 C 编译器编译的。

您可以通过运行检查您的 GCC 是如何构建的(在 C 或 C++ 中)

nm -D -C $(gcc -print-file-name=cc1) 

如果该命令显示键入的 C++ 管理名称,例如execute_ipa_pass_list(opt_pass*) 而不仅仅是 execute_ipa_pass_list 你的 GCC 已经用 C++ 编译器编译(可能是 g++

所以你可能需要使用g++(不是gcc)来编译你的GCC插件。

正如我所评论的,您是否考虑过使用 MELT(一种扩展 GCC 的特定领域语言)来扩展或自定义您的 gcc 编译器?

我建议下载最新的http://gcc-melt.org/melt-plugin-snapshot.tar.bz2,因为我将在几周后发布 GCC 4.7 和 4.8 的下一个 MELT

不要指望通过插件改变 GCC 的 解析 行为。这是不可能的(GCC 仅提供插件挂钩来添加您的内置函数和编译指示,而不是扩展解析的语法)。

【讨论】:

COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/home/rb/Tools/gcc-48/libexec/gcc/x86_64-unknown-linux-gnu/4.8.0/lto-wrapper 目标:x86_64-unknown-linux -gnu 配置:../gcc-4.8.0/configure --prefix=/home/rb/Tools/gcc-48 --disable-multilib 线程模型:posix gcc 4.8.0 (GCC) 谢谢巴西尔。我确实安装了一个插件开发包(使用 FC17),现在插件已加载并输出正确的消息。但是,我确实恢复到系统上预安装的编译器。使用 GCC4.8 是否需要采取额外的预防措施?也许我错过了一些标志。尽管如此,它似乎至少适用于 prebuild 4.7。再次感谢您的支持。 出于好奇,你愿意开发什么样的GCC插件? 一个插件,支持与我的运行时系统交互的应用程序(想想 OpenMP、StarPU、OmpSs、OpenStream、XKaapi、...)中的并行化。手动转码应用程序以使用我正在试验的功能有点痛苦。 我会很高兴看到更多细节,至少通过电子邮件给我(然后提及您问题的 URL)。谢谢。

以上是关于GCC 插件入门的主要内容,如果未能解决你的问题,请参考以下文章

Node.js插件编写-通过NAN编写简单插件入门

Node.js插件编写-通过NAN编写简单插件入门

Node.js插件编写-通过Node-Api编写简单插件入门

Node.js插件编写-通过Node-Api编写简单插件入门

Node.js插件编写-通过Node-Api编写简单插件入门

GCC使用入门