on master help sign in
Adds the ability to keep around the generated maven project
commit630c8b4c95867e4076f58c3ebe1d824fc4d18920 authorJan Bessai <Jan.Bessai@tu-dortmund.de> dateTue 29 Oct 2013, 13:58 (13 years ago) parentd7d31d1
6 files changed+122−52
src/IRTS/CodegenC.hs+1 src/IRTS/CodegenCommon.hs+1−1 src/IRTS/CodegenJava.hs+117−51 src/IRTS/CodegenLLVM.hs+1 src/Idris/REPL.hs+1 src/Main.hs+1
src/IRTS/CodegenC.hs+1
@@ -37,6 +37,7 @@ codegenC defs out exec incs objs libs flags dbg
3737 let cout = headers incs ++ debug dbg ++ h ++ cc ++
3838 (if (exec == Executable) then mprog else "")
3939 case exec of
40+ MavenProject -> putStrLn ("FAILURE: output type not supported")
4041 Raw -> writeFile out cout
4142 _ -> do
4243 (tmpn, tmph) <- tempfile
src/IRTS/CodegenCommon.hs+1−1
@@ -7,7 +7,7 @@ import Control.Exception
77import System.Environment
88
99data DbgLevel = NONE | DEBUG | TRACE deriving Eq
10−data OutputType = Raw | Object | Executable deriving (Eq, Show)
10+data OutputType = Raw | Object | Executable | MavenProject deriving (Eq, Show)
1111
1212environment :: String -> IO (Maybe String)
1313environment x = Control.Exception.catch (do e <- getEnv x
src/IRTS/CodegenJava.hs+117−51
@@ -37,66 +37,132 @@ import System.Process
3737
3838-----------------------------------------------------------------------
3939-- Main function
40−
4140codegenJava :: [(Name, SExp)] -> -- initialization of globals
42− [(Name, SDecl)] ->
41+ [(Name, SDecl)] -> -- decls
4342 FilePath -> -- output file name
4443 [String] -> -- headers
4544 [String] -> -- libs
4645 OutputType ->
4746 IO ()
48−codegenJava globalInit defs out hdrs libs exec = do
49− withTempdir (takeBaseName out) $ \ tmpDir -> do
50− let srcdir = tmpDir </> "src" </> "main" </> "java"
51− createDirectoryIfMissing True srcdir
52− let (Ident clsName) = either error id (mkClassName out)
53− let outjava = srcdir </> clsName <.> "java"
54− let jout = either error
47+codegenJava globalInit defs out hdrs libs exec =
48+ withTgtDir exec out (codegenJava' exec)
49+ where
50+ codegenJava' :: OutputType -> FilePath -> IO ()
51+ codegenJava' Raw tgtDir = do
52+ srcDir <- prepareSrcDir exec tgtDir
53+ generateJavaFile globalInit defs hdrs srcDir out
54+ codegenJava' MavenProject tgtDir = do
55+ codegenJava' Raw tgtDir
56+ generatePom tgtDir out libs
57+ codegenJava' Object tgtDir = do
58+ codegenJava' MavenProject tgtDir
59+ invokeMvn tgtDir "compile"
60+ copyClassFiles tgtDir out
61+ cleanUpTmp tgtDir
62+ codegenJava' _ tgtDir = do
63+ codegenJava' MavenProject tgtDir
64+ invokeMvn tgtDir "package";
65+ copyJar tgtDir out
66+ makeJarExecutable out
67+ cleanUpTmp tgtDir
68+
69+-----------------------------------------------------------------------
70+-- Compiler IO
71+
72+withTgtDir :: OutputType -> FilePath -> (FilePath -> IO ()) -> IO ()
73+withTgtDir Raw out action = action (dropFileName out)
74+withTgtDir MavenProject out action = createDirectoryIfMissing False out >> action out
75+withTgtDir _ out action = withTempdir (takeBaseName out) action
76+
77+prepareSrcDir :: OutputType -> FilePath -> IO FilePath
78+prepareSrcDir Raw tgtDir = return tgtDir
79+prepareSrcDir _ tgtDir = do
80+ let srcDir = (tgtDir </> "src" </> "main" </> "java")
81+ createDirectoryIfMissing True srcDir
82+ return srcDir
83+
84+javaFileName :: FilePath -> FilePath -> FilePath
85+javaFileName srcDir out =
86+ either error (\ (Ident clsName) -> srcDir </> clsName <.> "java") (mkClassName out)
87+
88+generateJavaFile :: [(Name, SExp)] -> -- initialization of globals
89+ [(Name, SDecl)] -> -- definitions
90+ [String] -> -- headers
91+ FilePath -> -- Source dir
92+ FilePath -> -- output target
93+ IO ()
94+generateJavaFile globalInit defs hdrs srcDir out = do
95+ let code = either error
5596 (prettyPrint)-- flatIndent . prettyPrint)
5697 (evalStateT (mkCompilationUnit globalInit defs hdrs out) mkCodeGenEnv)
57− writeFile outjava jout
58− if (exec == Raw)
59− then copyFile outjava (takeDirectory out </> clsName <.> "java")
60− else do
61− execPom <- getExecutablePom
62− execPomTemplate <- TIO.readFile execPom
63− let execPom = T.replace (T.pack "$MAIN-CLASS$")
64− (T.pack clsName)
65− (T.replace (T.pack "$ARTIFACT-NAME$")
66− (T.pack $ takeBaseName out)
67− (T.replace (T.pack "$DEPENDENCIES$")
68− (mkPomDependencies libs)
69− execPomTemplate
70− )
71− )
72− TIO.writeFile (tmpDir </> "pom.xml") execPom
73− mvnCmd <- getMvn
74− let args = ["-f", (tmpDir </> "pom.xml")]
75− (exit, mvout, err) <- readProcessWithExitCode mvnCmd (args ++ ["compile"]) ""
76− when (exit /= ExitSuccess) $ error ("FAILURE: " ++ mvnCmd ++ " compile\n" ++ err ++ mvout)
77− if (exec == Object)
78− then do
79− classFiles <-
80− map (\ clsFile -> tmpDir </> "target" </> "classes" </> clsFile)
98+ writeFile (javaFileName srcDir out) code
99+
100+pomFileName :: FilePath -> FilePath
101+pomFileName tgtDir = tgtDir </> "pom.xml"
102+
103+generatePom :: FilePath -> -- tgt dir
104+ FilePath -> -- output target
105+ [String] -> -- libs
106+ IO ()
107+generatePom tgtDir out libs = do
108+ execPom <- getExecutablePom
109+ execPomTemplate <- TIO.readFile execPom
110+ let (Ident clsName) = either error id (mkClassName out)
111+ let execPom = T.replace (T.pack "$MAIN-CLASS$")
112+ (T.pack clsName)
113+ (T.replace (T.pack "$ARTIFACT-NAME$")
114+ (T.pack $ takeBaseName out)
115+ (T.replace (T.pack "$DEPENDENCIES$")
116+ (mkPomDependencies libs)
117+ execPomTemplate
118+ )
119+ )
120+ TIO.writeFile (pomFileName tgtDir) execPom
121+
122+invokeMvn :: FilePath -> String -> IO ()
123+invokeMvn tgtDir command = do
124+ mvnCmd <- getMvn
125+ let args = ["-f", pomFileName tgtDir]
126+ (exit, mvout, err) <- readProcessWithExitCode mvnCmd (args ++ [command]) ""
127+ when (exit /= ExitSuccess) $
128+ error ("FAILURE: " ++ mvnCmd ++ " " ++ command ++ "\n" ++ err ++ mvout)
129+
130+classFileDir :: FilePath -> FilePath
131+classFileDir tgtDir = tgtDir </> "target" </> "classes"
132+
133+copyClassFiles :: FilePath -> FilePath -> IO ()
134+copyClassFiles tgtDir out = do
135+ classFiles <- map (\ clsFile -> classFileDir tgtDir </> clsFile)
81136 . filter ((".class" ==) . takeExtension)
82− <$> getDirectoryContents (tmpDir </> "target" </> "classes")
83− mapM_ (\ clsFile -> copyFile clsFile (takeDirectory out </> takeFileName clsFile))
84− classFiles
85− else do
86− (exit, mvout, err) <- readProcessWithExitCode mvnCmd (args ++ ["package"]) ""
87− when (exit /= ExitSuccess) (error ("FAILURE: " ++ mvnCmd ++ " package\n" ++ err ++ mvout))
88− copyFile (tmpDir </> "target" </> (takeBaseName out) <.> "jar") out
89− handle <- openBinaryFile out ReadMode
90− contents <- TIO.hGetContents handle
91− hClose handle
92− handle <- openBinaryFile out WriteMode
93− TIO.hPutStr handle (T.append (T.pack jarHeader) contents)
94− hFlush handle
95− hClose handle
96− perms <- getPermissions out
97− setPermissions out (setOwnerExecutable True perms)
98− readProcess mvnCmd (args ++ ["clean"]) ""
99− removeFile (tmpDir </> "pom.xml")
137+ <$> getDirectoryContents (classFileDir tgtDir)
138+ mapM_ (\ clsFile -> copyFile clsFile (takeDirectory out </> takeFileName clsFile)) classFiles
139+
140+jarFileName :: FilePath -> FilePath -> FilePath
141+jarFileName tgtDir out = tgtDir </> "target" </> (takeBaseName out) <.> "jar"
142+
143+copyJar :: FilePath -> FilePath -> IO ()
144+copyJar tgtDir out =
145+ copyFile (jarFileName tgtDir out) out
146+
147+makeJarExecutable :: FilePath -> IO ()
148+makeJarExecutable out = do
149+ handle <- openBinaryFile out ReadMode
150+ contents <- TIO.hGetContents handle
151+ hClose handle
152+ handle <- openBinaryFile out WriteMode
153+ TIO.hPutStr handle (T.append (T.pack jarHeader) contents)
154+ hFlush handle
155+ hClose handle
156+ perms <- getPermissions out
157+ setPermissions out (setOwnerExecutable True perms)
158+
159+removePom :: FilePath -> IO ()
160+removePom tgtDir = removeFile (pomFileName tgtDir)
161+
162+cleanUpTmp :: FilePath -> IO ()
163+cleanUpTmp tgtDir = do
164+ invokeMvn tgtDir "clean"
165+ removePom tgtDir
100166
101167-----------------------------------------------------------------------
102168-- Jar and Pom infrastructure
src/IRTS/CodegenLLVM.hs+1
@@ -94,6 +94,7 @@ outputModule tm file Executable m = withTmpFile $ \obj -> do
9494 defs <- (</> "llvm" </> "libidris_rts.a") <$> getDataDir
9595 exit <- rawSystem cc [obj, defs, "-lm", "-lgmp", "-lgc", "-o", file]
9696 when (exit /= ExitSuccess) $ ierror "FAILURE: Linking"
97+outputModule _ _ MavenProject _ = ierror "FAILURE: unsupported output type"
9798
9899withTmpFile :: (FilePath -> IO a) -> IO a
99100withTmpFile f = do
src/Idris/REPL.hs+1
@@ -817,6 +817,7 @@ parseArgs ("--bytecode":n:ns) = NoREPL : BCAsm n : (parseArgs ns)
817817parseArgs ("--fovm":n:ns) = NoREPL : FOVM n : (parseArgs ns)
818818parseArgs ("-S":ns) = OutputTy Raw : (parseArgs ns)
819819parseArgs ("-c":ns) = OutputTy Object : (parseArgs ns)
820+parseArgs ("--mvn":ns) = OutputTy MavenProject : (parseArgs ns)
820821parseArgs ("--dumpdefuns":n:ns) = DumpDefun n : (parseArgs ns)
821822parseArgs ("--dumpcases":n:ns) = DumpCases n : (parseArgs ns)
822823parseArgs ("--codegen":n:ns) = UseCodegen (parseCodegen n) : (parseArgs ns)
src/Main.hs+1
@@ -98,6 +98,7 @@ usagemsg = "Idris version " ++ ver ++ "\n" ++
9898 "\t--log [level] Type debugging log level\n" ++
9999 "\t-S Do no further compilation of code generator output\n" ++
100100 "\t-c Compile to object files rather than an executable\n" ++
101+ "\t--mvn Create a maven project (for Java codegen)\n" ++
101102 "\t--exec [expr] Execute the expression expr in the interpreter,\n" ++
102103 "\t defaulting to Main.main if none provided, and exit.\n" ++
103104 "\t--ideslave Ideslave mode (for editors; in/ouput wrapped in \n" ++