如何将已编译的模块接口与目标文件链接起来?
为了举个简单的例子,我有这样的一个项目:
.
├── animals.cpp
├── animals.cppm
├── gcm.cache
│ ├── animals.gcm
│ └── std.gcm
└── main.cpp
它可以像下面这样编译和链接:
g++ -std=c++26 -Wall -O2 -fmodules animals.cppm animals.cpp main.cpp -o animals
现在我想把对象文件的编译和链接分开进行,我已经尝试过:
g++ -std=c++26 -Wall -O2 -fmodules animals.cppm animals.cpp main.cpp -c
这一步成功,并产生 animals.o 和 main.o。对于链接,我尝试了:
g++ -fmodules animals.o main.o -o animals
这会导致诸如以下所示的错误:
/usr/bin/x86_64-linux-gnu-ld.bfd: main.o: warning: relocation against `_ZTIN7animalsW7animals3CatE' in read-only section `.text.startup'
/usr/bin/x86_64-linux-gnu-ld.bfd: animals.o: in function `animals::Animal@animals::Animal(std::basic_string_view<char, std::char_traits<char> >)':
/home/dode/BeginningC++23/12-objects/animals.cpp:12:(.text+0x606): undefined reference to `vtable for animals::Animal@animals'
[...]
/usr/bin/x86_64-linux-gnu-ld.bfd: main.o: in function `_GLOBAL__sub_I_main':
/home/dode/BeginningC++23/12-objects/main.cpp:68:(.text.startup+0x1): undefined reference to `initializer for module animals'
/usr/bin/x86_64-linux-gnu-ld.bfd: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
我想我可能漏掉了一些非常基础的东西,以至于链接器没有“看到”已编译的模块接口?
解决方案
编译一个模块除了会生成一个BMI之外,还会生成一个对象文件,因此你必须链接该对象文件。
我猜在你的情况下那个对象文件丢失了,因为 animals.cppm 和 animals.cpp 都生成 animals.o,因此它的先前版本被后面的版本覆盖。
我在这里写了关于C++20模块如何编译的详细描述 在这里。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。