I'm working in a team of embedded firmware developers. We all use make to build a lot of different targets - binaries, doxygen, release packages etc. Some of the team builds under DOS/mingw32 and others under cygwin. I don't want to / cannot force the whole team to choose only one side. So we try to make our makefiles cross platform compatible and mostly we are successful, but the current solutions have their warts. Specifically we are having a hard time writing cross platform rules for:
copy
dir exist
rmdir
rm
We use an os.mk
file to choose solutions for current platform like this:
ifeq ($(OS),Windows_NT)
HASUNAME := $(if $(shell where uname 2> NUL),$(shell echo yes),$(shell echo no))
ifeq ($(HASUNAME),yes)
UNAME := $(shell uname)
else
UNAME := WIN32
endif
ifneq (,$(findstring CYGWIN,$(UNAME)))
$(shell rm NUL)
PATHSEP:=/
COPY:=cp
RM:=rm -f
RMDIR:=rm -rf
else
ifneq (,$(findstring MINGW,$(UNAME)))
PATHSEP:=/
COPY:=cp
RM:=rm -f
RMDIR:=rm -rf
else
PATHSEP:=\\
COPY:=copy
RM:=del /q 2>NUL
RMDIR:=rmdir /q /s 2>NUL
endif
endif
else
COPY=UNEXPECTED_OS_ERROR
RM=UNEXPECTED_OS_ERROR
RMDIR=UNEXPECTED_OS_ERROR
endif
The warts come because of the differences in the different platform implementations of the file functions. E.g. for copy I need to manipulate the arguments because one platform uses slash for path separator and the other uses backslash. Like this:
BOOTSRC:=$(subst /,$(PATHSEP),../boot/build/$(BOARD)/Bootloader.hex)
Bootloader.hex:
$(COPY) $(BOOTSRC) Bootloader.hex
And DOS has issues with doing rm and rmdir without writing on stderr.
I have implemented dir exist
( [ -d folder ]
on cygwin/*nix) as a super short python script, but prefer to not mix python into it if I can avoid it.
import os
import sys
for arg in sys.argv[1:]:
if not os.path.isdir(arg):
sys.exit(1)
sys.exit()
It seems CMake was developed partly for this issue: Makefile for DOS/Windows and Cygwin
But I would prefer not to have to switch to CMake.
Can you help me find elegant solutions for the four file operations?