A commonly asked question is, “can I use Linux makefiles to build on Windows?”
Often, the simple (and rather naive) answer is “use NMake”. This post explains the nuanced differences between a Linux and Windows Makefile.
NMake is the native Windows alternative to the Linux make utility and the syntax is very similar too. However, let’s see if it can handle the following simple Linux Makefile. The example code can be accessed via GitHub at https://github.com/cognitivewaves/Simple-Makefile.
# Specify compiler CC=gcc # Specify linker LINK=gcc # Build all target .PHONY : all all : app # Link the object files and dependent libraries into a binary app : main.o $(LINK) -o app main.o -lstdc++ # Compile the source files into object files main.o : main.cpp $(CC) -c main.cpp -o main.o # Clean target .PHONY : clean clean : rm main.o app
Start a command prompt which can execute NMake
. An easy way is to start a command prompt from Visual Studio (Tools->Visual Studio Command Prompt
), so that all the necessary environment variables are set. Change directory to where the Makefile exists and run NMake.
D:\tmp\Simple-Makefile>nmake Microsoft (R) Program Maintenance Utility Version 10.00.30319.01 Copyright (C) Microsoft Corporation. All rights reserved. gcc -c main.cpp -o main.o 'gcc' is not recognized as an internal or external command, operable program or batch file. NMAKE : fatal error U1077: 'gcc' : return code '0x1' Stop.
The error points to the first problem. It’s easy to fix though as shown in the snippet.
- Compilers are different on Linux and Windows.
# Specify compiler CC=cl.exe # Specify linker LINK=link.exe
Run NMake
again after the change.
D:\tmp\Simple-Makefile>nmake Microsoft (R) Program Maintenance Utility Version 10.00.30319.01 Copyright (C) Microsoft Corporation. All rights reserved. cl.exe -c main.cpp -o main.o Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. cl : Command line warning D9035 : option 'o' has been deprecated and will be removed in a future release main.cpp link.exe -o app main.o -lstdc++ Microsoft (R) Incremental Linker Version 10.00.40219.01 Copyright (C) Microsoft Corporation. All rights reserved. LINK : warning LNK4044: unrecognized option '/o'; ignored LINK : warning LNK4044: unrecognized option '/lstdc++'; ignored LINK : fatal error LNK1181: cannot open input file 'app.obj' NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\link.exe"' : return code '0x49d' Stop.
These warnings and errors indicate the next set of problems, which are more perverse. To fix it, adjust the file as shown in the snippet.
- Libraries are never the same
- Linux uses dash (-) to specify compiler options. Fortunately, Visual Studio allows options to be specified by either a forward slash (/) or a dash (–). But the compiler and linker flags are not exactly the same. There are more differences than similarities.
# Link the object files and dependent libraries into a binary app : main.o $(LINK) /OUT:app.exe main.o # Compile the source files into object files main.o : main.cpp $(CC) /c main.cpp /Fomain.o
Run NMake
again.
D:\tmp\Simple-Makefile>nmake Microsoft (R) Program Maintenance Utility Version 10.00.30319.01 Copyright (C) Microsoft Corporation. All rights reserved. link.exe /OUT:app.exe main.o Microsoft (R) Incremental Linker Version 10.00.40219.01 Copyright (C) Microsoft Corporation. All rights reserved. rm main.o app.exe 'rm' is not recognized as an internal or external command, operable program or batch file. NMAKE : fatal error U1077: 'rm' : return code '0x1' Stop.
These indicate further problems.
- It doesn’t recognize the Linux built in target names like
.PHONY
- Linux commands are obviously not valid in Windows
Finally, to make it work, the following changes have to be made. So Linux makefiles need to be ported to NMake format.
In summary, Linux Makefile
s require some manual effort to run on Windows. Some of the options are,
- Port to Windows NMake format.
- Use a Linux like environment with Cygwin or MinGW to run “as is” on Windows (i.e. without NMake).
- Create an equivalent Visual Studio Solution.
- Create an equivalent CMake project. This is a more elegant alternative as the cross-platform build system CMake can generate Makefiles for Linux and Visual Studio solutions for Windows.
Makefile
and/or CMake
, see the following for a Visual Studio friendly introduction.Makefiles and Visual Studio
CMake and Visual Studio