1#!/usr/bin/env perl 2 3# Generate main file, individual apps and solution files for MS Visual Studio 4# 2010 5# 6# Must be run from mbedTLS root or scripts directory. 7# Takes no argument. 8# 9# Copyright The Mbed TLS Contributors 10# SPDX-License-Identifier: Apache-2.0 11# 12# Licensed under the Apache License, Version 2.0 (the "License"); you may 13# not use this file except in compliance with the License. 14# You may obtain a copy of the License at 15# 16# http://www.apache.org/licenses/LICENSE-2.0 17# 18# Unless required by applicable law or agreed to in writing, software 19# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 20# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21# See the License for the specific language governing permissions and 22# limitations under the License. 23 24use warnings; 25use strict; 26use Digest::MD5 'md5_hex'; 27 28my $vsx_dir = "visualc/VS2010"; 29my $vsx_ext = "vcxproj"; 30my $vsx_app_tpl_file = "scripts/data_files/vs2010-app-template.$vsx_ext"; 31my $vsx_main_tpl_file = "scripts/data_files/vs2010-main-template.$vsx_ext"; 32my $vsx_main_file = "$vsx_dir/mbedTLS.$vsx_ext"; 33my $vsx_sln_tpl_file = "scripts/data_files/vs2010-sln-template.sln"; 34my $vsx_sln_file = "$vsx_dir/mbedTLS.sln"; 35 36my $programs_dir = 'programs'; 37my $mbedtls_header_dir = 'include/mbedtls'; 38my $psa_header_dir = 'include/psa'; 39my $source_dir = 'library'; 40my $test_source_dir = 'tests/src'; 41my $test_header_dir = 'tests/include/test'; 42my $test_drivers_header_dir = 'tests/include/test/drivers'; 43 44my @thirdparty_header_dirs = qw( 45 3rdparty/everest/include/everest 46); 47my @thirdparty_source_dirs = qw( 48 3rdparty/everest/library 49 3rdparty/everest/library/kremlib 50 3rdparty/everest/library/legacy 51); 52 53# Directories to add to the include path. 54# Order matters in case there are files with the same name in more than 55# one directory: the compiler will use the first match. 56my @include_directories = qw( 57 include 58 3rdparty/everest/include/ 59 3rdparty/everest/include/everest 60 3rdparty/everest/include/everest/vs2010 61 3rdparty/everest/include/everest/kremlib 62 tests/include 63); 64my $include_directories = join(';', map {"../../$_"} @include_directories); 65 66# Directories to add to the include path when building the library, but not 67# when building tests or applications. 68my @library_include_directories = qw( 69 library 70); 71my $library_include_directories = 72 join(';', map {"../../$_"} (@library_include_directories, 73 @include_directories)); 74 75my @excluded_files = qw( 76 3rdparty/everest/library/Hacl_Curve25519.c 77); 78my %excluded_files = (); 79foreach (@excluded_files) { $excluded_files{$_} = 1 } 80 81# Need windows line endings! 82my $vsx_hdr_tpl = <<EOT; 83 <ClInclude Include="..\\..\\{NAME}" />\r 84EOT 85my $vsx_src_tpl = <<EOT; 86 <ClCompile Include="..\\..\\{NAME}" />\r 87EOT 88 89my $vsx_sln_app_entry_tpl = <<EOT; 90Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "{APPNAME}", "{APPNAME}.vcxproj", "{GUID}"\r 91 ProjectSection(ProjectDependencies) = postProject\r 92 {46CF2D25-6A36-4189-B59C-E4815388E554} = {46CF2D25-6A36-4189-B59C-E4815388E554}\r 93 EndProjectSection\r 94EndProject\r 95EOT 96 97my $vsx_sln_conf_entry_tpl = <<EOT; 98 {GUID}.Debug|Win32.ActiveCfg = Debug|Win32\r 99 {GUID}.Debug|Win32.Build.0 = Debug|Win32\r 100 {GUID}.Debug|x64.ActiveCfg = Debug|x64\r 101 {GUID}.Debug|x64.Build.0 = Debug|x64\r 102 {GUID}.Release|Win32.ActiveCfg = Release|Win32\r 103 {GUID}.Release|Win32.Build.0 = Release|Win32\r 104 {GUID}.Release|x64.ActiveCfg = Release|x64\r 105 {GUID}.Release|x64.Build.0 = Release|x64\r 106EOT 107 108exit( main() ); 109 110sub check_dirs { 111 foreach my $d (@thirdparty_header_dirs, @thirdparty_source_dirs) { 112 if (not (-d $d)) { return 0; } 113 } 114 return -d $vsx_dir 115 && -d $mbedtls_header_dir 116 && -d $psa_header_dir 117 && -d $source_dir 118 && -d $test_source_dir 119 && -d $test_header_dir 120 && -d $test_drivers_header_dir 121 && -d $programs_dir; 122} 123 124sub slurp_file { 125 my ($filename) = @_; 126 127 local $/ = undef; 128 open my $fh, '<', $filename or die "Could not read $filename\n"; 129 my $content = <$fh>; 130 close $fh; 131 132 return $content; 133} 134 135sub content_to_file { 136 my ($content, $filename) = @_; 137 138 open my $fh, '>', $filename or die "Could not write to $filename\n"; 139 print $fh $content; 140 close $fh; 141} 142 143sub gen_app_guid { 144 my ($path) = @_; 145 146 my $guid = md5_hex( "mbedTLS:$path" ); 147 $guid =~ s/(.{8})(.{4})(.{4})(.{4})(.{12})/\U{$1-$2-$3-$4-$5}/; 148 149 return $guid; 150} 151 152sub gen_app { 153 my ($path, $template, $dir, $ext) = @_; 154 155 my $guid = gen_app_guid( $path ); 156 $path =~ s!/!\\!g; 157 (my $appname = $path) =~ s/.*\\//; 158 159 my $srcs = "<ClCompile Include=\"..\\..\\programs\\$path.c\" \/>"; 160 if( $appname eq "ssl_client2" or $appname eq "ssl_server2" or 161 $appname eq "query_compile_time_config" ) { 162 $srcs .= "\r\n <ClCompile Include=\"..\\..\\programs\\test\\query_config.c\" \/>"; 163 } 164 165 my $content = $template; 166 $content =~ s/<SOURCES>/$srcs/g; 167 $content =~ s/<APPNAME>/$appname/g; 168 $content =~ s/<GUID>/$guid/g; 169 $content =~ s/INCLUDE_DIRECTORIES\r\n/$include_directories/g; 170 171 content_to_file( $content, "$dir/$appname.$ext" ); 172} 173 174sub get_app_list { 175 my $app_list = `cd $programs_dir && make list`; 176 die "make list failed: $!\n" if $?; 177 178 return split /\s+/, $app_list; 179} 180 181sub gen_app_files { 182 my @app_list = @_; 183 184 my $vsx_tpl = slurp_file( $vsx_app_tpl_file ); 185 186 for my $app ( @app_list ) { 187 gen_app( $app, $vsx_tpl, $vsx_dir, $vsx_ext ); 188 } 189} 190 191sub gen_entry_list { 192 my ($tpl, @names) = @_; 193 194 my $entries; 195 for my $name (@names) { 196 (my $entry = $tpl) =~ s/{NAME}/$name/g; 197 $entries .= $entry; 198 } 199 200 return $entries; 201} 202 203sub gen_main_file { 204 my ($headers, $sources, 205 $hdr_tpl, $src_tpl, 206 $main_tpl, $main_out) = @_; 207 208 my $header_entries = gen_entry_list( $hdr_tpl, @$headers ); 209 my $source_entries = gen_entry_list( $src_tpl, @$sources ); 210 211 my $out = slurp_file( $main_tpl ); 212 $out =~ s/SOURCE_ENTRIES\r\n/$source_entries/m; 213 $out =~ s/HEADER_ENTRIES\r\n/$header_entries/m; 214 $out =~ s/INCLUDE_DIRECTORIES\r\n/$library_include_directories/g; 215 216 content_to_file( $out, $main_out ); 217} 218 219sub gen_vsx_solution { 220 my (@app_names) = @_; 221 222 my ($app_entries, $conf_entries); 223 for my $path (@app_names) { 224 my $guid = gen_app_guid( $path ); 225 (my $appname = $path) =~ s!.*/!!; 226 227 my $app_entry = $vsx_sln_app_entry_tpl; 228 $app_entry =~ s/{APPNAME}/$appname/g; 229 $app_entry =~ s/{GUID}/$guid/g; 230 231 $app_entries .= $app_entry; 232 233 my $conf_entry = $vsx_sln_conf_entry_tpl; 234 $conf_entry =~ s/{GUID}/$guid/g; 235 236 $conf_entries .= $conf_entry; 237 } 238 239 my $out = slurp_file( $vsx_sln_tpl_file ); 240 $out =~ s/APP_ENTRIES\r\n/$app_entries/m; 241 $out =~ s/CONF_ENTRIES\r\n/$conf_entries/m; 242 243 content_to_file( $out, $vsx_sln_file ); 244} 245 246sub del_vsx_files { 247 unlink glob "'$vsx_dir/*.$vsx_ext'"; 248 unlink $vsx_main_file; 249 unlink $vsx_sln_file; 250} 251 252sub main { 253 if( ! check_dirs() ) { 254 chdir '..' or die; 255 check_dirs or die "Must but run from mbedTLS root or scripts dir\n"; 256 } 257 258 # Remove old files to ensure that, for example, project files from deleted 259 # apps are not kept 260 del_vsx_files(); 261 262 my @app_list = get_app_list(); 263 my @header_dirs = ( 264 $mbedtls_header_dir, 265 $psa_header_dir, 266 $test_header_dir, 267 $test_drivers_header_dir, 268 $source_dir, 269 @thirdparty_header_dirs, 270 ); 271 my @headers = (map { <$_/*.h> } @header_dirs); 272 my @source_dirs = ( 273 $source_dir, 274 $test_source_dir, 275 @thirdparty_source_dirs, 276 ); 277 my @sources = (map { <$_/*.c> } @source_dirs); 278 279 @headers = grep { ! $excluded_files{$_} } @headers; 280 @sources = grep { ! $excluded_files{$_} } @sources; 281 map { s!/!\\!g } @headers; 282 map { s!/!\\!g } @sources; 283 284 gen_app_files( @app_list ); 285 286 gen_main_file( \@headers, \@sources, 287 $vsx_hdr_tpl, $vsx_src_tpl, 288 $vsx_main_tpl_file, $vsx_main_file ); 289 290 gen_vsx_solution( @app_list ); 291 292 return 0; 293} 294