def _validate_src(self, src_entry): src = self.make_src_path(src_entry) print("Validating {0}:".format(t.make_file_name(src))) self._resolve_includes(src) if not self.sources[src].is_includes_resolved: raise PykeError( "{0} has #include paths that cannot be resolved.".format( t.make_file_name(src_entry)))
def _validate_src(self, src_entry): src = self.make_src_path(src_entry) print ("Validating {0}:".format( t.make_file_name(src))) self._resolve_includes(src) if not self.sources[src].is_includes_resolved: raise PykeError("{0} has #include paths that cannot be resolved.".format( t.make_file_name(src_entry)))
def _build_object(self, src_path, force=False): source = self.sources[src_path] doto_dir, doto_file = os.path.split(source.doto_path) print () title_bw = "Building {}".format(doto_file) title_co = "Building {}".format(t.make_file_name(doto_file)) t.print_title(title_co, len(title_bw)) src_entry = self.sources[src_path].src_entry if not os.path.exists(src_path): raise PykeError("{0} not found".format( t.make_file_name(src_path))) self._validate_src(src_path) self._ensure_dir_exists(doto_dir) if (force or not os.path.exists(source.doto_path) or not source.is_up_to_date(source.doto_mtime)): include_dirs = self._make_include_dirs() config = self.cpp_data.compile_args if self.cpp_data.output_type == 'so': config = ''.join((config, ' -fPIC')) if os.path.exists(source.doto_path): os.remove(source.doto_path) gcc_cmd = "g++ {std} -c {config} {src} {includes} {packages} -o {doto}".format( std = self._make_std(), packages = self._make_package_includes(), config = config, includes = include_dirs, src = src_path, doto = source.doto_path) print (t.make_syscommand(gcc_cmd)) comp_proc = subprocess.run(gcc_cmd, stdout=subprocess.PIPE, shell=True) if comp_proc.returncode != 0: raise PykeError('{0} building {1}'.format( t.make_error('Error'), t.make_file_name(source.doto_path))) else: print ("{0} built {1}.".format( t.make_file_name(source.doto_path), t.make_success('successfully'))) else: print ("{0} is up to date.".format( t.make_file_name(source.doto_path)))
def _build_object(self, src_path, force=False): source = self.sources[src_path] doto_dir, doto_file = os.path.split(source.doto_path) print() title_bw = "Building {}".format(doto_file) title_co = "Building {}".format(t.make_file_name(doto_file)) t.print_title(title_co, len(title_bw)) src_entry = self.sources[src_path].src_entry if not os.path.exists(src_path): raise PykeError("{0} not found".format(t.make_file_name(src_path))) self._validate_src(src_path) self._ensure_dir_exists(doto_dir) if (force or not os.path.exists(source.doto_path) or not source.is_up_to_date(source.doto_mtime)): include_dirs = self._make_include_dirs() config = self.cpp_data.compile_args if self.cpp_data.output_type == 'so': config = ''.join((config, ' -fPIC')) if os.path.exists(source.doto_path): os.remove(source.doto_path) gcc_cmd = "g++ {std} -c {config} {src} {includes} {packages} -o {doto}".format( std=self._make_std(), packages=self._make_package_includes(), config=config, includes=include_dirs, src=src_path, doto=source.doto_path) print(t.make_syscommand(gcc_cmd)) comp_proc = subprocess.run(gcc_cmd, stdout=subprocess.PIPE, shell=True) if comp_proc.returncode != 0: raise PykeError('{0} building {1}'.format( t.make_error('Error'), t.make_file_name(source.doto_path))) else: print("{0} built {1}.".format( t.make_file_name(source.doto_path), t.make_success('successfully'))) else: print("{0} is up to date.".format( t.make_file_name(source.doto_path)))
def _build_run_script(self): dep_p = [p for _, p in self.cpp_data.depends_on.items()] dep_d = [ os.path.dirname(p.tool.get_output_path()) for p in dep_p if p.tool.cpp_data.output_type == 'so' ] sodirs = ';'.join(dep_d) script_path = os.path.join(self.path, 'run.sh') print("Making run script {}".format(t.make_file_name(script_path))) try: with open(script_path, 'w') as f: output_dir = os.path.dirname(self.output_path) if len(dep_d) > 0: f.write('export LD_LIBRARY_PATH="$LD_LIBRARY_PATH;{}"\n'. format(sodirs)) f.write('{}\n'.format(self.output_path)) except IOError as e: raise PykeError(e) try: os.chmod(script_path, 0o755) except OSError as e: raise PykeError(e)
def _build_so_links(self, force=False): mod_name = self.output_path[0:self.output_path.rindex('.')] if not os.path.lexists(mod_name): print("Making soft link {}".format(t.make_file_name(mod_name))) os.unlink(mod_name) os.symlink(self.output_path, mod_name) else: print("{} is up to date.".format(t.make_file_name(mod_name))) mod_name = mod_name[0:mod_name.rindex('.')] if not os.path.lexists(mod_name): print("Making soft link {}".format(t.make_file_name(mod_name))) os.unlink(mod_name) os.symlink(self.output_path, mod_name) else: print("{} is up to date.".format(t.make_file_name(mod_name)))
def _build_so_links(self, force=False): mod_name = self.output_path[0:self.output_path.rindex('.')] if not os.path.lexists(mod_name): print ("Making soft link {}".format(t.make_file_name(mod_name))) os.unlink(mod_name) os.symlink(self.output_path, mod_name) else: print ("{} is up to date.".format( t.make_file_name(mod_name))) mod_name = mod_name[0:mod_name.rindex('.')] if not os.path.lexists(mod_name): print ("Making soft link {}".format(t.make_file_name(mod_name))) os.unlink(mod_name) os.symlink(self.output_path, mod_name) else: print ("{} is up to date.".format( t.make_file_name(mod_name)))
def is_up_to_date(self): for src in self.cpp_data.sources: full_src = self.make_src_path(src) src_mtime = os.path.get_mtime(full_src) try: self._resolve_includes(full_src) doto_path = self.make_doto_path(src) doto_mtime = 0.0 ouput_path = self.get_output_path() output_mtime = 0.0 if os.path.exists(doto_path): doto_mtime = os.path.getmtime(doto_path) if os.path.exists(output_path): output_mtime = os.path.getmtime(output_path) comparator = doto_mtime if self.cpp_data.whole_program: comparator = outut_mtime # If any include files are newer than the doto, we need to build. for incf in self.included_files[full_src]: if os.path.get_mtime(incf) > comparator: print( "{0} is out of date by {1} (and possibly others).". format(t.make_file_name(src), t.make_file_name(incf))) return False if self.cpp_data.whole_program: if src_mtime > output_mtime: print("{0} is out of date by {1}.".format( t.make_file_name(src), t.make_file_name(output_path))) return False else: if src_mtime > doto_mtime: print("{0} is out of date by {1}.".format( t.make_file_name(doto_path), t.make_file_name(full_src))) return False if doto_mtime > output_mtime: print("{0} is out of date by {1}.".format( t.make_file_name(output_path), t.make_file_name(doto_path))) return False except IOError as e: print("{0}: {1}".format(t.make_error('Error'), e)) return False return True
def is_up_to_date(self): for src in self.cpp_data.sources: full_src = self.make_src_path(src) src_mtime = os.path.get_mtime(full_src) try: self._resolve_includes(full_src) doto_path = self.make_doto_path(src) doto_mtime = 0.0 ouput_path = self.get_output_path() output_mtime = 0.0 if os.path.exists(doto_path): doto_mtime = os.path.getmtime(doto_path) if os.path.exists(output_path): output_mtime = os.path.getmtime(output_path) comparator = doto_mtime if self.cpp_data.whole_program: comparator = outut_mtime # If any include files are newer than the doto, we need to build. for incf in self.included_files[full_src]: if os.path.get_mtime(incf) > comparator: print ("{0} is out of date by {1} (and possibly others).".format( t.make_file_name(src), t.make_file_name(incf))) return False if self.cpp_data.whole_program: if src_mtime > output_mtime: print ("{0} is out of date by {1}.".format( t.make_file_name(src), t.make_file_name(output_path))) return False else: if src_mtime > doto_mtime: print ("{0} is out of date by {1}.".format( t.make_file_name(doto_path), t.make_file_name(full_src))) return False if doto_mtime > output_mtime: print ("{0} is out of date by {1}.".format( t.make_file_name(output_path), t.make_file_name(doto_path))) return False except IOError as e: print ("{0}: {1}".format( t.make_error('Error'), e)) return False return True
def _resolve_includes(self, src_path): cpp_cmd = "cpp -M {std} {includes} {packages} {src}".format( std = self._make_std(), includes = self._make_include_dirs(), packages = self._make_package_includes(), src = src_path) print (t.make_syscommand(cpp_cmd)) comp_proc = subprocess.run(cpp_cmd, input='', stdout=subprocess.PIPE, shell=True, universal_newlines=True) if comp_proc.returncode != 0: self.sources[src_path].is_includes_resolved = False raise PykeError('{0} resolving #includes for {1}'.format( t.make_error('Error'), t.make_file_name(src_path))) self.sources[src_path].is_includes_resolved = True self.sources[src_path].included_files = [f for d in comp_proc.stdout.splitlines()[1:] # each line of input can have n paths for f in str(d).rstrip(" \\").split()] # clean and split each line to list paths
def _build_run_script(self): dep_p = [p for _, p in self.cpp_data.depends_on.items()] dep_d = [os.path.dirname(p.tool.get_output_path()) for p in dep_p if p.tool.cpp_data.output_type == 'so'] sodirs = ';'.join(dep_d) script_path = os.path.join(self.path, 'run.sh') print ("Making run script {}".format(t.make_file_name(script_path))) try: with open(script_path, 'w') as f: output_dir = os.path.dirname(self.output_path) if len(dep_d) > 0: f.write('export LD_LIBRARY_PATH="$LD_LIBRARY_PATH;{}"\n'.format(sodirs)) f.write('{}\n'.format(self.output_path)) except IOError as e: raise PykeError(e) try: os.chmod(script_path, 0o755) except OSError as e: raise PykeError(e)
def _resolve_includes(self, src_path): cpp_cmd = "cpp -M {std} {includes} {packages} {src}".format( std=self._make_std(), includes=self._make_include_dirs(), packages=self._make_package_includes(), src=src_path) print(t.make_syscommand(cpp_cmd)) comp_proc = subprocess.run(cpp_cmd, input='', stdout=subprocess.PIPE, shell=True, universal_newlines=True) if comp_proc.returncode != 0: self.sources[src_path].is_includes_resolved = False raise PykeError('{0} resolving #includes for {1}'.format( t.make_error('Error'), t.make_file_name(src_path))) self.sources[src_path].is_includes_resolved = True self.sources[src_path].included_files = [ f for d in comp_proc.stdout.splitlines()[ 1:] # each line of input can have n paths for f in str(d).rstrip(" \\").split() ] # clean and split each line to list paths
def clean_project(self): print ("Cleaning object files from {}:".format( t.make_dir(self.get_intermediate_dir()))) for source in self.sources: if source.doto_exists: print ("\tCleaning {0}".format(t.make_file_name(source.doto_path))) os.remove(source.doto_path) print ("Cleaning target files from {}:".format( t.make_dir(self.output_dir))) if os.path.exists(self.output_path): print ("\tCleaning {0}".format(os.path.basename(self.output_path))) os.remove(self.output_path) if self.cpp_data.output_type == "so": mod_name = self.output_path[0:self.output_path.rindex('.')] if os.path.lexists(mod_name): print ("\tCleaning {}".format(mod_name)) os.unlink(mod_name) mod_name = mod_name[0:mod_name.rindex('.')] if os.path.lexists(mod_name): print ("\tCleaning {}".format(mod_name)) os.unlink(mod_name)
def clean_project(self): print("Cleaning object files from {}:".format( t.make_dir(self.get_intermediate_dir()))) for source in self.sources: if source.doto_exists: print("\tCleaning {0}".format( t.make_file_name(source.doto_path))) os.remove(source.doto_path) print("Cleaning target files from {}:".format( t.make_dir(self.output_dir))) if os.path.exists(self.output_path): print("\tCleaning {0}".format(os.path.basename(self.output_path))) os.remove(self.output_path) if self.cpp_data.output_type == "so": mod_name = self.output_path[0:self.output_path.rindex('.')] if os.path.lexists(mod_name): print("\tCleaning {}".format(mod_name)) os.unlink(mod_name) mod_name = mod_name[0:mod_name.rindex('.')] if os.path.lexists(mod_name): print("\tCleaning {}".format(mod_name)) os.unlink(mod_name)
def _link_objects(self, force=False): print() output_dir, output_name = os.path.split(self.output_path) title_bw = "Building {}".format(output_name) title_co = "Building {}".format(t.make_file_name(output_name)) t.print_title(title_co, len(title_bw)) self._ensure_dir_exists(output_dir) if self.cpp_data.output_type == "lib": gcc_cmd = "ar cvq -o {outfile} {objs}".format( outfile=self.output_path, objs=self._make_dotos()) elif self.cpp_data.output_type == "so": _, soname = os.path.split(self.output_path) soname = soname[0:soname.rindex('.')] gcc_cmd = "g++ {std} -shared -Wl,-soname,{name} {config} -o {outfile} {objs} {packages} {libs} {libdirs}".format( std=self._make_std(), name=soname, config=self.cpp_data.link_args, outfile=self.output_path, objs=self._make_dotos(), packages=self._make_package_libs(), libs=self._make_libs(), libdirs=self._make_lib_dirs()) elif self.cpp_data.output_type == "exe": gcc_cmd = "g++ {std} {config} -o {outfile} {objs} {libdirs} {libs} {packages}".format( std=self._make_std(), config=self.cpp_data.link_args, outfile=self.output_path, objs=self._make_dotos(), libs=self._make_libs(), libdirs=self._make_lib_dirs(), packages=self._make_package_libs()) objs = [self.make_doto_path(src) for src in self.cpp_data.sources] newest_obj_time = max([os.path.getmtime(obj) for obj in objs]) project_deps = [ p.tool.get_output_path() for _, p in self.cpp_data.depends_on.items() ] if len(project_deps) > 0: newest_obj_time = max( newest_obj_time, max([os.path.getmtime(p) for p in project_deps])) if (force or not os.path.exists(self.output_path) or newest_obj_time > os.path.getmtime(self.output_path)): if os.path.exists(self.output_path): os.remove(self.output_path) print(t.make_syscommand(gcc_cmd)) comp_proc = subprocess.run(gcc_cmd, stdout=subprocess.PIPE, shell=True) if comp_proc.returncode != 0: raise PykeError('{0} linking {1}'.format( t.make_error('Error'), t.make_file_name(self.output_path))) else: print("{0} linked {1}.".format( t.make_file_name(self.output_path), t.make_success('successfully'))) else: print("{0} is up to date.".format( t.make_file_name(self.output_path)))
def _link_objects(self, force=False): print () output_dir, output_name = os.path.split(self.output_path) title_bw = "Building {}".format(output_name) title_co = "Building {}".format(t.make_file_name(output_name)) t.print_title(title_co, len(title_bw)) self._ensure_dir_exists(output_dir) if self.cpp_data.output_type == "lib": gcc_cmd = "ar cvq -o {outfile} {objs}".format( outfile = self.output_path, objs = self._make_dotos()) elif self.cpp_data.output_type == "so": _, soname = os.path.split(self.output_path) soname = soname[0:soname.rindex('.')] gcc_cmd = "g++ {std} -shared -Wl,-soname,{name} {config} -o {outfile} {objs} {packages} {libs} {libdirs}".format( std = self._make_std(), name = soname, config = self.cpp_data.link_args, outfile = self.output_path, objs = self._make_dotos(), packages = self._make_package_libs(), libs = self._make_libs(), libdirs = self._make_lib_dirs()) elif self.cpp_data.output_type == "exe": gcc_cmd = "g++ {std} {config} -o {outfile} {objs} {libdirs} {libs} {packages}".format( std = self._make_std(), config = self.cpp_data.link_args, outfile = self.output_path, objs = self._make_dotos(), libs = self._make_libs(), libdirs = self._make_lib_dirs(), packages = self._make_package_libs()) objs = [self.make_doto_path(src) for src in self.cpp_data.sources] newest_obj_time = max([os.path.getmtime(obj) for obj in objs]) project_deps = [p.tool.get_output_path() for _, p in self.cpp_data.depends_on.items()] if len(project_deps) > 0: newest_obj_time = max(newest_obj_time, max([os.path.getmtime(p) for p in project_deps])) if (force or not os.path.exists(self.output_path) or newest_obj_time > os.path.getmtime(self.output_path)): if os.path.exists(self.output_path): os.remove(self.output_path) print (t.make_syscommand(gcc_cmd)) comp_proc = subprocess.run(gcc_cmd, stdout=subprocess.PIPE, shell=True) if comp_proc.returncode != 0: raise PykeError('{0} linking {1}'.format( t.make_error('Error'), t.make_file_name(self.output_path))) else: print ("{0} linked {1}.".format( t.make_file_name(self.output_path), t.make_success('successfully'))) else: print ("{0} is up to date.".format( t.make_file_name(self.output_path)))