#!/usr/bin/env perl
# Generate main file, individual apps and solution files for
# MS Visual Studio 2017
#
# Must be run from Mbed TLS root or scripts directory.
# Takes no argument.
#
# Copyright The Mbed TLS Contributors
# SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
use warnings;
use strict;
use Digest::MD5 'md5_hex';
my $vsx_dir = "visualc/VS2017";
my $vsx_ext = "vcxproj";
my $vsx_app_tpl_file = "scripts/data_files/vs2017-app-template.$vsx_ext";
my $vsx_main_tpl_file = "scripts/data_files/vs2017-main-template.$vsx_ext";
my $vsx_main_file = "$vsx_dir/mbedTLS.$vsx_ext";
my $vsx_sln_tpl_file = "scripts/data_files/vs2017-sln-template.sln";
my $vsx_sln_file = "$vsx_dir/mbedTLS.sln";
my $mbedtls_programs_dir = "programs";
my $tfpsacrypto_programs_dir = "tf-psa-crypto/programs";
my $mbedtls_header_dir = 'include/mbedtls';
my $drivers_builtin_header_dir = 'tf-psa-crypto/drivers/builtin/include/mbedtls';
my $psa_header_dir = 'tf-psa-crypto/include/psa';
my $tls_source_dir = 'library';
my $crypto_core_source_dir = 'tf-psa-crypto/core';
my $crypto_source_dir = 'tf-psa-crypto/drivers/builtin/src';
my $tls_test_source_dir = 'tests/src';
my $tls_test_header_dir = 'tests/include/test';
my $test_source_dir = 'framework/tests/src';
my $test_header_dir = 'framework/tests/include/test';
my $test_drivers_header_dir = 'framework/tests/include/test/drivers';
my $test_drivers_source_dir = 'framework/tests/src/drivers';
my @thirdparty_header_dirs = qw(
tf-psa-crypto/drivers/everest/include/everest
);
my @thirdparty_source_dirs = qw(
tf-psa-crypto/drivers/everest/library
tf-psa-crypto/drivers/everest/library/kremlib
tf-psa-crypto/drivers/everest/library/legacy
);
# Directories to add to the include path.
# Order matters in case there are files with the same name in more than
# one directory: the compiler will use the first match.
my @include_directories = qw(
include
tf-psa-crypto/include
tf-psa-crypto/drivers/builtin/include
tf-psa-crypto/drivers/everest/include/
tf-psa-crypto/drivers/everest/include/everest
tf-psa-crypto/drivers/everest/include/everest/vs2013
tf-psa-crypto/drivers/everest/include/everest/kremlib
tests/include
framework/tests/include
);
my $include_directories = join(';', map {"../../$_"} @include_directories);
# Directories to add to the include path when building the libraries, but not
# when building tests or applications.
my @library_include_directories = qw(
library
tf-psa-crypto/core
tf-psa-crypto/drivers/builtin/src
);
my $library_include_directories =
join(';', map {"../../$_"} (@library_include_directories,
@include_directories));
my @excluded_files = qw(
tf-psa-crypto/drivers/everest/library/Hacl_Curve25519.c
);
my %excluded_files = ();
foreach (@excluded_files) { $excluded_files{$_} = 1 }
my $vsx_hdr_tpl = <
EOT
my $vsx_src_tpl = <
EOT
my $vsx_sln_app_entry_tpl = <;
close $fh;
return $content;
}
sub content_to_file {
my ($content, $filename) = @_;
open my $fh, '>:crlf', $filename or die "Could not write to $filename\n";
print $fh $content;
close $fh;
}
sub gen_app_guid {
my ($path) = @_;
my $guid = md5_hex( "mbedTLS:$path" );
$guid =~ s/(.{8})(.{4})(.{4})(.{4})(.{12})/\U{$1-$2-$3-$4-$5}/;
return $guid;
}
sub gen_app {
my ($path, $template, $dir, $ext) = @_;
my $guid = gen_app_guid( $path );
$path =~ s!/!\\!g;
(my $appname = $path) =~ s/.*\\//;
my $is_test_app = ($path =~ m/^test\\/);
my $srcs = "";
if( $appname eq "ssl_client2" or $appname eq "ssl_server2" or
$appname eq "query_compile_time_config" ) {
$srcs .= "\n ";
}
if( $appname eq "ssl_client2" or $appname eq "ssl_server2" ) {
$srcs .= "\n ";
}
my $content = $template;
$content =~ s//$srcs/g;
$content =~ s//$appname/g;
$content =~ s//$guid/g;
$content =~ s/INCLUDE_DIRECTORIES\n/($is_test_app ?
$library_include_directories :
$include_directories)/ge;
content_to_file( $content, "$dir/$appname.$ext" );
}
sub get_app_list {
my $makefile_contents = slurp_file('programs/Makefile');
$makefile_contents =~ /\n\s*APPS\s*=[\\\s]*(.*?)(? } @header_dirs);
my @source_dirs = (
$tls_source_dir,
$crypto_core_source_dir,
$crypto_source_dir,
$test_source_dir,
$tls_test_source_dir,
$test_drivers_source_dir,
@thirdparty_source_dirs,
);
my @sources = (map { <$_/*.c> } @source_dirs);
@headers = grep { ! $excluded_files{$_} } @headers;
@sources = grep { ! $excluded_files{$_} } @sources;
map { s!/!\\!g } @headers;
map { s!/!\\!g } @sources;
gen_app_files( @app_list );
gen_main_file( \@headers, \@sources,
$vsx_hdr_tpl, $vsx_src_tpl,
$vsx_main_tpl_file, $vsx_main_file );
gen_vsx_solution( @app_list );
return 0;
}