diff options
author | ocielliottc <elliottc@objectcomputing.com> | 2023-01-03 07:37:33 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-03 07:37:33 -0600 |
commit | 60b0c90efa801c758911bdc4c7949db6809eb3f4 (patch) | |
tree | 5f67f61f50f045f374f8e0ab4067888da95b92af | |
parent | 5aad93c4292b7aa33395dd2bb96c5599c73bdf5a (diff) | |
parent | 26e3b92f9ed15c69f17baca125444b886b874055 (diff) | |
download | MPC-60b0c90efa801c758911bdc4c7949db6809eb3f4.tar.gz |
Merge pull request #164 from DOCGroup/elliottc/cmake-support
Elliottc/cmake support
-rw-r--r-- | config/openssl.mpb | 15 | ||||
-rw-r--r-- | config/xerces.mpb | 11 | ||||
-rw-r--r-- | docs/USAGE | 8 | ||||
-rw-r--r-- | docs/html/MakeProjectCreator.html | 45 | ||||
-rw-r--r-- | docs/templates/cmake.txt | 17 | ||||
-rw-r--r-- | modules/CMakeProjectCreator.pm | 117 | ||||
-rw-r--r-- | modules/CMakeWorkspaceCreator.pm | 195 | ||||
-rw-r--r-- | modules/Creator.pm | 2 | ||||
-rw-r--r-- | modules/DirectoryManager.pm | 24 | ||||
-rw-r--r-- | modules/ProjectCreator.pm | 23 | ||||
-rw-r--r-- | modules/StringProcessor.pm | 12 | ||||
-rw-r--r-- | modules/TemplateParser.pm | 38 | ||||
-rw-r--r-- | modules/WorkspaceCreator.pm | 10 | ||||
-rw-r--r-- | templates/cmake.mpd | 187 | ||||
-rw-r--r-- | templates/cmakedll.mpt | 18 | ||||
-rw-r--r-- | templates/cmakeexe.mpt | 3 |
16 files changed, 700 insertions, 25 deletions
diff --git a/config/openssl.mpb b/config/openssl.mpb index 8af0fef4..84e466fa 100644 --- a/config/openssl.mpb +++ b/config/openssl.mpb @@ -13,8 +13,10 @@ feature(openssl) { $(SSL_ROOT)/lib } - includes += $(SSL_INCDIR) - libpaths += $(SSL_LIBDIR) + specific(!cmake) { + includes += $(SSL_INCDIR) + libpaths += $(SSL_LIBDIR) + } specific(prop:windows) { lit_libs += libeay32 ssleay32 @@ -36,6 +38,15 @@ feature(openssl) { specific(prop:microsoft) { libpaths += $(SSL_ROOT)/lib/VC } + + specific(cmake) { + // Undo the else of the !prop:windows above. + lit_libs -= ssl crypto + includes -= /usr/kerberos/include + + lit_libs += ${OPENSSL_LIBRARIES} + includes += ${OPENSSL_INCLUDE_DIR} + } } feature(openssl11) { diff --git a/config/xerces.mpb b/config/xerces.mpb index 85f7e8aa..bfbd0d19 100644 --- a/config/xerces.mpb +++ b/config/xerces.mpb @@ -38,9 +38,6 @@ feature(xerces3) { $(XERCESCROOT)/lib } - includes += $(XERCESC_INCDIR) - libpaths += $(XERCESC_LIBDIR) - specific(prop:microsoft) { xerceslib = xerces-c_3 @@ -57,6 +54,14 @@ feature(xerces3) { xerceslib = xerces-c } + specific(cmake) { + includes += ${XercesC_INCLUDE_DIRS} + xerceslib = ${XercesC_LIBRARIES} + } else { + includes += $(XERCESC_INCDIR) + libpaths += $(XERCESC_LIBDIR) + } + // We have to use lit_libs here as the library decorator // does not necessarily match what MPC uses (particularly for // static builds). @@ -24,10 +24,10 @@ Usage: mwc.pl [-global <file>] [-include <directory>] [-recurse] [-workers <#>] [-workers_dir <dir> | -workers_port <#>] [-language <cplusplus | csharp | java | vb>] [-type <automake | bcb2007 | bcb2009 | bds4 | bmake | cc | cdt6 | - cdt7 | em3 | ghs | html | iar | make | nmake | rpmspec | - sle | uvis | vc6 | vc7 | vc71 | vc8 | vc9 | vc10 | vc11 | - vc12 | vc14 | vs2017 | vs2019 | vs2022 | wb26 | wb30 | - wix>] + cdt7 | cmake | em3 | ghs | html | iar | make | nmake | + rpmspec | sle | uvis | vc6 | vc7 | vc8 | vc9 | vc10 | + vc11 | vc12 | vc14 | vc71 | vs2017 | vs2019 | vs2022 | + wb26 | wb30 | wix>] [files] -base Add <project> as a base project to each generated diff --git a/docs/html/MakeProjectCreator.html b/docs/html/MakeProjectCreator.html index 6e59a72b..bede62d4 100644 --- a/docs/html/MakeProjectCreator.html +++ b/docs/html/MakeProjectCreator.html @@ -286,6 +286,18 @@ <tr> <td rowspan="1" colspan="1"> <p class="Tbl-Body"> + <em class="TableCode">cmake</em> + </p> + </td> + + <td rowspan="1" colspan="1"> + <p class="Tbl-Body">Support for CMake requires user provided modules for custom commands.</p> + </td> + </tr> + + <tr> + <td rowspan="1" colspan="1"> + <p class="Tbl-Body"> <em class="TableCode">em3</em> </p> </td> @@ -6782,7 +6794,7 @@ class="Code">specific</em> clause. </blockquote> <p class="Body"> - The following mpc file (<em class= + The following .mpc file (<em class= "Code">RTEC_Perf.mpc</em> ) shows the simple and small number of lines required to generate usable build tool project files. </p> @@ -6899,7 +6911,9 @@ class="Code">specific</em> clause. Line five adds <em class= "Code">TAO_RTEC_PERF_BUILD_DLL</em> to the <em class= "Code">dllflags</em>, which defines a macro that is used by the - <em class="Code">rtec_perf_export.h</em> header file. + <em class="Code">rtec_perf_export.h</em> header file when + building shared libraries on platforms that support symbol + visibility. </p> <blockquote> @@ -8174,7 +8188,7 @@ class="Code">specific</em> clause. <blockquote> - <p class="Code">document_template.pl v1.3</p> + <p class="Code">document_template.pl v1.4</p> <p class="Code"> Usage: document_template.pl <template> @@ -8184,6 +8198,16 @@ class="Code">specific</em> clause. <p class="Code"> </p> <p class="Code"> + template - .mpd file to document. Certain MPC types don't + use a template, + </p> + + <p class="Code"> + + in that case this aregument can be the Perl module. + </p> + + <p class="Code"> html output - This defaults to the name of the template file with the .mpd </p> @@ -8558,6 +8582,21 @@ class="Code">specific</em> clause. </td> </tr> + <tr> + <td rowspan="1" colspan="1"> + <p class="Tbl-Body"> + <em class= + "TableCode">command->type</em> + </p> + </td> + + <td rowspan="1" colspan="1"> + <p class="Tbl-Body"> + The original type of file for this command. + </p> + </td> + </tr> + </table> </p> diff --git a/docs/templates/cmake.txt b/docs/templates/cmake.txt new file mode 100644 index 00000000..c20cb054 --- /dev/null +++ b/docs/templates/cmake.txt @@ -0,0 +1,17 @@ +// Current as of 10/26/2022 +// This defines the role of all the template variables specific to the +// 'cmake' project type. +// +// The value $ is used below to represent the dollar sign. The dollar +// sign is interpreted by the parser in document_template.pl. +// +// Please try to keep this alphabetically sorted. +// +cmake_minimum_required = Sets the minimum required version for CMake. +env_dllout = The value of 'dllout' with $() values converted to $ENV{}. +env_exeout = The value of 'exeout' with $() values converted to $ENV{}. +env_includes = The value of 'includes' with $() values converted to $ENV{}. +env_libout = The value of 'libout' with $() values converted to $ENV{}. +env_libpaths = The value of 'libpaths' with $() values converted to $ENV{}. +packages = A list of packages to be used with the find_package() command. +pre_find_package = A specific command or set of commands to be issued before any find_package() commands are called. diff --git a/modules/CMakeProjectCreator.pm b/modules/CMakeProjectCreator.pm new file mode 100644 index 00000000..e1896dc4 --- /dev/null +++ b/modules/CMakeProjectCreator.pm @@ -0,0 +1,117 @@ +package CMakeProjectCreator; + +# ************************************************************ +# Description : A CMake Project Creator +# Author : Chad Elliott +# Create Date : 10/10/2022 +# ************************************************************ + +# ************************************************************ +# Pragmas +# ************************************************************ + +use strict; + +use ProjectCreator; + +use vars qw(@ISA); +@ISA = qw(ProjectCreator); + +# ************************************************************ +# Subroutine Section +# ************************************************************ + +sub pre_generation { + my $self = shift; + + ## For CMake, we are expecting a hybrid of custom types and modules. + ## We are turning off all automatic output so that the modules defined + ## for CMake can handle these artifacts. + foreach my $gentype (keys %{$self->{'generated_exts'}}) { + $self->{'generated_exts'}->{$gentype}->{'automatic_out'} = 0; + } +} + +sub default_to_library { + ## In case there are only generated source files... + return 1; +} + +sub need_to_write_project { + my $self = shift; + + ## Because we do not automatically add custom output, it is possible that + ## the project only has generated source files and expects them to cause + ## an automatic library name to be chosen. If the base + ## need_to_write_project() tells us that it's only generated source files + ## but the user didn't mark this project as "custom only", then we have to + ## override it back to 1 to retain the user provided target name. + my $status = $self->SUPER::need_to_write_project(); + if ($status == 2 && !$self->get_assignment('custom_only')) { + $status = 1; + } + + return $status; +} + +sub get_use_env { + ## Override the option getter so that, for CMake, MPC always functions as + ## if the -use_env option was supplied on the command line. + return 1; +} + +sub pre_write_output_file { + my $self = shift; + return $self->combine_custom_types(); +} + +sub dollar_special { + return 1; +} + +sub project_file_prefix { + return "CMakeLists."; +} + +sub escape_spaces { + #my $self = shift; + return 1; +} + +sub get_dll_exe_template_input_file { + return 'cmakeexe'; +} + +sub get_dll_template_input_file { + return 'cmakedll'; +} + +sub fill_value { + my($self, $name) = @_; + + if ($name eq 'language') { + ## Currently, we only support C++ + return 'CXX' if ($self->get_language() eq Creator::cplusplus()); + } + elsif ($name =~ /^env_(\w+)/) { + my $dotdir = '${CMAKE_CURRENT_SOURCE_DIR}' . + ($1 eq 'libpaths' ? ' ${CMAKE_CURRENT_BINARY_DIR}' : ''); + my $paths = $self->get_assignment($1); + if (defined $paths) { + $paths = $self->create_array($paths); + foreach my $path (@$paths) { + if ($path eq '.') { + $path = $dotdir; + } + else { + $path =~ s/\$\(([^\)]+)\)/\${$1}/g; + } + } + return "@$paths"; + } + } + + return undef; +} + +1; diff --git a/modules/CMakeWorkspaceCreator.pm b/modules/CMakeWorkspaceCreator.pm new file mode 100644 index 00000000..f5d9e63a --- /dev/null +++ b/modules/CMakeWorkspaceCreator.pm @@ -0,0 +1,195 @@ +package CMakeWorkspaceCreator; + +# ************************************************************ +# Description : A CMake Workspace creator +# Author : Chad Elliott +# Create Date : 10/10/2022 +# ************************************************************ + +# ************************************************************ +# Pragmas +# ************************************************************ + +use strict; +use File::Basename; + +use CMakeProjectCreator; +use WorkspaceCreator; + +use vars qw(@ISA); +@ISA = qw(WorkspaceCreator); + +# ************************************************************ +# Data Section +# ************************************************************ + +my $version = '3.12.0'; + +# ************************************************************ +# Subroutine Section +# ************************************************************ + +sub workspace_per_project { + #my $self = shift; + return 1; +} + +sub workspace_file_name { + return 'CMakeLists.txt'; +} + +sub pre_workspace { + my($self, $fh) = @_; + my $crlf = $self->crlf(); + + $self->print_workspace_comment($fh, + '# CMake Workspace', $crlf, + '#', $crlf, + '# This file was generated by MPC.', $crlf, + '#', $crlf, + '# MPC Command:', $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 +## a directory, the path will be returned unmodified. +sub get_top_directory { + my($self, $path) = @_; + + ## First, convert the path to a relative path based on the current working + ## directory. + my $dir = $self->path_to_relative($self->getcwd(), $path); + 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. + return $self->mpc_dirname($dir); + } + else { + my $done = 0; + do { + ## Go up one directory. If we were already at the top directory, + ## we're finished. + my $next = $self->mpc_dirname($dir); + if ($next eq '.') { + $done = 1; + } + else { + $dir = $next; + } + } while(!$done); + } + + 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_include_ws { + my($self, $prjs) = @_; + my $fh = new FileHandle(); + my $dir = $self->mpc_dirname($$prjs[0]); + 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)); + foreach my $prj (@$prjs) { + print $fh "${crlf}include(", basename($prj), ")"; + } + print $fh $crlf; + close($fh); + } +} + +sub write_comps { + my($self, $fh, $creator) = @_; + my $status = 1; + my $errorString = ''; + my @project_dirs; + my @projects = $self->sort_dependencies($self->get_projects(), 0); + + ## Build a list of top level directories. We only want to go down one + ## directory. The workspace in that directory will handle going to + ## other subdirectories. + my %dirs; + my %out_of_tree; + foreach my $entry (@projects) { + my $dir = $self->get_top_directory($entry); + if ($dir ne $entry) { + if (!exists $dirs{$dir}) { + ## Keep track of the project existing in this directory + $dirs{$dir} = 1; + + push(@project_dirs, $dir); + } + + ## 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 keep track of it here. + if ($self->out_of_tree($dir)) { + if (exists $out_of_tree{$dir}) { + push(@{$out_of_tree{$dir}}, $entry); + } + else { + $out_of_tree{$dir} = [$entry]; + } + } + } + } + + ## Create the basis of a project so that we can add our add_subdirectory() + ## calls below it. + my $crlf = $self->crlf(); + my $ws = TemplateParser::actual_normalize(undef, $self->get_workspace_name()); + $self->write_ws_top($fh, $ws); + + my $first = 1; + my %bin_used; + foreach my $dir (@project_dirs) { + if ($first) { + $first = undef; + print $fh $crlf; + } + my $bin_dir = ''; + if (exists $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; + $self->write_include_ws($out_of_tree{$dir}); + } + print $fh "add_subdirectory($dir$bin_dir)$crlf"; + } + + $first = 1; + foreach my $entry (@projects) { + my $dir = $self->mpc_dirname($entry); + if ($dir eq '.') { + if ($first) { + $first = undef; + print $fh $crlf; + } + print $fh "include($entry)$crlf"; + } + } + + return $status, $errorString; +} + +1; diff --git a/modules/Creator.pm b/modules/Creator.pm index 1d70dabe..00c64eac 100644 --- a/modules/Creator.pm +++ b/modules/Creator.pm @@ -1327,7 +1327,7 @@ sub get_initial_relative_values { sub get_secondary_relative_values { my $self = shift; - return ($self->{'use_env'} ? \%ENV : + return ($self->get_use_env() ? \%ENV : $self->{'relative'}), $self->{'expand_vars'}; } diff --git a/modules/DirectoryManager.pm b/modules/DirectoryManager.pm index 6dfdd92d..bdc23151 100644 --- a/modules/DirectoryManager.pm +++ b/modules/DirectoryManager.pm @@ -199,6 +199,30 @@ sub path_is_relative { return (index($_[1], '/') != 0 && $_[1] !~ /^[A-Z]:[\/\\]/i && $_[1] !~ /^\$\(\w+\)/); } +sub path_to_relative { + my($self, $check, $path) = @_; + + ## See if it's already relative. If it is, there's nothing to do. + if ($path !~ s/^.[\/]+// && !$self->path_is_relative($path)) { + ## See how many times we have to chop off a directory until we find that + ## the provided path contains part of the current working directory. + my $dircount = 0; + while($check ne '.' && index($path, $check) != 0) { + $dircount++; + $check = $self->mpc_dirname($check); + } + + ## If we didn't go all the way back up the current working directory, we + ## can create a relative path from it based on the number of directories + ## we removed above. + if ($check ne '.') { + $path = ('../' x $dircount) . substr($path, length($check) + 1); + } + } + + return $path; +} + # ************************************************************ # Virtual Methods To Be Overridden # ************************************************************ diff --git a/modules/ProjectCreator.pm b/modules/ProjectCreator.pm index 5ebbbd0e..5776ea72 100644 --- a/modules/ProjectCreator.pm +++ b/modules/ProjectCreator.pm @@ -835,6 +835,9 @@ sub parse_line { ## Project Ending if (!defined $self->{'reading_parent'}->[0] && !$self->{'reading_global'}) { + ## Call into the project type's pre-generation hook. + $self->pre_generation(); + ## Fill in all the default values $self->generate_defaults(); @@ -2862,7 +2865,7 @@ sub generate_default_target_names { if (!defined $sources[0]) { @sources = $self->get_component_list($self->get_resource_tag(), 1); } - if (defined $sources[0]) { + if (defined $sources[0] || $self->default_to_library()) { if (!$shared_empty) { $self->process_assignment('sharedname', $self->{'unmodified_project_name'}); @@ -3347,7 +3350,7 @@ sub remove_duplicated_files { sub generated_source_listed { - my($self, $gent, $tag, $arr, $sext) = @_; + my($self, $gent, $tag, $arr) = @_; my $names = $self->{$tag}; ## Find out which generated source files are listed @@ -3417,9 +3420,7 @@ sub list_default_generated { UNIVERSAL::isa($self->{'special_supplied'}->{$type}, 'ARRAY'))) && (!defined $self->{'generated_exts'}->{$type} || $self->{'generated_exts'}->{$type}->{'automatic_in'})) { - if (!$self->generated_source_listed( - $gentype, $type, \%arr, - $self->{'valid_components'}->{$gentype})) { + if (!$self->generated_source_listed($gentype, $type, \%arr)) { $self->add_generated_files($gentype, $type, $group, \%arr); } } @@ -4679,9 +4680,9 @@ sub get_custom_value { ## have extraneous data associated with commands from previous iterations. $self->{'custom_multi_details'} = {}; - my %details = ('flags' => 'commandflags', + my %details = ('flags' => 'commandflags', 'outopt' => 'output_option', - 'gdir' => 'gendir'); + 'gdir' => 'gendir'); for my $tag (@{$self->{'custom_multi_cmd'}->{$based}}) { my $command = $self->get_custom_assign_or_override('command', $tag, $based, @params); @@ -6127,4 +6128,12 @@ sub pre_write_output_file { return 1; } +sub pre_generation { + #my $self = shift; +} + +sub default_to_library { + return 0; +} + 1; diff --git a/modules/StringProcessor.pm b/modules/StringProcessor.pm index f6da1934..3d71e951 100644 --- a/modules/StringProcessor.pm +++ b/modules/StringProcessor.pm @@ -52,12 +52,16 @@ sub process_special { my $escaped = ($line =~ s/\\\\/\01/g); $escaped |= ($line =~ s/\\"/\02/g); - ## Un-escape all other characters - $line =~ s/\\(.)/$1/g; - ## Remove any non-escaped double quotes $line =~ s/"//g; + ## Un-escape all other characters. Using eval allows the user to pass + ## escaped characters that will be converted to their actual character + ## couterpart (i.e., \n, \f, etc). + if (index($line, '\\') != -1) { + eval("\$line = \"$line\""); + } + ## Put the escaped double quotes and backslashes back in if ($escaped) { $line =~ s/\02/"/g; @@ -82,6 +86,7 @@ sub create_array { $escaped |= ($line =~ s/\\\t/\04/g); $escaped |= ($line =~ s/\\\"/\05/g); $escaped |= ($line =~ s/\\\\/\06/g); + $escaped |= ($line =~ s/\n/\07/g); foreach my $part (grep(!/^\s*$/, split(/(\"[^\"]+\"|\'[^\']+\'|\s+)/, $line))) { @@ -98,6 +103,7 @@ sub create_array { $part =~ s/\04/\t/g; $part =~ s/\05/\"/g; $part =~ s/\06/\\/g; + $part =~ s/\07/\n/g; } ## Push it onto the array diff --git a/modules/TemplateParser.pm b/modules/TemplateParser.pm index f8fddaef..d2dd92e6 100644 --- a/modules/TemplateParser.pm +++ b/modules/TemplateParser.pm @@ -69,6 +69,7 @@ my %keywords = ('if' => 0, 'reverse' => $get_type|$perform_type, 'sort' => $get_type|$perform_type, 'uniq' => $get_type|$perform_type, + 'cmake_macro' => $get_type|$perform_type|$doif_type, 'multiple' => $get_type|$doif_type|$get_combined_type, 'starts_with' => $get_type|$doif_type|$get_combined_type, 'ends_with' => $get_type|$doif_type|$get_combined_type, @@ -1721,6 +1722,43 @@ sub handle_basename { } +sub actual_cmake_macro { + my($self, $value) = @_; + return $1 if ($value =~ /^\$\{(\w+)\}$/); + return ''; +} + + +sub perform_cmake_macro { + my($self, $value) = @_; + my @val; + foreach my $val (@$value) { + push(@val, $self->actual_cmake_macro($val)); + } + return @val; +} + + +sub get_cmake_macro { + my($self, $name) = @_; + return $self->actual_cmake_macro($self->get_value_with_default($name)); +} + + +sub doif_cmake_macro { + my($self, $value) = @_; + return (defined $value && $value ne ''); +} + + +sub handle_cmake_macro { + my($self, $name) = @_; + + $self->append_current( + $self->actual_cmake_macro($self->get_value_with_default($name))); +} + + sub handle_basenoextension { my($self, $name) = @_; my $val = $self->tp_basename($self->get_value_with_default($name)); 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); diff --git a/templates/cmake.mpd b/templates/cmake.mpd new file mode 100644 index 00000000..9e39dc43 --- /dev/null +++ b/templates/cmake.mpd @@ -0,0 +1,187 @@ +cmake_minimum_required(VERSION <%cmake_minimum_required(3.12.0)%>) + +<%marker(top)%> +project(<%project_name%> <%language%>) +option(BUILD_SHARED_LIBS "Build using shared libraries" <%if(need_staticflags)%>OFF<%else%>ON<%endif%>) + +<%if(pre_find_package)%> +<%pre_find_package%> +<%endif%> +<%foreach(packages)%> +find_package(<%package%> REQUIRED) +<%endfor%> + +<%if(header_files)%> +set(HEADER_FILES_<%uc(normalize(project_name))%> <%header_files%>) + +<%endif%> +<%if(inline_files)%> +set(INLINE_FILES_<%uc(normalize(project_name))%> <%inline_files%>) + +<%endif%> +<%if(template_files)%> +set(TEMPLATE_FILES_<%uc(normalize(project_name))%> <%template_files%>) + +<%endif%> +set(SOURCE_FILES_<%uc(normalize(project_name))%> <%source_files%>) +<%if(libs || lit_libs || pure_libs)%> +<%foreach(libs)%> +<%if(cmake_macro(lib))%> +if(<%cmake_macro(lib)%>) + set(<%cmake_macro(lib)%>_DEFINED TRUE) +endif() +<%endif%> +<%endfor%> +if(CMAKE_CONFIGURATION_TYPES) +set(TARGET_LINK_LIBRARIES_<%uc(normalize(project_name))%><%if(libs)%> <%foreach(configurations)%><%fornotfirst(" ")%>$<$<CONFIG:<%configuration%>>:<%foreach(libs)%><%fornotfirst(" ")%><%if(cmake_macro(lib))%>$<IF:$<BOOL:${<%cmake_macro(lib)%>_DEFINED}>,<%lib%>${LIBRARY_DECORATOR}<%lib_modifier%>,><%else%><%lib%>${LIBRARY_DECORATOR}<%lib_modifier%><%endif%><%endfor%>><%fornotlast("\n")%><%endfor%><%endif%><%if(lit_libs)%> <%lit_libs%><%endif%><%if(pure_libs)%> <%pure_libs%><%endif%>) +else() +set(TARGET_LINK_LIBRARIES_<%uc(normalize(project_name))%><%if(libs)%><%foreach(libs)%> <%if(cmake_macro(lib))%>$<IF:$<BOOL:${<%cmake_macro(lib)%>_DEFINED}>,<%lib%>${LIBRARY_DECORATOR},><%else%><%lib%>${LIBRARY_DECORATOR}<%endif%><%endfor%><%endif%><%if(lit_libs)%> <%lit_libs%><%endif%><%if(pure_libs)%> <%pure_libs%><%endif%>) +endif() +<%endif%> +set(PROJECT_TARGET_<%uc(normalize(project_name))%> <%if(exename)%><%exename%><%else%><%if(sharedname)%><%sharedname%>${LIBRARY_DECORATOR}<%else%><%if(staticname)%><%staticname%>${LIBRARY_DECORATOR}<%else%><%project_name%>${LIBRARY_DECORATOR}<%endif%><%endif%><%endif%>) +<%marker(macros)%> + +<%if(exeout)%> +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY <%env_exeout%>) +<%if(use_lib_modifier)%> +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG <%env_exeout%>) +<%endif%> +<%endif%> +<%if(!exename)%> +<%if(libout)%> +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY <%env_libout%>) +<%if(use_lib_modifier)%> +<%foreach(configurations)%> +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_<%uc(configuration)%> <%env_libout%>) +<%endfor%> +<%endif%> +<%endif%> +<%if(dllout)%> +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY <%env_dllout%>) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY <%env_dllout%>) +<%if(use_lib_modifier)%> +<%foreach(configurations)%> +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_<%uc(configuration)%> <%env_dllout%>) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_<%uc(configuration)%> <%env_dllout%>) +<%endfor%> +<%endif%> +<%else%> +<%if(libout)%> +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY <%env_libout%>) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY <%env_libout%>) +<%if(use_lib_modifier)%> +<%foreach(configurations)%> +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_<%uc(configuration)%> <%env_libout%>) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_<%uc(configuration)%> <%env_libout%>) +<%endfor%> +<%endif%> +<%endif%> +<%endif%> +<%endif%> + +<%if(compile_flags)%> +target_compile_options(${PROJECT_TARGET_<%uc(normalize(project_name))%>} PUBLIC <%compile_flags%>) + +<%endif%> +<%if(exename)%> +add_executable(${PROJECT_TARGET_<%uc(normalize(project_name))%>} ${SOURCE_FILES_<%uc(normalize(project_name))%>}) +target_link_libraries(${PROJECT_TARGET_<%uc(normalize(project_name))%>} ${TARGET_LINK_LIBRARIES_<%uc(normalize(project_name))%>}) +<%if(staticflags)%> +if(NOT BUILD_SHARED_LIBS) + target_compile_definitions(${PROJECT_TARGET_<%uc(normalize(project_name))%>} PRIVATE <%staticflags%>) + set_property(TARGET ${PROJECT_TARGET_<%uc(normalize(project_name))%>} PROPERTY + MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") +endif() +<%endif%> +<%else%> +<%if(sharedname)%> +add_library(${PROJECT_TARGET_<%uc(normalize(project_name))%>} ${SOURCE_FILES_<%uc(normalize(project_name))%>}) +<%if(dynamicflags)%> +if(BUILD_SHARED_LIBS) + target_compile_definitions(${PROJECT_TARGET_<%uc(normalize(project_name))%>} PRIVATE <%dynamicflags%>) +<%if(staticflags)%> +else() + target_compile_definitions(${PROJECT_TARGET_<%uc(normalize(project_name))%>} PRIVATE <%staticflags%>) +<%endif%> +endif() +<%else%> +<%if(staticflags)%> +if(NOT BUILD_SHARED_LIBS) + target_compile_definitions(${PROJECT_TARGET_<%uc(normalize(project_name))%>} PRIVATE <%staticflags%>) +endif() +<%endif%> +<%endif%> +target_link_libraries(${PROJECT_TARGET_<%uc(normalize(project_name))%>} ${TARGET_LINK_LIBRARIES_<%uc(normalize(project_name))%>}) +<%else%> +<%if(staticname)%> +add_library(${PROJECT_TARGET_<%uc(normalize(project_name))%>} ${SOURCE_FILES_<%uc(normalize(project_name))%>}) +<%if(staticflags)%> +target_compile_definitions(${PROJECT_TARGET_<%uc(normalize(project_name))%>} PRIVATE <%staticflags%>) +<%endif%> +<%endif%> +<%endif%> +<%if(use_lib_modifier)%> +<%foreach(configurations)%> +<%if(lib_modifier)%> +set_target_properties(${PROJECT_TARGET_<%uc(normalize(project_name))%>} PROPERTIES <%uc(configuration)%>_POSTFIX "<%lib_modifier%>") +<%endif%> +<%endfor%> +<%endif%> +<%endif%> + +if(CMAKE_CONFIGURATION_TYPES) +target_compile_definitions(${PROJECT_TARGET_<%uc(normalize(project_name))%>} PUBLIC +<%foreach(configurations)%> $<$<CONFIG:<%configuration%>>:MPC_LIB_MODIFIER="${LIBRARY_DECORATOR}<%lib_modifier%>"><%fornotlast("\n")%><%endfor%>) +endif() + +<%if(includes)%> +target_include_directories(${PROJECT_TARGET_<%uc(normalize(project_name))%>} PRIVATE <%env_includes%>) + +<%endif%> +<%if(libpaths)%> +target_link_directories(${PROJECT_TARGET_<%uc(normalize(project_name))%>} PRIVATE <%env_libpaths%>) + +<%endif%> +<%if(pch_header)%> +target_precompile_headers(${PROJECT_TARGET_<%uc(normalize(project_name))%>} PRIVATE <%pch_header%>) + +<%endif%> +<%if(pch_source)%> +target_compile_definitions(${PROJECT_TARGET_<%uc(normalize(project_name))%>} PUBLIC <%pch_defines%>) +<%endif%> +<%if(macros)%> +target_compile_definitions(${PROJECT_TARGET_<%uc(normalize(project_name))%>} PUBLIC <%macros%>) + +<%endif%> +<%if(custom_types)%> +<%foreach(custom_types)%> +<%if(custom_type->input_files)%> +<%if(custom_type->command)%> + +include(<%custom_type%> OPTIONAL) +<%foreach(custom_type->input_files)%> +<%uc(custom_type)%>_TARGET_SOURCES( + ${PROJECT_TARGET_<%uc(normalize(project_name))%>} PUBLIC <%custom_type->input_file%> + <%uc(custom_type)%>_OPTIONS <%if(flag_overrides(custom_type->input_file, commandflags))%><%flag_overrides(custom_type->input_file, commandflags)%><%else%><%custom_type->commandflags%><%endif%><%if(custom_type->output_option)%> <%custom_type->output_option%> <%if(flag_overrides(custom_type->input_file, gendir))%><%flag_overrides(custom_type->input_file, gendir)%>/<%basename(custom_type->input_file->output_file)%><%else%><%custom_type->input_file->output_file%><%endif%><%endif%>) + +<%endfor%> +<%else%> +<%foreach(custom_type->input_files)%> +<%if(custom_type->input_file->commands)%> +<%if(forfirst)%> +include(<%custom_type%> OPTIONAL) +<%endif%> +<%uc(custom_type)%>_TARGET_SOURCES( + ${PROJECT_TARGET_<%uc(normalize(project_name))%>} PUBLIC <%custom_type->input_file%> +<%foreach(custom_type->input_file->commands)%> + <%uc(custom_type->input_file->command->type)%>_OPTIONS <%custom_type->input_file->command->flags%><%fornotlast("\n")%><%endfor%>) + +<%endif%> +<%endfor%> +<%endif%> +<%endif%> +<%endfor%> +<%endif%> + +<%marker(local)%> +<%marker(bottom)%> diff --git a/templates/cmakedll.mpt b/templates/cmakedll.mpt new file mode 100644 index 00000000..4b83cf64 --- /dev/null +++ b/templates/cmakedll.mpt @@ -0,0 +1,18 @@ +// -*- MPC -*- + +conditional_include "common" + +configurations = Debug Release + +// *********************************************************************** +// Configuration Section +// *********************************************************************** + +Debug { + lib_modifier = d +} + +Release { +} + +conditional_include "user_cmakedll" diff --git a/templates/cmakeexe.mpt b/templates/cmakeexe.mpt new file mode 100644 index 00000000..55c1608f --- /dev/null +++ b/templates/cmakeexe.mpt @@ -0,0 +1,3 @@ +// -*- MPC -*- +conditional_include "cmakedll" +conditional_include "user_cmakeexe" |