Makefile for Windows和Cygwin
我需要在Windows和Cygwin下使用makefile
。 我遇到makefile正确检测OS并设置适当变量的问题。
目标是为以下命令设置变量,然后使用变量调用规则中的命令:
- 删除文件:在Cygwin中的
rm
,在Windows中的del
。 - 删除目录:
rmdir
(Cygwin和Windows中的不同参数) - 复制文件:Cygwin中的
cp
,在Windows中copy
。 - 测试文件存在:在Cygwin中
test
,在Windows中test
IF EXIST
。 - 列出文件的内容:在Cygwin中
type
cat
,在Windows中输入。
这是我的尝试,它始终使用else
子句:
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
我正在使用正斜杠字符’/’作为目录分隔符。 这是Windows命令的问题,因为它将其解释为程序参数而不是分隔符。 有谁知道如何解决这个问题?
我在Windows控制台和Cygwin中使用make与Mingw。
Matt B.建议的CMake是这个问题的正确答案之一。 其他正确的答案是SCons , Jam和Bakefile 。
由于您使用的是Cygwin, Autoconf + Automake还为您提供了解决问题的工具。 不过,它更像是一个解决问题的工具包,而不是开箱即用的解决方案。
最重要的一点是提升一层抽象,这样你就可以只从一个来源支持大量的构建系统。
我强烈建议您转到CMake自动生成Makefile。 这些问题都已解决,它支持MingW,MSYS和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 ) 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])
如果要生成MinGW Makefile,则所有路径都会自动转换为DOS样式。 这是一件美好的事情。
而且,最后,它使Makefile的其余部分也变得更加简单。
准确地检测构建平台是棘手的部分。 我就是这样做的。
ifeq '$(findstring ;,$(PATH))' ';' UNAME := Windows else UNAME := $(shell uname 2>/dev/null || echo Unknown) UNAME := $(patsubst CYGWIN%,Cygwin,$(UNAME)) # CYGWIN_NT-10.0 -> Cygwin endif
UNAME变量设置为Linux,Cygwin,Windows,FreeBSD,NetBSD(或者可能是Solaris,Darwin,OpenBSD,AIX,HP-UX)或Unknown。 然后可以在Makefile的其余部分中对其进行比较,以分离任何对操作系统敏感的变量和命令。
我在另一个post中进一步讨论