Toplevel directory cleanup
[senf.git] / tools / scons-1.2.0 / engine / SCons / Tool / mslink.py
1 """SCons.Tool.mslink
2
3 Tool-specific initialization for the Microsoft linker.
4
5 There normally shouldn't be any need to import this module directly.
6 It will usually be imported through the generic SCons.Tool.Tool()
7 selection method.
8
9 """
10
11 #
12 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
13 #
14 # Permission is hereby granted, free of charge, to any person obtaining
15 # a copy of this software and associated documentation files (the
16 # "Software"), to deal in the Software without restriction, including
17 # without limitation the rights to use, copy, modify, merge, publish,
18 # distribute, sublicense, and/or sell copies of the Software, and to
19 # permit persons to whom the Software is furnished to do so, subject to
20 # the following conditions:
21 #
22 # The above copyright notice and this permission notice shall be included
23 # in all copies or substantial portions of the Software.
24 #
25 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
26 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
27 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 #
33
34 __revision__ = "src/engine/SCons/Tool/mslink.py 3842 2008/12/20 22:59:52 scons"
35
36 import os.path
37
38 import SCons.Action
39 import SCons.Defaults
40 import SCons.Errors
41 import SCons.Platform.win32
42 import SCons.Tool
43 import SCons.Tool.msvc
44 import SCons.Tool.msvs
45 import SCons.Util
46
47 def pdbGenerator(env, target, source, for_signature):
48     try:
49         return ['/PDB:%s' % target[0].attributes.pdb, '/DEBUG']
50     except (AttributeError, IndexError):
51         return None
52
53 def windowsShlinkTargets(target, source, env, for_signature):
54     listCmd = []
55     dll = env.FindIxes(target, 'SHLIBPREFIX', 'SHLIBSUFFIX')
56     if dll: listCmd.append("/out:%s"%dll.get_string(for_signature))
57
58     implib = env.FindIxes(target, 'LIBPREFIX', 'LIBSUFFIX')
59     if implib: listCmd.append("/implib:%s"%implib.get_string(for_signature))
60
61     return listCmd
62
63 def windowsShlinkSources(target, source, env, for_signature):
64     listCmd = []
65
66     deffile = env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX")
67     for src in source:
68         if src == deffile:
69             # Treat this source as a .def file.
70             listCmd.append("/def:%s" % src.get_string(for_signature))
71         else:
72             # Just treat it as a generic source file.
73             listCmd.append(src)
74     return listCmd
75
76 def windowsLibEmitter(target, source, env):
77     SCons.Tool.msvc.validate_vars(env)
78
79     extratargets = []
80     extrasources = []
81
82     dll = env.FindIxes(target, "SHLIBPREFIX", "SHLIBSUFFIX")
83     no_import_lib = env.get('no_import_lib', 0)
84
85     if not dll:
86         raise SCons.Errors.UserError, "A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX")
87
88     insert_def = env.subst("$WINDOWS_INSERT_DEF")
89     if not insert_def in ['', '0', 0] and \
90        not env.FindIxes(source, "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX"):
91
92         # append a def file to the list of sources
93         extrasources.append(
94             env.ReplaceIxes(dll,
95                             "SHLIBPREFIX", "SHLIBSUFFIX",
96                             "WINDOWSDEFPREFIX", "WINDOWSDEFSUFFIX"))
97
98     version_num, suite = SCons.Tool.msvs.msvs_parse_version(env.get('MSVS_VERSION', '6.0'))
99     if version_num >= 8.0 and env.get('WINDOWS_INSERT_MANIFEST', 0):
100         # MSVC 8 automatically generates .manifest files that must be installed
101         extratargets.append(
102             env.ReplaceIxes(dll,
103                             "SHLIBPREFIX", "SHLIBSUFFIX",
104                             "WINDOWSSHLIBMANIFESTPREFIX", "WINDOWSSHLIBMANIFESTSUFFIX"))
105
106     if env.has_key('PDB') and env['PDB']:
107         pdb = env.arg2nodes('$PDB', target=target, source=source)[0]
108         extratargets.append(pdb)
109         target[0].attributes.pdb = pdb
110
111     if not no_import_lib and \
112        not env.FindIxes(target, "LIBPREFIX", "LIBSUFFIX"):
113         # Append an import library to the list of targets.
114         extratargets.append(
115             env.ReplaceIxes(dll,
116                             "SHLIBPREFIX", "SHLIBSUFFIX",
117                             "LIBPREFIX", "LIBSUFFIX"))
118         # and .exp file is created if there are exports from a DLL
119         extratargets.append(
120             env.ReplaceIxes(dll,
121                             "SHLIBPREFIX", "SHLIBSUFFIX",
122                             "WINDOWSEXPPREFIX", "WINDOWSEXPSUFFIX"))
123
124     return (target+extratargets, source+extrasources)
125
126 def prog_emitter(target, source, env):
127     SCons.Tool.msvc.validate_vars(env)
128
129     extratargets = []
130
131     exe = env.FindIxes(target, "PROGPREFIX", "PROGSUFFIX")
132     if not exe:
133         raise SCons.Errors.UserError, "An executable should have exactly one target with the suffix: %s" % env.subst("$PROGSUFFIX")
134
135     version_num, suite = SCons.Tool.msvs.msvs_parse_version(env.get('MSVS_VERSION', '6.0'))
136     if version_num >= 8.0 and env.get('WINDOWS_INSERT_MANIFEST', 0):
137         # MSVC 8 automatically generates .manifest files that have to be installed
138         extratargets.append(
139             env.ReplaceIxes(exe,
140                             "PROGPREFIX", "PROGSUFFIX",
141                             "WINDOWSPROGMANIFESTPREFIX", "WINDOWSPROGMANIFESTSUFFIX"))
142
143     if env.has_key('PDB') and env['PDB']:
144         pdb = env.arg2nodes('$PDB', target=target, source=source)[0]
145         extratargets.append(pdb)
146         target[0].attributes.pdb = pdb
147
148     return (target+extratargets,source)
149
150 def RegServerFunc(target, source, env):
151     if env.has_key('register') and env['register']:
152         ret = regServerAction([target[0]], [source[0]], env)
153         if ret:
154             raise SCons.Errors.UserError, "Unable to register %s" % target[0]
155         else:
156             print "Registered %s sucessfully" % target[0]
157         return ret
158     return 0
159
160 regServerAction = SCons.Action.Action("$REGSVRCOM", "$REGSVRCOMSTR")
161 regServerCheck = SCons.Action.Action(RegServerFunc, None)
162 shlibLinkAction = SCons.Action.Action('${TEMPFILE("$SHLINK $SHLINKFLAGS $_SHLINK_TARGETS $( $_LIBDIRFLAGS $) $_LIBFLAGS $_PDB $_SHLINK_SOURCES")}')
163 compositeLinkAction = shlibLinkAction + regServerCheck
164
165 def generate(env):
166     """Add Builders and construction variables for ar to an Environment."""
167     SCons.Tool.createSharedLibBuilder(env)
168     SCons.Tool.createProgBuilder(env)
169
170     env['SHLINK']      = '$LINK'
171     env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS /dll')
172     env['_SHLINK_TARGETS'] = windowsShlinkTargets
173     env['_SHLINK_SOURCES'] = windowsShlinkSources
174     env['SHLINKCOM']   =  compositeLinkAction
175     env.Append(SHLIBEMITTER = [windowsLibEmitter])
176     env['LINK']        = 'link'
177     env['LINKFLAGS']   = SCons.Util.CLVar('/nologo')
178     env['_PDB'] = pdbGenerator
179     env['LINKCOM'] = '${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $( $_LIBDIRFLAGS $) $_LIBFLAGS $_PDB $SOURCES.windows")}'
180     env.Append(PROGEMITTER = [prog_emitter])
181     env['LIBDIRPREFIX']='/LIBPATH:'
182     env['LIBDIRSUFFIX']=''
183     env['LIBLINKPREFIX']=''
184     env['LIBLINKSUFFIX']='$LIBSUFFIX'
185
186     env['WIN32DEFPREFIX']        = ''
187     env['WIN32DEFSUFFIX']        = '.def'
188     env['WIN32_INSERT_DEF']      = 0
189     env['WINDOWSDEFPREFIX']      = '${WIN32DEFPREFIX}'
190     env['WINDOWSDEFSUFFIX']      = '${WIN32DEFSUFFIX}'
191     env['WINDOWS_INSERT_DEF']    = '${WIN32_INSERT_DEF}'
192
193     env['WIN32EXPPREFIX']        = ''
194     env['WIN32EXPSUFFIX']        = '.exp'
195     env['WINDOWSEXPPREFIX']      = '${WIN32EXPPREFIX}'
196     env['WINDOWSEXPSUFFIX']      = '${WIN32EXPSUFFIX}'
197
198     env['WINDOWSSHLIBMANIFESTPREFIX'] = ''
199     env['WINDOWSSHLIBMANIFESTSUFFIX'] = '${SHLIBSUFFIX}.manifest'
200     env['WINDOWSPROGMANIFESTPREFIX']  = ''
201     env['WINDOWSPROGMANIFESTSUFFIX']  = '${PROGSUFFIX}.manifest'
202
203     env['REGSVRACTION'] = regServerCheck
204     env['REGSVR'] = os.path.join(SCons.Platform.win32.get_system_root(),'System32','regsvr32')
205     env['REGSVRFLAGS'] = '/s '
206     env['REGSVRCOM'] = '$REGSVR $REGSVRFLAGS ${TARGET.windows}'
207
208     try:
209         version = SCons.Tool.msvs.get_default_visualstudio_version(env)
210
211         if env.has_key('MSVS_IGNORE_IDE_PATHS') and env['MSVS_IGNORE_IDE_PATHS']:
212             include_path, lib_path, exe_path = SCons.Tool.msvc.get_msvc_default_paths(env,version)
213         else:
214             include_path, lib_path, exe_path = SCons.Tool.msvc.get_msvc_paths(env,version)
215
216         # since other tools can set these, we just make sure that the
217         # relevant stuff from MSVS is in there somewhere.
218         env.PrependENVPath('INCLUDE', include_path)
219         env.PrependENVPath('LIB', lib_path)
220         env.PrependENVPath('PATH', exe_path)
221     except (SCons.Util.RegError, SCons.Errors.InternalError):
222         pass
223
224     # For most platforms, a loadable module is the same as a shared
225     # library.  Platforms which are different can override these, but
226     # setting them the same means that LoadableModule works everywhere.
227     SCons.Tool.createLoadableModuleBuilder(env)
228     env['LDMODULE'] = '$SHLINK'
229     env['LDMODULEPREFIX'] = '$SHLIBPREFIX'
230     env['LDMODULESUFFIX'] = '$SHLIBSUFFIX'
231     env['LDMODULEFLAGS'] = '$SHLINKFLAGS'
232     # We can't use '$SHLINKCOM' here because that will stringify the
233     # action list on expansion, and will then try to execute expanded
234     # strings, with the upshot that it would try to execute RegServerFunc
235     # as a command.
236     env['LDMODULECOM'] = compositeLinkAction
237
238 def exists(env):
239     platform = env.get('PLATFORM', '')
240     if SCons.Tool.msvs.is_msvs_installed():
241         # there's at least one version of MSVS installed.
242         return 1
243     elif platform in ('win32', 'cygwin'):
244         # Only explicitly search for a 'link' executable on Windows
245         # systems.  Some other systems (e.g. Ubuntu Linux) have an
246         # executable named 'link' and we don't want that to make SCons
247         # think Visual Studio is installed.
248         return env.Detect('link')
249     return None