Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile that distinguishes between Windows and Unix-like systems

I would like to have the same Makefile for building on Linux and on Windows. I use the default GNU make on Linux and the mingw32-make (also GNU make) on Windows.

I want the Makefile to detect whether it operates on Windows or Linux.


For example make clean command on Windows looks like:

clean:     del $(DESTDIR_TARGET) 

But on Linux:

clean:     rm $(DESTDIR_TARGET) 

Also I would like to use different directory separator on Windows (\) and Linux (/).


It is possible to detect Windows operating system in Makefile?

PS: I do not want to emulate Linux on Windows (cygwin etc.)

There is similiar question: OS detecting makefile, but I didn't find the answer here.

like image 444
Tom Pažourek Avatar asked Oct 30 '10 13:10

Tom Pažourek


People also ask

Can you use makefile on Windows?

If it is a "NMake Makefile", that is to say the syntax and command is compatible with NMake, it will work natively on Windows.

What is the equivalent of make command in Windows?

Look for a Visual C++ makefile; it's usually named Makefile. mak. Then run nmake . But if you only have files named Makefile.in and Makefile.am, then you don't yet have a makable environment.

What is a makefile called?

By default, when make looks for the makefile, it tries the following names, in order: GNUmakefile , makefile and Makefile . Normally you should call your makefile either makefile or Makefile .


1 Answers

I solved this by looking for an env variable that will only be set on windows.

ifdef OS    RM = del /Q    FixPath = $(subst /,\,$1) else    ifeq ($(shell uname), Linux)       RM = rm -f       FixPath = $1    endif endif  clean:     $(RM) $(call FixPath,objs/*) 

Because %OS% is the type of windows, it should be set on all Windows computers but not on Linux.

The blocks then setups up variables for the different programs as well as a function for converting the forward slashes into backslashes.

You to have to use $(call FixPath,path) when you call an outside command (internal commands work fine). You could also use something like:

/ := / 

and then

objs$(/)* 

if you like that format better.

like image 112
Paul Hutchinson Avatar answered Sep 19 '22 03:09

Paul Hutchinson