0 | module Compiler.Scheme.ChezSep
2 | import Compiler.Common
3 | import Compiler.CompileExpr
4 | import Compiler.Generated
5 | import Compiler.Scheme.Common
6 | import Compiler.Scheme.Chez
7 | import Compiler.Separate
10 | import Core.Directory
11 | import Libraries.Data.String.Builder
12 | import Libraries.Utils.Path
20 | import System.Directory
23 | import Libraries.Data.Version
24 | import Libraries.Utils.String
28 | schHeader : List String -> List String -> Builder
29 | schHeader libs compilationUnits = fromString """
30 | (import (chezscheme) (support)
31 | \{ unwords ["(" ++ cu ++ ")" | cu <- compilationUnits] })
32 | (case (machine-type)
33 | [(i3le ti3le a6le ta6le tarm64le) (load-shared-object "libc.so.6")]
34 | [(i3osx ti3osx a6osx ta6osx tarm64osx tppc32osx tppc64osx) (load-shared-object "libc.dylib")]
35 | [(i3nt ti3nt a6nt ta6nt) (load-shared-object "msvcrt.dll")]
36 | [else (load-shared-object "libc.so")]
37 | \{ unlines [" (load-shared-object \"" ++ escapeStringChez lib ++ "\")" | lib <- libs] })
44 | (collect-request-handler (lambda () (collect (collect-maximum-generation)) (blodwen-run-finalisers)))
45 | (collect-rendezvous)
48 | startChez : String -> String -> String -> String
49 | startChez chez appDirSh targetSh = Chez.startChezPreamble ++ """
50 | export LD_LIBRARY_PATH="$DIR/\{ appDirSh }:$LD_LIBRARY_PATH"
51 | export DYLD_LIBRARY_PATH="$DIR/\{ appDirSh }:$DYLD_LIBRARY_PATH"
54 | --libdirs "$DIR/\{ appDirSh }" \
55 | --program "$DIR/\{ targetSh }" \
59 | startChezCmd : String -> String -> String -> String
60 | startChezCmd chez appDirSh targetSh = """
63 | rem \{ generatedString "ChezSep" }
66 | set PATH=%APPDIR%\{ appDirSh };%PATH%
69 | --libdirs "%APPDIR%\{ appDirSh }" \
70 | --program "%APPDIR%\{ targetSh }" \
74 | startChezWinSh : String -> String -> String -> String
75 | startChezWinSh chez appDirSh targetSh = """
77 | # \{ generatedString "ChezSep" }
79 | set -e # exit on any error
81 | DIR=$(dirname "$(readlink -f -- "$0" || cygpath -a -- "$0")")
82 | PATH="$DIR/\{ appDirSh }:$PATH"
84 | "\{ chez }" --program "$DIR/\{ targetSh }" "$@"
86 | --libdirs "$DIR/\{ appDirSh }" \
87 | --program "$DIR/\{ targetSh }" \
92 | compileChezLibraries : (chez : String) -> (libDir : String) -> (ssFiles : List String) -> Core ()
93 | compileChezLibraries chez libDir ssFiles = coreLift_ $
system
96 | [ "'(parameterize ([optimize-level 3] [compile-file-message #f]) (compile-library " ++ build (chezString ssFile) ++ "))'"
97 | ++ " '(delete-file " ++ build (chezString ssFile) ++ ")'"
100 | | ssFile <- ssFiles
102 | , "|", chez, "-q", "--libdirs", libDir
105 | compileChezLibrary : (chez : String) -> (libDir : String) -> (ssFile : String) -> Core ()
106 | compileChezLibrary chez libDir ssFile = coreLift_ $
system
108 | , "'(parameterize ([optimize-level 3] [compile-file-message #f]) (compile-library " ++ build (chezString ssFile) ++ "))'"
109 | , "'(delete-file " ++ build (chezString ssFile) ++ ")'"
110 | , "|", chez, "-q", "--libdirs", libDir
113 | compileChezProgram : (chez : String) -> (libDir : String) -> (ssFile : String) -> Core ()
114 | compileChezProgram chez libDir ssFile = coreLift_ $
system
116 | , "'(parameterize ([optimize-level 3] [compile-file-message #f]) (compile-program " ++ build (chezString ssFile) ++ "))'"
117 | , "'(delete-file " ++ build (chezString ssFile) ++ ")'"
118 | , "|", chez, "-q", "--libdirs", libDir
121 | chezNS : Namespace -> String
122 | chezNS ns = case showNSWithSep "-" ns of
123 | "" => "unqualified"
128 | chezLibraryName : CompilationUnit def -> String
129 | chezLibraryName cu = chezNS (foldl1 min cu.namespaces)
131 | touch : String -> Core ()
132 | touch s = coreLift_ $
system ["touch", s]
134 | record ChezLib where
135 | constructor MkChezLib
140 | compileToSS : Ref Ctxt Defs -> String -> String -> ClosedTerm -> Core (Bool, List ChezLib)
141 | compileToSS c chez appdir tm = do
143 | ds <- getDirectives Chez
144 | libs <- findLibs ds
145 | traverse_ copyLib libs
146 | version <- coreLift $
chezVersion chez
149 | cdata <- getCompileData False Cases tm
150 | let ctm = forget (mainExpr cdata)
151 | let ndefs = namedDefs cdata
152 | let cui = getCompilationUnits ndefs
155 | support <- readDataFile "chez/support-sep.ss"
156 | let supportHash = show $
hash support
158 | coreLift (readFile (appdir </> "support.hash")) >>= \case
159 | Left err => pure True
160 | Right fileHash => pure (fileHash /= supportHash)
161 | when supportChanged $
do
162 | Core.writeFile (appdir </> "support.ss") support
163 | Core.writeFile (appdir </> "support.hash") supportHash
170 | chezLibs <- for cui.compilationUnits $
\cu => do
171 | let chezLib = chezLibraryName cu
175 | let cuHash = show (hash cu)
177 | coreLift (readFile (appdir </> chezLib <.> "hash")) >>= \case
178 | Left err => pure True
179 | Right fileHash => pure (fileHash /= cuHash)
182 | when hashChanged $
do
184 | l <- newRef {t = List String} Loaded ["libc", "libc 6"]
185 | s <- newRef {t = List String} Structs []
188 | let imports = unwords
193 | (SortedMap.lookup cuid cui.byId)
195 | | cuid <- Prelude.toList cu.dependencies
197 | let exports = sepBy " " $
catMaybes
200 | MkNmCon {} => Nothing
201 | _ => Just $ schName dn
202 | | (dn, fc, d) <- cu.definitions
205 | "(library (" ++ fromString chezLib ++ ")\n"
206 | ++ " (export " ++ exports ++ ")\n"
207 | ++ " (import (chezscheme) (support) " ++ fromString imports ++ ")\n\n"
210 | fgndefs <- traverse (Chez.getFgnCall version) cu.definitions
211 | compdefs <- traverse (getScheme empty (Chez.chezExtPrim empty defaultLaziness) Chez.chezString defaultLaziness) cu.definitions
212 | loadlibs <- traverse (map fromString . loadLib appdir) (mapMaybe fst fgndefs)
215 | log "compiler.scheme.chez" 3 $
"Generating code for " ++ chezLib
216 | Core.writeFile (appdir </> chezLib <.> "ss") $
build $
concat $
223 | Core.writeFile (appdir </> chezLib <.> "hash") cuHash
225 | pure (MkChezLib chezLib hashChanged)
228 | main <- schExp empty (Chez.chezExtPrim empty defaultLaziness) Chez.chezString defaultLaziness 0 ctm
229 | Core.writeFile (appdir </> "mainprog.ss") $
build $
sepBy "\n"
230 | [ schHeader (map snd libs) [lib.name | lib <- chezLibs]
231 | , collectRequestHandler
236 | pure (supportChanged, chezLibs)
238 | makeSh : String -> String -> String -> String -> Core ()
239 | makeSh chez outShRel appDirSh targetSh =
240 | Core.writeFile outShRel (startChez chez appDirSh targetSh)
243 | makeShWindows : String -> String -> String -> String -> Core ()
244 | makeShWindows chez outShRel appDirSh targetSh = do
245 | let cmdFile = outShRel ++ ".cmd"
246 | Core.writeFile cmdFile (startChezCmd chez appDirSh targetSh)
247 | Core.writeFile outShRel (startChezWinSh chez appDirSh targetSh)
253 | Ref Syn SyntaxInfo ->
254 | (tmpDir : String) -> (outputDir : String) ->
255 | ClosedTerm -> (outfile : String) -> Core (Maybe String)
256 | compileExpr makeitso c s tmpDir outputDir tm outfile = do
258 | Just cwd <- coreLift currentDir
259 | | Nothing => throw (InternalError "Can't get current directory")
260 | let appDirSh = outfile ++ "_app"
261 | let appDirRel = outputDir </> appDirSh
262 | let appDirAbs = cwd </> appDirRel
263 | coreLift_ $
mkdirAll appDirRel
266 | chez <- coreLift $
findChez
267 | (supportChanged, chezLibs) <- compileToSS c chez appDirRel tm
270 | logTime 2 "Make SO" $
when makeitso $
do
272 | when supportChanged $
do
273 | log "compiler.scheme.chez" 3 $
"Compiling support"
274 | compileChezLibrary chez appDirRel (appDirRel </> "support.ss")
277 | compileChezLibraries chez appDirRel
278 | [appDirRel </> lib.name <.> "ss" | lib <- chezLibs, lib.isOutdated]
282 | for_ chezLibs $
\lib => do
283 | log "compiler.scheme.chez" 3 $
"Touching " ++ lib.name
284 | touch (appDirRel </> lib.name <.> "so")
287 | compileChezProgram chez appDirRel (appDirRel </> "mainprog.ss")
290 | let outShRel = outputDir </> outfile
291 | let launchTargetSh = appDirSh </> "mainprog" <.> (if makeitso then "so" else "ss")
293 | then makeShWindows chez outShRel appDirSh launchTargetSh
294 | else makeSh chez outShRel appDirSh launchTargetSh
295 | coreLift_ $
chmodRaw outShRel 0o755
296 | pure (Just outShRel)
302 | Ref Syn SyntaxInfo ->
303 | (tmpDir : String) -> ClosedTerm -> Core ()
304 | executeExpr c s tmpDir tm
305 | = do Just sh <- compileExpr False c s tmpDir tmpDir tm "_tmpchez"
306 | | Nothing => throw (InternalError "compileExpr returned Nothing")
307 | coreLift_ $
system [sh]
311 | codegenChezSep : Codegen
312 | codegenChezSep = MkCG (compileExpr True) executeExpr Nothing Nothing