代码之家  ›  专栏  ›  技术社区  ›  Thomas Matthews

为Windows和Cygwin生成文件

  •  2
  • Thomas Matthews  · 技术社区  · 14 年前

    我需要一个 makefile 在窗户和Cygwin下工作。我在makefile正确检测操作系统和设置适当的变量方面遇到了问题。

    目标是为以下命令设置变量,然后使用变量调用规则中的命令:

    • 删除文件: rm 在CygWin, del 在Windows中。
    • 删除目录: rmdir (不同) cygwin和windows中的参数)
    • 复制文件: cp 在CygWin, copy 在里面 窗户。
    • 文件存在测试: test 在CygWin, IF EXIST 在Windows中。
    • 列出文件内容: cat 在里面 CygWin type 在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中都使用makewithming。

    3 回复  |  直到 6 年前
        1
  •  1
  •   Warren Young    10 年前

    CMake 由MattB提出,是这个问题的正确答案之一。其他正确答案是 SCons , Jam Bakefile .

    既然你用的是Cygwin, Autoconf + Automake 还提供了解决问题的工具。不过,它更像是解决问题的工具包,而不是开箱即用的解决方案。

    首要的一点是向上移动一个抽象层,这样您就可以只从一个源支持许多构建系统。

        2
  •  3
  •   mbauman    14 年前

    我强烈建议你搬到 CMake 自动生成生成生成文件。这些问题都得到了解决,它支持明威、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 <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])
    

    如果生成mingw生成文件,则所有路径都将自动转换为DOS样式。这是一件美丽的事情。

    最后,它也使makefile的其余部分变得更简单。

        3
  •  0
  •   Ken Jackson    6 年前

    准确地检测构建平台是一个棘手的部分。我就是这样做的。

    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的其余部分进行比较,以分离任何操作系统敏感的变量和命令。

    我进一步讨论这个问题 another thread