git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
C++: simpler make system (cmake no longer needed)
commitb075b4250ab677d444edd735ae550deb1a004a8c authorAndy Arvanitis <andyarvanitis@gmail.com> dateSun 13 Mar 2016, 12:42 (11 years ago) parent5a42964
6 files changed+122−61
pcc/Main.hs+2 pcc/Make.hs−13 pcc/Makefile+61 pcc/Makefile.example−19 pcc/Makefile.hs+50 pcc/TestMain.hs+9−29
pcc/Main.hs+2
@@ -37,6 +37,7 @@ import qualified Language.PureScript as P
3737import qualified Paths_purescript as Paths
3838
3939import Make
40+import Makefile
4041
4142data PCCOptions = PCCOptions
4243 { pccmInput :: [FilePath]
@@ -52,6 +53,7 @@ data InputOptions = InputOptions
5253
5354compile :: PCCOptions -> IO ()
5455compile (PCCOptions input _ outputDir opts usePrefix) = do
56+ when (null input) generateMakefile
5557 moduleFiles <- readInput (InputOptions input)
5658 case runWriterT (parseInputs moduleFiles []) of
5759 Left errs -> do
pcc/Make.hs−13
@@ -119,7 +119,6 @@ buildMakeActions outputDir filePathMap usePrefix =
119119 let supportDir = outputDir </> "PureScript"
120120 supportFilesExist <- dirExists supportDir
121121 when (not supportFilesExist) $ do
122− writeTextFile (outputDir </> "CMakeLists.txt") (fromString cmakeListsTxt)
123122 writeTextFile (supportDir </> "PureScript.hh") $ B.unpack $(embedFile "pcc/include/purescript.hh")
124123 writeTextFile (supportDir </> "PureScript.cc") $ B.unpack $(embedFile "pcc/include/purescript.cc")
125124
@@ -173,15 +172,3 @@ buildMakeActions outputDir filePathMap usePrefix =
173172
174173dotsTo :: Char -> String -> String
175174dotsTo chr = map (\c -> if c == '.' then chr else c)
176−
177−-- TODO: quick and dirty for now -- explicit file list would be better
178−cmakeListsTxt :: String
179−cmakeListsTxt = intercalate "\n" lines'
180− where lines' = [ "cmake_minimum_required (VERSION 3.0)"
181− , "project (Main)"
182− , "file (GLOB_RECURSE SRCS *.cc)"
183− , "file (GLOB_RECURSE HDRS *.hh)"
184− , "add_executable (Main ${SRCS} ${HDRS})"
185− , "include_directories (${CMAKE_CURRENT_SOURCE_DIR})"
186− , "set (CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} \"-std=c++11 -DDEBUG\")"
187− ]
pcc/Makefilenew file+61
@@ -0,0 +1,61 @@
1+# PureScript to native binary (via C++) Makefile
2+#
3+# Run 'make' or 'make release' to build an optimized release build
4+# Run 'make debug' to build a non-optimized build suitable for debugging
5+#
6+# You can also perform a parallel build with 'make -jN', where N is the
7+# number of cores to use.
8+#
9+# PCC, PURESCRIPT_PKGS, OUTPUT, and BIN can all be overridden with the
10+# command itself. For example: 'make PURESCRIPT_PKGS=../gitpackages BIN=myexe'
11+#
12+# Flags can be added to either the codegen or native build phases.
13+# For example: 'make PCCFLAGS=--no-tco CXXFLAGS=-DDEBUG LDFLAGS=lobjc'
14+#
15+# You can also edit the generated version of this file directly.
16+#
17+PCC := {bin/pcc} # example: /usr/local/bin/pcc
18+PURESCRIPT_PKGS := packages # example: bower_components
19+PURESCRIPT_SRC := src
20+OUTPUT := output
21+BIN := main
22+
23+override PCCFLAGS += --comments
24+override CXXFLAGS += -std=c++11
25+override LDFLAGS +=
26+
27+DEBUG := "-DDEBUG -g"
28+RELEASE := "-O3 -flto"
29+
30+PURESCRIPT_PKG_SRCS := $(shell find $(PURESCRIPT_PKGS) -name '*.purs' | grep -v \/test\/ | grep -v \/example\/ | grep -v \/examples\/)
31+PURESCRIPT_SRCS := $(shell find $(PURESCRIPT_SRC) -name '*.purs')
32+
33+INCLUDES := -I $(OUTPUT)
34+BIN_DIR := $(OUTPUT)/bin
35+
36+release: codegen
37+ $(MAKE) $(BIN) CXXFLAGS=$(RELEASE)
38+
39+debug: codegen
40+ $(MAKE) $(BIN) CXXFLAGS=$(DEBUG)
41+
42+codegen:
43+ $(PCC) $(PCCFLAGS) --output $(OUTPUT) $(PURESCRIPT_PKG_SRCS) $(PURESCRIPT_SRCS)
44+
45+SRCS := $(shell find $(OUTPUT) 2>/dev/null -name '*.cc')
46+
47+OBJS = $(SRCS:.cc=.o)
48+DEPS = $(SRCS:.cc=.d)
49+
50+$(BIN): $(OBJS)
51+ @mkdir -p $(BIN_DIR)
52+ $(CXX) $(LDFLAGS) $^ -o $(BIN_DIR)/$@
53+
54+-include $(DEPS)
55+
56+%.o: %.cc
57+ $(CXX) $(CXXFLAGS) $(INCLUDES) -MMD -MP -c $< -o $@
58+
59+.PHONY: clean
60+clean:
61+ @-rm -rf $(OUTPUT)
pcc/Makefile.exampledeleted−19
@@ -1,19 +0,0 @@
1−PCC := "../.cabal-sandbox/bin/pcc"
2−
3−MODULE_DIR="../../packages"
4−#MODULE_DIR="bower_components"
5−SOURCE_DIR="src"
6−
7−MODULES := $(shell find $(MODULE_DIR) -name '*.purs' | grep -v \/test\/ | grep -v \/example\/ | grep -v \/examples\/)
8−SOURCES := $(shell find $(SOURCE_DIR) -name '*.purs')
9−
10−all: Main
11−
12−Main: src/*
13− $(PCC) $(MODULES) $(SOURCES)
14− @mkdir -p build && cd build && cmake ../output && $(MAKE) && cp Main ../
15−
16−clean:
17− @rm -f Main
18− @rm -rf output
19− @rm -rf build
pcc/Makefile.hsnew file+50
@@ -0,0 +1,50 @@
1+-------------------------------------------------------------------------------
2+--
3+-- Module : Main
4+-- Copyright : (c) 2016 Andy Arvanitis and other contributors
5+-- License : MIT
6+--
7+-- Maintainer : Andy Arvanitis
8+-- Stability : experimental
9+-- Portability :
10+--
11+-------------------------------------------------------------------------------
12+{-# LANGUAGE OverloadedStrings #-}
13+{-# LANGUAGE TemplateHaskell #-}
14+
15+module Makefile where
16+
17+import Control.Monad (when)
18+import Data.FileEmbed (embedFile)
19+import Data.List
20+import System.Environment (getExecutablePath)
21+import System.Directory (doesFileExist)
22+
23+import qualified Data.ByteString.Char8 as B
24+
25+generateMakefile :: IO ()
26+generateMakefile = do
27+ makefileExists <- doesFileExist "Makefile"
28+ when (not makefileExists) $ do
29+ let makefile = $(embedFile "pcc/Makefile")
30+ exePath <- getExecutablePath
31+ putStrLn ""
32+ putStrLn "Generating Makefile..."
33+ putStrLn $ "pcc executable location: " ++ exePath
34+ writeFile "Makefile" $ replace makefile pccPath exePath
35+ putStrLn "Done"
36+ putStrLn "Run 'make' or 'make release' to build an optimized release build."
37+ putStrLn "The resulting binary executable will be located in output/bin (by default)."
38+ putStrLn ""
39+
40+replace :: B.ByteString -> B.ByteString -> String -> String
41+replace s orig repl = replace'
42+ where
43+ replace'
44+ | (p1, p2) <- B.breakSubstring orig s,
45+ not (B.null p2) = B.unpack p1 ++ repl ++ trim (B.unpack p2)
46+ | otherwise = B.unpack s
47+ trim = drop (B.length orig)
48+
49+pccPath :: B.ByteString
50+pccPath = "{bin/pcc}"
pcc/TestMain.hs+9−29
@@ -44,34 +44,30 @@ main = do
4444 let srcDir = outputDir </> "src"
4545 createDirectory srcDir
4646
47− let buildDir = outputDir </> "build"
48− createDirectory buildDir
49−
50− let makefile = outputDir </> "Makefile"
51− writeFile makefile makefileText
52−
5347 let passingDir = baseDir </> "examples" </> "passing"
5448 passingTestCases <- sort . filter (".purs" `isSuffixOf`) <$> getDirectoryContents passingDir
5549
50+ -- Auto-generate Makefile
51+ setCurrentDirectory outputDir
52+ callProcess "../.cabal-sandbox/bin/pcc" []
53+
5654 let tests = filter (`notElem` skipped) passingTestCases
5755
5856 -- Run the tests
5957 --
6058 forM_ tests $ \inputFile -> do
6159 --
62− -- Compile PureScript file
60+ -- Compile/build
6361 --
6462 putStrLn $ "Compiling test " ++ inputFile ++ " ..."
6563 setCurrentDirectory outputDir
6664 copyFile (passingDir </> inputFile) (srcDir </> inputFile)
67− callProcess "make" ["clean", "main"]
65+ callProcess "make" ["clean"]
66+ callProcess "make" ["debug"]
6867 --
69− -- Build and run C++ files
68+ -- Run C++ files
7069 --
71− setCurrentDirectory buildDir
72− callProcess "cmake" ["../output"]
73− callProcess "make" []
74− callProcess (buildDir </> "Main") []
70+ callProcess ("output" </> "bin" </> "main") []
7571
7672 removeFile (srcDir </> inputFile)
7773
@@ -116,22 +112,6 @@ fetchPackages = do
116112 callProcess "git" $ ["clone"] ++ (if null branch then [] else ["--branch", branch]) ++ [repo ++ (fst package) ++ ".git"]
117113 setCurrentDirectory baseDir
118114
119−-------------------------------------------------------------------------------
120−makefileText :: String
121−-------------------------------------------------------------------------------
122−makefileText = intercalate "\n" lines'
123− where lines' = [ "PCC := '../.cabal-sandbox/bin/pcc'"
124− , "MODULE_DIR='packages'"
125− , "SOURCE_DIR='src'"
126− , "MODULES := $(shell find $(MODULE_DIR) -name '*.purs' | grep -v \\/test\\/ | grep -v \\/example\\/ | grep -v \\/examples\\/)"
127− , "SOURCES := $(shell find $(SOURCE_DIR) -name '*.purs')"
128− , "all: main"
129− , "main:"
130− , "\t$(PCC) $(MODULES) $(SOURCES)"
131− , "clean:"
132− , "\t@rm -rf output/*"
133− ]
134−
135115-------------------------------------------------------------------------------
136116skipped :: [String]
137117-------------------------------------------------------------------------------