我在Linux上开发了一个C ++项目,我希望通过向他们提供可执行文件传递给我的Windows用户同事。
我搜索了这个问题,发现可以使用i586-mingw32msvc-g++
而不是g++
进行编译。我也明白这个解决方案会追踪需要重建的链接库的问题,我希望通过使用MXE脚本(http://mxe.cc/)解决这个问题。
我的makefile是(我是新手,欢迎提出建议):
#main.make
CC = i586-mingw32msvc-g++
CFLAGS = -Wall -O2
LDFLAGS =
SOURCES = <list of cpp files>
LDLIBS = -L/usr/i586-mingw32msvc/lib/ -llapack -lblas -lgsl -lgslcblas -lm -lmingw32
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE = main_simple.exe
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@ $(LDLIBS)
.cpp.o:
$(CC) $(CFLAGS) -c $<
clean:
rm *.o main_simple.exe ./Output/* ./Output/*/* ./Output/*/*/*
如果我尝试make
,我会收到一堆与gsl相关的错误,例如:
utilities.o:utilities.cpp:(.text+0x2d1): undefined reference to `_gsl_matrix_alloc'
utilities.o:utilities.cpp:(.text+0x2dc): undefined reference to `_gsl_vector_alloc'
....
utilities.o:utilities.cpp:(.text+0x42e): undefined reference to `_gsl_matrix_free'
utilities.o:utilities.cpp:(.text+0x70f): undefined reference to `_gsl_fit_linear'
utilities.o:utilities.cpp:(.text+0x722): undefined reference to `_gsl_stats_correlation'
collect2: ld returned 1 exit status
这是否意味着编译器确实找到了我认为我用MXE交叉构建的库?我该怎么办?
或者,cmake
会更清洁吗?我可以使用它从我的Linux机器创建.exe
文件吗?或者在这种情况下,我应该让我的同事重新编译他们的机器?
感谢您提供给我的任何帮助!
答案 0 :(得分:1)
问题是,目前(2016年11月)gsl作为共享库的编译在mxe中被停用。这就是为什么链接器无法找到对这些函数的引用而导致此错误的原因。
您现在可以使用mxe交叉编译器自己编译gsl或激活共享版本(请参阅mxe源代码中的src / gsl.mk)。
由于我需要gsl用于我自己的项目,因此我尝试在对mxe(https://github.com/mxe/mxe/pull/1568)的pull请求中启用共享构建。你可以试试这个修改,它对我有用。
答案 1 :(得分:0)
对于diganose,我建议以下
提供完整的&#39;构建转储&#39;被调用的实际编译器和被调用的标志
提供完整的错误日志
使用一些二进制探索工具,例如&#39; objdump&#39; (也许它将在MXE构建的mingw文件夹下,例如&#39; i686-pc-mingw32-objdump&#39;)来查看你构建的库并查看它们是否包含缺失的符号。
换句话说,如果你构建了一个应该具有`_gsl_matrix_alloc&#39;在其中的函数,然后查看您构建的库以确保它在那里。如果您不知道哪个库应该包含该函数,那么执行一些shell工作来搜索所有查找该符号名称的库。
是的,像cmake或qmake这样的构建系统可能会让事情变得更容易,尽管每次使用构建系统时,您都必须首先了解构建系统。
最后,对你最有帮助的是,找到另一个使用与你相同的库的程序,并且你知道交叉编译到windows,然后复制他们所做的。这些程序的一个很好的来源是转到mxe.cc并使用mxe&#39;来查看项目。列出他们的网页,看看他们是否使用GSL,然后看看他们是如何做到的。查找项目的另一种方法是使用GSL查找开源项目,看看他们是否在主网页上宣传了Windows二进制下载。如果是这样,很可能他们正在使用交叉编译。
祝你好运!