我正在编写一个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)
Mik*_*kov 16
引用GHC手册:
GHC定义的符号如下所列.
[...]
os_HOST_OS=1- 此定义允许基于操作系统的条件编译,其中os是当前操作系统的名称(例如linux,mingw32对于Windowssolaris,等).
因此,要检测您的代码是否在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.
Cabal 的 Distribution.System 模块具有OS 数据类型和Arch 数据类型,因此您可以针对命名构造函数而不是字符串数据进行模式匹配。
例如,您可以使用buildOS:
case buildOS of
Windows -> -- do something
_ -> -- do something else
Run Code Online (Sandbox Code Playgroud)
这些都是很好的答案。为了完整起见,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的工作归类于此,而不是属于我。