Skip to content

Commit dac126c

Browse files
committed
Merge branch 'stable'
2 parents bcc0bd8 + 2e0c04a commit dac126c

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

doc/GUIDE.md

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,103 @@ modified version of a dependency that hasn't yet been released upstream.
10911091
See [stack.yaml documentation](yaml_configuration.md#packages) for more
10921092
details.
10931093

1094+
## Haskell packages with C code
1095+
1096+
A Haskell package can include C source code. For example, consider a simple
1097+
one-package project named `c-example`, created by `stack new c-example` but with
1098+
these changes:
1099+
1100+
A C header file `my-library.h` added in new directory `include`:
1101+
~~~c
1102+
#ifndef MY_LIBRARY_HEADER
1103+
#define MY_LIBRARY_HEADER
1104+
int max(int, int);
1105+
#endif
1106+
~~~
1107+
1108+
A C source code file `my-library.c` added in new directory `c-source`:
1109+
~~~c
1110+
#include "my-library.h"
1111+
1112+
/* Function returning the larger of two integers */
1113+
int max(int x1, int x2) {
1114+
if (x1 > x2)
1115+
return x1;
1116+
else
1117+
return x2;
1118+
}
1119+
~~~
1120+
1121+
A different `src/Lib.hs` Haskell module, including a Haskell foreign import
1122+
declaration making use of the C `max` function:
1123+
~~~haskell
1124+
module Lib
1125+
( someFunc
1126+
, c_max
1127+
) where
1128+
1129+
someFunc :: IO ()
1130+
someFunc = putStrLn "someFunc"
1131+
1132+
foreign import ccall "max" c_max :: Int -> Int -> Int
1133+
~~~
1134+
1135+
A different `app/Main.hs` Haskell module, making use of the Haskell `c_max`
1136+
function now exported from module `Lib`:
1137+
~~~haskell
1138+
module Main ( main ) where
1139+
1140+
import Lib ( c_max, someFunc )
1141+
1142+
main :: IO ()
1143+
main = do
1144+
someFunc
1145+
print $ c_max 10 100
1146+
~~~
1147+
1148+
The package's `package.yaml` file (simplied), used to create the package's
1149+
Cabal file, might look like this:
1150+
~~~yaml
1151+
spec-version: 0.36.0
1152+
1153+
name: c-example
1154+
version: 0.1.0.0
1155+
1156+
# Hpack 0.36.1 and earlier does not support Cabal's 'includes' field
1157+
extra-source-files:
1158+
- include/my-library.h
1159+
1160+
dependencies:
1161+
- base >= 4.7 && < 5
1162+
1163+
library:
1164+
source-dirs: src
1165+
include-dirs: # Where to look for C header files?
1166+
- include
1167+
c-sources: # What C source code files to be compiled and linked?
1168+
- c-source/my-library.c
1169+
1170+
executables:
1171+
c-example-exe:
1172+
main: Main.hs
1173+
source-dirs: app
1174+
ghc-options:
1175+
- -threaded
1176+
- -rtsopts
1177+
- -with-rtsopts=-N
1178+
dependencies:
1179+
- c-example
1180+
~~~
1181+
1182+
The project's `stack.yaml` file only needs to identify a snapshot:
1183+
~~~yaml
1184+
snapshot: lts-22.26 # GHC 9.6.5
1185+
~~~
1186+
1187+
This example project can be built with Stack in the normal way (`stack build`),
1188+
and the built executable can then be executed in the Stack environment in the
1189+
normal way (`stack exec c-example-exe`).
1190+
10941191
## Flags and GHC options
10951192

10961193
There are two common ways to alter how a package will install: with Cabal flags

0 commit comments

Comments
 (0)