AC-BuildPlatform (empty) → 1.0.0
raw patch · 5 files changed
+308/−0 lines, 5 filesdep +basebuild-type:Customsetup-changed
Dependencies added: base
Files
- AC-BuildPlatform.cabal +43/−0
- License.txt +30/−0
- ReadMe.xhtml +74/−0
- Setup.hs +87/−0
- System/Platform.hs +74/−0
+ AC-BuildPlatform.cabal view
@@ -0,0 +1,43 @@+Cabal-version: >=1.6 +Name: AC-BuildPlatform +Version: 1.0.0 +Synopsis: Detect which OS you're running on. +Description: + + This package lets you easily query various facts about the system + that your code is running on. Currently, it reports whether the + operating system is \"Windows\" or \"Unix\", and also the name and + version of the Haskell compiler used. + . + This package implements lots of complicated trickery to determine + the build environment. Once built, other packages can query this + information without needing to do complex trickery themselves. + . + Design assumptions: + . + * You are using GHC, version 6.8.1 or newer. + . + * You build this package using the Cabal-install tool. (Just doing + @runhaskell Setup@ won't work properly.) + . + If these conditions are not met, the package should still /build/, + it's just that all the compile-time constants will come back as + 'Nothing'. + . + See also the included @ReadMe.xhtml@ file. + +License: BSD3 +License-file: License.txt +Author: Andrew Coppin +Maintainer: MathematicalOrchid@hotmail.com +Category: System +Build-type: Custom +Extra-tmp-files: Include/Platform.h +Extra-source-files: ReadMe.xhtml + +Library + Exposed-modules: + System.Platform + Build-depends: + base == 4.* + Include-dirs: Include
+ License.txt view
@@ -0,0 +1,30 @@+Copyright (c)2011, Andrew Coppin + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of Andrew Coppin nor the names of other + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ReadMe.xhtml view
@@ -0,0 +1,74 @@+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>AC-BuildPlatform v1.0.0: Read Me</title> + <style type="text/css"> + body {background-color: rgb(80%, 100%, 80%); font-family: Georgia, Times, serif;} + </style> +</head> +<body> + +<h1>Package <code>AC-BuildPlatform</code> version 1.0.0: Read me</h1> + +<h2>Cleaning</h2> +<p> +Due to <a href="http://hackage.haskell.org/trac/hackage/ticket/303">Cabal bug #303</a>, under Windows you can't do “<code>cabal clean</code>”. In this instance, please use “<code>runhaskell Setup clean</code>” instead. +</p> +<p> +(Apparently Unix has some weird mis-feature whereby deleting a running executable file is not an error. Apparently cabal-install relies on this flaw. Obviously this means that on operating systems that actually support the concept of file locking, it doesn't work. In fairness, it's not obvious how to solve this little problem.) +</p> + +<h2>Design assumptions</h2> +<ol> + <li>Any platform that isn't Windows is Unix. (This should be clear from the package description.)</li> + <li>The <code>{-# LANGUAGE CPP #-}</code> pragma works. (If not, you'll likely get random syntax errors.)</li> +</ol> + +<h2>Platform detection</h2> +<p> +This package allows you to query at run-time what operating system and compiler are in use. This information is not easy to discover — hence why this package exists in the first place. The package runs some custom code during the “configure” stage. This code attempts to detect what platform it's running under. Note that the script <em>prints out</em> the values detected, so you don't have to actually build and install the package just to find out if platform detection is working right. +</p> +<p> +The platform detection code makes a number of assumptions, which are documented here. From the Haddock documentation, you can see that all the queries provided by this package return <code>Maybe</code> something. If part of the detection algorithm fails, the corresponding value is just reported as <code>Nothing</code> rather than a value. The package should <em>build</em> under all circumstances; it's just that you will only get useful information if the assumptions below are respected. +</p> + +<h2>Platform detection assumptions</h2> +<p> +The platform detection logic makes a number of assumptions. The first two are the only ones that most users need to worry about. +</p> +<ol> + <li> + <p><b>You configure the package using “<code>cabal configure</code>”, not “<code>runhaskell Setup configure</code>”.</b></p> + <p>If this is not the case, no information is detected.</p> + </li> + <li> + <p><b>Your compiler is GHC, version 6.8.1 or newer.</b></p> + <p>If this is not the case, most likely no information will be detected.</p> + <p>I realise that being able to query the compiler is a bit pointless when only one possible compiler is supported. Note though that if the compiler is <em>not</em> GHC, it will <em>not</em> be reported as GHC. So there is some small information content there.</p> + </li> + <li> + <p><b>The cabal-install tool compiles <code>Setup.hs</code> before running it.</b></p> + <p>(And, additionally, stores it in <code>./dist/setup/Setup[.exe]</code>. And, additionally, runs it with the package root folder as the current working folder.)</p> + <p>In theory, the path might change in future, breaking the detection code.</p> + </li> + <li> + <p><b>The compiler used for configuring is the same as the one used for building.</b></p> + <p>As far as I know, Cabal does not allow you to violate this assumption. But if you did, the detected information would refer to the compiler used for configuring and not the one used for building.</p> + </li> + <li> + <p><b>The GHC “<code>+RTS --info</code>” option is available.</b></p> + <p>This option was added in GHC 6.8.1; older versions do not support it. Additionally, as of GHC 7.0.1, most RTS options are disabled by default (but <em>not</em> this one). If in future this option is disabled as well, detection will break.</p> + <p>As far as I know, no other compilers support this option. But if they did, the existing detection logic is intended to respond gracefully. The detection script looks for only two keys: “<code>GHC version</code>” and “<code>Target platform</code>”. The latter might plausibly be available from other implementations, in which case OS detection would work.</p> + </li> + <li> + <p><b>GHC for Windows uses MinGW.</b></p> + <p>This has always been the case in the past, but it could potentially change in future. (Here's to hoping, anyway!)</p> + <p>Of course, the detection logic doesn't <em>really</em> care whether MinGW is in use or not. It only cares whether the target platform is reported as “<code>mingw32</code>”. If yes, it assumes the platform is <code>MS_Windows</code>. For <em>any other value</em> it assumes <code>Unix</code>. So if some day GHC actually reports Windows as being “<code>Windows</code>”, the detection logic will need updating.</p> + </li> +</ol> +<p> +In summary: The detection algorithm depends on precise details of GHC, the GHC RTS, the Cabal library, and the cabal-install tool. If any of these tools change in particularly unusual ways in the future, the detection code might break. +</p> + +</body> +</html>
+ Setup.hs view
@@ -0,0 +1,87 @@+module Main where + +import Prelude hiding (catch) +import Distribution.Simple +import Control.Exception (catch, IOException) +import System.IO +import System.Directory +import System.Process +import System.Exit (ExitCode (..)) + +main = defaultMainWithHooks hooks + +hooks = simpleUserHooks {postConf = gather} + +gather args cfg pkg bld = do + putStrLn "-| Gathering platform data..." + + putStrLn "---| Attempting to invoke Setup.hs compiled program..." + let cmd0 = proc "./dist/setup/setup" ["+RTS", "--info"] + let cmd1 = cmd0 {std_out = CreatePipe} + + catch + (do + (Nothing, Just hout, Nothing, pid) <- createProcess cmd1 + txt <- hGetContents hout + exit <- waitForProcess pid + + case exit of + ExitFailure n -> do + putStrLn $ "---| Compiled Setup.hs program failed with return code " ++ show n + save Nothing Nothing Nothing + ExitSuccess -> do + (os, cn, cv) <- parse txt + save os cn cv + ) + (\ e -> do + let f = e `asTypeOf` (undefined :: IOException) + putStrLn "---| Could not run." + save Nothing Nothing Nothing + ) + +parse :: String -> IO (Maybe String, Maybe String, Maybe String) +parse txt = do + putStrLn "---| OK. Parsing program result..." + case txt of + "" -> do + putStrLn "---| Empty result." + return (Nothing, Nothing, Nothing) + _ -> + case readsPrec 0 txt of + [] -> do + putStrLn "---| Parser error." + return (Nothing, Nothing, Nothing) + (info, _):_ -> + let + os = + case lookup "Target OS" info of + Nothing -> Nothing + Just "mingw32" -> Just "MS_Windows" + Just _ -> Just "Unix" + (name, ver) = + case lookup "GHC version" info of + Nothing -> (Nothing , Nothing) + Just v -> (Just "GHC", Just v ) + in return (os, name, ver) + +save :: Maybe String -> Maybe String -> Maybe String -> IO () +save os cn cv = do + putStrLn $ "-----| Operating System = " ++ show os + putStrLn $ "-----| Compiler name = " ++ show cn + putStrLn $ "-----| Compiler version = " ++ show cv + + x <- doesDirectoryExist "Include" + if x + then return () + else do + putStrLn "-| Create Include folder..." + createDirectory "Include" + + putStrLn $ "-| Saving results..." + writeFile "Include/Platform.h" $ unlines $ + [ + "#define HS_PNAME " ++ (case os of Nothing -> "Nothing"; Just t -> "Just " ++ t), + "#define HS_CNAME " ++ show cn, + "#define HS_CVERS " ++ show cv + ] + putStrLn $ "-| Done."
+ System/Platform.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE CPP #-} + +{- | + Query basic properties of the current platform. + + All of these values are compile-time constants. If the special + magic in the package configure step was unable to determine the + correct value for something, it comes back as 'Nothing'. +-} + +module System.Platform + ( + -- * Operating system + OS_Type (..), os_type, + + -- * Compiler + compiler_name, compiler_version, + + -- * Local values + -- $local + ) + where + +#include "Platform.h" + +#ifndef HS_PNAME +#define HS_PNAME Nothing +#endif + +#ifndef HS_CNAME +#define HS_CNAME Nothing +#endif + +#ifndef HS_CVERS +#define HS_CVERS Nothing +#endif + +-- | A list of all possible operating system types. +data OS_Type = + -- | Some version of Microsoft Windows. + MS_Windows | + -- | Any sufficiently \"Unix-like\" system. + Unix + deriving (Eq, Show) + +{- | + The type of operating system under which we are running (or + 'Nothing' if this could not be detected). +-} +os_type :: Maybe OS_Type +os_type = HS_PNAME + +{- | + The name of the compiler (e.g., @\"GHC\"@), or 'Nothing' if + this could not be detected. +-} +compiler_name :: Maybe String +compiler_name = HS_CNAME + +{- | + The numerical version string for the compiler + (e.g., @\"6.10.2\"@), or 'Nothing' if this could not be detected. +-} +compiler_version :: Maybe String +compiler_version = HS_CVERS + +{- $local + Your local copy of this package was configured with the following + settings: + + > os_type = HS_PNAME + > compiler_name = HS_CNAME + > compiler_version = HS_CVERS +-}