summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorChad Elliott <elliottc@objectcomputing.com>2022-11-17 10:41:03 -0600
committerChad Elliott <elliottc@objectcomputing.com>2022-11-17 10:41:03 -0600
commitd4736ff20e0db3ec6a1d8d8c98af8027ebbb83c3 (patch)
tree0b236932b7bc82daa1bcf3ba7cb01e141d069f62 /modules
parentf6915f51c2244fe7303d38ddc747055d64b72820 (diff)
downloadMPC-d4736ff20e0db3ec6a1d8d8c98af8027ebbb83c3.tar.gz
Handle out-of-tree directories properly by creating a workspace for each project group directory and adding the bin dir parameter to add_subdirectory().
Diffstat (limited to 'modules')
-rw-r--r--modules/CMakeWorkspaceCreator.pm54
-rw-r--r--modules/WorkspaceCreator.pm10
2 files changed, 57 insertions, 7 deletions
diff --git a/modules/CMakeWorkspaceCreator.pm b/modules/CMakeWorkspaceCreator.pm
index ceca1cbe..a3cdafea 100644
--- a/modules/CMakeWorkspaceCreator.pm
+++ b/modules/CMakeWorkspaceCreator.pm
@@ -48,7 +48,12 @@ sub pre_workspace {
'# This file was generated by MPC.', $crlf,
'#', $crlf,
'# MPC Command:', $crlf,
- '# ', $self->create_command_line_string($0, @ARGV), $crlf);
+ '# ', $self->create_command_line_string($0, @ARGV), $crlf, $crlf);
+}
+
+sub out_of_tree {
+ my($self, $dir) = @_;
+ return ($dir =~ /^\.\.\// || !$self->path_is_relative($dir));
}
## Get the top level directory in the path. If the path does not contain
@@ -59,7 +64,7 @@ sub get_top_directory {
## First, convert the path to a relative path based on the current working
## directory.
my $dir = $self->path_to_relative($self->getcwd(), $path);
- if ($dir =~ /^\.\.\// || !$self->path_is_relative($dir)) {
+ if ($self->out_of_tree($dir)) {
## If the directory is above the current directory or not relative to
## the current working directory, we need to give the directory portion
## back and call it a day.
@@ -83,6 +88,28 @@ sub get_top_directory {
return $dir;
}
+sub write_ws_top {
+ my($self, $fh, $ws) = @_;
+ my $crlf = $self->crlf();
+ print $fh "cmake_minimum_required(VERSION $version)", $crlf,
+ "project($ws CXX)", $crlf;
+}
+
+sub write_single_include_ws {
+ my($self, $prj) = @_;
+ my $fh = new FileHandle();
+ my $dir = $self->mpc_dirname($prj);
+ my $file = $dir . '/' . $self->workspace_file_name();
+
+ if (open($fh, ">$file")) {
+ my $crlf = $self->crlf();
+ $self->pre_workspace($fh);
+ $self->write_ws_top($fh, basename($dir));
+ print $fh "${crlf}include(", basename($prj), ")$crlf";
+ close($fh);
+ }
+}
+
sub write_comps {
my($self, $fh, $creator) = @_;
my $status = 1;
@@ -100,6 +127,12 @@ sub write_comps {
## Keep track of the project existing in this directory
$dirs{$dir} = 1;
+ ## If this directory is out-of-tree, it will not contain a top-level
+ ## workspace (due to the way that workspace-per-directory works). We
+ ## need to generate one here.
+ if ($self->out_of_tree($dir)) {
+ $self->write_single_include_ws($entry);
+ }
push(@project_dirs, $dir);
}
}
@@ -108,16 +141,27 @@ sub write_comps {
## calls below it.
my $crlf = $self->crlf();
my $ws = TemplateParser::actual_normalize(undef, $self->get_workspace_name());
- print $fh "cmake_minimum_required(VERSION $version)", $crlf,
- "project($ws CXX)", $crlf;
+ $self->write_ws_top($fh, $ws);
my $first = 1;
+ my %bin_used;
foreach my $dir (@project_dirs) {
if ($first) {
$first = undef;
print $fh $crlf;
}
- print $fh "add_subdirectory($dir)$crlf";
+ my $bin_dir = '';
+ if ($self->out_of_tree($dir)) {
+ ## Because this directory is out-of-tree, CMake requires a binary
+ ## directory to be passed to add_subdirectory().
+ my $bin = basename($dir);
+ while(exists $bin_used{$bin}) {
+ $bin .= '_';
+ }
+ $bin_dir = " $bin";
+ $bin_used{$bin} = 1;
+ }
+ print $fh "add_subdirectory($dir$bin_dir)$crlf";
}
$first = 1;
diff --git a/modules/WorkspaceCreator.pm b/modules/WorkspaceCreator.pm
index b6be9879..b8b993f8 100644
--- a/modules/WorkspaceCreator.pm
+++ b/modules/WorkspaceCreator.pm
@@ -1343,8 +1343,14 @@ sub generate_hierarchy {
my %projinfo = %{$originfo};
foreach my $prj (@projects) {
- my($top, $rest) = $self->topname($prj);
-
+ ## If the project path starts with ./ the code assumed that the top was
+ ## the current directory and would end up not creating the workspace as
+ ## it should have been. We will clean up the project directory and pass
+ ## that to topname() instead.
+ my $clean = $prj;
+ $clean =~ s/^\.[\/]+//;
+
+ my($top, $rest) = $self->topname($clean);
if (!defined $current) {
$current = $top;
push(@saved, $rest);