summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2013-04-08 16:38:49 +0200
committerAraq <rumpf_a@web.de>2013-04-08 16:38:49 +0200
commit5893a9195c10181392262bf1a541737c2e2a142f (patch)
tree73f8fd3d0766eaeb839b642c210fcfa4a23a39dd
parentc4edcf3ea2fef970c3528f74cf3abb988a69e0e2 (diff)
downloadNim-5893a9195c10181392262bf1a541737c2e2a142f.tar.gz
implemented --dynlibOverride option for static linking of 'dynlib'
-rw-r--r--compiler/ast.nim1
-rw-r--r--compiler/commands.nim7
-rw-r--r--compiler/options.nim15
-rw-r--r--compiler/pragmas.nim7
-rw-r--r--doc/advopt.txt5
-rw-r--r--todo.txt2
6 files changed, 34 insertions, 3 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 8816d461a..c43bef926 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -594,6 +594,7 @@ type
   TLib* = object of lists.TListEntry # also misused for headers!
     kind*: TLibKind
     generated*: bool          # needed for the backends:
+    isOverriden*: bool
     name*: PRope
     path*: PNode              # can be a string literal!
   
diff --git a/compiler/commands.nim b/compiler/commands.nim
index 4dcf011f4..8f8afe206 100644
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -212,6 +212,11 @@ proc track(arg: string, info: TLineInfo) =
     LocalError(info, errInvalidNumber, a[2])
   msgs.addCheckpoint(newLineInfo(a[0], line, column))
 
+proc dynlibOverride(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
+  if pass in {passCmd2, passPP}:
+    expectArg(switch, arg, pass, info)
+    options.inclDynlibOverride(arg)
+
 proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = 
   var 
     theOS: TSystemOS
@@ -480,6 +485,8 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
   of "listfullpaths":
     expectNoArg(switch, arg, pass, info)
     gListFullPaths = true
+  of "dynliboverride":
+    dynlibOverride(switch, arg, pass, info)
   else:
     if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
     else: InvalidCmdLineOption(pass, switch, info)
diff --git a/compiler/options.nim b/compiler/options.nim
index ad7c834dc..b38263ec5 100644
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -124,6 +124,7 @@ const
 # additional configuration variables:
 var
   gConfigVars* = newStringTable(modeStyleInsensitive)
+  gDllOverrides = newStringtable(modeCaseInsensitive)
   libpath* = ""
   gProjectName* = "" # holds a name like 'nimrod'
   gProjectPath* = "" # holds a path like /home/alice/projects/nimrod/compiler/
@@ -256,6 +257,20 @@ proc libCandidates*(s: string, dest: var seq[string]) =
   else: 
     add(dest, s)
 
+proc canonDynlibName(s: string): string =
+  let start = if s.startsWith("lib"): 3 else: 0
+  let ende = strutils.find(s, {'(', ')', '.'})
+  if ende >= 0:
+    result = s.substr(start, ende-1)
+  else:
+    result = s.substr(start)
+
+proc inclDynlibOverride*(lib: string) =
+  gDllOverrides[lib.canonDynlibName] = "true"
+
+proc isDynlibOverride*(lib: string): bool =
+  result = gDllOverrides.hasKey(lib.canonDynlibName)
+
 proc binaryStrSearch*(x: openarray[string], y: string): int = 
   var a = 0
   var b = len(x) - 1
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 8f06beecd..ba761739a 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -202,6 +202,8 @@ proc getLib(c: PContext, kind: TLibKind, path: PNode): PLib =
   result = newLib(kind)
   result.path = path
   Append(c.libs, result)
+  if path.kind in {nkStrLit..nkTripleStrLit}:
+    result.isOverriden = options.isDynLibOverride(path.strVal)
 
 proc expectDynlibNode(c: PContext, n: PNode): PNode =
   if n.kind != nkExprColonExpr:
@@ -225,8 +227,9 @@ proc processDynLib(c: PContext, n: PNode, sym: PSym) =
   else:
     if n.kind == nkExprColonExpr:
       var lib = getLib(c, libDynamic, expectDynlibNode(c, n))
-      addToLib(lib, sym)
-      incl(sym.loc.flags, lfDynamicLib)
+      if not lib.isOverriden:
+        addToLib(lib, sym)
+        incl(sym.loc.flags, lfDynamicLib)
     else:
       incl(sym.loc.flags, lfExportLib)
     # since we'll be loading the dynlib symbols dynamically, we must use
diff --git a/doc/advopt.txt b/doc/advopt.txt
index b8088bbcd..bfeee0c64 100644
--- a/doc/advopt.txt
+++ b/doc/advopt.txt
@@ -70,6 +70,11 @@ Advanced options:
   --putenv:key=value        set an environment variable
   --babelPath:PATH          add a path for Babel support
   --excludePath:PATH        exclude a path from the list of search paths
+  --dynlibOverride:SYMBOL   marks SYMBOL so that dynlib:SYMBOL
+                            has no effect and can be statically linked instead;
+                            symbol matching is fuzzy so
+                            that --dynlibOverride:lua matches 
+                            dynlib: "liblua.so.3"
   --listCmd                 list the commands used to execute external programs
   --parallelBuild=0|1|...   perform a parallel build
                             value = number of processors (0 for auto-detect)
diff --git a/todo.txt b/todo.txt
index f83083202..ce3705a20 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,7 +1,6 @@
 version 0.9.2
 =============
 
-- a project wide override option for 'dynlib'
 - FFI:
   * test libffi on windows
   * test: times.format with the FFI
@@ -29,6 +28,7 @@ Bugs
 version 0.9.4
 =============
 
+- ``try`` as an expression
 - provide tool/API to track leaks/object counts
 - hybrid GC
 - use big blocks in the allocator