Skip to content

Commit

Permalink
Fixes for bad merge.
Browse files Browse the repository at this point in the history
  • Loading branch information
GPMueller committed Oct 30, 2020
1 parent 5659927 commit d663463
Show file tree
Hide file tree
Showing 14 changed files with 54 additions and 164 deletions.
4 changes: 1 addition & 3 deletions clang_build/directories.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
class Directories:
def __init__(self, files, dependencies, public_dependencies):
self.dependencies = dependencies

def __init__(self, files, public_dependencies):
# Include directories
self.include_private = files["include_directories"]
self.include_public = files["public_include_directories"]
Expand Down
63 changes: 28 additions & 35 deletions clang_build/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,6 @@ def add_targets(self, target_list: list):
# Add nodes and edges for targets in self
for target in target_list:
self._project_tree.add_node(target, data=target)
self._project_tree.add_edges_from((self, target) for target in target_list)

# Create a dotfile of the dependency graph
create_dotfile = False
Expand All @@ -342,12 +341,8 @@ def add_targets(self, target_list: list):
# Add edges for dependencies in targets defined in project
for target in target_list:
target.config["dependencies"] = self._get_dependencies_2(target, target.config.get("dependencies", []))
target.config["public_dependencies"] = self._get_dependencies_2(target, target.config.get("public_dependencies", []))

for dependency in target.config["dependencies"]:
self._project_tree.add_edge(target, dependency)
for dependency in target.config["public_dependencies"]:
self._project_tree.add_edge(target, dependency, public=True)

# Create new dotfile with full dependency graph
if create_dotfile:
Expand Down Expand Up @@ -445,43 +440,47 @@ def build(
targets_to_build = self._get_targets_to_build(build_all, target_list)

# Sort targets in build order
target_build_description_list = [
build_list = [
target
for target in reversed(list(_nx.topological_sort(self._project_tree)))
if target in targets_to_build
if (target in targets_to_build or build_all)
and not isinstance(self._project_tree.nodes[target]["data"], Project)
]

# Get project sources, if any
project_build_list = []
for target_description in target_build_description_list:
for predecessor in self._project_tree.predecessors(target_description):
if isinstance(predecessor, Project):
project_build_list.append(predecessor)
for target_description in build_list:
project_build_list.append(target_description.parent_project)
project_build_list = list(dict.fromkeys(project_build_list))
for project in project_build_list:
project.get_sources()

for target in target_build_description_list:
parent_project = next(self._project_tree.predecessors(target))
target.parent_directory = parent_project._directory
target.parent_build_directory = parent_project._build_directory

### Note: the project_tree needs to be updated directly for dependencies
### to be used correctly in the `_target_from_description` function
target_build_list = []
for target in target_build_description_list:
if isinstance(target, _TargetDescription):
target_instance = self._target_from_description(
self._project_tree.nodes[target]["data"]#, self._project_tree
for list_entry in build_list:
if isinstance(list_entry, _TargetDescription):
target = self._target_from_description(
self._project_tree.nodes[list_entry]["data"]
)
target_build_list.append(target_instance)
self._project_tree.nodes[target]["data"] = target_instance
if target:
target_build_list.append(target)
self._project_tree.nodes[list_entry]["data"] = target
elif isinstance(list_entry, _Target):
target_build_list.append(list_entry)
else:
target_build_list.append(target)
error_message = self.parent.log_message(
f"Found {target} in target list, which cannot be used because"
" it is not derived from Target or TargetDescription."
)

self._logger.exception(error_message)
raise RuntimeError(error_message)

if not target_build_list:
self._logger.info("No targets to be built")
else:
self._logger.info(f"Building {', '.join([str(target) for target in target_build_list])}")

# Compile
with _Pool(processes=number_of_threads) as process_pool:
Expand Down Expand Up @@ -623,15 +622,9 @@ def _get_dependencies(self, target_description):
for dependency in self._project_tree.successors(target_description)
]

public_dependencies = []
successors = self._project_tree.successors(target_description)
for target, dependency, public in self._project_tree.subgraph([target_description] + [s for s in successors]).edges(data="public"):
if public == True:
public_dependencies.append(self._project_tree.nodes()[dependency]["data"])

# Are there executables named as dependencies?
executable_dependencies = [
target for target in dependencies+public_dependencies if isinstance(target, _Executable)
target for target in dependencies if isinstance(target, _Executable)
]
if executable_dependencies:
exelist = ", ".join([f"[{dep.name}]" for dep in executable_dependencies])
Expand All @@ -641,7 +634,7 @@ def _get_dependencies(self, target_description):
self._logger.error(error_message)
raise RuntimeError(error_message)

return dependencies, public_dependencies
return dependencies

def _get_dependencies_2(self, target, names):
dependencies = []
Expand Down Expand Up @@ -686,7 +679,7 @@ def _target_from_description(self, target_description):
Returns the correct target type based on input parameters
"""

dependencies, public_dependencies = self._get_dependencies(target_description)
dependencies = self._get_dependencies(target_description)

# Sources
target_description.get_sources()
Expand All @@ -703,7 +696,7 @@ def _target_from_description(self, target_description):
if target_type is not None:
target_type = str(target_type).lower()
if target_type in _TARGET_MAP:
return _TARGET_MAP[target_type](target_description, files, dependencies, public_dependencies)
return _TARGET_MAP[target_type](target_description, files, dependencies)
else:
error_message = target_description.log_message(
f'ERROR: Unsupported target type: "{target_description.config["target_type"].lower()}"'
Expand All @@ -717,12 +710,12 @@ def _target_from_description(self, target_description):
target_description.log_message(
"no source files found. Creating header-only target."
)
return _HeaderOnly(target_description, files, dependencies, public_dependencies)
return _HeaderOnly(target_description, files, dependencies)

target_description.log_message(
f'{len(files["sourcefiles"])} source file(s) found. Creating executable target.'
)
return _Executable(target_description, files, dependencies, public_dependencies)
return _Executable(target_description, files, dependencies)

def get_sources(self):
"""External sources, if present, will be downloaded to build_directory/external_sources.
Expand Down
69 changes: 25 additions & 44 deletions clang_build/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,6 @@ def dependencies(self):
"""
return self._dependencies

@property
def public_dependencies(self):
"""Return a list of any:`clang_build.target.Target`, which this
target depends on.
"""
return self._public_dependencies

@property
def root_directory(self):
"""Folders "include", "src", etc. are searched
Expand Down Expand Up @@ -87,7 +80,7 @@ def directories(self):
"""
return self._directories

def __init__(self, target_description, files, dependencies=None, public_dependencies=None):
def __init__(self, target_description, files, dependencies=None):
"""Initialise a target.
The procedure for initialisation is:
Expand All @@ -107,9 +100,6 @@ def __init__(self, target_description, files, dependencies=None, public_dependen
dependencies
Optional. A list of any:`clang_build.target.Target` which this target
depends on.
public_dependencies
Optional. A list of any:`clang_build.target.Target` which this target
depends on and which should also be available to dependent targets.
"""
_NamedLogger.__init__(self, _LOGGER)
self._name = target_description.name
Expand All @@ -118,23 +108,20 @@ def __init__(self, target_description, files, dependencies=None, public_dependen

if dependencies is None:
dependencies = []

self._dependencies = dependencies

if public_dependencies is None:
public_dependencies = []

self._public_dependencies = public_dependencies
self._root_directory = _Path(target_description.root_directory)
self._build_directory = target_description.build_directory

self._headers = list(dict.fromkeys(files["headers"]))

self._directories = Directories(files, self.dependencies, self.public_dependencies)
self._directories = Directories(files, self.dependencies)

# Compile and link flags
self._build_flags = self._get_default_flags()

# Dependencies' flags
for target in self.dependencies + self.public_dependencies:
for target in self.dependencies:
# Header only libraries will forward all non-private flags
self._add_dependency_flags(target)

Expand Down Expand Up @@ -182,7 +169,7 @@ def bundle(self):
"""
self.unsuccessful_bundle = False
bundle_files = []
for dependency in self.dependencies + self.public_dependencies:
for dependency in self.dependencies:
bundle_files += dependency.bundle()
return bundle_files

Expand Down Expand Up @@ -213,16 +200,15 @@ class HeaderOnly(Target):
TODO: need to check whether "public" makes sense for header-only, when we have implemented "private" dependencies
"""

def __init__(self, target_description, files, dependencies=None, public_dependencies=None):
def __init__(self, target_description, files, dependencies=None):
"""Initialise a header-only target.
Header-only targets' private flags and include-directories are public.
"""
super().__init__(
target_description=target_description,
files=files,
dependencies=dependencies,
public_dependencies=public_dependencies
dependencies=dependencies
)

if files["sourcefiles"]:
Expand Down Expand Up @@ -274,8 +260,7 @@ def __init__(
platform_flags,
prefix,
suffix,
dependencies=None,
public_dependencies=None
dependencies=None
):
self.source_files = files["sourcefiles"]
self.is_c_target = not any(
Expand All @@ -285,8 +270,7 @@ def __init__(
super().__init__(
target_description=target_description,
files=files,
dependencies=dependencies,
public_dependencies=public_dependencies
dependencies=dependencies
)

if not self.source_files:
Expand Down Expand Up @@ -342,12 +326,12 @@ def compile(self, process_pool, progress_disabled):
"""

# Object file only needs to be (re-)compiled if the source file or headers it depends on changed
if not self._environment.force_build:
if self._environment.force_build:
self.needed_buildables = self.buildables
else:
self.needed_buildables = [
buildable for buildable in self.buildables if buildable.needs_rebuild
]
else:
self.needed_buildables = self.buildables

# If the target was not modified, it may not need to compile
if not self.needed_buildables:
Expand Down Expand Up @@ -407,7 +391,7 @@ class Executable(Compilable):
An executable cannot be the dependency of another target.
"""

def __init__(self, target_description, files, dependencies=None, public_dependencies=None):
def __init__(self, target_description, files, dependencies=None):
"""Initialise an executable target.
"""

Expand All @@ -418,8 +402,7 @@ def __init__(self, target_description, files, dependencies=None, public_dependen
platform_flags=target_description.environment.toolchain.platform_defaults['PLATFORM_EXTRA_FLAGS_EXECUTABLE'],
prefix=target_description.environment.toolchain.platform_defaults['EXECUTABLE_PREFIX'],
suffix=target_description.environment.toolchain.platform_defaults['EXECUTABLE_SUFFIX'],
dependencies=dependencies,
public_dependencies=public_dependencies
dependencies=dependencies
)

### Bundling requires extra flags
Expand All @@ -431,7 +414,7 @@ def bundle(self):

### Gather
bundle_files = []
for dependency in self.dependencies + self.public_dependencies:
for dependency in self.dependencies:
bundle_files += dependency.bundle()

### Copy
Expand Down Expand Up @@ -529,8 +512,8 @@ def link(self):
[buildable.object_file for buildable in self.buildables],
self.outfile,
self._build_flags._language_flags() + self._build_flags.final_link_flags_list(),
[target.output_folder.resolve() for target in self.dependencies+self.public_dependencies if target.__class__ is not HeaderOnly],
[target.outname for target in self.dependencies+self.public_dependencies if target.__class__ is not HeaderOnly],
[target.output_folder.resolve() for target in self.dependencies if target.__class__ is not HeaderOnly],
[target.outname for target in self.dependencies if target.__class__ is not HeaderOnly],
False,
self.is_c_target)

Expand All @@ -542,7 +525,7 @@ def link(self):
{self.identifier: self.link_report})

class SharedLibrary(Compilable):
def __init__(self, target_description, files, dependencies=None, public_dependencies=None):
def __init__(self, target_description, files, dependencies=None):

super().__init__(
target_description=target_description,
Expand All @@ -551,8 +534,7 @@ def __init__(self, target_description, files, dependencies=None, public_dependen
platform_flags=target_description.environment.toolchain.platform_defaults['PLATFORM_EXTRA_FLAGS_SHARED'],
prefix=target_description.environment.toolchain.platform_defaults['SHARED_LIBRARY_PREFIX'],
suffix=target_description.environment.toolchain.platform_defaults['SHARED_LIBRARY_SUFFIX'],
dependencies=dependencies,
public_dependencies=public_dependencies
dependencies=dependencies
)

# TODO: This has to go to the flags department I guess
Expand All @@ -576,7 +558,7 @@ def bundle(self):
self_bundle_files.append(_Path(str(self.outfile)[:-3] + "lib"))

bundle_files = []
for dependency in self.dependencies + self.public_dependencies:
for dependency in self.dependencies:
bundle_files += dependency.bundle()

### Copy
Expand Down Expand Up @@ -611,8 +593,8 @@ def link(self):
[buildable.object_file for buildable in self.buildables],
self.outfile,
self._build_flags._language_flags() + self._build_flags.final_link_flags_list(),
[target.output_folder.resolve() for target in self.dependencies+self.public_dependencies if target.__class__ is not HeaderOnly],
[target.outname for target in self.dependencies+self.public_dependencies if target.__class__ is not HeaderOnly],
[target.output_folder.resolve() for target in self.dependencies if target.__class__ is not HeaderOnly],
[target.outname for target in self.dependencies if target.__class__ is not HeaderOnly],
True,
self.is_c_target)

Expand All @@ -634,8 +616,7 @@ def __init__(self, target_description, files, dependencies=None):
platform_flags=target_description.environment.toolchain.platform_defaults['PLATFORM_EXTRA_FLAGS_STATIC'],
prefix=target_description.environment.toolchain.platform_defaults['STATIC_LIBRARY_PREFIX'],
suffix=target_description.environment.toolchain.platform_defaults['STATIC_LIBRARY_SUFFIX'],
dependencies=dependencies,
public_dependencies=public_dependencies
dependencies=dependencies
)

def _add_dependency_flags(self, target):
Expand All @@ -656,7 +637,7 @@ def link(self):
objects = [buildable.object_file for buildable in self.buildables]

# Dependencies' objects
for target in self.dependencies+self.public_dependencies:
for target in self.dependencies:
if not target.__class__ is HeaderOnly:
objects += [buildable.object_file for buildable in target.buildables]

Expand Down
8 changes: 0 additions & 8 deletions test/public_dependency/clang-build.toml

This file was deleted.

9 changes: 0 additions & 9 deletions test/public_dependency/libA/clang-build.toml

This file was deleted.

Loading

0 comments on commit d663463

Please sign in to comment.