Add 'libs' directory to paths

This is for finding support libraries for code generators, e.g. the
shared objects that chez will load for glue code for foreign libraries.
It'll be used more shortly...
This commit is contained in:
Edwin Brady 2019-07-28 11:48:00 +01:00
parent 0bb9a13d37
commit d5409ac2d0
8 changed files with 69 additions and 8 deletions

View File

@ -46,6 +46,7 @@ install: all install-exec install-libs
install-exec: idris2 install-exec: idris2
mkdir -p ${PREFIX}/bin mkdir -p ${PREFIX}/bin
mkdir -p ${PREFIX}/idris2/lib
mkdir -p ${PREFIX}/idris2/support/chez mkdir -p ${PREFIX}/idris2/support/chez
mkdir -p ${PREFIX}/idris2/support/chicken mkdir -p ${PREFIX}/idris2/support/chicken
mkdir -p ${PREFIX}/idris2/support/racket mkdir -p ${PREFIX}/idris2/support/racket

View File

@ -63,6 +63,14 @@ mkNameTags defs tags t (n :: ns)
=> mkNameTags defs (insert n t tags) (t + 1) ns => mkNameTags defs (insert n t tags) (t + 1) ns
_ => mkNameTags defs tags t ns _ => mkNameTags defs tags t ns
natHackNames : List Name
natHackNames
= [UN "prim__add_Integer",
UN "prim__sub_Integer",
UN "prim__mul_Integer",
NS ["Prelude"] (UN "natToInteger"),
NS ["Prelude"] (UN "integerToNat")]
-- Find all the names which need compiling, from a given expression, and compile -- Find all the names which need compiling, from a given expression, and compile
-- them to CExp form (and update that in the Defs) -- them to CExp form (and update that in the Defs)
export export
@ -71,7 +79,8 @@ findUsedNames : {auto c : Ref Ctxt Defs} -> Term vars ->
findUsedNames tm findUsedNames tm
= do defs <- get Ctxt = do defs <- get Ctxt
let ns = getRefs (Resolved (-1)) tm let ns = getRefs (Resolved (-1)) tm
allNs <- getAllDesc (keys ns) empty defs natHackNames' <- traverse toResolvedNames natHackNames
allNs <- getAllDesc (natHackNames' ++ keys ns) empty defs
cns <- traverse toFullNames (keys allNs) cns <- traverse toFullNames (keys allNs)
-- Initialise the type constructor list with explicit names for -- Initialise the type constructor list with explicit names for
-- the primitives (this is how we look up the tags) -- the primitives (this is how we look up the tags)

View File

@ -75,6 +75,9 @@ expandToArity num fn [] = etaExpand 0 num fn []
-- None of these should be hard coded, but we'll do it this way until we -- None of these should be hard coded, but we'll do it this way until we
-- have a more general approach to optimising data types! -- have a more general approach to optimising data types!
-- NOTE: Make sure that names mentioned here are listed in 'natHackNames' in
-- Common.idr, so that they get compiled, as they won't be spotted by the
-- usual calls to 'getRefs'.
natHack : CExp vars -> CExp vars natHack : CExp vars -> CExp vars
natHack (CCon fc (NS ["Prelude"] (UN "Z")) _ []) = CPrimVal fc (BI 0) natHack (CCon fc (NS ["Prelude"] (UN "Z")) _ []) = CPrimVal fc (BI 0)
natHack (CCon fc (NS ["Prelude"] (UN "S")) _ [k]) natHack (CCon fc (NS ["Prelude"] (UN "S")) _ [k])

View File

@ -31,9 +31,26 @@ findChez
x <- ["scheme", "chez", "chezscheme9.5"]] x <- ["scheme", "chez", "chezscheme9.5"]]
maybe (pure "/usr/bin/env scheme") pure e maybe (pure "/usr/bin/env scheme") pure e
findLibs : List String -> List String -- Given the chez compiler directives, return a list of pairs of:
findLibs = mapMaybe (isLib . trim) -- - the library file name
-- - the full absolute path of the library file name, if it's in one
-- of the library paths managed by Idris
-- If it can't be found, we'll assume it's a system library and that chez
-- will thus be able to find it.
findLibs : {auto c : Ref Ctxt Defs} ->
List String -> Core (List (String, String))
findLibs ds
= do let libs = mapMaybe (isLib . trim) ds
traverse locate (nub libs)
where where
locate : String -> Core (String, String)
locate fname
= do fullname <- catch (findLibraryFile fname)
(\err => -- assume a system library so not
-- in our library path
pure fname)
pure (fname, fullname)
isLib : String -> Maybe String isLib : String -> Maybe String
isLib d isLib d
= if isPrefixOf "lib" d = if isPrefixOf "lib" d
@ -107,7 +124,7 @@ compileToSS : Ref Ctxt Defs ->
ClosedTerm -> (outfile : String) -> Core () ClosedTerm -> (outfile : String) -> Core ()
compileToSS c tm outfile compileToSS c tm outfile
= do ds <- getDirectives Chez = do ds <- getDirectives Chez
let libs = findLibs ds libs <- findLibs ds
(ns, tags) <- findUsedNames tm (ns, tags) <- findUsedNames tm
defs <- get Ctxt defs <- get Ctxt
compdefs <- traverse (getScheme chezExtPrim defs) ns compdefs <- traverse (getScheme chezExtPrim defs) ns
@ -115,7 +132,8 @@ compileToSS c tm outfile
main <- schExp chezExtPrim 0 [] !(compileExp tags tm) main <- schExp chezExtPrim 0 [] !(compileExp tags tm)
chez <- coreLift findChez chez <- coreLift findChez
support <- readDataFile "chez/support.ss" support <- readDataFile "chez/support.ss"
let scm = schHeader chez libs ++ support ++ code ++ main ++ schFooter let scm = schHeader chez (map snd libs) ++
support ++ code ++ main ++ schFooter
Right () <- coreLift $ writeFile outfile scm Right () <- coreLift $ writeFile outfile scm
| Left err => throw (FileErr outfile err) | Left err => throw (FileErr outfile err)
coreLift $ chmod outfile 0o755 coreLift $ chmod outfile 0o755

View File

@ -1569,6 +1569,12 @@ addDataDir dir
= do defs <- get Ctxt = do defs <- get Ctxt
put Ctxt (record { options->dirs->data_dirs $= (++ [dir]) } defs) put Ctxt (record { options->dirs->data_dirs $= (++ [dir]) } defs)
export
addLibDir : {auto c : Ref Ctxt Defs} -> String -> Core ()
addLibDir dir
= do defs <- get Ctxt
put Ctxt (record { options->dirs->lib_dirs $= (++ [dir]) } defs)
export export
setBuildDir : {auto c : Ref Ctxt Defs} -> String -> Core () setBuildDir : {auto c : Ref Ctxt Defs} -> String -> Core ()
setBuildDir dir setBuildDir dir

View File

@ -36,7 +36,7 @@ dropExtension fname
-- assert that root can't be empty -- assert that root can't be empty
reverse (assert_total (strTail root)) reverse (assert_total (strTail root))
-- Return the contents of the first file available in the list -- Return the name of the first file available in the list
firstAvailable : List String -> Core (Maybe String) firstAvailable : List String -> Core (Maybe String)
firstAvailable [] = pure Nothing firstAvailable [] = pure Nothing
firstAvailable (f :: fs) firstAvailable (f :: fs)
@ -57,6 +57,21 @@ readDataFile fname
| Left err => throw (FileErr f err) | Left err => throw (FileErr f err)
pure d pure d
-- Look for a library file required by a code generator. Look in the
-- library directories, and in the lib/ subdirectoriy of all the 'extra import'
-- directories
export
findLibraryFile : {auto c : Ref Ctxt Defs} ->
String -> Core String
findLibraryFile fname
= do d <- getDirs
let fs = map (\p => p ++ cast sep ++ fname)
(lib_dirs d ++ map (\x => x ++ cast sep ++ "lib")
(extra_dirs d))
Just f <- firstAvailable fs
| Nothing => throw (InternalError ("Can't find library " ++ fname))
pure f
-- Given a namespace, return the full path to the checked module, -- Given a namespace, return the full path to the checked module,
-- looking first in the build directory then in the extra_dirs -- looking first in the build directory then in the extra_dirs
export export

View File

@ -11,15 +11,17 @@ record Dirs where
build_dir : String -- build directory, relative to working directory build_dir : String -- build directory, relative to working directory
dir_prefix : String -- installation prefix, for finding data files (e.g. run time support) dir_prefix : String -- installation prefix, for finding data files (e.g. run time support)
extra_dirs : List String -- places to look for import files extra_dirs : List String -- places to look for import files
lib_dirs : List String -- places to look for libraries (for code generation)
data_dirs : List String -- places to look for data file data_dirs : List String -- places to look for data file
public export public export
toString : Dirs -> String toString : Dirs -> String
toString (MkDirs wdir bdir dfix edirs ddirs) = toString (MkDirs wdir bdir dfix edirs ldirs ddirs) =
unlines [ "+ Working Directory :: " ++ show wdir unlines [ "+ Working Directory :: " ++ show wdir
, "+ Build Directory :: " ++ show bdir , "+ Build Directory :: " ++ show bdir
, "+ Installation Prefix :: " ++ show dfix , "+ Installation Prefix :: " ++ show dfix
, "+ Extra Directories :: " ++ show edirs , "+ Extra Directories :: " ++ show edirs
, "+ CG Library Directories :: " ++ show ldirs
, "+ Data Directories :: " ++ show ddirs] , "+ Data Directories :: " ++ show ddirs]
public export public export
@ -105,7 +107,7 @@ record Options where
extensions : List LangExt extensions : List LangExt
defaultDirs : Dirs defaultDirs : Dirs
defaultDirs = MkDirs "." "build" "/usr/local" ["."] [] defaultDirs = MkDirs "." "build" "/usr/local" ["."] ["."] []
defaultPPrint : PPrinter defaultPPrint : PPrinter
defaultPPrint = MkPPOpts False True False defaultPPrint = MkPPOpts False True False

View File

@ -53,6 +53,11 @@ updatePaths
Just path => do traverse addDataDir (map trim (split (==pathSep) path)) Just path => do traverse addDataDir (map trim (split (==pathSep) path))
pure () pure ()
Nothing => pure () Nothing => pure ()
blibs <- coreLift $ getEnv "IDRIS2_LIBS"
case blibs of
Just path => do traverse addLibDir (map trim (split (==pathSep) path))
pure ()
Nothing => pure ()
-- BLODWEN_PATH goes first so that it overrides this if there's -- BLODWEN_PATH goes first so that it overrides this if there's
-- any conflicts. In particular, that means that setting BLODWEN_PATH -- any conflicts. In particular, that means that setting BLODWEN_PATH
-- for the tests means they test the local version not the installed -- for the tests means they test the local version not the installed
@ -61,6 +66,8 @@ updatePaths
addPkgDir "base" addPkgDir "base"
addDataDir (dir_prefix (dirs (options defs)) ++ dirSep ++ addDataDir (dir_prefix (dirs (options defs)) ++ dirSep ++
"idris2" ++ dirSep ++ "support") "idris2" ++ dirSep ++ "support")
addLibDir (dir_prefix (dirs (options defs)) ++ dirSep ++
"idris2" ++ dirSep ++ "lib")
updateREPLOpts : {auto o : Ref ROpts REPLOpts} -> updateREPLOpts : {auto o : Ref ROpts REPLOpts} ->
Core () Core ()