相关文章推荐

区分Windows和类Unix系统的Makefile

55 人关注

我希望有相同的Makefile用于在Linux和Windows上构建。我使用默认的 GNU make 在Linux上和 mingw32-make (还 GNU make ) on Windows.

我想让Makefile检测到它是在Windows还是Linux上操作。

例如,Windows上的 make clean 命令看起来像。

clean:
    del $(DESTDIR_TARGET)

But on Linux:

clean:
    rm $(DESTDIR_TARGET)

我还想在Windows(\)和Linux(/)上使用不同的目录分隔符。

是否可以在Makefile中检测到Windows操作系统?

PS: 我不希望在Windows上模拟Linux(cygwin等)。

有一个类似的问题。操作系统检测makefile,但我在这里没有找到答案。

5 个评论
Ency
Windows能够处理斜线"/"和"/"都是等同的。
如果这是一个实质性的项目,我想知道是否值得让autotools处理一些便携性的东西?
@Jefromi: autotools假设有一个基本的UNIX工具集(sh, m4, sed, rm, ...)。 @tomp:还不如把它们安装在windows上(从MSYS或GnuWin),把你的精力花在更具挑战性的可移植性问题上。
@ephemient:啊,对,我的错。我不是一个真正的windows人。(但现在我很困惑--mingw工具链不也可以提供吗?我知道,OP说没有Linux仿真)。
@Ency,Windows上的 "del "命令不喜欢被赋予"/"。
linux
windows
makefile
os-detection
Tom Pažourek
Tom Pažourek
发布于 2010-10-30
5 个回答
Paul Hutchinson
Paul Hutchinson
发布于 2010-10-30
已采纳
0 人赞同

我通过寻找一个只在windows上设置的环境变量解决了这个问题。

ifdef OS
   RM = del /Q
   FixPath = $(subst /,\,$1)
   ifeq ($(shell uname), Linux)
      RM = rm -f
      FixPath = $1
   endif
endif
clean:
    $(RM) $(call FixPath,objs/*)

因为%OS%是windows的类型,它应该在所有的Windows电脑上设置,但在Linux上不应该设置。

然后,这些块为不同的程序设置了变量,以及将正斜线转换为反斜线的函数。

当你调用外部命令时,你必须使用$(call FixPath,path)(内部命令可以正常工作)。 你也可以使用类似的方法。

/ := /
objs$(/)*

如果你更喜欢这种格式。

谢谢你的帮助。我在Windows上的MinGW和Linux上的GCC之间切换,这很好用。
在Mingw中,它应该是 SYSTEMROOT 的大写字母。
kebs
你也可以检查ComSpec,这只在Windows上定义。
如果你因为某些原因运行COMMAND.COM,你也应该检查大写的SYSTEMROOT。"SystemRoot "不会被定义为大写字母(而在CMD.EXE中会)。
更新了例子以使用SYSTEMROOT的大写版本
tomsgd
tomsgd
发布于 2010-10-30
0 人赞同

The SystemRoot trick didn't work for me on Windows XP but this did:

ifeq ($(OS),Windows_NT)
    #Windows stuff
    #Linux stuff
endif
    
sagi
如果你安装了cygwin,并且make可执行文件来自cygwin,这可能很棘手。你会得到OS=Windows_NT,但你可以使用Linux命令,如mkdir -p。目录分隔符的方向也很重要
Antoine Pelisse
Antoine Pelisse
发布于 2010-10-30
0 人赞同

你可能应该使用$(RM)变量来删除一些文件。

sezero
sezero
发布于 2010-10-30
0 人赞同

检查WINDIR或COMSPEC是区分大小写的。 相反,我想出了 的解决方案,希望有一天能帮助到别人。

# detect if running under unix by finding 'rm' in $PATH :
ifeq ($(wildcard $(addsuffix /rm,$(subst :, ,$(PATH)))),)
WINMODE=1
WINMODE=0
endif
ifeq ($(WINMODE),1)
# native windows setup :
UNLINK = del $(subst /,\,$(1))
CAT = type $(subst /,\,$(1))
# cross-compile setup :
UNLINK = $(RM) $(1)
CAT = cat $(1)
endif
    
Mads Elvheim
发布于 2010-10-30
0 人赞同
 
推荐文章