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