From e5e42f3dd04ea9f6fe0cd62034fc5882a3bf25ac Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Fri, 30 Jul 2010 11:14:06 +0000 Subject: [PATCH] Port processing of relative paths in sources. [SVN r64465] --- src/build/generators.py | 26 +++++++++++++++++++++++--- src/build/project.py | 18 ++++++++++++++---- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/build/generators.py b/src/build/generators.py index d2106033e..4dea2afda 100644 --- a/src/build/generators.py +++ b/src/build/generators.py @@ -349,6 +349,21 @@ class Generator: return result + def determine_target_name(self, fullname): + # Determine target name from fullname (maybe including path components) + # Place optional prefix and postfix around basename + + dir = os.path.dirname(fullname) + name = os.path.basename(fullname) + + if dir and not ".." in dir and not os.path.isabs(dir): + # Relative path is always relative to the source + # directory. Retain it, so that users can have files + # with the same in two different subdirectories. + name = dir + "/" + name + + return name + def determine_output_name(self, sources): """Determine the name of the produced target from the names of the sources.""" @@ -371,8 +386,8 @@ class Generator: "%s: source targets have different names: cannot determine target name" % (self.id_)) - # Names of sources might include directory. We should strip it. - return os.path.basename(name) + # Names of sources might include directory. We should strip it. + return self.determine_target_name(sources[0].name()) def generated_targets (self, sources, prop_set, project, name): @@ -409,7 +424,12 @@ class Generator: pre = self.name_prefix_ post = self.name_postfix_ for t in self.target_types_: - generated_name = pre[0] + name + post[0] + basename = os.path.basename(name) + idx = basename.find(".") + if idx != -1: + basename = basename[:idx] + generated_name = pre[0] + basename + post[0] + generated_name = os.path.join(os.path.dirname(name), generated_name) pre = pre[1:] post = post[1:] diff --git a/src/build/project.py b/src/build/project.py index c0cdb8649..9d2f3acc0 100644 --- a/src/build/project.py +++ b/src/build/project.py @@ -565,12 +565,12 @@ actual value %s""" % (jamfile_module, saved_project, self.current_project)) return self.project_rules_ def glob_internal(self, project, wildcards, excludes, rule_name): - location = project.get("source-location") + location = project.get("source-location")[0] result = [] callable = b2.util.path.__dict__[rule_name] - paths = callable(location, wildcards, excludes) + paths = callable([location], wildcards, excludes) has_dir = 0 for w in wildcards: if os.path.dirname(w): @@ -578,11 +578,21 @@ actual value %s""" % (jamfile_module, saved_project, self.current_project)) break if has_dir or rule_name != "glob": + result = [] # The paths we've found are relative to current directory, # but the names specified in sources list are assumed to # be relative to source directory of the corresponding - # prject. So, just make the name absolute. - result = [os.path.join(os.getcwd(), p) for p in paths] + # prject. Either translate them or make absolute. + + for p in paths: + rel = os.path.relpath(p, location) + # If the path is below source location, use relative path. + if not ".." in rel: + result.append(rel) + else: + # Otherwise, use full path just to avoid any ambiguities. + result.append(os.path.abspath(p)) + else: # There were not directory in wildcard, so the files are all # in the source directory of the project. Just drop the