views:

305

answers:

2

I need to have a makefile work under DOS (Windows) and Cygwin. I having problems with the makefile detecting the OS correctly and setting appropriate variables.

The objective is to set variables for the following commands, then invoke the commands in rules using the variables:

  • Delete file: rm in Cygwin, del in DOS.
  • Remove directory: rmdir (different parameters in Cygwin and DOS)
  • Copy file: cp in Cygwin, copy in DOS.
  • Testing for file existance: test in Cygwin, IF EXIST in DOS.
  • Listing contents of a file: cat in Cygwin, type in DOS.

Here is my attempt, which always uses the else clause:

OS_KIND = $(OSTYPE) #OSTYPE is an environment variable set by Cygwin.
ifeq ($(OS_KIND), cygwin)
 ENV_OS = Cygwin
 RM = rm -f
 RMDIR = rmdir -r
 CP = cp
 REN = mv
 IF_EXIST = test -a
 IF_NOT_EXIST = ! test -a
 LIST_FILE = cat
else
 ENV_OS = Win_Cmd
 RM = del -f -Q
 RMDIR = rmdir /S /Q
 IF_EXIST = if exist
 IF_NOT_EXIST = if not exist
 LIST_FILE = type
endif

I'm using the forward slash character, '/', as a directory separator. This is a problem with the DOS command, as it is interpreting it as program argument rather than a separator. Anybody know how to resolve this issue?

Edit: I am using make with Mingw in both Windows Console (DOS) and Cygwin.

+2  A: 

I highly recommend you move to CMake to automatically generate your Makefiles. These problems have all been solved, and it supports MingW, MSYS and Cygwin.

RM:           file(REMOVE [file1 ...])
RMDIR:        file(REMOVE_RECURSE [file1 ...]) # (not quite the same functionality; deletes files, too)
CP:           file(COPY files... DESTINATION...)
REN:          file(RENAME <oldname> <newname>)
IF_EXIST:     if(EXISTS file-name)
IF_NOT_EXIST: if(NOT EXISTS file-name)
LIST_FILE:    file(READ filename variable [LIMIT numBytes] [OFFSET offset] [HEX])

All your paths are automagically converted to DOS-style if you are generating MinGW Makefiles. It's a beautiful thing.

And, finally, it makes the rest of your Makefile stuff much simpler, too.

Matt B.
A: 

CMake, suggested by Matt B., is one of the right answers to this question. Other right answers are Bakefile and SCons.

The overarching point is to move up a layer of abstraction so you can support lots of build systems from only a single source.

Warren Young
The company is using makefiles. Is there any way to do what I want using a makefile? I don't know if I can convince the company to use Bakefile or CMake.
Thomas Matthews
If you can't convince the company to add a layer of abstraction to solve a real problem, you're in bigger trouble than you may know. Hacking a problem in place instead of moving to a higher level where both problems become one problem that's easier to solve is well established software development practice. A company that ignores this principle is like to end up with a teetering pile of technology that falls over frequently.
Warren Young