相关文章推荐
内向的馒头  ·  POI导出excel执行公式 ...·  2 月前    · 
要出家的钥匙扣  ·  Item 21: ...·  11 月前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

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.

If this is for a substantial project, I wonder if it'd be worth letting autotools handle some of the portability stuff? – Cascabel Oct 30, 2010 at 14:30 @Jefromi: autotools assumes a basic UNIX toolset (sh, m4, sed, rm, ...). @tomp: Might as well install them on windows (from MSYS or GnuWin) and spend your efforts on the more challenging portability issues. – ephemient Oct 30, 2010 at 16:07 @ephemient: Ah, right, my bad. I'm not really a windows person. (But now I'm confused - can't the mingw toolchain provide that too? I know, the OP said no linux emulation.) – Cascabel Oct 30, 2010 at 16:57

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.

If you're running COMMAND.COM for some reason, you should also be checking for SYSTEMROOT in uppercase: "SystemRoot" won't be defined with that capitalisation (whereas it will in CMD.EXE). – user458541 Jan 19, 2016 at 4:24

The SystemRoot trick didn't work for me on Windows XP but this did:

ifeq ($(OS),Windows_NT)
    #Windows stuff
    #Linux stuff
endif
                this might be tricky if you have cygwin installed and make executable comes from cygwin. You will get OS=Windows_NT but you can use Linux commands like mkdir -p. The direction of the directory separator is also important
– sagi
                Mar 30, 2020 at 20:54

Checking WINDIR or COMSPEC is case-sensitive. Instead, I came up with the following solution, hope that helps someone someday:

# detect if running under unix by finding 'rm' in $PATH :
ifeq ($(wildcard $(addsuffix /rm,$(subst :, ,$(PATH)))),)
WINMODE=1
WINMODE=0
endif
ifeq ($(WINMODE),1)
# native windows setup :
UNLINK = del $(subst /,\,$(1))
CAT = type $(subst /,\,$(1))
# cross-compile setup :
UNLINK = $(RM) $(1)
CAT = cat $(1)
endif
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.