Commits

Russel Winder committed 725b926

Rearrange, refactor, rework, rewrite, fix.

Comments (0)

Files changed (19)

src/engine/SCons/Tool/DCommon.py

+"""
+Common code for the various D tools.
+
+Coded by Russel Winder (russel@winder.org.uk)
+2012-09-06
+"""
+import os.path
+
+def isD(source):
+    if not source:
+        return 0
+    for s in source:
+        if s.sources:
+            ext = os.path.splitext(str(s.sources[0]))[1]
+            if ext == '.d':
+                return 1
+    return 0
+
+def addDPATHToEnv(env, executable):
+    dPath = env.WhereIs(executable)
+    if dPath:
+        phobosDir = dPath[:dPath.rindex(executable)] + '/../src/phobos'
+        if os.path.isdir(phobosDir):
+            env.Append(DPATH=[phobosDir])
+
+def setSmartLink(env, smart_link, smart_lib):
+    linkcom = env.get('LINKCOM')
+    try:
+        env['SMART_LINKCOM'] = smart_link[linkcom]
+    except KeyError:
+        def _smartLink(source, target, env, for_signature, defaultLinker=linkcom):
+            if isD(source):
+                # TODO: I'm not sure how to add a $DLINKCOMSTR variable
+                # so that it works with this _smartLink() logic,
+                # and I don't have a D compiler/linker to try it out,
+                # so we'll leave it alone for now.
+                return '$DLINKCOM'
+            else:
+                return defaultLinker
+        env['SMART_LINKCOM'] = smart_link[linkcom] = _smartLink
+
+    arcom = env.get('ARCOM')
+    try:
+        env['SMART_ARCOM'] = smart_lib[arcom]
+    except KeyError:
+        def _smartLib(source, target, env, for_signature, defaultLib=arcom):
+            if isD(source):
+                # TODO: I'm not sure how to add a $DLIBCOMSTR variable
+                # so that it works with this _smartLib() logic, and
+                # I don't have a D compiler/archiver to try it out,
+                # so we'll leave it alone for now.
+                return '$DLIBCOM'
+            else:
+                return defaultLib
+        env['SMART_ARCOM'] = smart_lib[arcom] = _smartLib
+

src/engine/SCons/Tool/dmd.py

 import SCons.Scanner.D
 import SCons.Tool
 
-def isD(source):
-    if not source:
-        return 0
-    for s in source:
-        if s.sources:
-            ext = os.path.splitext(str(s.sources[0]))[1]
-            if ext == '.d':
-                return 1
-    return 0
+import DCommon
 
 smart_link = {}
-
 smart_lib = {}
 
 def generate(env):
-    global smart_link
-    global smart_lib
-
     static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
 
     DAction = SCons.Action.Action('$DCOM', '$DCOMSTR')
     env['DDEBUG'] = []
 
     if dc:
-        # Add the path to the standard library.
-        # This is merely for the convenience of the dependency scanner.
-        dmd_path = env.WhereIs(dc)
-        if dmd_path:
-            x = dmd_path.rindex(dc)
-            phobosDir = dmd_path[:x] + '/../src/phobos'
-            if os.path.isdir(phobosDir):
-                env.Append(DPATH = [phobosDir])
+        DCommon.addDPATHToEnv(env, dc)
 
     env['DINCPREFIX'] = '-I'
     env['DINCSUFFIX'] = ''
     # these builders check for the presence of D source, and swap out
     # the system's defaults for the Digital Mars tools.  If there's no D
     # source, then we silently return the previous settings.
-    linkcom = env.get('LINKCOM')
-    try:
-        env['SMART_LINKCOM'] = smart_link[linkcom]
-    except KeyError:
-        def _smartLink(source, target, env, for_signature, defaultLinker=linkcom):
-            if isD(source):
-                # TODO: I'm not sure how to add a $DLINKCOMSTR variable
-                # so that it works with this _smartLink() logic,
-                # and I don't have a D compiler/linker to try it out,
-                # so we'll leave it alone for now.
-                return '$DLINKCOM'
-            else:
-                return defaultLinker
-        env['SMART_LINKCOM'] = smart_link[linkcom] = _smartLink
-
-    arcom = env.get('ARCOM')
-    try:
-        env['SMART_ARCOM'] = smart_lib[arcom]
-    except KeyError:
-        def _smartLib(source, target, env, for_signature, defaultLib=arcom):
-            if isD(source):
-                # TODO: I'm not sure how to add a $DLIBCOMSTR variable
-                # so that it works with this _smartLib() logic, and
-                # I don't have a D compiler/archiver to try it out,
-                # so we'll leave it alone for now.
-                return '$DLIBCOM'
-            else:
-                return defaultLib
-        env['SMART_ARCOM'] = smart_lib[arcom] = _smartLib
+    DCommon.setSmartLink(env, smart_link, smart_lib)
 
     # It is worth noting that the final space in these strings is
     # absolutely pivotal.  SCons sees these as actions and not generators

src/engine/SCons/Tool/gdc.py

 import SCons.Defaults
 import SCons.Tool
 
+import DCommon
+
+smart_link = {}
+smart_lib = {}
+
 def generate(env):
-
     static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
 
     DAction = SCons.Action.Action('$DCOM', '$DCOMSTR')
     static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter)
     shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter)
 
-    env['DC'] = env.Detect('gdc')
+    dc = env.Detect('gdc')
+    env['DC'] = dc
     env['DCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -o $TARGET $SOURCES'
     env['_DINCFLAGS'] = '$( ${_concat(DINCPREFIX, DPATH, DINCSUFFIX, __env__, RDirs, TARGET, SOURCE)}  $)'
     env['_DVERFLAGS'] = '$( ${_concat(DVERPREFIX, DVERSIONS, DVERSUFFIX, __env__)}  $)'
     env['DVERSIONS'] = []
     env['DDEBUG'] = []
 
+    if dc:
+        DCommon.addDPATHToEnv(env, dc)
+
     env['DINCPREFIX'] = '-I'
     env['DINCSUFFIX'] = ''
     env['DVERPREFIX'] = '-version='
     env['DFLAGSUFFIX'] = ''
     env['DFILESUFFIX'] = '.d'
 
-    env['LINK'] = '$DC'
+    env['DLINK'] = '$DC'
+    env['DLINKCOM'] = '$DLINK -o $TARGET $SOURCES $DFLAGS $DLINKFLAGS $_DLINKLIBFLAGS'
+    env['DLIB'] = 'lib'
+    env['DLIBCOM'] = '$DLIB $_DLIBFLAGS -c $TARGET $SOURCES $_DLINKLIBFLAGS'
+
+    env['_DLINKLIBFLAGS'] = '$( ${_concat(DLIBLINKPREFIX, LIBS, DLIBLINKSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
+    env['_DLIBFLAGS'] = '$( ${_concat(DLIBFLAGPREFIX, DLIBFLAGS, DLIBFLAGSUFFIX, __env__)} $)'
+    env['DLINKFLAGS'] = []
+    env['DLIBLINKPREFIX'] = '' if env['PLATFORM'] == 'win32' else '-l'
+    env['DLIBLINKSUFFIX'] = '.lib' if env['PLATFORM'] == 'win32' else ''
+    env['DLIBFLAGPREFIX'] = '-'
+    env['DLIBFLAGSUFFIX'] = ''
+    env['DLINKFLAGPREFIX'] = '-'
+    env['DLINKFLAGSUFFIX'] = ''
+
+    SCons.Tool.createStaticLibBuilder(env)
+
+    # Basically, we hijack the link and ar builders with our own.
+    # these builders check for the presence of D source, and swap out
+    # the system's defaults for the Digital Mars tools.  If there's no D
+    # source, then we silently return the previous settings.
+    DCommon.setSmartLink(env, smart_link, smart_lib)
+
+    # It is worth noting that the final space in these strings is
+    # absolutely pivotal.  SCons sees these as actions and not generators
+    # if it is not there. (very bad)
+    env['ARCOM'] = '$SMART_ARCOM '
+    env['LINKCOM'] = '$SMART_LINKCOM '
 
 def exists(env):
     return env.Detect('gdc')

src/engine/SCons/Tool/ldc.py

 (http://www.dsource.org/projects/ldc)
 
 Coded by Russel Winder (russel@winder.org.uk)
-2012-05-09
+2012-05-09, 2012-09-06
 
 Compiler variables:
-    DC - The name of the D compiler to use.  Defaults to ldc.
+    DC - The name of the D compiler to use.  Defaults to ldc2.
     DPATH - List of paths to search for import modules.
     DVERSIONS - List of version tags to enable when compiling.
     DDEBUG - List of debug tags to enable when compiling.
 import SCons.Scanner.D
 import SCons.Tool
 
-# Adapted from c++.py
-def isD(source):
-    if not source:
-        return 0
+import DCommon
 
-    for s in source:
-        if s.sources:
-            ext = os.path.splitext(str(s.sources[0]))[1]
-            if ext == '.d':
-                return 1
-    return 0
+smart_link = {}
+smart_lib = {}
 
 def generate(env):
-
     static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
 
     DAction = SCons.Action.Action('$DCOM', '$DCOMSTR')
     static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter)
     shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter)
 
-    dc = env.Detect('ldc')
+    dc = env.Detect('ldc2')
     env['DC'] = dc
     env['DCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -of=$TARGET $SOURCES'
     env['_DINCFLAGS'] = '$( ${_concat(DINCPREFIX, DPATH, DINCSUFFIX, __env__, RDirs, TARGET, SOURCE)}  $)'
     env['DDEBUG'] = []
 
     if dc:
-        # Add the path to the standard library.
-        # This is merely for the convenience of the dependency scanner.
-        dmd_path = env.WhereIs(dc)
-        if dmd_path:
-            x = dmd_path.rindex(dc)
-            phobosDir = dmd_path[:x] + '/../src/phobos'
-            if os.path.isdir(phobosDir):
-                env.Append(DPATH = [phobosDir])
+        DCommon.addDPATHToEnv(env, dc)
 
     env['DINCPREFIX'] = '-I='
     env['DINCSUFFIX'] = ''
     env['DFLAGSUFFIX'] = ''
     env['DFILESUFFIX'] = '.d'
 
-    try :
-        env['LIBS'].append ( [ '-lgphobos2' ] )
-    except KeyError :
-        env['LIBS'] = [ '-lgphobos2' , '-lpthread' , '-lrt' , '-lm' ]
+    env['DLINK'] = '$DC'
+    env['DLINKCOM'] = '$DLINK -of$TARGET $SOURCES $DFLAGS $DLINKFLAGS $_DLINKLIBFLAGS'
+    env['DLIB'] = 'lib'
+    env['DLIBCOM'] = '$DLIB $_DLIBFLAGS -c $TARGET $SOURCES $_DLINKLIBFLAGS'
+
+    env['_DLINKLIBFLAGS'] = '$( ${_concat(DLIBLINKPREFIX, LIBS, DLIBLINKSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
+    env['_DLIBFLAGS'] = '$( ${_concat(DLIBFLAGPREFIX, DLIBFLAGS, DLIBFLAGSUFFIX, __env__)} $)'
+    env['DLINKFLAGS'] = []
+    env['DLIBLINKPREFIX'] = '' if env['PLATFORM'] == 'win32' else '-L-l'
+    env['DLIBLINKSUFFIX'] = '.lib' if env['PLATFORM'] == 'win32' else ''
+    env['DLIBFLAGPREFIX'] = '-'
+    env['DLIBFLAGSUFFIX'] = ''
+    env['DLINKFLAGPREFIX'] = '-'
+    env['DLINKFLAGSUFFIX'] = ''
+
+    SCons.Tool.createStaticLibBuilder(env)
+
+    # Basically, we hijack the link and ar builders with our own.
+    # these builders check for the presence of D source, and swap out
+    # the system's defaults for the Digital Mars tools.  If there's no D
+    # source, then we silently return the previous settings.
+    DCommon.setSmartLink(env, smart_link, smart_lib)
+
+    # It is worth noting that the final space in these strings is
+    # absolutely pivotal.  SCons sees these as actions and not generators
+    # if it is not there. (very bad)
+    env['ARCOM'] = '$SMART_ARCOM '
+    env['LINKCOM'] = '$SMART_LINKCOM '
 
 
 def exists(env):
-    return env.Detect('ldc')
+    return env.Detect('ldc2')
 
 # Local Variables:
 # tab-width:4

test/D/CoreScanner/Image/SConstruct_template

 # -*- mode:python; coding:utf-8; -*-
 
-environment = Environment(tools=['link', '{}'])
+import os
+
+environment = Environment(
+    ENV=os.environ,
+    tools=['link', '{}'])
 environment.Program('test1.d')
 environment.Program('test2.d')

test/D/CoreScanner/common.py

 
 import TestSCons
 
-from os.path import isfile
+from os.path import abspath, dirname
+
+import sys
+sys.path.insert(1, abspath(dirname(__file__) + '/../Support'))
+
+from executablesSearch import isExecutableOfToolAvailable
 
 def testForTool(tool):
 
 
     _obj = TestSCons._obj
 
-    toolPath = '../../../{}.py'.format(tool)
-    if isfile(toolPath):
-        test.file_fixture(toolPath)
-    if not test.where_is(tool) :
-        test.skip_test("Could not find '{}'; skipping test.\n".format(tool))
+    if not isExecutableOfToolAvailable(test, tool) :
+        test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool))
 
     test.dir_fixture('Image')
     test.write('SConstruct', open('SConstruct_template', 'r').read().format(tool))

test/D/HSTeoh/LinkingProblem/SConstruct_template

 # -*- mode:python; coding=utf-8; -*-
 
+import os
+
 environment = Environment(
+    ENV=os.environ,
     tools = ['cc', 'link' , '{}'],
-    LIBS = ['ncurses']
-)
+    LIBS = ['ncurses'])
 
 environment.Object('ncurs_impl.o', 'ncurs_impl.c')
 

test/D/HSTeoh/SingleStringCannotBeMultipleOptions/SConstruct_template

 # -*- mode:python; coding=utf-8; -*-
 
+import os
+
 environment = Environment(
+    ENV=os.environ,
     tools=['link', '{}'],
     # It might be thought that a single string can contain multiple options space separated. Actually this
     # is deemed to be a single option, so leads to an error.
-    DFLAGS = '-m64 -O'
-    )
+    DFLAGS = '-m64 -O')
 
 environment.Program('proj', Split("""
 proj.d

test/D/HSTeoh/linkingProblem_common.py

 
 import TestSCons
 
-from os.path import isfile
+from os.path import abspath, dirname
+
+import sys
+sys.path.insert(1, abspath(dirname(__file__) + '/../Support'))
+
+from executablesSearch import isExecutableOfToolAvailable
 
 def testForTool(tool):
 
     test = TestSCons.TestSCons()
 
-    toolPath = '../../{}.py'.format(tool)
-    if isfile(toolPath):
-        test.file_fixture(toolPath)
-    if not test.where_is(tool) :
-        test.skip_test("Could not find '{}'; skipping test.\n".format(tool))
+    if not isExecutableOfToolAvailable(test, tool) :
+        test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool))
 
     test.dir_fixture('LinkingProblem')
     test.write('SConstruct', open('SConstruct_template', 'r').read().format(tool))

test/D/HSTeoh/sconstest-linkingProblem_ldc.py

 """
-Test compiling and executing using the gdc tool.
+Test compiling and executing using the ldc tool.
 """
 
 #

test/D/HSTeoh/singleStringCannotBeMultipleOptions_common.py

 
 import TestSCons
 
-from os.path import isfile
+from os.path import abspath, dirname
+
+import sys
+sys.path.insert(1, abspath(dirname(__file__) + '/../Support'))
+
+from executablesSearch import isExecutableOfToolAvailable
 
 def testForTool(tool):
 
     test = TestSCons.TestSCons()
 
-    toolPath = '../../../{}.py'.format(tool)
-    if isfile(toolPath):
-        test.file_fixture(toolPath)
-    if not test.where_is(tool) :
-        test.skip_test("Could not find '{}', skipping test.\n".format(tool))
+    if not isExecutableOfToolAvailable(test, tool) :
+        test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool))
 
     test.dir_fixture('SingleStringCannotBeMultipleOptions')
     test.write('SConstruct', open('SConstruct_template', 'r').read().format(tool))
 
     test.run(status=2, stdout=None, stderr=None)
 
-    if tool == 'gdc':
-        result = ".*unrecognized command line option '-m64 -O'.*"
-    else:
-        result = ".*unrecognized switch '-m64 -O'.*"
+    result = {
+        'dmd': ".*unrecognized switch '-m64 -O'.*",
+        'gdc': ".*unrecognized command line option.*",
+        'ldc': ".*Unknown command line argument '-m64 -O'.*",
+        }[tool]
 
     test.fail_test(not test.match_re_dotall(test.stderr(), result))
 

test/D/HelloWorld/CompileAndLinkOneStep/Image/SConstruct_template

 # -*- mode:python; coding:utf-8; -*-
 
-environment = Environment(tools=['link', '{}'])
+import os
+
+environment = Environment(
+    ENV=os.environ,
+    tools=['link', '{}'])
 
 environment.Program('helloWorld.d')

test/D/HelloWorld/CompileAndLinkOneStep/common.py

 
 import TestSCons
 
-from os.path import isfile
+from os.path import abspath, dirname
+
+import sys
+sys.path.insert(1, abspath(dirname(__file__) + '/../../Support'))
+
+from executablesSearch import isExecutableOfToolAvailable
 
 def testForTool(tool):
 
     test = TestSCons.TestSCons()
 
-    toolPath = '../../../{}.py'.format(tool)
-    if isfile(toolPath):
-        test.file_fixture(toolPath)
-    if not test.where_is(tool):
-        test.skip_test("Could not find '{}', skipping test.\n".format(tool))
+    if not isExecutableOfToolAvailable(test, tool) :
+        test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool))
 
     test.dir_fixture('Image')
     test.write('SConstruct', open('SConstruct_template', 'r').read().format(tool))

test/D/HelloWorld/CompileThenLinkTwoSteps/Image/SConstruct_template

 # -*- mode:python; coding:utf-8; -*-
 
-environment = Environment(tools=['link', '{}'])
+import os
+
+environment = Environment(
+    ENV=os.environ,
+    tools=['link', '{}'])
 
 objects = environment.Object('helloWorld.d')
 

test/D/HelloWorld/CompileThenLinkTwoSteps/common.py

 
 import TestSCons
 
-from os.path import isfile
+from os.path import abspath, dirname
+
+import sys
+sys.path.insert(1, abspath(dirname(__file__) + '/../../Support'))
+
+from executablesSearch import isExecutableOfToolAvailable
 
 def testForTool(tool):
 
     test = TestSCons.TestSCons()
 
-    toolPath = '../../../{}.py'.format(tool)
-    if isfile(toolPath):
-        test.file_fixture(toolPath)
-    if not test.where_is(tool) :
-        test.skip_test("Could not find '{}'; skipping test.\n".format(tool))
+    if not isExecutableOfToolAvailable(test, tool) :
+        test.skip_test("Required executable for tool '{}' not found, skipping test.\n".format(tool))
 
     test.dir_fixture('Image')
     test.write('SConstruct', open('SConstruct_template', 'r').read().format(tool))
 
 import TestSCons
 
+from os.path import abspath, dirname
+
+import sys
+sys.path.insert(1, abspath(dirname(__file__) + '/Support'))
+
+from executablesSearch import isExecutableOfToolAvailable
+
 _exe = TestSCons._exe
 test = TestSCons.TestSCons()
 
-if not test.where_is('ldc'):
+if not isExecutableOfToolAvailable(test, 'ldc'):
     test.skip_test("Could not find 'ldc', skipping test.\n")
 
 test.write('SConstruct', """\

test/D/MixedDAndC/Image/SConstruct

-env = Environment(
-    DFLAGS=['-m64', '-O'],
-    )
+# -*- codig:utf-8; -*-
 
-env.Program('proj', [
+import os
+
+environment = Environment(
+    ENV=os.environ,
+    DFLAGS=['-m64', '-O'])
+
+environment.Program('proj', [
 'proj.d',
 'dmod.d',
 'cmod.c',

test/D/Support/executablesSearch.py

+"""
+Support functions for all the tests.
+"""
+
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+def isExecutableOfToolAvailable(test, tool):
+    for executable in {
+        'dmd': ['dmd', 'gdmd'],
+        'gdc': ['gdc'],
+        'ldc': ['ldc2', 'ldc']}[tool]:
+        if test.where_is(executable):
+            return True
+    return False
Add a comment to this file

test/D/Support/sconstest.skip

Empty file added.

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.