I routinely work on several different computers and several different operating systems, which are Mac OS X, Linux, or Solaris. For the project I'm working on, I pull my code from a remote git repository.
I like to be able to work on my projects regardless of which terminal I'm at. So far, I've found ways to get around the OS changes by changing the makefile every time I switch computers. However, this is tedious and causes a bunch of headaches.
How can I modify my makefile so that it detects which OS I'm using and modifies syntax accordingly?
Here is the makefile:
cc = gcc -g
CC = g++ -g
yacc=$(YACC)
lex=$(FLEX)
all: assembler
assembler: y.tab.o lex.yy.o
$(CC) -o assembler y.tab.o lex.yy.o -ll -l y
assembler.o: assembler.c
$(cc) -o assembler.o assembler.c
y.tab.o: assem.y
$(yacc) -d assem.y
$(CC) -c y.tab.c
lex.yy.o: assem.l
$(lex) assem.l
$(cc) -c lex.yy.c
clean:
rm -f lex.yy.c y.tab.c y.tab.h assembler *.o *.tmp *.debug *.acts
There are many good answers here already, but I wanted to share a more complete example that both:
uname
exists on Windows The CCFLAGS defined here aren't necessarily recommended or ideal; they're just what the project to which I was adding OS/CPU auto-detection happened to be using.
ifeq ($(OS),Windows_NT)
CCFLAGS += -D WIN32
ifeq ($(PROCESSOR_ARCHITEW6432),AMD64)
CCFLAGS += -D AMD64
else
ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
CCFLAGS += -D AMD64
endif
ifeq ($(PROCESSOR_ARCHITECTURE),x86)
CCFLAGS += -D IA32
endif
endif
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
CCFLAGS += -D LINUX
endif
ifeq ($(UNAME_S),Darwin)
CCFLAGS += -D OSX
endif
UNAME_P := $(shell uname -p)
ifeq ($(UNAME_P),x86_64)
CCFLAGS += -D AMD64
endif
ifneq ($(filter %86,$(UNAME_P)),)
CCFLAGS += -D IA32
endif
ifneq ($(filter arm%,$(UNAME_P)),)
CCFLAGS += -D ARM
endif
endif
PROCESSOR_ARCHITECTURE
envvar seems to be virtualized depending on whether the process is 32-bit or 64-bit. So if your make
is 32-bit and you're trying to build a 64-bit application, it will fail. Using it in combination with PROCESSOR_ARCHITEW6432
worked for me (see this, and that) — Nov 29, 2013 at 12:59 make
team add a couple of magic variables with os and arch, probably too much trouble. — Aug 25, 2014 at 15:00 OS
is set on non-Windows systems. Make treats unset the same as empty, which will cause a jump to the uname
-based block. You just need to add a FreeBSD check there. — Oct 02, 2015 at 16:53 /bin/sh: -c: line 0: syntax error near unexpected token
,Windows_NT' /bin/sh: -c: line 0: ifeq (,Windows_NT)' make: *** [os] Error 2
— Dec 02, 2016 at 07:58 if
,else
and endif
MUST NOT be indented (in my experiments). I also only got this to work outside of the target blocks — May 15, 2018 at 07:52