Что не так с моим make-файлом для кросс-компиляции?

Я провел несколько дней, пытаясь перекрестно скомпилировать программу c на моей машине с Windows. код отлично работает на моей машине с Linux, но у меня было слишком много ошибок при попытке перекрестной компиляции на этой машине. Сейчас использую Cygwin и Mingw32.

    CC = x86_64-w64-mingw32-gcc
    CFLAGS = -Wall -O2 -lmingw32 -lGL -lGLU -lm -lSDL_image -lfftw3 -lftdi1 
    -mwindows `sdl-config --cflags --libs`

    OBJECTS = main.o fft.o draw.o table.o serial.o

    main : $(OBJECTS)
    $(CC) $(CFLAGS) $(OBJECTS) -o main

    %.o : %.c
    $(CC) $(CFLAGS) -c $<

    clean:
    @echo Cleaning up...
    rm -fr *.o main
    @echo Done.

Вот как выглядит мой make-файл после его редактирования до того, что, по моему мнению, было необходимо для его кросс-компиляции. Но я получаю много ошибок неопределенных ссылок. Я понимаю, что этот вопрос очень похож на несколько других, которые я просмотрел на SO, но я не могу найти свою ошибку.

 $ make
 x86_64-w64-mingw32-gcc -Wall -O2 -lmingw32 -lGL -lGLU -lm -lSDL_image - 
 lfftw3 -lftdi1 -mwindows `sdl-config --cflags --libs` -c main.c
 x86_64-w64-mingw32-gcc -Wall -O2 -lmingw32 -lGL -lGLU -lm -lSDL_image - 
 lfftw3 -lftdi1 -mwindows `sdl-config --cflags --libs` -c fft.c
 x86_64-w64-mingw32-gcc -Wall -O2 -lmingw32 -lGL -lGLU -lm -lSDL_image - 
 lfftw3 -lftdi1 -mwindows `sdl-config --cflags --libs` -c draw.c
 x86_64-w64-mingw32-gcc -Wall -O2 -lmingw32 -lGL -lGLU -lm -lSDL_image - 
 lfftw3 -lftdi1 -mwindows `sdl-config --cflags --libs` -c table.c
 x86_64-w64-mingw32-gcc -Wall -O2 -lmingw32 -lGL -lGLU -lm -lSDL_image - 
 lfftw3 - 
 lftdi1 -mwindows `sdl-config --cflags --libs` -c serial.c
 x86_64-w64-mingw32-gcc -Wall -O2 -lmingw32 -lGL -lGLU -lm -lSDL_image - 
 lfftw3 - 
 lftdi1 -mwindows `sdl-config --cflags --libs` main.o fft.o draw.o table.o 
 serial.o -o main
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o): In function `main':
/usr/src/debug/mingw64-x86_64-runtime-5.0.3-1/crt/crt0_c.c:18: undefined reference to `WinMain'
fft.o:fft.c:(.text+0xa): undefined reference to `fftw_malloc'
fft.o:fft.c:(.text+0x1b): undefined reference to `fftw_malloc'
fft.o:fft.c:(.text+0x2c): undefined reference to `fftw_malloc'
fft.o:fft.c:(.text+0x4d): undefined reference to `fftw_plan_dft_r2c_1d'
fft.o:fft.c:(.text+0x73d): undefined reference to `fftw_execute'
draw.o:draw.c:(.text+0xb): undefined reference to `__imp_glShadeModel'
draw.o:draw.c:(.text+0x1e): undefined reference to `__imp_glClearColor'
draw.o:draw.c:(.text+0x43): undefined reference to `gluOrtho2D'
draw.o:draw.c:(.text+0x4e): undefined reference to `__imp_glDisable'
draw.o:draw.c:(.text+0x5e): undefined reference to `__imp_glEnable'
draw.o:draw.c:(.text+0x82): undefined reference to `__imp_glViewport'
draw.o:draw.c:(.text+0x8e): undefined reference to `__imp_glMatrixMode'
draw.o:draw.c:(.text+0x97): undefined reference to `__imp_glLoadIdentity'
draw.o:draw.c:(.text+0xbe): undefined reference to `gluOrtho2D'
draw.o:draw.c:(.text+0xeb): undefined reference to `SDL_Init'
draw.o:draw.c:(.text+0xf4): undefined reference to `SDL_GetVideoInfo'
draw.o:draw.c:(.text+0x11c): undefined reference to `SDL_GL_SetAttribute'
draw.o:draw.c:(.text+0x13a): undefined reference to `SDL_SetVideoMode'
draw.o:draw.c:(.text+0x171): undefined reference to `SDL_GetError'
draw.o:draw.c:(.text+0x1a1): undefined reference to `SDL_GetError'
draw.o:draw.c:(.text+0x1d1): undefined reference to `SDL_GetError'
draw.o:draw.c:(.text+0x244): undefined reference to `__imp_glBegin'
draw.o:draw.c:(.text+0x24b): undefined reference to `__imp_glColor3ub'
draw.o:draw.c:(.text+0x252): undefined reference to `__imp_glVertex2f'
draw.o:draw.c:(.text+0x29f): undefined reference to `__imp_glEnd'
draw.o:draw.c:(.text+0x415): undefined reference to `__imp_glBegin'
draw.o:draw.c:(.text+0x42c): undefined reference to `__imp_glColor3ub'
draw.o:draw.c:(.text+0x447): undefined reference to `__imp_glVertex2f'
draw.o:draw.c:(.text+0x4ef): undefined reference to `__imp_glEnd'
draw.o:draw.c:(.text+0x55b): undefined reference to `__imp_glColor3ub'
draw.o:draw.c:(.text+0x574): undefined reference to `__imp_glBegin'
draw.o:draw.c:(.text+0x580): undefined reference to `__imp_glVertex2f'
draw.o:draw.c:(.text+0x5e4): undefined reference to `__imp_glEnd'
draw.o:draw.c:(.text+0x602): undefined reference to `__imp_glColor3ub'
draw.o:draw.c:(.text+0x638): undefined reference to `__imp_glBegin'
draw.o:draw.c:(.text+0x648): undefined reference to `__imp_glColor3ub'
draw.o:draw.c:(.text+0x664): undefined reference to `__imp_glVertex2f'
draw.o:draw.c:(.text+0x6b8): undefined reference to `__imp_glEnd'
draw.o:draw.c:(.text+0x6e8): undefined reference to `__imp_glBegin'
draw.o:draw.c:(.text+0x6fb): undefined reference to `__imp_glColor3ub'
draw.o:draw.c:(.text+0x717): undefined reference to `__imp_glVertex2f'
draw.o:draw.c:(.text+0x76b): undefined reference to `__imp_glEnd'
draw.o:draw.c:(.text+0x7b5): undefined reference to `__imp_glBegin'
draw.o:draw.c:(.text+0x80d): undefined reference to `__imp_glColor3ub'
draw.o:draw.c:(.text+0x814): undefined reference to `__imp_glVertex2f'
draw.o:draw.c:(.text+0x935): undefined reference to `__imp_glEnd'
draw.o:draw.c:(.text+0xa00): undefined reference to `__imp_glBegin'
draw.o:draw.c:(.text+0xa07): undefined reference to `__imp_glColor3ub'
draw.o:draw.c:(.text+0xa0e): undefined reference to `__imp_glVertex2f'
draw.o:draw.c:(.text+0xb0b): undefined reference to `__imp_glEnd'
draw.o:draw.c:(.text+0xc09): undefined reference to `__imp_glBegin'
draw.o:draw.c:(.text+0xc10): undefined reference to `__imp_glColor3ub'
draw.o:draw.c:(.text+0xc19): undefined reference to `__imp_glVertex2f'
draw.o:draw.c:(.text+0xc20): undefined reference to `__imp_glEnd'
draw.o:draw.c:(.text+0xea7): undefined reference to `__imp_glClear'
draw.o:draw.c:(.text+0xeb2): undefined reference to `__imp_glMatrixMode'
draw.o:draw.c:(.text+0xeb8): undefined reference to `__imp_glLoadIdentity'
draw.o:draw.c:(.text+0xec7): undefined reference to `__imp_glTranslatef'
draw.o:draw.c:(.text+0xf48): undefined reference to `__imp_glBegin'
draw.o:draw.c:(.text+0xf72): undefined reference to `__imp_glColor3ub'
draw.o:draw.c:(.text+0xf8f): undefined reference to `__imp_glVertex2f'
draw.o:draw.c:(.text+0xfba): undefined reference to `__imp_glEnd'
draw.o:draw.c:(.text+0x1089): undefined reference to `SDL_GL_SwapBuffers'
draw.o:draw.c:(.text+0x10c3): undefined reference to `__imp_glColor3ub'
draw.o:draw.c:(.text+0x10d8): undefined reference to `SDL_GetKeyState'
draw.o:draw.c:(.text+0x133d): undefined reference to `SDL_WM_ToggleFullScreen'
draw.o:draw.c:(.text+0x1364): undefined reference to `SDL_PollEvent'
draw.o:draw.c:(.text+0x1385): undefined reference to `SDL_PollEvent'
draw.o:draw.c:(.text+0x13ab): undefined reference to `SDL_SetVideoMode'
draw.o:draw.c:(.text+0x13e1): undefined reference to `SDL_GetError'
serial.o:serial.c:(.text+0x11): undefined reference to `ftdi_init'
serial.o:serial.c:(.text+0x1f): undefined reference to `ftdi_set_interface'
serial.o:serial.c:(.text+0x32): undefined reference to `ftdi_usb_open'
serial.o:serial.c:(.text+0x45): undefined reference to `ftdi_set_baudrate'
serial.o:serial.c:(.text+0x94): undefined reference to `ftdi_get_error_string'
serial.o:serial.c:(.text+0xc7): undefined reference to `ftdi_get_error_string'
serial.o:serial.c:(.text+0x139): undefined reference to `ftdi_write_data'
serial.o:serial.c:(.text+0x233): undefined reference to `ftdi_write_data'
collect2: error: ld returned 1 exit status
make: *** [makefile:6: main] Error 1

person Jeremy Gilbert    schedule 03.04.2018    source источник
comment
Кажется, я помню, что параметры -lwhatever должны быть после объектных файлов из-за того, как компоновщик работает в Windows. Обычно лучше разделить CFLAGS и LDFLAGS для опций компилятора и компоновщика.   -  person rodrigo    schedule 04.04.2018
comment
Спасибо за вклад, я переместил вещи так, чтобы -lfiles были после объектов, но все равно получаю ту же ошибку.   -  person Jeremy Gilbert    schedule 04.04.2018
comment
Можете ли вы опубликовать полную команду компоновщика, которая на самом деле работает?   -  person rodrigo    schedule 04.04.2018
comment
Вы имеете в виду вывод, который я вижу в терминале, когда набираю make?   -  person Jeremy Gilbert    schedule 04.04.2018
comment
Ну да, самая интересная строчка это вызов x86_64-w64-mingw32-gcc с -o main и все такое прочее.   -  person rodrigo    schedule 04.04.2018
comment
Но у вас все еще есть -l* перед объектными файлами!   -  person rodrigo    schedule 04.04.2018
comment
Ах, я скопировал код ДО того, как изменил его, ха-ха. хорошо, а сейчас?   -  person Jeremy Gilbert    schedule 04.04.2018
comment
Я так много догадывался ... не могли бы вы опубликовать эту командную строку ПОСЛЕ изменения? А также не могли бы вы проверить, какие сообщения об ошибках отличаются от этого изменения?   -  person rodrigo    schedule 04.04.2018


Ответы (2)


Когда вы связываетесь с SO в Linux, например, с помощью -lGL, вы напрямую связываете общий объект libGL.so.

Но в Windows, когда вы связываете DLL, вы фактически связываете статическую библиотеку libGL.a (libGL.lib в родной Windows), которая содержит один преобразователь для каждой импортированной функции.

И как это бывает, правила компоновщика различаются между разделяемыми и статическими библиотеками. Статические библиотеки подключаются с использованием порядка в командной строке компоновщика.

TL;DR; Вы должны поставить -l* в конце команды компоновщика. Кроме того, рекомендуется разделять CFLAGS и LDFLAGS:

CC = x86_64-w64-mingw32-gcc
CFLAGS = -Wall -O2 `sdl-config --cflags`
LDFLAGS = -lmingw32 -lGL -lGLU -lm -lSDL_image -lfftw3 -lftdi1 -mwindows `sdl-config --libs`

OBJECTS = main.o fft.o draw.o table.o serial.o

main : $(OBJECTS)
$(CC) -o $@ $(CFLAGS) $(OBJECTS) $(LDFLAGS)

%.o : %.c
$(CC) $(CFLAGS) -c $<

Что касается ссылки WinMain, это потому, что вы написали -mwindows: для создания приложения Windows, то есть такого, которое начинается с WinMain() вместо main(). Если вы хотите придерживаться своего main(), вы можете вместо него использовать -mconsole.

person rodrigo    schedule 03.04.2018
comment
А, хорошо, я вижу разницу. Макет выглядит более организованным. Я попытался изменить -mwindows на -mconsole, но ошибка не изменилась. - person Jeremy Gilbert; 04.04.2018
comment
До сих пор нет продвижения по ссылке WinMain. Я пытался добавить #include <windows.h> в свой файл main.c, который я где-то читал. Кроме того, в моем файле main.c есть строка с надписью int main, так что может ли это быть причиной какой-то проблемы? мне нужно что-то сделать с cygwin, чтобы он искал что-то еще? - person Jeremy Gilbert; 04.04.2018
comment
Ах! Вы используете SDL, поэтому у вас есть печально известная проблема SDL_main. Вы можете попробовать связать с SDL_main.a ИЛИ добавить #undef main непосредственно перед вашей функцией main. - person rodrigo; 04.04.2018
comment
Привет! #ifdef main # undef main #endif /* main */ сработало! - person Jeremy Gilbert; 04.04.2018
comment
Теперь у меня есть мой .exe! но когда я пытаюсь запустить его, я получаю несколько отсутствующих ошибок .dll, включая cygftdi-1.2.dll cygGLU-1.dll cygfftw3-3.dll cygGL-1.dll - person Jeremy Gilbert; 04.04.2018
comment
Извините, я не знаком с внутренностями Cygwin, только с MinGW... Но у вас есть эти DLL в PATH? Также я слышал, что у вас могут быть проблемы, если вы неправильно смешиваете MinGW и Cygwin... - person rodrigo; 04.04.2018
comment
Я нахожу их в своем каталоге ..\cygwin\lib, но все они имеют .dll.a могу ли я скопировать их в другое место, чтобы .exe мог их найти? - person Jeremy Gilbert; 04.04.2018
comment
Я так не думаю, вам нужна настоящая DLL. Я думаю, что Cygwin поставляется с менеджером пакетов, так что с этого и нужно начинать. Затем вам нужно добавить каталог в PATH или скопировать библиотеки DLL в тот же каталог, где находится EXE. - person rodrigo; 04.04.2018
comment
Хорошо, я использовал диспетчер пакетов, чтобы добавить fftw3, ftdi1, GLU и GL, так что теперь мне просто нужно выяснить, как добавить их в PATH. Это то, что мне нужно вернуться и добавить в make-файл? - person Jeremy Gilbert; 04.04.2018
comment
Нет, PATH — это переменная среды, ничего общего с Makefile. - person rodrigo; 04.04.2018
comment
Хорошо, теперь я нашел все файлы .dll без .a в папке cygwin/bin. - person Jeremy Gilbert; 04.04.2018

Я переключил объекты и cflags вверху, но забыл переключить объекты и cflags в

main : $(OBJECTS) $(CC) $(OBJECTS) $(CFLAGS) -o main

Теперь я получаю только неопределенную ссылку на WinMain

$ make
x86_64-w64-mingw32-gcc -Wall -O2 -lmingw32 -lm -lGL -lGLU -lSDL_image - 
lfftw3 -lftdi1 -mwindows `sdl-config --cflags --libs` -c main.c
x86_64-w64-mingw32-gcc -Wall -O2 -lmingw32 -lm -lGL -lGLU -lSDL_image - 
lfftw3 -lftdi1 -mwindows `sdl-config --cflags --libs` -c fft.c
x86_64-w64-mingw32-gcc -Wall -O2 -lmingw32 -lm -lGL -lGLU -lSDL_image - 
lfftw3 -lftdi1 -mwindows `sdl-config --cflags --libs` -c draw.c
x86_64-w64-mingw32-gcc -Wall -O2 -lmingw32 -lm -lGL -lGLU -lSDL_image - 
lfftw3 -lftdi1 -mwindows `sdl-config --cflags --libs` -c table.c
x86_64-w64-mingw32-gcc -Wall -O2 -lmingw32 -lm -lGL -lGLU -lSDL_image - 
lfftw3 -lftdi1 -mwindows `sdl-config --cflags --libs` -c serial.c
x86_64-w64-mingw32-gcc main.o fft.o draw.o table.o serial.o -Wall -O2 - 
lmingw32 -lm -lGL -lGLU -lSDL_image -lfftw3 -lftdi1 -mwindows `sdl-config -- 
cflags --libs` -o main
/usr/x86_64-w64-mingw32/sys- 
root/mingw/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o): In function 
`main':
/usr/src/debug/mingw64-x86_64-runtime-5.0.3-1/crt/crt0_c.c:18: undefined 
reference to `WinMain'
collect2: error: ld returned 1 exit status
make: *** [makefile:6: main] Error 1
person Jeremy Gilbert    schedule 03.04.2018