Search code examples
cgccmakefilecross-compilingmingw32

What's wrong with my cross compiling makefile?


I have spent several days now trying to cross compile a c program on my windows machine. the code runs fine on my linux machine but I had too many errors trying to cross compile it on that machine. Now I'm using Cygwin and 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.

This is what my makefile looks like after editing it to what I thought was needed to cross compile it. But I get many undefined reference errors. I realize this question is very similar to a few others I've looked over on SO, but I cannot seem to find my mistake.

 $ 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

Solution

  • When you link to a SO in Linux , for example with -lGL, you are linking the shared object directly libGL.so.

    But in Windows, when you link a DLL you are actually linking a static library libGL.a (libGL.lib in native Windows) that contains one thunk per imported function.

    And as it happens, linker rules are different between shared and static libraries. Static libraries are linked using the order in the linker command line.

    TL;DR; You have to put the -l* at the end of the linker command. Also, it is a good practice to separate CFLAGS and 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 $<
    

    About the WinMain reference, that is because you wrote -mwindows: that is to build a Windows application, that is one that starts with WinMain() instead of main(). If you want to stick to your main() you can use -mconsole instead.