这是一个涉及 C++、SWIG 和 Lua 的非常具体的编译问题。
我有一个非常简单的基本代码:
[ AClass.hpp ]
class AClass {
public:
AClass();
};
[ AClass.cpp ]
#include "AClass.hpp"
AClass::AClass() {}
[主.cpp ]
#include "AClass.hpp"
int main() {
AClass my_a;
}
此时,与编译无关。我首先编译libengine.dll中的类,然后使用共享库构建可执行文件。
让我们引入一个 SWIG 模块,并将其添加到 dll 中:
[ A类.i ]
%module M_AClass
%{
#include "AClass.hpp"
%}
%include "AClass.hpp"
此后,当链接可执行文件中的所有内容时,出现以下错误:
g++ -c main.cpp
g++ -c AClass.cpp
swig.exe -c++ -lua AClass.i
g++ -Iinclude -c AClass_wrap.cxx
g++ AClass.o AClass_wrap.o -shared -o libengine.dll -Wl,--out-implib,libengine.dll.a -L. -llua5.1
Creating library file: libengine.dll.a
g++ main.o libengine.dll.a -o main.exe
main.o:main.cpp:(.text+0x16): undefined reference to `AClass::AClass()'
collect2: ld returned 1 exit status
有人会有线索吗?我尝试使用nm查看 dll,但我不知道如何将另一个.o添加到共享库中可以“隐藏”一个方法(这不是特定于构造函数)。
为了重现上下文,这里是放置在目录中以构建测试的必要文件:
include/ # Contains "lauxlib.h", "lua.h" & "luaconf.h"
liblua5.1.dll
AClass.hpp
AClass.cpp
AClass.i
main.cpp
Makefile
最后,这是 Makefile 内容:
ifneq (,$(findstring Linux,$(shell uname -o)))
EXEC := main
LIB := libengine.so
LIB_FLAGS := -o $(LIB)
else
EXEC := main.exe
LIB := libengine.dll.a
LIB_FLAGS := -o libengine.dll -Wl,--out-implib,$(LIB)
#NO DIFFERENCE using ".dll.a" as in CMake (option: -Wl,--out-implib,) or only ".dll"
ifdef SystemRoot
# Pure Windows, no Cygwin
RM := del /Q
endif
endif
LANG_LIB := -L. -llua5.1
LANG_INC := include
LANG_SWIG := -lua
all: clean $(EXEC)
clean:
$(RM) main *.exe *_wrap.cxx *.o libengine.*
$(EXEC): main.o $(LIB)
g++ $^ -o $@
main.o: main.cpp
g++ -c $<
#NO PB without dependency to AClass_wrap.o
$(LIB): AClass.o AClass_wrap.o
g++ $^ -shared $(LANG_LIB) $(LIB_FLAGS)
AClass.o: AClass.cpp
g++ -fPIC -c $<
AClass_wrap.o: AClass_wrap.cxx
g++ -fPIC -I$(LANG_INC) -c $<
AClass_wrap.cxx: AClass.i
swig -c++ $(LANG_SWIG) $<
这是在 Windows 7 下使用 MingGW g++ v4.5.2、SWIG 2.0.2 和 Lua5.1 测试的。
编辑:当 SWIG 导出到 tcl 时,也会出现问题。但是,在 Linux 下编译绝对没有问题。我比较了生成的 AClass_wrap.cxx,它们很相似。