Haskell:检测当前的操作系统

Mat*_*hid 13 haskell

我正在编写一个Haskell包.我希望它在Windows和Unix上表现不同.什么是最"正确"的方法来检测正在编译我的代码的OS?

我确实尝试过使用CPP #ifdef _WIN32,但这似乎根本不起作用.

还有另一个宏吗?我可以让Cabal告诉我吗?我需要完全尝试别的吗?

Lee*_*hem 32

你可以使用System.Info:

> :m + System.Info
> [os, arch]
["darwin","i386"]
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这个,因为它只是简单普通的Haskell代码,它看着普通的普通常量.太好了! (3认同)

Mik*_*kov 16

引用GHC手册:

GHC定义的符号如下所列.

[...]

os_HOST_OS=1- 此定义允许基于操作系统的条件编译,其中os是当前操作系统的名称(例如linux,mingw32对于Windows solaris,等).

因此,要检测您的代码是否在Windows上编译,您应该使用

#ifdef mingw32_HOST_OS
Run Code Online (Sandbox Code Playgroud)

显然,您需要启用CPP才能工作.

对于那些想知道的人 - mingw32_HOST_OS也是在64位Windows上定义的:

C:\ghc-7.8.2\bin>ghc --info
...
,("Build platform","x86_64-unknown-mingw32")
,("Host platform","x86_64-unknown-mingw32")
,("Target platform","x86_64-unknown-mingw32")
...

C:\ghc-7.8.2\bin>ghc -E -optP-dM -cpp foo.hs

C:\ghc-7.8.2\bin>cat foo.hspp
{-# LINE 1 "foo.hs" #-}
#define __ASSEMBLER__ 1
#define mingw32_HOST_OS 1    
#define __GLASGOW_HASKELL__ 708    
#define __STDC_HOSTED__ 1    
#define TABLES_NEXT_TO_CODE 1    
#define x86_64_HOST_ARCH 1    
#define x86_64_BUILD_ARCH 1    
#define mingw32_BUILD_OS 1    
#define __SSE2__ 1    
#define __SSE__ 1
Run Code Online (Sandbox Code Playgroud)

令人困惑的mingw64_HOST_OS是,不是 - 用于x86_64_HOST_ARCH专门检测64位Windows.

  • 你对"明确的MinGW"是什么意思?正如手册所说,你也可以使用`linux_HOST_OS`,`solaris_HOST_OS`等. (2认同)

cut*_*lus 6

Cabal 的 Distribution.System 模块具有OS 数据类型Arch 数据类型,因此您可以针对命名构造函数而不是字符串数据进行模式匹配。

例如,您可以使用buildOS

case buildOS of
  Windows -> -- do something
  _ -> -- do something else
Run Code Online (Sandbox Code Playgroud)


Mat*_*hid 5

这些都是很好的答案。为了完整起见,Cabal似乎对此也有一个迷惑:

http://www.haskell.org/ghc/docs/7.0.3/html/Cabal/authors.html#conditions

尤其令人遗憾的是,“ Windows”被标识为“ mingw32”。我不想考虑如果我去安装64位GHC会发生什么!(那会是“ mingw64”吗?)如果有一天用其他编译器构建GHC会怎样?或者,我们敢于梦想,存在不是GHC的Haskell编译器?(好吧,这听起来有些牵强,但是有可能发生……)

Cabal似乎具有特殊情况的逻辑来处理此问题,因此os(windows)应该一直有效。在我看来,如果让Cabal进行这项工作,那么如果将来发生“野生物”,那么将Cabal的工作归类于此,而不是属于我。

  • 在64位Windows上也定义了“ mingw32_HOST_OS”。看到我更新的答案。 (3认同)