0 | module Compiler.RefC.CC
  1 |
  2 | import Core.Context.Log
  3 | import Core.Options
  4 | import Core.Directory
  5 |
  6 | import System
  7 | import Idris.Env
  8 |
  9 | import Data.String
 10 |
 11 | %default total
 12 |
 13 | findCC : IO String
 14 | findCC
 15 |     = do Nothing <- idrisGetEnv "IDRIS2_CC"
 16 |            | Just cc => pure cc
 17 |          Nothing <- idrisGetEnv "CC"
 18 |            | Just cc => pure cc
 19 |          pure "cc"
 20 |
 21 | findCFLAGS : IO String
 22 | findCFLAGS
 23 |   = do Nothing <- idrisGetEnv "IDRIS2_CFLAGS"
 24 |          | Just cflags => pure cflags
 25 |        Nothing <- idrisGetEnv "CFLAGS"
 26 |          | Just cflags => pure cflags
 27 |        pure ""
 28 |
 29 | findCPPFLAGS : IO String
 30 | findCPPFLAGS
 31 |   = do Nothing <- idrisGetEnv "IDRIS2_CPPFLAGS"
 32 |          | Just cppflags => pure cppflags
 33 |        Nothing <- idrisGetEnv "CPPFLAGS"
 34 |          | Just cppflags => pure cppflags
 35 |        pure ""
 36 |
 37 | findLDFLAGS : IO String
 38 | findLDFLAGS
 39 |   = do Nothing <- idrisGetEnv "IDRIS2_LDFLAGS"
 40 |          | Just ldflags => pure ldflags
 41 |        Nothing <- idrisGetEnv "LDFLAGS"
 42 |          | Just ldflags => pure ldflags
 43 |        pure ""
 44 |
 45 | findLDLIBS : IO String
 46 | findLDLIBS
 47 |   = do Nothing <- idrisGetEnv "IDRIS2_LDLIBS"
 48 |          | Just ldlibs => pure ldlibs
 49 |        Nothing <- idrisGetEnv "LDLIBS"
 50 |          | Just ldlibs => pure ldlibs
 51 |        pure ""
 52 |
 53 | clibdirs : List String -> List String
 54 | clibdirs ds = map (\d => "-L" ++ d) ds
 55 |
 56 | -- cincdirs : List String -> String
 57 | -- cincdirs ds = concat (map (\d => "-I" ++ d ++ " ") ds)
 58 |
 59 | export
 60 | compileCObjectFile : {auto c : Ref Ctxt Defs}
 61 |                   -> {default False asLibrary : Bool}
 62 |                   -> (sourceFile : String)
 63 |                   -> (objectFile : String)
 64 |                   -> Core (Maybe String)
 65 | compileCObjectFile {asLibrary} sourceFile objectFile =
 66 |   do cc <- coreLift findCC
 67 |      cFlags <- coreLift findCFLAGS
 68 |      cppFlags <- coreLift findCPPFLAGS
 69 |
 70 |      refcDir <- findDataFile "refc"
 71 |      cDir <- findDataFile "c"
 72 |
 73 |      let libraryFlag = if asLibrary then ["-fpic"] else []
 74 |
 75 |      let runccobj = (escapeCmd $
 76 |          [cc, "-Werror", "-c"] ++ libraryFlag ++ [sourceFile,
 77 |               "-o", objectFile,
 78 |               "-I" ++ refcDir,
 79 |               "-I" ++ cDir])
 80 |               ++ " " ++ cppFlags ++ " " ++ cFlags
 81 |
 82 |
 83 |      log "compiler.refc.cc" 10 runccobj
 84 |      0 <- coreLift $ system runccobj
 85 |        | _ => pure Nothing
 86 |
 87 |      pure (Just objectFile)
 88 |
 89 | export
 90 | compileCFile : {auto c : Ref Ctxt Defs}
 91 |             -> {default False asShared : Bool}
 92 |             -> (objectFile : String)
 93 |             -> (outFile : String)
 94 |             -> Core (Maybe String)
 95 | compileCFile {asShared} objectFile outFile =
 96 |   do cc <- coreLift findCC
 97 |      cFlags <- coreLift findCFLAGS
 98 |      ldFlags <- coreLift findLDFLAGS
 99 |      ldLibs <- coreLift findLDLIBS
100 |
101 |      dirs <- getDirs
102 |      refcDir <- findDataFile "refc"
103 |      supportFile <- findLibraryFile "libidris2_support.a"
104 |
105 |      let sharedFlag = if asShared then ["-shared"] else []
106 |
107 |      let runcc = (escapeCmd $
108 |          [cc, "-Werror"] ++ sharedFlag ++ [objectFile,
109 |               "-o", outFile,
110 |               supportFile,
111 |               "-lidris2_refc",
112 |               "-L" ++ refcDir
113 |               ] ++ clibdirs (lib_dirs dirs) ++ [
114 |               "-lgmp", "-lm"])
115 |               ++ " " ++ (unwords [cFlags, ldFlags, ldLibs])
116 |
117 |      log "compiler.refc.cc" 10 runcc
118 |      0 <- coreLift $ system runcc
119 |        | _ => pure Nothing
120 |
121 |      pure (Just outFile)
122 |