Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you compile 32-bit and 64-bit applications at the same time in Visual Studio for C/C++ in a makefile?

My question is similar to Targeting both 32bit and 64bit with Visual Studio in same solution/project.

However, I need to accomplish this in a GNUmakefile.

For instance, if i wanted to cross compile 32 and 64 bit applications via gcc, I can use the -m32 & -m64 flags during compilation and linking. This method is different for visual studio because I have to run vcvarsall.bat x86 to compile for 32 bit and vcvarsall.bat x64 for 64 bit to setup my environment for compilation.

all: foo.exe foo64.exe

foo.exe: obj32/foo.o
    link.exe /MACHINE:X86 $(OTHER_FLAGS) /out:$@ $^

foo64.exe: obj64/foo.o
    link.exe /MACHINE:X64 $(OTHER_FLAGS) /out:$@ $^

obj32/foo.o: foo.c
    cl.exe $(CFLAGS) $(INCLUDE_DIRS) /Fo$@ /c $<

obj64/foo.o: foo.c
    cl.exe $(CFLAGS) $(INCLUDE_DIRS) /Fo$@ /c $<

The above sample would not work because you need to rerun the vcvarsall.bat environment script in between compilation of 32 and 64 bit. If I try to compile the above sample makefile when after running vcvarsall.bat x86, I would get this error when trying to link the 64 bit executable:

 fatal error LNK1112: module machine type 'X86' conflicts with target machine type 'x64'

Is there a way we can accomplish building both 32 and 64 bit applications with one invocation of make?

like image 728
Mark Trinh Avatar asked Apr 27 '11 16:04

Mark Trinh


1 Answers

You don't have to use vcvars. Those are convenience scripts for building in one platform environment or the other. By explicitly invoking the proper commands and passing them the appropriate options you can compile both without having to invoke two different batch files.

Here is one way to write your "foo" program example as a GNU makefile:

BIN32 = $(VS100COMNTOOLS)..\..\vc\bin
BIN64 = $(VS100COMNTOOLS)..\..\vc\bin\amd64
LIB32 =
LIB64 = \
    /libpath:"$(VS100COMNTOOLS)..\..\vc\lib\amd64" \
    /libpath:"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\lib\x64"

all: foo.exe foo64.exe

foo.exe: obj32/foo.obj
    "$(BIN32)/link.exe" /MACHINE:X86 $(OTHER_FLAGS) $(LIB32) /out:$@ $^

foo64.exe: obj64/foo.obj
    "$(BIN64)/link.exe" /MACHINE:X64 $(OTHER_FLAGS) $(LIB64) /out:$@ $^

obj32/foo.obj: foo.c
    "$(BIN32)/cl.exe" $(CFLAGS) $(INCLUDE_DIRS) /Fo$@ /c $<

obj64/foo.obj: foo.c
    "$(BIN64)/cl.exe" $(CFLAGS) $(INCLUDE_DIRS) /Fo$@ /c $<

This still assumes vcvarsall.bat x86 was run beforehand but with more work even that can be eliminated.

like image 186
Rick Sladkey Avatar answered Oct 19 '22 17:10

Rick Sladkey