def generate_h_code(self, env, result): public_vars_and_funcs = [] public_extension_types = [] for entry in env.var_entries: if entry.visibility == 'public': public_vars_and_funcs.append(entry) for entry in env.cfunc_entries: if entry.visibility == 'public': public_vars_and_funcs.append(entry) for entry in env.c_class_entries: if entry.visibility == 'public': public_extension_types.append(entry) if public_vars_and_funcs or public_extension_types: result.h_file = replace_suffix(result.c_file, ".h") result.i_file = replace_suffix(result.c_file, ".pxi") h_code = Code.CCodeWriter(open_new_file(result.h_file)) i_code = Code.PyrexCodeWriter(result.i_file) self.generate_extern_c_macro_definition(h_code) for entry in public_vars_and_funcs: h_code.putln("%s %s;" % ( Naming.extern_c_macro, entry.type.declaration_code( entry.cname, dll_linkage = "DL_IMPORT"))) i_code.putln("cdef extern %s" % entry.type.declaration_code(entry.cname, pyrex = 1)) for entry in public_extension_types: self.generate_cclass_header_code(entry.type, h_code) self.generate_cclass_include_code(entry.type, i_code) h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
def generate_h_code(self, env, result): public_vars_and_funcs = [] public_extension_types = [] for entry in env.var_entries: if entry.visibility == 'public': public_vars_and_funcs.append(entry) for entry in env.cfunc_entries: if entry.visibility == 'public': public_vars_and_funcs.append(entry) for entry in env.c_class_entries: if entry.visibility == 'public': public_extension_types.append(entry) if public_vars_and_funcs or public_extension_types: result.h_file = replace_suffix(result.c_file, ".h") result.i_file = replace_suffix(result.c_file, ".pxi") h_code = Code.CCodeWriter(open_new_file(result.h_file)) i_code = Code.PyrexCodeWriter(result.i_file) self.generate_extern_c_macro_definition(h_code) for entry in public_vars_and_funcs: h_code.putln("%s %s;" % (Naming.extern_c_macro, entry.type.declaration_code( entry.cname, dll_linkage="DL_IMPORT"))) i_code.putln("cdef extern %s" % entry.type.declaration_code(entry.cname, pyrex=1)) for entry in public_extension_types: self.generate_cclass_header_code(entry.type, h_code) self.generate_cclass_include_code(entry.type, i_code) h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
def compile(self, source, options = None): # Compile a Pyrex implementation file in this context # and return a CompilationResult. if not options: options = default_options result = CompilationResult() cwd = os.getcwd() source = os.path.join(cwd, source) if options.use_listing_file: result.listing_file = replace_suffix(source, ".lis") Errors.open_listing_file(result.listing_file, echo_to_stderr = options.errors_to_stderr) else: Errors.open_listing_file(None) if options.output_file: result.c_file = os.path.join(cwd, options.output_file) else: result.c_file = replace_suffix(source, ".c") module_name = self.extract_module_name(source) initial_pos = (source, 1, 0) scope = self.find_module(module_name, pos = initial_pos, need_pxd = 0) try: tree = self.parse(source, scope.type_names, pxd = 0) tree.process_implementation(scope, result) except CompileError: result.c_file = None Errors.close_listing_file() result.num_errors = Errors.num_errors if result.num_errors > 0: result.c_file = None if result.c_file and not options.c_only and c_compile: result.object_file = c_compile(result.c_file) if not options.obj_only and c_link: result.extension_file = c_link(result.object_file) return result
def __init__(self, source, options): cwd = os.getcwd() source = os.path.join(cwd, source) if options.use_listing_file: self.listing_file = replace_suffix(source, ".lis") if options.output_file: self.c_file = os.path.join(cwd, options.output_file) else: if options.cplus: self.c_file = replace_suffix(source, cplus_suffix) else: self.c_file = map_suffix(source, pyx_to_c_suffix, ".c")
def compile(self, source, options=None): # Compile a Pyrex implementation file in this context # and return a CompilationResult. if not options: options = default_options result = CompilationResult() cwd = os.getcwd() source = os.path.join(cwd, source) if options.use_listing_file: result.listing_file = replace_suffix(source, ".lis") Errors.open_listing_file(result.listing_file, echo_to_stderr=options.errors_to_stderr) else: Errors.open_listing_file(None) if options.output_file: result.c_file = os.path.join(cwd, options.output_file) else: if options.cplus: result.c_file = replace_suffix(source, cplus_suffix) else: result.c_file = map_suffix(source, pyx_to_c_suffix, ".c") module_name = self.extract_module_name(source) initial_pos = (source, 1, 0) def_scope = self.find_module(module_name, pos=initial_pos, need_pxd=0) imp_scope = ImplementationScope(def_scope) errors_occurred = False try: tree = self.parse(source, imp_scope, pxd=0) tree.process_implementation(imp_scope, options, result) except CompileError: errors_occurred = True Errors.close_listing_file() result.num_errors = Errors.num_errors if result.num_errors > 0: errors_occurred = True if errors_occurred and result.c_file: try: st = os.stat(source) castrate_file(result.c_file, st) except EnvironmentError: pass result.c_file = None if result.c_file and not options.c_only and c_compile: result.object_file = c_compile(result.c_file, verbose_flag=options.show_version, cplus=options.cplus) if not options.obj_only and c_link: result.extension_file = c_link( result.object_file, extra_objects=options.objects, verbose_flag=options.show_version, cplus=options.cplus) return result
def compile(self, source, options = None): # Compile a Pyrex implementation file in this context # and return a CompilationResult. if not options: options = default_options result = CompilationResult() cwd = os.getcwd() source = os.path.join(cwd, source) if options.use_listing_file: result.listing_file = replace_suffix(source, ".lis") Errors.open_listing_file(result.listing_file, echo_to_stderr = options.errors_to_stderr) else: Errors.open_listing_file(None) if options.output_file: result.c_file = os.path.join(cwd, options.output_file) else: if options.cplus: result.c_file = replace_suffix(source, cplus_suffix) else: result.c_file = map_suffix(source, pyx_to_c_suffix, ".c") module_name = self.extract_module_name(source) initial_pos = (source, 1, 0) def_scope = self.find_module(module_name, pos = initial_pos, need_pxd = 0) imp_scope = ImplementationScope(def_scope) errors_occurred = False try: tree = self.parse(source, imp_scope, pxd = 0) tree.process_implementation(imp_scope, options, result) except CompileError: errors_occurred = True Errors.close_listing_file() result.num_errors = Errors.num_errors if result.num_errors > 0: errors_occurred = True if errors_occurred and result.c_file: try: st = os.stat(source) castrate_file(result.c_file, st) except EnvironmentError: pass result.c_file = None if result.c_file and not options.c_only and c_compile: result.object_file = c_compile(result.c_file, verbose_flag = options.show_version, cplus = options.cplus) if not options.obj_only and c_link: result.extension_file = c_link(result.object_file, extra_objects = options.objects, verbose_flag = options.show_version, cplus = options.cplus) return result
def c_compile(self, c_file, verbose_flag=0, cplus=0, obj_suffix=".o", use_timestamps=0, options=None): # Compile the given C source file to produce # an object file. Returns the pathname of the # resulting file. c_file = os.path.join(os.getcwd(), c_file) o_file = replace_suffix(c_file, obj_suffix) if use_timestamps and not file_newer_than_file(c_file, o_file): return include_dirs = [] if options: include_dirs.extend(options.include_path) include_dirs.extend(py_include_dirs) include_options = ["-I%s" % dir for dir in include_dirs] compiler = self.compilers[bool(cplus)] args = [compiler] + self.compiler_options + include_options \ + [c_file, "-o", o_file] if verbose_flag or self.verbose: print " ".join(args) status = os.spawnvp(os.P_WAIT, compiler, args) if status <> 0: raise CCompilerError("C compiler returned status %s" % status) return o_file
def read_dependency_file(self, source_path): dep_path = replace_suffix(source_path, ".dep") if os.path.exists(dep_path): f = open(dep_path, "rU") for line in f.readlines(): chunks = line.strip().split(" ", 1) if len(chunks) == 2: yield chunks f.close()
def run_functional_test(pyx_file, keep_files=0): "Run a compile, link and execute test." try: mark_item(pyx_file, "failed") result = compile_and_link(pyx_file) aux_pyx_file = functional_test_aux_file(pyx_file) if os.path.exists(aux_pyx_file): aux_result = compile_and_link(aux_pyx_file) else: aux_result = None #new_c = compare_with_reference(result.c_file, show_diffs = 1) new_c = 0 py_file = replace_suffix(pyx_file, "_t.py") out_file = replace_suffix(pyx_file, ".out") err_file = replace_suffix(pyx_file, ".err") try: stat = run_python_file(py_file, out_file, err_file) except: print_file(err_file) fail_with_exception("Python script execution failed.") if stat: fail("Exit status %s" % stat) new_output = compare_with_reference( out_file, show_diffs=0, line_munger=munge_runnable_test_output_line) if not keep_files: remove_file(replace_suffix(pyx_file, ".lis")) if not new_c: remove_file(result.c_file) remove_file(result.object_file) remove_file(result.extension_file) remove_file(err_file) if aux_result: remove_file(replace_suffix(aux_pyx_file, ".lis")) remove_file(aux_result.c_file) remove_file(aux_result.object_file) remove_file(aux_result.extension_file) mark_item(pyx_file, "passed") return "passed" except FailureError: return "failed"
def c_link_list(obj_files): # Link the given object files into a dynamically # loadable extension file. Returns the pathname # of the resulting file. out_file = replace_suffix(obj_files[0], shared_lib_suffix) command = "%s -xm s -export all %s %s %s -o %s" % ( c_linker, string.join(obj_files), pythoncore, string.join(libraries), out_file) stat = do_toolserver_command(command) if stat: raise CCompilerError("Linker returned status %s" % stat) return out_file
def c_link_list(obj_files, verbose_flag = 0): # Link the given object files into a dynamically # loadable extension file. Returns the pathname # of the resulting file. out_file = replace_suffix(obj_files[0], ".so") args = [linker] + linker_options + obj_files + ["-o", out_file] if verbose_flag or verbose: print " ".join(args) status = os.spawnvp(os.P_WAIT, linker, args) if status <> 0: raise CCompilerError("Linker returned status %s" % status) return out_file
def run_functional_test(pyx_file, keep_files = 0): "Run a compile, link and execute test." try: mark_item(pyx_file, "failed") result = compile_and_link(pyx_file) aux_pyx_file = functional_test_aux_file(pyx_file) if os.path.exists(aux_pyx_file): aux_result = compile_and_link(aux_pyx_file) else: aux_result = None #new_c = compare_with_reference(result.c_file, show_diffs = 1) new_c = 0 py_file = replace_suffix(pyx_file, "_t.py") out_file = replace_suffix(pyx_file, ".out") err_file = replace_suffix(pyx_file, ".err") try: stat = run_python_file(py_file, out_file, err_file) except: print_file(err_file) fail_with_exception("Python script execution failed.") if stat: fail("Exit status %s" % stat) new_output = compare_with_reference(out_file, show_diffs = 0, line_munger = munge_runnable_test_output_line) if not keep_files: remove_file(replace_suffix(pyx_file, ".lis")) if not new_c: remove_file(result.c_file) remove_file(result.object_file) remove_file(result.extension_file) remove_file(err_file) if aux_result: remove_file(replace_suffix(aux_pyx_file, ".lis")) remove_file(aux_result.c_file) remove_file(aux_result.object_file) remove_file(aux_result.extension_file) mark_item(pyx_file, "passed") return "passed" except FailureError: return "failed"
def c_link_list(obj_files, verbose_flag=0, cplus=0): # Link the given object files into a dynamically # loadable extension file. Returns the pathname # of the resulting file. out_file = replace_suffix(obj_files[0], ".so") linker = linkers[bool(cplus)] args = [linker] + linker_options + obj_files + ["-o", out_file] if verbose_flag or verbose: print " ".join(args) status = os.spawnvp(os.P_WAIT, linker, args) if status <> 0: raise CCompilerError("Linker returned status %s" % status) return out_file
def c_link_list(self, obj_files, verbose_flag=0, cplus=0, use_timestamps=0, options=None): # Link the given object files into a dynamically # loadable extension file. Returns the pathname # of the resulting file. in_file = obj_files[0] out_file = replace_suffix(in_file, ".so") if use_timestamps and not file_newer_than_file(in_file, out_file): return linker = self.linkers[bool(cplus)] args = [linker] + self.get_linker_options(options) + obj_files + self.get_libraries(options) + ["-o", out_file] if verbose_flag or self.verbose: print " ".join(args) status = os.spawnvp(os.P_WAIT, linker, args) if status <> 0: raise CCompilerError("Linker returned status %s" % status) return out_file
def c_compile(c_file, verbose_flag = 0): # Compile the given C source file to produce # an object file. Returns the pathname of the # resulting file. c_file = os.path.join(os.getcwd(), c_file) o_file = replace_suffix(c_file, ".o") include_options = [] for dir in py_include_dirs: include_options.append("-I%s" % dir) args = [compiler] + compiler_options + include_options + [c_file, "-o", o_file] if verbose_flag or verbose: print " ".join(args) status = os.spawnvp(os.P_WAIT, compiler, args) if status <> 0: raise CCompilerError("C compiler returned status %s" % status) return o_file
def c_compile(c_file, verbose_flag=0, cplus=0, obj_suffix=".o"): # Compile the given C source file to produce # an object file. Returns the pathname of the # resulting file. c_file = os.path.join(os.getcwd(), c_file) o_file = replace_suffix(c_file, obj_suffix) include_options = [] for dir in py_include_dirs: include_options.append("-I%s" % dir) compiler = compilers[bool(cplus)] args = [compiler ] + compiler_options + include_options + [c_file, "-o", o_file] if verbose_flag or verbose: print " ".join(args) status = os.spawnvp(os.P_WAIT, compiler, args) if status <> 0: raise CCompilerError("C compiler returned status %s" % status) return o_file
def c_compile(self, c_file, verbose_flag=0, cplus=0, obj_suffix=".o", use_timestamps=0, options=None): # Compile the given C source file to produce # an object file. Returns the pathname of the # resulting file. c_file = os.path.join(os.getcwd(), c_file) o_file = replace_suffix(c_file, obj_suffix) if use_timestamps and not file_newer_than_file(c_file, o_file): return include_dirs = [] if options: include_dirs.extend(options.include_path) include_dirs.extend(py_include_dirs) include_options = ["-I%s" % dir for dir in include_dirs] compiler = self.compilers[bool(cplus)] args = [compiler] + self.compiler_options + include_options + [c_file, "-o", o_file] if verbose_flag or self.verbose: print " ".join(args) status = os.spawnvp(os.P_WAIT, compiler, args) if status <> 0: raise CCompilerError("C compiler returned status %s" % status) return o_file
def c_link_list(self, obj_files, verbose_flag=0, cplus=0, use_timestamps=0, options=None): # Link the given object files into a dynamically # loadable extension file. Returns the pathname # of the resulting file. in_file = obj_files[0] out_file = replace_suffix(in_file, ".so") if use_timestamps and not file_newer_than_file(in_file, out_file): return linker = self.linkers[bool(cplus)] args = [linker] + self.get_linker_options(options) + obj_files \ + self.get_libraries(options) + ["-o", out_file] if verbose_flag or self.verbose: print " ".join(args) status = os.spawnvp(os.P_WAIT, linker, args) if status <> 0: raise CCompilerError("Linker returned status %s" % status) return out_file
def c_file_out_of_date(self, source_path): if debug_timestamps: print "Checking whether", source_path, "is out of date" c_path = map_suffix(source_path, pyx_to_c_suffix, ".c") if not os.path.exists(c_path): if debug_timestamps: print "...yes, c file doesn't exist" return 1 c_time = modification_time(c_path) if file_newer_than(source_path, c_time): if debug_timestamps: print "...yes, newer than c file" return 1 pos = [source_path] module_name = self.extract_module_name(source_path) pxd_path = self.find_pxd_file(module_name, pos) if pxd_path and file_newer_than(pxd_path, c_time): if debug_timestamps: print "...yes, pxd file newer than c file" return 1 dep_path = replace_suffix(source_path, ".dep") if not os.path.exists(dep_path): if debug_timestamps: print "...yes, dep file does not exist" return 1 for kind, name in self.read_dependency_file(source_path): if kind == "cimport": dep_path = self.find_pxd_file(name, pos) elif kind == "include": dep_path = self.search_include_directories(name, pos) else: continue if dep_path and file_newer_than(dep_path, c_time): if debug_timestamps: print "...yes,", dep_path, "newer than c file" return 1 if debug_timestamps: print "...no"
def c_compile(c_file): # Compile the given C source file to produce # an object file. Returns the pathname of the # resulting file. c_file = os.path.join(os.getcwd(), c_file) #print "c_compile: c_file =", repr(c_file) ### c_file_dir = os.path.dirname(c_file) o_file = replace_suffix(c_file, ".o") include_options = ["-i %s" % c_file_dir] for dir in py_include_dirs: include_options.append("-i %s" % dir) command = "%s -opt %s -nomapcr -w off -r %s %s -o %s" % ( c_compiler, c_optimizations, string.join(include_options), c_file, o_file, #e_file ) #print "...command =", repr(command) ### stat = do_toolserver_command(command) if stat: raise CCompilerError("C compiler returned status %s" % stat) return o_file
def run_compile_test(item, link = 0): """Run a single compile-only or compile-and-link test. If linking, the linked extension module is kept for use by later tests. """ try: mark_item(item, "failed") dir = path.dirname(item) name = path.basename(item) global mangled_module_name module_name, _ = os.path.splitext(name) mangled_module_name = "%d%s_" % (len(module_name), module_name) produces_include_files = name.startswith("i_") or name.startswith("ia_") produces_api_file = name.startswith("a_") or name.startswith("ia_") is_error_test = ( name[:2] == "e_" or name[:3] == "se_") options = Main.CompilationOptions(Main.default_options) if is_error_test: options.use_listing_file = 1 options.errors_to_stderr = 0 try: result = Main.compile(item, options) except CCompilerError: fail("C compilation error.") except: fail_with_exception("Exception raised in Pyrex compiler.") #print "result =", result.__dict__ ### if is_error_test: if result.num_errors == 0: fail("No errors produced, expected some") if result.listing_file is None: fail("No listing file produced") compare_with_reference(result.listing_file, show_diffs = 0, line_munger = munge_error_line) remove_file(replace_suffix(item, ".c")) remove_file(replace_suffix(item, ".cpp")) else: if result.num_errors <> 0: #display_files(replace_suffix(item, ".lis")) fail("%s errors reported, expected none" % result.num_errors) if result.c_file is None: fail("No C file produced") compare_with_reference(result.c_file, show_diffs = 1, line_munger = munge_c_line) if produces_include_files: if result.h_file is None: fail("No header file produced") compare_with_reference(result.h_file, show_diffs = 1, line_munger = munge_c_line) if result.i_file is None: pass # .pxi files no longer produced by default #fail("No include file produced") else: compare_with_reference(result.i_file, show_diffs = 1, line_munger = None) if produces_api_file: if result.api_file is None: fail("No api header file produced") compare_with_reference(result.api_file, show_diffs = 1, line_munger = munge_c_line) try: result.object_file = c_compile(result.c_file) except CCompilerError: fail("C compilation error.") except: fail_with_exception("C compiler failed.") try: cplus_object_file = c_compile(result.c_file, cplus = 1, obj_suffix = ".cplus.o") except CCompilerError: fail("C++ compilation error.") except: fail_with_exception("C++ compiler failed.") if link: try: c_link(result.object_file) except CCompilerError: fail("C linking error.") remove_file(result.listing_file) remove_file(result.object_file) remove_file(cplus_object_file) mark_item(item, "passed") return "passed" except FailureError: return "failed"
def dep_file_out_of_date(self, source_path): dep_path = replace_suffix(source_path, ".dep") if not os.path.exists(dep_path): return 1 dep_time = modification_time(dep_path) return file_newer_than(source_path, dep_time)
def run_compile_test(item, link=0): """Run a single compile-only or compile-and-link test. If linking, the linked extension module is kept for use by later tests. """ try: mark_item(item, "failed") dir = path.dirname(item) name = path.basename(item) global mangled_module_name module_name, _ = os.path.splitext(name) mangled_module_name = "%d%s_" % (len(module_name), module_name) produces_include_files = name.startswith("i_") or name.startswith( "ia_") produces_api_file = name.startswith("a_") or name.startswith("ia_") is_error_test = (name[:2] == "e_" or name[:3] == "se_") options = Main.CompilationOptions(Main.default_options) if is_error_test: options.use_listing_file = 1 options.errors_to_stderr = 0 try: result = Main.compile(item, options) except CCompilerError: fail("C compilation error.") except: fail_with_exception("Exception raised in Pyrex compiler.") #print "result =", result.__dict__ ### if is_error_test: if result.num_errors == 0: fail("No errors produced, expected some") if result.listing_file is None: fail("No listing file produced") compare_with_reference(result.listing_file, show_diffs=0, line_munger=munge_error_line) remove_file(replace_suffix(item, ".c")) remove_file(replace_suffix(item, ".cpp")) else: if result.num_errors <> 0: #display_files(replace_suffix(item, ".lis")) fail("%s errors reported, expected none" % result.num_errors) if result.c_file is None: fail("No C file produced") compare_with_reference(result.c_file, show_diffs=1, line_munger=munge_c_line) if produces_include_files: if result.h_file is None: fail("No header file produced") compare_with_reference(result.h_file, show_diffs=1, line_munger=munge_c_line) if result.i_file is None: pass # .pxi files no longer produced by default #fail("No include file produced") else: compare_with_reference(result.i_file, show_diffs=1, line_munger=None) if produces_api_file: if result.api_file is None: fail("No api header file produced") compare_with_reference(result.api_file, show_diffs=1, line_munger=munge_c_line) try: result.object_file = c_compile(result.c_file) except CCompilerError: fail("C compilation error.") except: fail_with_exception("C compiler failed.") try: cplus_object_file = c_compile(result.c_file, cplus=1, obj_suffix=".cplus.o") except CCompilerError: fail("C++ compilation error.") except: fail_with_exception("C++ compiler failed.") if link: try: c_link(result.object_file) except CCompilerError: fail("C linking error.") remove_file(result.listing_file) remove_file(result.object_file) remove_file(cplus_object_file) mark_item(item, "passed") return "passed" except FailureError: return "failed"