Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/compiler-build-settings.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public defstruct BuildSettings :
ccflags: Tuple<String|Tuple<String>>
flags: Tuple<Symbol>
macro-plugins: Tuple<String>
link-type: Symbol|False
with:
printer => true

Expand Down
13 changes: 9 additions & 4 deletions compiler/compiler-linking.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ public defmulti issue-error (e:LinkerEnv, err:LinkingError) -> False
;will induce. Note that foreign-packages are not allowed here, only ccfiles and ccflags.
public defmulti foreign-package-manager-dependencies (e:LinkerEnv,
params:ForeignPackageParamsStmt,
platform:Symbol)
platform:Symbol,
link-type:Symbol)
-> ProjDependencies

;Report to the caller that the external dependencies have been computed.
Expand All @@ -88,7 +89,8 @@ public defmulti computed-build-commands (e:LinkerEnv, stmts:Tuple<CompileStmt>)
public defmulti satisfy-foreign-packages (e:LinkerEnv,
files:ForeignPackageFiles,
params:ForeignPackageParamsStmt,
platform:Symbol) -> True|False
platform:Symbol,
link-type:Symbol) -> True|False

;Called to report to the caller that an external dependency has already been built.
public defmulti notify-external-dependency-up-to-date (e:LinkerEnv,
Expand Down Expand Up @@ -146,11 +148,13 @@ public defn link (input:LinkerInput, env:LinkerEnv) -> False :

;Satisfy the foreign package dependencies.
val build-platform = platform(build-settings(input)) as Symbol
val link-type = link-type(build-settings(input)) as Symbol
for package in foreign-packages(dependencies(deps)) do :
satisfy-foreign-packages(env,
package,
package-manager-params(proj(input), package-manager(package)),
build-platform)
build-platform,
link-type)

;Execute the given build commands if they are not
;already up-to-date.
Expand Down Expand Up @@ -308,7 +312,8 @@ defn compute-dependencies (result:CompilationResult,
match(get?(package-params, package-manager(package))) :
(params:ForeignPackageParamsStmt) :
val platform = platform(settings) as Symbol
add(new-deps, foreign-package-manager-dependencies(env, params, platform))
val link-type = link-type(settings) as Symbol
add(new-deps, foreign-package-manager-dependencies(env, params, platform, link-type))
(f:False) :
encountered-error(NoConfigurationForPackageManager(package-manager(package), files(package)))

Expand Down
17 changes: 10 additions & 7 deletions compiler/compiler.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ defn compute-build-settings (projenv:StandardProjEnv,
match(inputs(settings)) :
(inputs:BuildTarget) :
val proj-files = default-proj-files()
val proj = read-proj-files(proj-files, platform, projenv)
val proj = read-proj-files(proj-files, platform, default-link-type(link-type(settings)), projenv)
;Retrieve build target statement
val s = build-target!(proj, target(inputs))
;Compute build flags
Expand Down Expand Up @@ -101,15 +101,16 @@ defn compute-build-settings (projenv:StandardProjEnv,
build-ccfiles,
build-ccflags,
to-tuple(build-flags),
macro-plugins(settings))
macro-plugins(settings),
link-type(settings))

;Return new settings.
[proj, settings*]

(inputs:BuildPackages) :
val proj-files = default-proj-files()
add-all(proj-files, /proj-files(names(inputs)))
val proj = read-proj-files(proj-files, platform, projenv)
val proj = read-proj-files(proj-files, platform, default-link-type(link-type(settings)), projenv)
val inputs* = BuildPackages $ to-tuple $ non-files-to-symbols $ non-proj-files $ names $ inputs
val vm-packages* = to-tuple $ non-files-to-symbols $ vm-packages $ settings
val build-out = add-exe-suffix?(output(settings), platform)
Expand Down Expand Up @@ -277,15 +278,17 @@ public defn compile (settings:BuildSettings, system:System, verbose?:True|False)
add(errors, err)
defmethod foreign-package-manager-dependencies (this,
params:ForeignPackageParamsStmt,
platform:Symbol) :
platform:Symbol,
link-type:Symbol) :
val pm = package-manager(projenv, package-manager(params))
system-dependencies(pm, to-params(params, platform))
system-dependencies(pm, to-params(params, platform, link-type))
defmethod satisfy-foreign-packages (this,
files:ForeignPackageFiles,
params:ForeignPackageParamsStmt,
platform:Symbol) :
platform:Symbol,
link-type:Symbol) :
val pm = package-manager(projenv, package-manager(files))
satisfy-dependencies(pm, /files(files), to-params(params, platform), package-manager-system())
satisfy-dependencies(pm, /files(files), to-params(params, platform, link-type), package-manager-system())
defmethod computed-dependencies (this, deps:ProjDependencies) :
if external-dependencies(settings) is String :
val filename = external-dependencies(settings) as String
Expand Down
8 changes: 8 additions & 0 deletions compiler/conan-package-manager.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,17 @@ public defn ConanPackageManager () -> ForeignPackageManager :
; Now call 'conan install' in the conan root directory.
val conanlog = to-string("%_/conanlog.txt" % [conan-build-dir])
val additional-flags = lookup(entries(params), `conan-install-extra-args)
val shared-flags =
if link-type(params) == `dynamic :
to-tuple $ for package in packages seq :
val name = next(split(package, "/"))
[ "-o" string-join([name ":shared=True"])]
else :
[]
val install-args = flatten-tuple $ [
"install" conan-build-dir
"--install-folder" conan-build-dir
shared-flags
additional-flags]
call-conan(install-args, conanlog)

Expand Down
5 changes: 3 additions & 2 deletions compiler/defs-db.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public defn defs-db (input:DefsDbInput, filename:String) :

protected-when(TESTING) defn analyze-input (input:DefsDbInput) -> DependencyResult :
;Read all listed packages from given project files
val proj-file = read-proj-files(proj-files(input), platform(input), StandardProjEnv())
val proj-file = read-proj-files(proj-files(input), platform(input), default-link-type(false), StandardProjEnv())
val stanza-files = all-package-files(proj-file)
val proj-and-stanza-files = to-tuple $
cat(proj-files(input), stanza-files)
Expand All @@ -97,7 +97,8 @@ protected-when(TESTING) defn analyze-input (input:DefsDbInput) -> DependencyResu
[], ;ccfiles
[], ;ccflags
flags(input) ;flags
macro-plugins(input)) ;macro-plugin
macro-plugins(input) ;macro-plugin
false)

;Compute dependencies (compiles to IL-IR)
dependencies(build-settings, true)
Expand Down
1 change: 1 addition & 0 deletions compiler/foreign-package-manager.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public defn registered-foreign-package-managers () -> Tuple<ForeignPackageManage
public defstruct PackageManagerParams :
projdir: String
platform: Symbol
link-type: Symbol
entries: Tuple<KeyValue<Symbol,?>>

;This represents the capability of a foreign package manager.
Expand Down
28 changes: 20 additions & 8 deletions compiler/main.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ val COMMON-STANZA-FLAGS = [
"Requests the compiler to output the .pkg files. The name of the folder to store the output .pkg files can be optionally provided.")
Flag("optimize", ZeroFlag, OptionalFlag,
"Requests the compiler to compile in optimized mode.")
Flag("link", OneFlag, OptionalFlag,
"Provide the type of linking to use.")
Flag("ccfiles", ZeroOrMoreFlag, OptionalFlag,
"The set of C language files to link the final generated assembly against to produce the final executable.")
Flag("ccflags", GreedyFlag, OptionalFlag,
Expand Down Expand Up @@ -301,7 +303,8 @@ defn compile-command () :
get?(cmd-args, "ccfiles", [])
ccflags
map(to-symbol, get?(cmd-args, "flags", []))
get?(cmd-args, "macros", []))
get?(cmd-args, "macros", [])
false)

;Launch!
within run-with-timing-log(cmd-args) :
Expand Down Expand Up @@ -345,7 +348,8 @@ defn build-command () :
[]
ccflags
map(to-symbol, get?(cmd-args, "flags", []))
get?(cmd-args, "macros", []))
get?(cmd-args, "macros", []),
link?(get?(cmd-args, "link", false)))

;Launch!
within run-with-timing-log(cmd-args) :
Expand All @@ -355,7 +359,7 @@ defn build-command () :
;Command definition
Command("build",
ZeroOrOneArg, "the name of the build target. If not supplied, the default build target is 'main'.",
common-stanza-flags(["s" "o" "external-dependencies" "pkg" "flags" "optimize" "verbose" "ccflags" "macros" "timing-log"]),
common-stanza-flags(["s" "o" "external-dependencies" "pkg" "flags" "optimize" "verbose" "ccflags" "macros" "link" "timing-log"]),
build-msg, intercept-no-match-exceptions(build))

;============================================================
Expand Down Expand Up @@ -412,7 +416,8 @@ defn extend-command () :
get?(cmd-args, "ccfiles", [])
ccflags
map(to-symbol, get?(cmd-args, "flags", []))
get?(cmd-args, "macros", []))
get?(cmd-args, "macros", [])
false)

;Launch!
run-with-timing-log(main, cmd-args)
Expand Down Expand Up @@ -481,7 +486,8 @@ defn compile-test-command () :
get?(cmd-args, "ccfiles", [])
ccflags
new-flags
get?(cmd-args, "macros", []))
get?(cmd-args, "macros", [])
false)

;Launch!
run-with-timing-log(main, cmd-args)
Expand Down Expand Up @@ -547,7 +553,8 @@ defn compile-macros-command () :
get?(cmd-args, "ccfiles", [])
ccflags
get?(cmd-args, "flags", [])
get?(cmd-args, "macros", []))
get?(cmd-args, "macros", []),
false)

;Launch!
run-with-timing-log(main, cmd-args)
Expand Down Expand Up @@ -930,7 +937,8 @@ defn analyze-dependencies-command () :
[]
[]
map(to-symbol, get?(cmd-args, "flags", []))
get?(cmd-args, "macros", []))
get?(cmd-args, "macros", []),
false)

;Launch!
run-with-timing-log(main, cmd-args)
Expand Down Expand Up @@ -1000,7 +1008,8 @@ defn auto-doc-command () :
[]
[]
map(to-symbol, get?(cmd-args, "flags", []))
get?(cmd-args, "macros", []))
get?(cmd-args, "macros", [])
false)

;Launch!
run-with-timing-log(main, cmd-args)
Expand Down Expand Up @@ -1113,6 +1122,9 @@ defn AsmFile? (filename:String|False) -> AsmFile|False :
match(filename:String) :
AsmFile(filename,false)

defn link? (arg:String|False) -> Symbol|False :
match(arg:String) : to-symbol(arg)

;============================================================
;==================== Main Commands =========================
;============================================================
Expand Down
18 changes: 18 additions & 0 deletions compiler/params.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,24 @@ public defn platform-flag (platform:Symbol) -> Symbol :
`linux : `PLATFORM-LINUX
`windows : `PLATFORM-WINDOWS

;======== Link Types =========
public defn supported-link-type? (l:Symbol) :
contains?([`dynamic, `static], l)

public defn ensure-supported-link-types (l:Symbol) :
if not supported-link-type?(l) :
throw $ Exception("%_ is not a supported link-type." % [l])

public defn link-flag (link-type:Symbol) -> Symbol :
switch(link-type) :
`static : `LINK-STATIC
`dynamic : `LINK-DYNAMIC

public defn default-link-type (link:Symbol|False) -> Symbol :
match(link) :
(l:Symbol) : l
(l:False) : `static

;======= Versions ========
public defn valid-stanza-version-format? (xs:Tuple<Int>) -> True|False :
if length(xs) == 3 :
Expand Down
3 changes: 2 additions & 1 deletion compiler/proj-env.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ public defmulti foreign-package-managers (env:ProjEnv) -> Tuple<ForeignPackageMa
;and it will be translated over to a ProjValue before substitution.
public defmulti package-manager-variables (env:ProjEnv,
params:ForeignPackageParamsStmt,
platform:Symbol)
platform:Symbol,
link-type:Symbol)
-> Tuple<KeyValue<Symbol, ?>> :
[]

Expand Down
29 changes: 26 additions & 3 deletions compiler/proj-normalization.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ defpackage stz/proj-normalization :

;This pass normalizes all ProjValue within the proj file.
;- Collapses all CondPlatform values into a single value.
;- Collapses all CondLink values into a single value.
;- Collapses all SplicedString values into an AtomValue containing a String.
;- Guarantees that ProjValues do not recursively contain ProjValues.

public defn normalize (f:ProjFileS0,
current-platform:Symbol,
current-link-type:Symbol,
dirtable:SpecialDirTable) -> ProjFileS0 :
defn norm (item:ProjItem) -> ProjItem :
match(item:ProjValue) : normalize(item, current-platform, dirtable)
match(item:ProjValue) : normalize(item, current-platform, current-link-type, dirtable)
else : map(norm, item)
val new-stmts = map({norm(_) as ProjStmt}, stmts(f))
sub-stmts(f, new-stmts)
Expand All @@ -33,24 +35,28 @@ public defn normalize (f:ProjFileS0,
;- proj-path: The full path of the ProjFile containing this value.
public defn normalize (v:ProjValue,
current-platform:Symbol,
current-link-type:Symbol,
workdir:String,
proj-path:String) -> ProjValue :
val dirtable = SpecialDirTable(workdir, proj-path)
normalize(v, current-platform, dirtable)
normalize(v, current-platform, current-link-type, dirtable)

;============================================================
;=================== Value Normalization ====================
;============================================================

;Normalize the given value under the given platform.
;- Collapses all CondPlatform values into a single value.
;- Collapses all CondLink values into a single value.
;- Separates SplicedString values that contain ProjValues.
;- Guarantees that ProjValues do not recursively contain ProjValues.

defn normalize (v:ProjValue,
platform:Symbol,
link-type:Symbol,
dirtable:SpecialDirTable) -> ProjValue :
v $> eval-condplatform{_, platform}
$> eval-condlink{_, link-type}
$> substitute-special-dirs{_, dirtable}
$> collapse-spliced-strings
$> flatten-projvalues
Expand All @@ -71,14 +77,31 @@ defn eval-condplatform (v:ProjValue, platform:Symbol) -> ProjValue :
val result = map(eval-condplatform{_ as ProjValue, platform}, v)
result as ProjValue

;============================================================
;++================ Evaluate CondLink =======================
;============================================================

;Evaluate all CondLink in the given ProjValue.
defn eval-condlink (v:ProjValue, link-type:Symbol) -> ProjValue :
match(v:CondLink) :
for e in values(v) first! :
if key(e) == link-type or key(e) == `else :
One(eval-condlink(value(e), link-type))
else :
None()
else :
val result = map(eval-condlink{_ as ProjValue, link-type}, v)
result as ProjValue

;============================================================
;================= Collapse SplicedString ===================
;============================================================

;If a SplicedString contains a ProjValues, then treat the
;values as if they contain a separator, and hence splits up the
;overall string into multiple separate values.
;The input SplicedString assumes that values contain no CondPlatform.
;The input SplicedString assumes that values contain
;no CondPlatform and no CondLink.

defn collapse-spliced-strings (v:ProjValue) -> ProjValue :
val result = map(collapse-spliced-strings{_ as ProjValue}, v)
Expand Down
9 changes: 6 additions & 3 deletions compiler/proj-reader.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ defsyntax stanza-projfile :
DylibDirectoryStmtS0(closest-info(), dirs)

defrule projstmt = (package ?package:#symbol! requires #:! (?rs:#require! ...)) :
val dylib = entry?(rs, `dylib)
val dylibs = entry?(rs, `dylibs)
val ccfiles = entry?(rs, `ccfiles)
val ccflags = entry?(rs, `ccflags)
val fpackages = entries(rs, `foreign-packages)
RequiresStmtS0(closest-info(), package, dylib, ccfiles, ccflags, fpackages)
RequiresStmtS0(closest-info(), package, dylibs, ccfiles, ccflags, fpackages)

defrule projstmt = (import ?package:#symbol! when-imported ?deps:#projvalue!) :
ImportWhenStmtS0(closest-info(), package, deps)
Expand Down Expand Up @@ -143,6 +143,9 @@ defsyntax stanza-projfile :
defrule projvalue = (on-platform #:! (?es:#key-projvalue! ...)) :
CondPlatform(closest-info(), to-tuple(es))

defrule projvalue = (on-link #:! (?es:#key-projvalue! ...)) :
CondLink(closest-info(), to-tuple(es))

defproduction key-projvalue! : KeyValue<Symbol,ProjValue>
defrule key-projvalue! = (?key:#symbol! #:! ?v:#projvalue!) : key => v

Expand Down Expand Up @@ -175,7 +178,7 @@ defsyntax stanza-projfile :
;----------------- Require Statement Entries --------------
;----------------------------------------------------------
defproduction require! : KeyValue<Symbol,?>
defrule require! = (dynamic-library #:! ?v:#projvalue!) : `dylib => v
defrule require! = (dynamic-libraries #:! ?v:#projvalue!) : `dylibs => v
defrule require! = (ccfiles #:! ?v:#projvalue!) : `ccfiles => v
defrule require! = (ccflags #:! ?v:#projvalue!) : `ccflags => v
defrule require! = (?fps:#foreign-packages) : `foreign-packages => fps
Expand Down
Loading