def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) libraries, library_dirs, runtime_library_dirs = fixed_args # filter out standard library paths, which are not explicitely needed # for linking library_dirs = [dir for dir in library_dirs if not dir in ('/lib', '/lib64', '/usr/lib', '/usr/lib64')] runtime_library_dirs = [dir for dir in runtime_library_dirs if not dir in ('/lib', '/lib64', '/usr/lib', '/usr/lib64')] lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if not isinstance(output_dir, (str, type(None))): raise TypeError("'output_dir' must be a string or None") if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: # skip over environment variable settings if /usr/bin/env # is used to set up the linker's environment. # This is needed on OSX. Note: this assumes that the # normal and C++ compiler have the same environment # settings. i = 0 if os.path.basename(linker[0]) == "env": i = 1 while '=' in linker[i]: i += 1 linker[i] = self.compiler_cxx[i] if sys.platform == 'darwin': linker = _darwin_compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename)
def link_executable (self, objects, output_progname, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, debug=0, extra_preargs=None, extra_postargs=None): (objects, output_dir) = self._fix_object_args (objects, output_dir) (libraries, library_dirs, runtime_library_dirs) = \ self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) lib_opts = gen_lib_options (self, library_dirs, runtime_library_dirs, libraries) output_filename = output_progname # Unix-ism! if output_dir is not None: output_filename = os.path.join (output_dir, output_filename) if self._need_link (objects, output_filename): ld_args = objects + self.objects + lib_opts + ['-o', output_filename] if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend (extra_postargs) self.mkpath (os.path.dirname (output_filename)) try: self.spawn (self.linker_exe + ld_args) except DistutilsExecError, msg: raise LinkError, msg
def link( self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None, ): if not self.initialized: self.initialize() objects, output_dir = self._fix_object_args(objects, output_dir) libraries, library_dirs, runtime_library_dirs = self._fix_lib_args( libraries, library_dirs, runtime_library_dirs ) if runtime_library_dirs: self.warn("I don't know what to do with 'runtime_library_dirs': " + str(runtime_library_dirs)) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): if target_desc == CCompiler.EXECUTABLE: if debug: ldflags = self.ldflags_shared_debug[1:] else: ldflags = self.ldflags_shared[1:] elif debug: ldflags = self.ldflags_shared_debug else: ldflags = self.ldflags_shared export_opts = [] for sym in export_symbols or []: export_opts.append("/EXPORT:" + sym) ld_args = ldflags + lib_opts + export_opts + objects + ["/OUT:" + output_filename] if export_symbols is not None: dll_name, dll_ext = os.path.splitext(os.path.basename(output_filename)) implib_file = os.path.join(os.path.dirname(objects[0]), self.library_filename(dll_name)) ld_args.append("/IMPLIB:" + implib_file) if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: self.spawn([self.linker] + ld_args) except DistutilsExecError as msg: raise LinkError, msg else: log.debug("skipping %s (up-to-date)", output_filename) return
def test_gen_lib_options(self): compiler = FakeCompiler() libdirs = ["lib1", "lib2"] runlibdirs = ["runlib1"] libs = [os.path.join("dir", "name"), "name2"] opts = gen_lib_options(compiler, libdirs, runlibdirs, libs) wanted = ["-Llib1", "-Llib2", "-cool", "-Rrunlib1", "found", "-lname2"] self.assertEqual(opts, wanted)
def link(self, target_desc, objects, output_filename, output_dir = None, libraries = None, library_dirs = None, runtime_library_dirs = None, export_symbols = None, debug = 0, extra_preargs = None, extra_postargs = None, build_temp = None, target_lang = None): if not self.initialized: self.initialize() objects, output_dir = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) libraries, library_dirs, runtime_library_dirs = fixed_args if runtime_library_dirs: self.warn("I don't know what to do with 'runtime_library_dirs': " + str(runtime_library_dirs)) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): if target_desc == CCompiler.EXECUTABLE: if debug: ldflags = self.ldflags_shared_debug[1:] else: ldflags = self.ldflags_shared[1:] elif debug: ldflags = self.ldflags_shared_debug else: ldflags = self.ldflags_shared export_opts = [] for sym in export_symbols or []: export_opts.append('/EXPORT:' + sym) ld_args = ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename] build_temp = os.path.dirname(objects[0]) if export_symbols is not None: dll_name, dll_ext = os.path.splitext(os.path.basename(output_filename)) implib_file = os.path.join(build_temp, self.library_filename(dll_name)) ld_args.append('/IMPLIB:' + implib_file) self.manifest_setup_ldargs(output_filename, build_temp, ld_args) if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: self.spawn([self.linker] + ld_args) except DistutilsExecError as msg: raise LinkError(msg) mfinfo = self.manifest_get_embed_info(target_desc, ld_args) if mfinfo is not None: mffilename, mfid = mfinfo out_arg = '-outputresource:%s;%s' % (output_filename, mfid) try: self.spawn(['mt.exe', '-nologo', '-manifest', mffilename, out_arg]) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug('skipping %s (up-to-date)', output_filename) return
def link( self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None, ): objects, output_dir = self._fix_object_args(objects, output_dir) libraries, library_dirs, runtime_library_dirs = self._fix_lib_args( libraries, library_dirs, runtime_library_dirs ) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if type(output_dir) not in (StringType, NoneType): raise TypeError, "'output_dir' must be a string or None" if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = objects + self.objects + lib_opts + ["-o", output_filename] if debug: ld_args[:0] = ["-g"] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: i = 0 if os.path.basename(linker[0]) == "env": i = 1 while "=" in linker[i]: i = i + 1 linker[i] = self.compiler_cxx[i] if sys.platform == "darwin": linker = _osx_support.compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError as msg: raise LinkError, msg else: log.debug("skipping %s (up-to-date)", output_filename) return
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) libraries, library_dirs, runtime_library_dirs = \ self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if type(output_dir) not in (StringType, NoneType): raise TypeError, "'output_dir' must be a string or None" if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: i = 0 if os.path.basename(linker[0]) == "env": i = 1 while '=' in linker[i]: i = i + 1 linker[i] = self.compiler_cxx[0] # is used to set up the linker's environment. # This is needed on OSX. Note: this assumes that the # normal and C++ compiler have the same environment # settings. i = 0 if os.path.basename(linker[0]) == "env": i = 1 while '=' in linker[i]: i = i + 1 linker[i] = self.compiler_cxx[i] if sys.platform == 'darwin': linker = _darwin_compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError, msg: raise LinkError, msg
def test_gen_lib_options(self): compiler = FakeCompiler() libdirs = ['lib1', 'lib2'] runlibdirs = ['runlib1'] libs = [os.path.join('dir', 'name'), 'name2'] opts = gen_lib_options(compiler, libdirs, runlibdirs, libs) wanted = ['-Llib1', '-Llib2', '-cool', '-Rrunlib1', 'found', '-lname2'] self.assertEqual(opts, wanted)
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) libraries, library_dirs, runtime_library_dirs = fixed_args lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if not isinstance(output_dir, (str, type(None))): raise TypeError("'output_dir' must be a string or None") if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_lang == "c++": if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe_cxx[:] else: linker = self.linker_so_cxx[:] else: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if sys.platform == 'darwin': linker = _darwin_compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename)
def link_executable (self, objects, output_progname, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, debug=0, extra_preargs=None, extra_postargs=None): (objects, output_dir) = self._fix_object_args (objects, output_dir) (libraries, library_dirs, runtime_library_dirs) = \ self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) if runtime_library_dirs: self.warn ("I don't know what to do with 'runtime_library_dirs': " + str (runtime_library_dirs)) lib_opts = gen_lib_options (self, library_dirs, runtime_library_dirs, libraries) output_filename = output_progname + self.exe_extension if output_dir is not None: output_filename = os.path.join (output_dir, output_filename) if self._need_link (objects, output_filename): if debug: ldflags = self.ldflags_shared_debug[1:] else: ldflags = self.ldflags_shared[1:] ld_args = ldflags + lib_opts + \ objects + ['/OUT:' + output_filename] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend (extra_postargs) self.mkpath (os.path.dirname (output_filename)) try: self.spawn ([self.link] + ld_args) except DistutilsExecError, msg: raise LinkError, msg
def link (self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None): (objects, output_dir) = self._fix_object_args(objects, output_dir) (libraries, library_dirs, runtime_library_dirs) = \ self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if type(output_dir) not in (StringType, NoneType): raise TypeError, "'output_dir' must be a string or None" if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: self.spawn(self.linker_exe + ld_args) else: self.spawn(self.linker_so + ld_args) except DistutilsExecError, msg: raise LinkError, msg
def get_setuptools_options(): build_ext = get_prepared_build_ext() compiler = build_ext.compiler options = [] if compiler: if compiler.compiler_so: options.extend(compiler.compiler_so[1:]) options.extend(ccompiler.gen_preprocess_options( macros=compiler.macros, include_dirs=compiler.include_dirs)) options.extend(ccompiler.gen_lib_options( compiler=compiler, library_dirs=compiler.library_dirs, runtime_library_dirs=compiler.runtime_library_dirs, libraries=compiler.libraries)) if build_ext.extensions: for ext in build_ext.extensions: options.extend(ext.extra_compile_args) return options
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) libraries, library_dirs, runtime_library_dirs = \ self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) # filter out standard library paths, which are not explicitely needed # for linking library_dirs = [dir for dir in library_dirs if not dir in ('/lib', '/lib64', '/usr/lib', '/usr/lib64')] runtime_library_dirs = [dir for dir in runtime_library_dirs if not dir in ('/lib', '/lib64', '/usr/lib', '/usr/lib64')] lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if type(output_dir) not in (StringType, NoneType): raise TypeError, "'output_dir' must be a string or None" if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: linker[0] = self.compiler_cxx[0] self.spawn(linker + ld_args) except DistutilsExecError, msg: raise LinkError, msg
"""distutils.unixccompiler
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): if not self.initialized: self.initialize() (objects, output_dir) = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) (libraries, library_dirs, runtime_library_dirs) = fixed_args if runtime_library_dirs: self.warn ("I don't know what to do with 'runtime_library_dirs': " + str (runtime_library_dirs)) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): if target_desc == CCompiler.EXECUTABLE: if debug: ldflags = self.ldflags_shared_debug[1:] else: ldflags = self.ldflags_shared[1:] else: if debug: ldflags = self.ldflags_shared_debug else: ldflags = self.ldflags_shared export_opts = [] for sym in (export_symbols or []): export_opts.append("/EXPORT:" + sym) ld_args = (ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename]) # The MSVC linker generates .lib and .exp files, which cannot be # suppressed by any linker switches. The .lib files may even be # needed! Make sure they are generated in the temporary build # directory. Since they have different names for debug and release # builds, they can go into the same directory. build_temp = os.path.dirname(objects[0]) if export_symbols is not None: (dll_name, dll_ext) = os.path.splitext( os.path.basename(output_filename)) implib_file = os.path.join( build_temp, self.library_filename(dll_name)) ld_args.append ('/IMPLIB:' + implib_file) # Embedded manifests are recommended - see MSDN article titled # "How to: Embed a Manifest Inside a C/C++ Application" # (currently at http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx) # Ask the linker to generate the manifest in the temp dir, so # we can embed it later. temp_manifest = os.path.join( build_temp, os.path.basename(output_filename) + ".manifest") ld_args.append('/MANIFESTFILE:' + temp_manifest) if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: self.spawn([self.linker] + ld_args) except DistutilsExecError as msg: raise LinkError(msg) # embed the manifest # XXX - this is somewhat fragile - if mt.exe fails, distutils # will still consider the DLL up-to-date, but it will not have a # manifest. Maybe we should link to a temp file? OTOH, that # implies a build environment error that shouldn't go undetected. if target_desc == CCompiler.EXECUTABLE: mfid = 1 else: mfid = 2 try: # Remove references to the Visual C runtime, so they will # fall through to the Visual C dependency of Python.exe. # This way, when installed for a restricted user (e.g. # runtimes are not in WinSxS folder, but in Python's own # folder), the runtimes do not need to be in every folder # with .pyd's. manifest_f = open(temp_manifest, "rb") manifest_buf = manifest_f.read() manifest_f.close() pattern = re.compile( r"""<assemblyIdentity.*?name=("|')Microsoft\."""\ r"""VC\d{2}\.CRT("|').*?(/>|</assemblyIdentity>)""", re.DOTALL) manifest_buf = re.sub(pattern, "", manifest_buf) pattern = "<dependentAssembly>\s*</dependentAssembly>" manifest_buf = re.sub(pattern, "", manifest_buf) manifest_f = open(temp_manifest, "wb") manifest_f.write(manifest_buf) manifest_f.close() except IOError: pass out_arg = '-outputresource:%s;%s' % (output_filename, mfid) try: self.spawn(['mt.exe', '-nologo', '-manifest', temp_manifest, out_arg]) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename)
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) libraries, library_dirs, runtime_library_dirs = \ self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) # filter out standard library paths, which are not explicitely needed # for linking library_dirs = [ dir for dir in library_dirs if not dir in ('/lib', '/lib64', '/usr/lib', '/usr/lib64') ] runtime_library_dirs = [ dir for dir in runtime_library_dirs if not dir in ('/lib', '/lib64', '/usr/lib', '/usr/lib64') ] lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if type(output_dir) not in (StringType, NoneType): raise TypeError, "'output_dir' must be a string or None" if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: # skip over environment variable settings if /usr/bin/env # is used to set up the linker's environment. # This is needed on OSX. Note: this assumes that the # normal and C++ compiler have the same environment # settings. i = 0 if os.path.basename(linker[0]) == "env": i = 1 while '=' in linker[i]: i = i + 1 linker[i] = self.compiler_cxx[i] if sys.platform == 'darwin': linker = _osx_support.compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError, msg: raise LinkError, msg
def build(self, directory='output', compile=True, run=True, debug=False, clean=True, with_output=True, native=True, additional_source_files=None, run_args=None, **kwds): ''' Build the project TODO: more details Parameters ---------- directory : str The output directory to write the project to, any existing files will be overwritten. compile : bool Whether or not to attempt to compile the project run : bool Whether or not to attempt to run the built project if it successfully builds. debug : bool Whether to compile in debug mode. with_output : bool Whether or not to show the ``stdout`` of the built program when run. native : bool Whether or not to compile for the current machine's architecture (best for speed, but not portable) clean : bool Whether or not to clean the project before building additional_source_files : list of str A list of additional ``.cpp`` files to include in the build. ''' renames = { 'project_dir': 'directory', 'compile_project': 'compile', 'run_project': 'run' } if len(kwds): msg = '' for kwd in kwds: if kwd in renames: msg += ("Keyword argument '%s' has been renamed to " "'%s'. ") % (kwd, renames[kwd]) else: msg += "Unknown keyword argument '%s'. " % kwd raise TypeError(msg) if additional_source_files is None: additional_source_files = [] if run_args is None: run_args = [] self.project_dir = directory ensure_directory(directory) compiler, extra_compile_args = get_compiler_and_args() compiler_obj = ccompiler.new_compiler(compiler=compiler) compiler_flags = (ccompiler.gen_preprocess_options( prefs['codegen.cpp.define_macros'], prefs['codegen.cpp.include_dirs']) + extra_compile_args) linker_flags = (ccompiler.gen_lib_options( compiler_obj, library_dirs=prefs['codegen.cpp.library_dirs'], runtime_library_dirs=prefs['codegen.cpp.runtime_library_dirs'], libraries=prefs['codegen.cpp.libraries']) + prefs['codegen.cpp.extra_link_args']) for d in ['code_objects', 'results', 'static_arrays']: ensure_directory(os.path.join(directory, d)) writer = CPPWriter(directory) # Get the number of threads if specified in an openmp context nb_threads = prefs.devices.cpp_standalone.openmp_threads # If the number is negative, we need to throw an error if (nb_threads < 0): raise ValueError( 'The number of OpenMP threads can not be negative !') logger.debug("Writing C++ standalone project to directory " + os.path.normpath(directory)) self.check_openmp_compatible(nb_threads) arange_arrays = sorted( [(var, start) for var, start in self.arange_arrays.iteritems()], key=lambda (var, start): var.name) self.write_static_arrays(directory) self.find_synapses() # Not sure what the best place is to call Network.after_run -- at the # moment the only important thing it does is to clear the objects stored # in magic_network. If this is not done, this might lead to problems # for repeated runs of standalone (e.g. in the test suite). for net in self.networks: net.after_run() self.generate_objects_source(writer, arange_arrays, self.net_synapses, self.static_array_specs, self.networks) self.generate_main_source(writer) self.generate_codeobj_source(writer) self.generate_network_source(writer, compiler) self.generate_synapses_classes_source(writer) self.generate_run_source(writer) self.copy_source_files(writer, directory) writer.source_files.extend(additional_source_files) self.generate_makefile(writer, compiler, native=native, compiler_flags=' '.join(compiler_flags), linker_flags=' '.join(linker_flags), nb_threads=nb_threads) if compile: self.compile_source(directory, compiler, debug, clean, native) if run: self.run(directory, with_output, run_args)
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): if not self.initialized: self.initialize() objects, output_dir = self._fix_object_args(objects, output_dir) libraries, library_dirs, runtime_library_dirs = self._fix_lib_args( libraries, library_dirs, runtime_library_dirs) if runtime_library_dirs: self.warn("I don't know what to do with 'runtime_library_dirs': " + str(runtime_library_dirs)) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): if target_desc == CCompiler.EXECUTABLE: if debug: ldflags = self.ldflags_shared_debug[1:] else: ldflags = self.ldflags_shared[1:] elif debug: ldflags = self.ldflags_shared_debug else: ldflags = self.ldflags_shared export_opts = [] for sym in export_symbols or []: export_opts.append('/EXPORT:' + sym) ld_args = ldflags + lib_opts + export_opts + objects + [ '/OUT:' + output_filename ] if export_symbols is not None: dll_name, dll_ext = os.path.splitext( os.path.basename(output_filename)) implib_file = os.path.join(os.path.dirname(objects[0]), self.library_filename(dll_name)) ld_args.append('/IMPLIB:' + implib_file) if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: self.spawn([self.linker] + ld_args) except DistutilsExecError as msg: raise LinkError, msg else: log.debug('skipping %s (up-to-date)', output_filename) return
def link( self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None, ): objects, output_dir = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) libraries, library_dirs, runtime_library_dirs = fixed_args lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if not isinstance(output_dir, (str, type(None))): raise TypeError("'output_dir' must be a string or None") if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = objects + self.objects + lib_opts + [ '-o', output_filename ] if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: # Select a linker based on context: linker_exe when # building an executable or linker_so (with shared options) # when building a shared library. building_exe = target_desc == CCompiler.EXECUTABLE linker = (self.linker_exe if building_exe else self.linker_so)[:] if target_lang == "c++" and self.compiler_cxx: env, linker_ne = _split_env(linker) aix, linker_na = _split_aix(linker_ne) _, compiler_cxx_ne = _split_env(self.compiler_cxx) _, linker_exe_ne = _split_env(self.linker_exe) params = _linker_params(linker_na, linker_exe_ne) linker = env + aix + compiler_cxx_ne + params linker = compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename)
def link_osx(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): """Link the objects.""" # use separate copies, so we can modify the lists libraries = copy.copy(libraries or []) libraries.extend(self.dll_libraries) # Copy of unix link so we can remove the darwin test #UnixCCompiler.link(self, target_desc, objects, output_filename, # output_dir, libraries, library_dirs, runtime_library_dirs, # None, # export_symbols, we do this in our def-file # debug, extra_preargs, extra_postargs, build_temp, target_lang) objects, output_dir = self._fix_object_args(objects, output_dir) libraries, library_dirs, runtime_library_dirs = \ self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) #if type(output_dir) not in (StringType, NoneType): # raise TypeError("'output_dir' must be a string or None") if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: # skip over environment variable settings if /usr/bin/env # is used to set up the linker's environment. # This is needed on OSX. Note: this assumes that the # normal and C++ compiler have the same environment # settings. i = 0 if os.path.basename(linker[0]) == "env": i = 1 while '=' in linker[i]: i = i + 1 linker[i] = self.compiler_cxx[i] #if sys.platform == 'darwin': # linker = _osx_support.compiler_fixup(linker, ld_args) # ld_args = ['-arch', 'x86_64'] + ld_args self.spawn(linker + ld_args) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename)
def link (self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): if not self.initialized: self.initialize() (objects, output_dir) = self._fix_object_args (objects, output_dir) (libraries, library_dirs, runtime_library_dirs) = \ self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) if runtime_library_dirs: self.warn ("I don't know what to do with 'runtime_library_dirs': " + str (runtime_library_dirs)) lib_opts = gen_lib_options (self, library_dirs, runtime_library_dirs, libraries) if output_dir is not None: output_filename = os.path.join (output_dir, output_filename) if self._need_link (objects, output_filename): if target_desc == CCompiler.EXECUTABLE: if debug: ldflags = self.ldflags_shared_debug[1:] else: ldflags = self.ldflags_shared[1:] else: if debug: ldflags = self.ldflags_shared_debug else: ldflags = self.ldflags_shared export_opts = [] for sym in (export_symbols or []): export_opts.append("/EXPORT:" + sym) ld_args = (ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename]) # The MSVC linker generates .lib and .exp files, which cannot be # suppressed by any linker switches. The .lib files may even be # needed! Make sure they are generated in the temporary build # directory. Since they have different names for debug and release # builds, they can go into the same directory. if export_symbols is not None: (dll_name, dll_ext) = os.path.splitext( os.path.basename(output_filename)) implib_file = os.path.join( os.path.dirname(objects[0]), self.library_filename(dll_name)) ld_args.append ('/IMPLIB:' + implib_file) if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath (os.path.dirname (output_filename)) try: self.spawn ([self.linker] + ld_args) except DistutilsExecError, msg: raise LinkError, msg
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) libraries, library_dirs, runtime_library_dirs = fixed_args lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if not isinstance(output_dir, (str, type(None))): raise TypeError("'output_dir' must be a string or None") if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: # skip over environment variable settings if /usr/bin/env # is used to set up the linker's environment. # This is needed on OSX. Note: this assumes that the # normal and C++ compiler have the same environment # settings. i = 0 if os.path.basename(linker[0]) == "env": i = 1 while '=' in linker[i]: i += 1 if os.path.basename(linker[i]) == 'ld_so_aix': # AIX platforms prefix the compiler with the ld_so_aix # script, so we need to adjust our linker index offset = 1 else: offset = 0 linker[i + offset] = self.compiler_cxx[i] if sys.platform == 'darwin': linker = _osx_support.compiler_fixup(linker, ld_args) # iOS: since clang is not available, we send a nicer error message: if (sys.platform == 'darwin' and os.uname().machine.startswith('iP')): raise DistutilsExecError( "There are no linkers available on iOS, sorry.") self.spawn(linker + ld_args) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename)
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): if not self.initialized: self.initialize() (objects, output_dir) = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) (libraries, library_dirs, runtime_library_dirs) = fixed_args if runtime_library_dirs: self.warn ("I don't know what to do with 'runtime_library_dirs': " + str (runtime_library_dirs)) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): if target_desc == CCompiler.EXECUTABLE: if debug: ldflags = self.ldflags_shared_debug[1:] else: ldflags = self.ldflags_shared[1:] else: if debug: ldflags = self.ldflags_shared_debug else: ldflags = self.ldflags_shared export_opts = [] for sym in (export_symbols or []): export_opts.append("/EXPORT:" + sym) ld_args = (ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename]) # The MSVC linker generates .lib and .exp files, which cannot be # suppressed by any linker switches. The .lib files may even be # needed! Make sure they are generated in the temporary build # directory. Since they have different names for debug and release # builds, they can go into the same directory. build_temp = os.path.dirname(objects[0]) if export_symbols is not None: (dll_name, dll_ext) = os.path.splitext( os.path.basename(output_filename)) implib_file = os.path.join( build_temp, self.library_filename(dll_name)) ld_args.append ('/IMPLIB:' + implib_file) # Embedded manifests are recommended - see MSDN article titled # "How to: Embed a Manifest Inside a C/C++ Application" # (currently at http://msdn2.microsoft.com/en-us/library/ms235591(VS.80).aspx) # Ask the linker to generate the manifest in the temp dir, so # we can embed it later. temp_manifest = os.path.join( build_temp, os.path.basename(output_filename) + ".manifest") ld_args.append('/MANIFESTFILE:' + temp_manifest) if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: self.spawn([self.linker] + ld_args) except DistutilsExecError as msg: raise LinkError(msg) # embed the manifest # XXX - this is somewhat fragile - if mt.exe fails, distutils # will still consider the DLL up-to-date, but it will not have a # manifest. Maybe we should link to a temp file? OTOH, that # implies a build environment error that shouldn't go undetected. mfid = 1 if target_desc == CCompiler.EXECUTABLE else 2 out_arg = '-outputresource:%s;%s' % (output_filename, mfid) try: self.spawn(['mt.exe', '-nologo', '-manifest', temp_manifest, out_arg]) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename)
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): if not self.initialized: self.initialize() objects, output_dir = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) libraries, library_dirs, runtime_library_dirs = fixed_args if runtime_library_dirs: self.warn("I don't know what to do with 'runtime_library_dirs': " + str(runtime_library_dirs)) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ldflags = self._ldflags[target_desc, debug] export_opts = ["/EXPORT:" + sym for sym in (export_symbols or [])] ld_args = (ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename]) # The MSVC linker generates .lib and .exp files, which cannot be # suppressed by any linker switches. The .lib files may even be # needed! Make sure they are generated in the temporary build # directory. Since they have different names for debug and release # builds, they can go into the same directory. build_temp = os.path.dirname(objects[0]) if export_symbols is not None: (dll_name, dll_ext) = os.path.splitext( os.path.basename(output_filename)) implib_file = os.path.join( build_temp, self.library_filename(dll_name)) ld_args.append ('/IMPLIB:' + implib_file) if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) output_dir = os.path.dirname(os.path.abspath(output_filename)) self.mkpath(output_dir) try: log.debug('Executing "%s" %s', self.linker, ' '.join(ld_args)) self.spawn([self.linker] + ld_args) self._copy_vcruntime(output_dir) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename)
def link( self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None, ): # Distutils defaults to None for "unspecified option list"; we want # empty lists in that case (this substitution is done here in the body # rather than by changing the default parameters in case distutils # passes None explicitly). libraries = libraries or [] library_dirs = library_dirs or [] runtime_library_dirs = runtime_library_dirs or [] export_symbols = export_symbols or [] extra_preargs = extra_preargs or [] extra_postargs = extra_postargs or [] binpath = self._binpath outputOpts = self._outputOpts[:] objectOpts = [_qp(fn) for fn in objects] (objects, output_dir) = self._fix_object_args(objects, output_dir) (libraries, library_dirs, runtime_library_dirs) = self._fix_lib_args( libraries, library_dirs, runtime_library_dirs ) if runtime_library_dirs: self.warn( "This CCompiler implementation does nothing with" ' "runtime_library_dirs": ' + str(runtime_library_dirs) ) if output_dir and os.path.basename(output_filename) == output_filename: output_filename = os.path.join(output_dir, output_filename) else: if not output_filename: raise DistutilsFileError, "Neither output_dir nor" " output_filename was specified." output_dir = os.path.dirname(output_filename) if not output_dir: raise DistutilsFileError, "Unable to guess output_dir on the" ' bases of output_filename "%s" alone.' % output_filename # Format the output filename option # (-offilename in DMD, -o filename in GDC) outputOpts[-1] = outputOpts[-1] % _qp(output_filename) if not os.path.exists(output_dir): os.makedirs(output_dir) if not self._need_link(objects, output_filename): print "All binary output files are up to date." return # The .def file (on Windows) or -shared and -soname (on Linux) sharedOpts = self._def_file(build_temp, output_filename) # The python .lib file, if needed pythonLibOpt = self._lib_file(libraries) if pythonLibOpt: pythonLibOpt = _qp(pythonLibOpt) if target_desc != cc.CCompiler.SHARED_OBJECT: raise LinkError( "This CCompiler implementation does not know" " how to link anything except an extension module (that is, a" " shared object file)." ) # Library linkage options print "library_dirs:", library_dirs print "runtime_library_dirs:", runtime_library_dirs print "libraries:", libraries libOpts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) # Optimization opts args = [a.lower() for a in sys.argv[1:]] optimize = "-o" in args or "--optimize" in args if debug: optimizationOpts = self._debugOptimizeOpts elif optimize: optimizationOpts = self._releaseOptimizeOpts else: optimizationOpts = self._defaultOptimizeOpts cmdElements = ( [binpath] + extra_preargs + self._linkOpts + optimizationOpts + outputOpts + [pythonLibOpt] + objectOpts + libOpts + sharedOpts + extra_postargs ) cmdElements = [el for el in cmdElements if el] try: self.spawn(cmdElements) except DistutilsExecError, msg: raise CompileError(msg)
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): if not self.initialized: self.initialize() (objects, output_dir) = self._fix_object_args(objects, output_dir) (libraries, library_dirs, runtime_library_dirs) = \ self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) if runtime_library_dirs: self.warn("I don't know what to do with 'runtime_library_dirs': " + str(runtime_library_dirs)) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): if target_desc == CCompiler.EXECUTABLE: if debug: ldflags = self.ldflags_shared_debug[1:] else: ldflags = self.ldflags_shared[1:] else: if debug: ldflags = self.ldflags_shared_debug else: ldflags = self.ldflags_shared export_opts = [] for sym in (export_symbols or []): export_opts.append("/EXPORT:" + sym) ld_args = (ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename]) # The MSVC linker generates .lib and .exp files, which cannot be # suppressed by any linker switches. The .lib files may even be # needed! Make sure they are generated in the temporary build # directory. Since they have different names for debug and release # builds, they can go into the same directory. if export_symbols is not None: (dll_name, dll_ext) = os.path.splitext(os.path.basename(output_filename)) implib_file = os.path.join(os.path.dirname(objects[0]), self.library_filename(dll_name)) ld_args.append('/IMPLIB:' + implib_file) if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: self.spawn([self.linker] + ld_args) except DistutilsExecError, msg: raise LinkError, msg
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) libraries, library_dirs, runtime_library_dirs = \ self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if type(output_dir) not in (StringType, NoneType): raise TypeError, "'output_dir' must be a string or None" if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) # NDK HACK: # Avoid dependency on libgcc dll on mingw. -static-libgcc works # while compiling for the host and windows, but not darwin. We # can't easily tell whether we're compiling for windows or the # host, so rely on the fact that we don't cross-compile darwin # binaries on linux. if sys.platform[:6] != "darwin": ld_args.extend(["-static-libgcc"]) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: # skip over environment variable settings if /usr/bin/env # is used to set up the linker's environment. # This is needed on OSX. Note: this assumes that the # normal and C++ compiler have the same environment # settings. i = 0 if os.path.basename(linker[0]) == "env": i = 1 while '=' in linker[i]: i = i + 1 linker[i] = self.compiler_cxx[i] if sys.platform == 'darwin': linker = _osx_support.compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError, msg: raise LinkError, msg
def build(self, directory='output', compile=True, run=True, debug=False, clean=True, with_output=True, native=True, additional_source_files=None, run_args=None, **kwds): ''' Build the project TODO: more details Parameters ---------- directory : str The output directory to write the project to, any existing files will be overwritten. compile : bool Whether or not to attempt to compile the project run : bool Whether or not to attempt to run the built project if it successfully builds. debug : bool Whether to compile in debug mode. with_output : bool Whether or not to show the ``stdout`` of the built program when run. Output will be shown in case of compilation or runtime error. native : bool Whether or not to compile for the current machine's architecture (best for speed, but not portable) clean : bool Whether or not to clean the project before building additional_source_files : list of str A list of additional ``.cpp`` files to include in the build. ''' renames = {'project_dir': 'directory', 'compile_project': 'compile', 'run_project': 'run'} if len(kwds): msg = '' for kwd in kwds: if kwd in renames: msg += ("Keyword argument '%s' has been renamed to " "'%s'. ") % (kwd, renames[kwd]) else: msg += "Unknown keyword argument '%s'. " % kwd raise TypeError(msg) if additional_source_files is None: additional_source_files = [] if run_args is None: run_args = [] self.project_dir = directory ensure_directory(directory) compiler, extra_compile_args = get_compiler_and_args() compiler_obj = ccompiler.new_compiler(compiler=compiler) compiler_flags = (ccompiler.gen_preprocess_options(prefs['codegen.cpp.define_macros'], prefs['codegen.cpp.include_dirs']) + extra_compile_args) linker_flags = (ccompiler.gen_lib_options(compiler_obj, library_dirs=prefs['codegen.cpp.library_dirs'], runtime_library_dirs=prefs['codegen.cpp.runtime_library_dirs'], libraries=prefs['codegen.cpp.libraries']) + prefs['codegen.cpp.extra_link_args']) for d in ['code_objects', 'results', 'static_arrays']: ensure_directory(os.path.join(directory, d)) writer = CPPWriter(directory) # Get the number of threads if specified in an openmp context nb_threads = prefs.devices.cpp_standalone.openmp_threads # If the number is negative, we need to throw an error if (nb_threads < 0): raise ValueError('The number of OpenMP threads can not be negative !') logger.debug("Writing C++ standalone project to directory "+os.path.normpath(directory)) self.check_openmp_compatible(nb_threads) arange_arrays = sorted([(var, start) for var, start in self.arange_arrays.iteritems()], key=lambda (var, start): var.name) self.write_static_arrays(directory) self.find_synapses() # Not sure what the best place is to call Network.after_run -- at the # moment the only important thing it does is to clear the objects stored # in magic_network. If this is not done, this might lead to problems # for repeated runs of standalone (e.g. in the test suite). for net in self.networks: net.after_run() # Check that all names are globally unique names = [obj.name for net in self.networks for obj in net.objects] non_unique_names = [name for name, count in Counter(names).iteritems() if count > 1] if len(non_unique_names): formatted_names = ', '.join("'%s'" % name for name in non_unique_names) raise ValueError('All objects need to have unique names in ' 'standalone mode, the following name(s) were used ' 'more than once: %s' % formatted_names) self.generate_objects_source(writer, arange_arrays, self.net_synapses, self.static_array_specs, self.networks) self.generate_main_source(writer) self.generate_codeobj_source(writer) self.generate_network_source(writer, compiler) self.generate_synapses_classes_source(writer) self.generate_run_source(writer) self.copy_source_files(writer, directory) writer.source_files.extend(additional_source_files) self.generate_makefile(writer, compiler, native=native, compiler_flags=' '.join(compiler_flags), linker_flags=' '.join(linker_flags), nb_threads=nb_threads) if compile: self.compile_source(directory, compiler, debug, clean, native) if run: self.run(directory, with_output, run_args)
def link( # noqa: C901 self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None, ): if not self.initialized: self.initialize() (objects, output_dir) = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) (libraries, library_dirs, runtime_library_dirs) = fixed_args if runtime_library_dirs: self.warn("I don't know what to do with 'runtime_library_dirs': " + str(runtime_library_dirs)) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): if target_desc == CCompiler.EXECUTABLE: if debug: ldflags = self.ldflags_shared_debug[1:] else: ldflags = self.ldflags_shared[1:] else: if debug: ldflags = self.ldflags_shared_debug else: ldflags = self.ldflags_shared export_opts = [] for sym in export_symbols or []: export_opts.append("/EXPORT:" + sym) ld_args = (ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename]) # The MSVC linker generates .lib and .exp files, which cannot be # suppressed by any linker switches. The .lib files may even be # needed! Make sure they are generated in the temporary build # directory. Since they have different names for debug and release # builds, they can go into the same directory. build_temp = os.path.dirname(objects[0]) if export_symbols is not None: (dll_name, dll_ext) = os.path.splitext(os.path.basename(output_filename)) implib_file = os.path.join(build_temp, self.library_filename(dll_name)) ld_args.append('/IMPLIB:' + implib_file) self.manifest_setup_ldargs(output_filename, build_temp, ld_args) if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: self.spawn([self.linker] + ld_args) except DistutilsExecError as msg: raise LinkError(msg) # embed the manifest # XXX - this is somewhat fragile - if mt.exe fails, distutils # will still consider the DLL up-to-date, but it will not have a # manifest. Maybe we should link to a temp file? OTOH, that # implies a build environment error that shouldn't go undetected. mfinfo = self.manifest_get_embed_info(target_desc, ld_args) if mfinfo is not None: mffilename, mfid = mfinfo out_arg = '-outputresource:{};{}'.format(output_filename, mfid) try: self.spawn([ 'mt.exe', '-nologo', '-manifest', mffilename, out_arg ]) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename)
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): # Distutils defaults to None for "unspecified option list"; we want # empty lists in that case (this substitution is done here in the body # rather than by changing the default parameters in case distutils # passes None explicitly). libraries = libraries or [] library_dirs = library_dirs or [] runtime_library_dirs = runtime_library_dirs or [] export_symbols = export_symbols or [] extra_preargs = extra_preargs or [] extra_postargs = extra_postargs or [] # On 64-bit Windows we just link to pythonXX.lib from the installation if _is_win64(): library_dirs = list(set(_build_ext_library_dirs() + library_dirs)) binpath = self._binpath if hasattr(self, '_linkOutputOpts'): outputOpts = self._linkOutputOpts[:] else: outputOpts = self._outputOpts[:] objectOpts = [_qp(fn) for fn in objects] (objects, output_dir) = self._fix_object_args(objects, output_dir) (libraries, library_dirs, runtime_library_dirs) = \ self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) if runtime_library_dirs: self.warn('This CCompiler implementation does nothing with' ' "runtime_library_dirs": ' + str(runtime_library_dirs)) if output_dir and os.path.basename(output_filename) == output_filename: output_filename = os.path.join(output_dir, output_filename) else: if not output_filename: raise DistutilsFileError( 'Neither output_dir nor' \ ' output_filename was specified.') output_dir = os.path.dirname(output_filename) if not output_dir: raise DistutilsFileError( 'Unable to guess output_dir on the'\ ' bases of output_filename "%s" alone.' % output_filename) # Format the output filename option # (-offilename in DMD, -o filename in GDC, -of=filename in LDC) outputOpts[-1] = outputOpts[-1] % _qp( winpath(output_filename, self.winonly)) if not os.path.exists(output_dir): os.makedirs(output_dir) if not self._need_link(objects, output_filename): print("All binary output files are up to date.") return if self.build_exe: sharedOpts = [] linkOpts = self._exeLinkOpts pythonLibOpt = [] if target_desc != cc.CCompiler.EXECUTABLE: raise LinkError( 'This CCompiler implementation should be building' ' an executable') else: # The .def file (on Windows) or -shared and -soname (on Linux) sharedOpts = self._def_file(build_temp, output_filename) if target_desc != cc.CCompiler.SHARED_OBJECT: raise LinkError( 'This CCompiler implementation should be building ' ' a shared object') linkOpts = self._linkOpts # The python .lib file, if needed pythonLibOpt = self._lib_file(libraries) if pythonLibOpt: pythonLibOpt = _qp(pythonLibOpt) # Library linkage options print("library_dirs: %s" % (library_dirs, )) print("runtime_library_dirs: %s" % (runtime_library_dirs, )) print("libraries: %s" % (libraries, )) libOpts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) # Optimization opts if debug: optimizationOpts = self._debugOptimizeOpts elif self.optimize: optimizationOpts = self._releaseOptimizeOpts else: optimizationOpts = self._defaultOptimizeOpts cmdElements = ([binpath] + extra_preargs + linkOpts + optimizationOpts + outputOpts + [pythonLibOpt] + objectOpts + libOpts + sharedOpts + extra_postargs) cmdElements = [el for el in cmdElements if el] wrapped_spawn(self, cmdElements, 'pyd_link')
def _unix_piecemeal_link( self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None, ): """`link` externalized method taken almost verbatim from UnixCCompiler. Modifies the link command for unix-like compilers by using a command file so that long command line argument strings don't break the command shell's ARG_MAX character limit. """ objects, output_dir = self._fix_object_args(objects, output_dir) libraries, library_dirs, runtime_library_dirs = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) # filter out standard library paths, which are not explicitely needed # for linking library_dirs = [dir for dir in library_dirs if not dir in ("/lib", "/lib64", "/usr/lib", "/usr/lib64")] runtime_library_dirs = [ dir for dir in runtime_library_dirs if not dir in ("/lib", "/lib64", "/usr/lib", "/usr/lib64") ] lib_opts = ccompiler.gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if not (isinstance(output_dir, str) or isinstance(output_dir, bytes)) and output_dir is not None: raise TypeError("'output_dir' must be a string or None") if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = objects + self.objects + lib_opts + ["-o", output_filename] if debug: ld_args[:0] = ["-g"] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == ccompiler.CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: # skip over environment variable settings if /usr/bin/env # is used to set up the linker's environment. # This is needed on OSX. Note: this assumes that the # normal and C++ compiler have the same environment # settings. i = 0 if os.path.basename(linker[0]) == "env": i = 1 while "=" in linker[i]: i = i + 1 linker[i] = self.compiler_cxx[i] if sys.platform == "darwin": import _osx_support linker = _osx_support.compiler_fixup(linker, ld_args) temporary_directory = tempfile.mkdtemp() command_filename = os.path.abspath(os.path.join(temporary_directory, "command")) with open(command_filename, "w") as command_file: escaped_ld_args = [arg.replace("\\", "\\\\") for arg in ld_args] command_file.write(" ".join(escaped_ld_args)) self.spawn(linker + ["@{}".format(command_filename)]) except errors.DistutilsExecError: raise ccompiler.LinkError else: log.debug("skipping %s (up-to-date)", output_filename)
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): if not self.initialized: self.initialize() objects, output_dir = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) libraries, library_dirs, runtime_library_dirs = fixed_args if runtime_library_dirs: self.warn("I don't know what to do with 'runtime_library_dirs': " + str(runtime_library_dirs)) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ldflags = self._ldflags[target_desc, debug] export_opts = ["/EXPORT:" + sym for sym in (export_symbols or [])] ld_args = (ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename]) # The MSVC linker generates .lib and .exp files, which cannot be # suppressed by any linker switches. The .lib files may even be # needed! Make sure they are generated in the temporary build # directory. Since they have different names for debug and release # builds, they can go into the same directory. build_temp = os.path.dirname(objects[0]) if export_symbols is not None: (dll_name, dll_ext) = os.path.splitext(os.path.basename(output_filename)) implib_file = os.path.join(build_temp, self.library_filename(dll_name)) ld_args.append('/IMPLIB:' + implib_file) if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: log.debug('Executing "%s" %s', self.linker, ' '.join(ld_args)) self.spawn([self.linker] + ld_args) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename)
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): if not self.initialized: self.initialize() (objects, output_dir) = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) (libraries, library_dirs, runtime_library_dirs) = fixed_args if runtime_library_dirs: self.warn ("I don't know what to do with 'runtime_library_dirs': " + str (runtime_library_dirs)) lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): if target_desc == CCompiler.EXECUTABLE: if debug: ldflags = self.ldflags_shared_debug[1:] else: ldflags = self.ldflags_shared[1:] else: if debug: ldflags = self.ldflags_shared_debug else: ldflags = self.ldflags_shared export_opts = [] for sym in (export_symbols or []): export_opts.append("/EXPORT:" + sym) ld_args = (ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename]) # The MSVC linker generates .lib and .exp files, which cannot be # suppressed by any linker switches. The .lib files may even be # needed! Make sure they are generated in the temporary build # directory. Since they have different names for debug and release # builds, they can go into the same directory. build_temp = os.path.dirname(objects[0]) if export_symbols is not None: (dll_name, dll_ext) = os.path.splitext( os.path.basename(output_filename)) implib_file = os.path.join( build_temp, self.library_filename(dll_name)) ld_args.append ('/IMPLIB:' + implib_file) self.manifest_setup_ldargs(output_filename, build_temp, ld_args) if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: self.spawn([self.linker] + ld_args) except DistutilsExecError, msg: raise LinkError(msg) # embed the manifest # XXX - this is somewhat fragile - if mt.exe fails, distutils # will still consider the DLL up-to-date, but it will not have a # manifest. Maybe we should link to a temp file? OTOH, that # implies a build environment error that shouldn't go undetected. mfinfo = self.manifest_get_embed_info(target_desc, ld_args) if mfinfo is not None: mffilename, mfid = mfinfo out_arg = '-outputresource:%s;%s' % (output_filename, mfid) try: self.spawn(['mt.exe', '-nologo', '-manifest', mffilename, out_arg]) except DistutilsExecError, msg: raise LinkError(msg)
def link(self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None): objects, output_dir = self._fix_object_args(objects, output_dir) fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs) libraries, library_dirs, runtime_library_dirs = fixed_args lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) if not isinstance(output_dir, (str, type(None))): raise TypeError("'output_dir' must be a string or None") if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) if self._need_link(objects, output_filename): ld_args = (objects + self.objects + lib_opts + ['-o', output_filename]) if debug: ld_args[:0] = ['-g'] if extra_preargs: ld_args[:0] = extra_preargs if extra_postargs: ld_args.extend(extra_postargs) self.mkpath(os.path.dirname(output_filename)) try: if target_desc == CCompiler.EXECUTABLE: linker = self.linker_exe[:] else: linker = self.linker_so[:] if target_lang == "c++" and self.compiler_cxx: # skip over environment variable settings if /usr/bin/env # is used to set up the linker's environment. # This is needed on OSX. Note: this assumes that the # normal and C++ compiler have the same environment # settings. i = 0 if os.path.basename(linker[0]) == "env": i = 1 while '=' in linker[i]: i += 1 linker[i] = self.compiler_cxx[i] if sys.platform == 'darwin': linker = _darwin_compiler_fixup(linker, ld_args) self.spawn(linker + ld_args) except DistutilsExecError as msg: raise LinkError(msg) else: log.debug("skipping %s (up-to-date)", output_filename)
def link (self, target_desc, objects, output_filename, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None ): # Distutils defaults to None for "unspecified option list"; we want # empty lists in that case (this substitution is done here in the body # rather than by changing the default parameters in case distutils # passes None explicitly). libraries = libraries or [] library_dirs = library_dirs or [] runtime_library_dirs = runtime_library_dirs or [] export_symbols = export_symbols or [] extra_preargs = extra_preargs or [] extra_postargs = extra_postargs or [] # On 64-bit Windows we just link to pythonXX.lib from the installation if _is_win64(): library_dirs = list(set(_build_ext_library_dirs() + library_dirs)) binpath = self._binpath if hasattr(self, '_linkOutputOpts'): outputOpts = self._linkOutputOpts[:] else: outputOpts = self._outputOpts[:] objectOpts = [_qp(fn) for fn in objects] (objects, output_dir) = self._fix_object_args (objects, output_dir) (libraries, library_dirs, runtime_library_dirs) = \ self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) if runtime_library_dirs: self.warn('This CCompiler implementation does nothing with' ' "runtime_library_dirs": ' + str(runtime_library_dirs) ) if output_dir and os.path.basename(output_filename) == output_filename: output_filename = os.path.join(output_dir, output_filename) else: if not output_filename: raise DistutilsFileError( 'Neither output_dir nor' \ ' output_filename was specified.') output_dir = os.path.dirname(output_filename) if not output_dir: raise DistutilsFileError( 'Unable to guess output_dir on the'\ ' bases of output_filename "%s" alone.' % output_filename) # Format the output filename option # (-offilename in DMD, -o filename in GDC, -of=filename in LDC) outputOpts[-1] = outputOpts[-1] % _qp(winpath(output_filename,self.winonly)) if not os.path.exists(output_dir): os.makedirs(output_dir) if not self._need_link(objects, output_filename): print ("All binary output files are up to date.") return if self.build_exe: sharedOpts = [] linkOpts = self._exeLinkOpts pythonLibOpt = [] if target_desc != cc.CCompiler.EXECUTABLE: raise LinkError('This CCompiler implementation should be building' ' an executable' ) else: # The .def file (on Windows) or -shared and -soname (on Linux) sharedOpts = self._def_file(build_temp, output_filename) if target_desc != cc.CCompiler.SHARED_OBJECT: raise LinkError('This CCompiler implementation should be building ' ' a shared object' ) linkOpts = self._linkOpts # The python .lib file, if needed pythonLibOpt = self._lib_file(libraries) if pythonLibOpt: pythonLibOpt = _qp(pythonLibOpt) # Library linkage options print ("library_dirs: %s" % (library_dirs,)) print ("runtime_library_dirs: %s" % (runtime_library_dirs,)) print ("libraries: %s"% (libraries,)) libOpts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) # Optimization opts if debug: optimizationOpts = self._debugOptimizeOpts elif self.optimize: optimizationOpts = self._releaseOptimizeOpts else: optimizationOpts = self._defaultOptimizeOpts cmdElements = ( [binpath] + extra_preargs + linkOpts + optimizationOpts + outputOpts + [pythonLibOpt] + objectOpts + libOpts + sharedOpts + extra_postargs ) cmdElements = [el for el in cmdElements if el] wrapped_spawn(self,cmdElements, 'pyd_link')