Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the board
Thread view  Mix view  Order
RayeR

Homepage

CZ,
26.03.2010, 01:14
 

Multiplatform makefile for gcc (Developers)

Could someone give me an idea how to detect OS from makefile? I have some sources that I'm compiling with DJGPP, MinGW32 and Linux gcc. I need to link it with some OS specific libraries so I need to detect OS and use proper -l arguments and then just type "make" without different options. In C source I can simply use e.g. #ifdef __WIN32__ but make probably doesn't have something similar. It would need to call some other utility for OS detection but how this utility will run under all OSes? I can also got rough guess by testing specific environment variables e.g. "WINDIR". Or maybe grepping output of "gcc -v" (I have set proper path to compiler). But maybe it's bad idea and I should rather make 3 scripts maked, makew, makel which will call make with some args...

---
DOS gives me freedom to unlimited HW access.

Rugxulo

Homepage

Usono,
26.03.2010, 03:56
(edited by Rugxulo, 26.03.2010, 19:39)

@ RayeR

Multiplatform makefile for gcc

> Could someone give me an idea how to detect OS from makefile? I have some
> sources that I'm compiling with DJGPP, MinGW32 and Linux gcc. I need to
> link it with some OS specific libraries so I need to detect OS and use
> proper -l arguments and then just type "make" without different options.
> In C source I can simply use e.g. #ifdef __WIN32__ but make probably
> doesn't have something similar.

I suspected it did, but a quick check of make.info doesn't show anything. (Eli Z. probably knows, ask on comp.os.msdos.djgpp).

> It would need to call some other utility
> for OS detection but how this utility will run under all OSes?

"uname", most likely, although it's not always installed except on *nix and Cygwin.


ifeq ($(DJGPP),)
 UNAME=uname
else
 UNAME ?= $(foreach dir,$(subst ;, ,$(PATH)),$(wildcard $(dir)/uname$(EXE)))
 ifeq ($(strip $(UNAME)),)
  UNAME=$(wildcard uname$(EXE))
 endif
endif

ifneq ($(strip $(UNAME)),)
 empty=
 space=$(empty) $(empty)
 backslashspace=\$(space)
 backslashlparen=\(
 backslashrparen=\)
 leftparen=(
 rightparen=)
TARGET=$(shell $(UNAME) -srm)
 OS_TARGET=$(subst $(rightparen),$(backslashrparen),$(subst (leftparen),$(backslashlparen),$(subst $(space),$(backslashspace),$(TARGET))))
endif


> I can also
> got rough guess by testing specific environment variables e.g. "WINDIR".

"windir" (case sensitive!) is a good choice. "DJGPP" is another good one. Not sure about detecting Cygwin uniquely, but you get the idea. ;-)

> Or maybe grepping output of "gcc -v" (I have set proper path to compiler).
> But maybe it's bad idea and I should rather make 3 scripts maked, makew,
> makel which will call make with some args...

No, you don't have to do that. (Although I think "gcc -dumpversion" is better, heh.) At least things like CBuild can detect OS for you. Not sure about CMake, Ant, Jam, etc.

EDIT: Almost forgot about this.

%OS%="Windows_NT" (or "DRDOS", "NWDOS", "OPENDOS")
(under GNU Bash) see %MACHTYPE% (i786-pc-msdosdjgpp), %OSTYPE% (msdosdjgpp)

MS-DOS 6.x on up (but not DR-DOS):

ver | find "XP"
if errorlevel 1 echo Windows XP *NOT* detected!

---
Know your limits.h

marcov

26.03.2010, 14:20

@ RayeR

Multiplatform makefile for gcc

> Could someone give me an idea how to detect OS from makefile?

I don't know how GCC handles this, but the FPC (g)makefiles query the compiler, which can print host and target OS and CPU.

This also means that the makefile can autoconfigure crosscompiling.

Rugxulo

Homepage

Usono,
26.03.2010, 19:35

@ marcov

Multiplatform makefile for gcc

> > Could someone give me an idea how to detect OS from makefile?
>
> I don't know how GCC handles this, but the FPC (g)makefiles query the
> compiler, which can print host and target OS and CPU.
>
> This also means that the makefile can autoconfigure crosscompiling.

"gcc -dumpmachine" is probably what you mean.

FYI, old DJGPP (GCC 2.6.3 and 2.7.2.3) says "go32" while everything since 2.8.1 says "djgpp". ;-)

P.S. marcov didn't mention, but *BSD doesn't come with GNU make by default, only its own (aka, pmake). I'm a lame coder, but even I did something like this (in "BSDmakefile"):


GCCVER != gcc -dumpversion
UNAME1 != uname -s
UNAME2 != uname -r
UNAME3 != uname -m
UNAME=$(UNAME1)\ $(UNAME2)\ $(UNAME3)
CPU=i686

.if ${GCCVER} == "3.3.3" || ${GCCVER} == "3.3.4" || ${GCCVER} == "3.3.5" || ${GCCVER} == "3.3.6"
MTUNE=-mcpu=$(CPU) -DMTUNE=\"$(CPU)\"
.else
MTUNE=-mtune=$(CPU) -DMTUNE=\"$(CPU)\"
.endif

OPTIMIZE=-O2 -fomit-frame-pointer

CXX=g++
CXXFLAGS=-s -static $(OPTIMIZE) $(MTUNE) -DOS_TARGET=\"$(UNAME)\"

---
Know your limits.h

RayeR

Homepage

CZ,
29.03.2010, 01:23

@ Rugxulo

Multiplatform makefile for gcc

Thanks for all suggestions. After some thinking it seems that
gcc -dumpmachine
is the best choice for me. So I added following into my makefile:

CCSYSTEM = $(shell $(CC) -dumpmachine)
to get current compiler platform (path is set) and then decide target filename:

# Files
PROGNAME = SPIPGM
ifeq ($(findstring mingw32, $(CCSYSTEM)), mingw32)
PROGNAME = SPIPGMW
endif
ifeq ($(findstring cygwin, $(CCSYSTEM)), cygwin)
PROGNAME = SPIPGMW
endif
PROGEXT = EXE
ifeq ($(findstring linux, $(CCSYSTEM)), linux)
PROGEXT =
endif


BTW I wonder if make is too silly that don't know logical operators to be able to write
ifeq ($(findstring mingw32, $(CCSYSTEM)), mingw32) || ($(findstring cygwin, $(CCSYSTEM)), cygwin)
or even simpler if multiple substring search possible
infeq ($(findstring mingw32 cygwin ..., $(CCSYSTEM)), )
condition in one line but probably I missed that - not a make guru ;)

---
DOS gives me freedom to unlimited HW access.

Back to the board
Thread view  Mix view  Order
22049 Postings in 2034 Threads, 396 registered users, 240 users online (0 registered, 240 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum