Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/haskell-ci-windows-macos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Haskell-CI-Windows-Macos
on:
push:
pull_request:
branches:
- "main"
jobs:
Build:
name: Haskell-CI - ${{ matrix.os }} - ghc-${{ matrix.ghc }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-latest, macos-latest]
cabal: ["3.16.1.0"]
ghc: ["9.12.4", "9.14.1"]
timeout-minutes:
60

steps:
- uses: actions/checkout@v4
- uses: haskell-actions/setup@v2
id: setup-haskell-cabal
name: Setup Haskell
with:
ghc-version: ${{ matrix.ghc }}
cabal-version: ${{ matrix.cabal }}

- name: Configure
run: cabal configure --enable-tests --enable-benchmarks --test-show-details=direct

- name: Freeze
run: cabal freeze

- uses: actions/cache@v6
name: Cache ~/.cabal/store
with:
path: ${{ steps.setup-haskell-cabal.outputs.cabal-store }}
key: ${{ runner.os }}-${{ matrix.ghc }}-${{ hashFiles('cabal.project.freeze') }}

- name: Install dependencies
run: cabal build all --only-dependencies

- name: Build
run: cabal build all

- name: Test
run: cabal test all
133 changes: 1 addition & 132 deletions Setup.hs
Original file line number Diff line number Diff line change
@@ -1,133 +1,2 @@
{-# LANGUAGE CPP #-}
import Control.Monad
import Distribution.Simple
import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.Setup
import Distribution.PackageDescription
import Distribution.Simple.Utils
import Distribution.Simple.Program
import Distribution.Verbosity
import System.Process
import System.Directory
import System.FilePath
import System.Exit
import System.IO

main = defaultMainWithHooks hk
where
hk = simpleUserHooks { buildHook = \pd lbi uh bf -> do
-- let ccProg = Program "gcc" undefined undefined undefined
let mConf = lookupProgram ghcProgram (withPrograms lbi)
err = error "Could not determine C compiler"
cc = locationPath . programLocation . maybe err id $ mConf
lbiNew <- checkRDRAND cc lbi >>= checkGetrandom cc >>= checkGetentropy cc
buildHook simpleUserHooks pd lbiNew uh bf
}

compileCheck :: FilePath -> String -> String -> String -> IO Bool
compileCheck cc testName message sourceCode = do
withTempDirectory normal "" testName $ \tmpDir -> do
writeFile (tmpDir ++ "/" ++ testName ++ ".c") sourceCode
ec <- myRawSystemExitCode normal cc [tmpDir </> testName ++ ".c", "-o", tmpDir ++ "/a","-no-hs-main"]
notice normal $ message ++ show (ec == ExitSuccess)
return (ec == ExitSuccess)

addOptions :: [String] -> [String] -> LocalBuildInfo -> LocalBuildInfo
addOptions cArgs hsArgs lbi = lbi {withPrograms = newWithPrograms }
where newWithPrograms1 = userSpecifyArgs "gcc" cArgs (withPrograms lbi)
newWithPrograms = userSpecifyArgs "ghc" (hsArgs ++ map ("-optc" ++) cArgs) newWithPrograms1

checkRDRAND :: FilePath -> LocalBuildInfo -> IO LocalBuildInfo
checkRDRAND cc lbi = do
b <- compileCheck cc "testRDRAND" "Result of RDRAND Test: "
(unlines [ "#include <stdint.h>"
, "int main() {"
, " uint64_t therand;"
, " unsigned char err;"
, " asm volatile(\"rdrand %0 ; setc %1\""
, " : \"=r\" (therand), \"=qm\" (err));"
, " return (!err);"
, "}"
])
return $ if b then addOptions cArgs cArgs lbi else lbi
where cArgs = ["-DHAVE_RDRAND"]

checkGetrandom :: FilePath -> LocalBuildInfo -> IO LocalBuildInfo
checkGetrandom cc lbi = do
libcGetrandom <- compileCheck cc "testLibcGetrandom" "Result of libc getrandom() Test: "
(unlines [ "#define _GNU_SOURCE"
, "#include <errno.h>"
, "#include <sys/random.h>"

, "int main()"
, "{"
, " char tmp;"
, " return getrandom(&tmp, sizeof(tmp), GRND_NONBLOCK) != -1;"
, "}"
])
if libcGetrandom then return $ addOptions cArgsLibc cArgsLibc lbi
else do
syscallGetrandom <- compileCheck cc "testSyscallGetrandom" "Result of syscall getrandom() Test: "
(unlines [ "#define _GNU_SOURCE"
, "#include <errno.h>"
, "#include <unistd.h>"
, "#include <sys/syscall.h>"
, "#include <sys/types.h>"
, "#include <linux/random.h>"

, "static ssize_t getrandom(void* buf, size_t buflen, unsigned int flags)"
, "{"
, " return syscall(SYS_getrandom, buf, buflen, flags);"
, "}"

, "int main()"
, "{"
, " char tmp;"
, " return getrandom(&tmp, sizeof(tmp), GRND_NONBLOCK) != -1;"
, "}"
])
return $ if syscallGetrandom then addOptions cArgs cArgs lbi else lbi
where cArgs = ["-DHAVE_GETRANDOM"]
cArgsLibc = cArgs ++ ["-DHAVE_LIBC_GETRANDOM"]

checkGetentropy :: FilePath -> LocalBuildInfo -> IO LocalBuildInfo
checkGetentropy cc lbi = do
b <- compileCheck cc "testGetentropy" "Result of getentropy() Test: "
(unlines [ "#define _GNU_SOURCE"
, "#include <unistd.h>"

, "int main()"
, "{"
, " char tmp;"
, " return getentropy(&tmp, sizeof(tmp));"
, "}"
])
return $ if b then addOptions cArgs cArgs lbi else lbi
where cArgs = ["-DHAVE_GETENTROPY"]

myRawSystemExitCode :: Verbosity -> FilePath -> [String] -> IO ExitCode
#if MIN_VERSION_Cabal(3,14,0)
myRawSystemExitCode verbosity program arguments =
rawSystemExitCode verbosity Nothing program arguments Nothing
#elif __GLASGOW_HASKELL__ >= 704
-- We know for sure, that if GHC >= 7.4 implies Cabal >= 1.14
myRawSystemExitCode = rawSystemExitCode
#else
-- Legacy branch:
-- We implement our own 'rawSystemExitCode', this will even work if
-- the user happens to have Cabal >= 1.14 installed with GHC 7.0 or
-- 7.2
myRawSystemExitCode verbosity path args = do
printRawCommandAndArgs verbosity path args
hFlush stdout
exitcode <- rawSystem path args
unless (exitcode == ExitSuccess) $ do
debug verbosity $ path ++ " returned " ++ show exitcode
return exitcode
where
printRawCommandAndArgs :: Verbosity -> FilePath -> [String] -> IO ()
printRawCommandAndArgs verbosity path args
| verbosity >= deafening = print (path, args)
| verbosity >= verbose = putStrLn $ unwords (path : args)
| otherwise = return ()
#endif
main = defaultMainWithHooks autoconfUserHooks
2 changes: 2 additions & 0 deletions System/Entropy.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ module System.Entropy
closeHandle
) where

#include "config.h"

#ifdef ghcjs_HOST_OS
import System.EntropyGhcjs
#elif defined(isWindows)
Expand Down
2 changes: 2 additions & 0 deletions System/EntropyNix.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import Foreign.C.Error
import Foreign.C.Types
import Data.ByteString.Internal as B

#include "config.h"

#ifdef arch_i386
-- See .cabal wrt GCC 4.8.2 asm compilation bug
#undef HAVE_RDRAND
Expand Down
2 changes: 2 additions & 0 deletions System/EntropyWindows.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import Foreign.Marshal.Alloc (alloca)
import Foreign.Marshal.Utils (toBool)
import Foreign.Storable (peek)

#include "config.h"

-- C example for windows rng - taken from a blog, can't recall which one but thank you!
-- #include <Windows.h>
-- #include <Wincrypt.h>
Expand Down
120 changes: 120 additions & 0 deletions cbits/config.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/* cbits/config.h.in. Generated from configure.ac by autoheader. */

/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H

/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H

/* Define if the function getentropy exists. */
#undef HAVE_GETENTROPY

/* Define if getrandom either from libc / via linux syscalls is available. */
#undef HAVE_GETRANDOM

/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H

/* Define if getrandom from sys/random.h exists. */
#undef HAVE_LIBC_GETRANDOM

/* Define to 1 if you have the <linux/random.h> header file. */
#undef HAVE_LINUX_RANDOM_H

/* Define to 1 if you have the <linux/types.h> header file. */
#undef HAVE_LINUX_TYPES_H

/* Define if the assembly instruction rdrand exists. */
#undef HAVE_RDRAND

/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H

/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H

/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H

/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H

/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H

/* Define to 1 if you have the <sys/random.h> header file. */
#undef HAVE_SYS_RANDOM_H

/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H

/* Define to 1 if you have the <sys/syscall.h> header file. */
#undef HAVE_SYS_SYSCALL_H

/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H

/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H

/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT

/* Define to the full name of this package. */
#undef PACKAGE_NAME

/* Define to the full name and version of this package. */
#undef PACKAGE_STRING

/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME

/* Define to the home page for this package. */
#undef PACKAGE_URL

/* Define to the version of this package. */
#undef PACKAGE_VERSION

/* Define to 1 if all of the C89 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#undef STDC_HEADERS

/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
#undef _UINT32_T

/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
#undef _UINT64_T

/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
#define below would cause a syntax error. */
#undef _UINT8_T

/* Define to '__inline__' or '__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif

/* Define as 'unsigned int' if <stddef.h> doesn't define. */
#undef size_t

/* Define as 'int' if <sys/types.h> doesn't define. */
#undef ssize_t

/* Define to the type of an unsigned integer type of width exactly 32 bits if
such a type exists and the standard includes do not define it. */
#undef uint32_t

/* Define to the type of an unsigned integer type of width exactly 64 bits if
such a type exists and the standard includes do not define it. */
#undef uint64_t

/* Define to the type of an unsigned integer type of width exactly 8 bits if
such a type exists and the standard includes do not define it. */
#undef uint8_t
1 change: 1 addition & 0 deletions cbits/getrandom.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "config.h"
#ifdef HAVE_GETRANDOM

#define _GNU_SOURCE
Expand Down
6 changes: 6 additions & 0 deletions cbits/random_initialized.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
#include "config.h"
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <sys/stat.h>
#include <unistd.h>

// on macos, getentropy is in sys/random.h
#ifdef HAVE_SYS_RANDOM_H
# include <sys/random.h>
#endif

#ifdef HAVE_GETENTROPY
#ifndef DO_NOT_USE_GET_ENTROPY
static int ensure_pool_initialized_getentropy()
Expand Down
1 change: 1 addition & 0 deletions cbits/rdrand.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "config.h"
#ifdef HAVE_RDRAND

#include <stdint.h>
Expand Down
1 change: 1 addition & 0 deletions cbits/rdrand.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#ifndef rdrand_h
#include "config.h"
#ifdef HAVE_RDRAND
#include <stdint.h>

Expand Down
Loading