Merge "use std::string_view to avoid shader string duplication." into devel/master
[platform/core/uifw/dali-core.git] / build / scripts / dali_env
1 #!/usr/bin/perl
2
3 # Copyright (c) 2020 Samsung Electronics Co., Ltd.
4
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8
9 # http://www.apache.org/licenses/LICENSE-2.0
10
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 use Config;
18 use Cwd;
19 use Cwd 'abs_path';
20 use File::Basename;
21 use File::Path;
22 use File::Copy;
23 use File::Copy::Recursive qw(dircopy);
24 use strict;
25 use Getopt::Long;
26 use Pod::Usage;
27
28 ################################################################################
29 #                                SYSTEM PACKAGES                               #
30 ################################################################################
31 # Add any required system packages to this list - if they are not present, then
32 # this script will attempt to install them for you.
33 my @system_packages = (
34     "automake",
35     "cmake",
36     "g++",
37     "pkg-config",
38     "libtool",
39     "ccache",
40     "libelementary-dev",
41     "libexif-dev",
42     "libgles2-mesa-dev",
43     "libdrm-dev",
44     "libgif-dev",
45     "libturbojpeg",
46     "libturbojpeg0-dev",
47     "libfribidi-dev",
48     "libharfbuzz-dev",
49     "libhyphen-dev",
50     "doxygen",
51     "lcov",
52     "libcurl4-gnutls-dev",
53     "curl",
54     "libssl-dev",
55     "cifs-utils",
56     "libgtest-dev",
57     "libcairo2-dev",
58     "libopencv-dev",
59     "gettext",
60     "libwebp-dev",
61 );
62
63 # Some packages like require building from source
64 # v8 is currently disabled until we can get it working without a http proxy being setup
65 my @source_pkgs = (
66
67     {"name" => "disabled-v8",
68      "force-rebuild" => 0,
69      "use_depot_tools" => 1,
70      "repo" => "https://chromium.googlesource.com/v8/v8.git",
71      "depot_tools_repo" => "https://chromium.googlesource.com/chromium/tools/depot_tools.git",
72
73      # original version used with DALi is 3.25.19. 3.32.7 is the latest we can use before
74      # upgrading DALi to use  c++0x or c++11
75      "version" => " 3.32.7", "make" => "make -j8 library=shared", "build-mode" =>"debug" },
76     {"name" => "gtest" },
77 );
78
79 ### Detect any http proxy, part of v8 installation requires this information
80 my $http_proxy_port;
81 my $http_proxy_ip;
82
83 if( exists $ENV{http_proxy} )
84 {
85   # string  split into 3 items  http, //ip, port
86   my @http_proxy_info =  split( /:/,$ENV{http_proxy}, );
87
88   $http_proxy_ip =  @http_proxy_info[1];
89   $http_proxy_ip =~ s/[\/]//g;;  # remove forward slashes
90   $http_proxy_port =  @http_proxy_info[2];
91 }
92
93 # Make best guess as to where this program was run from (note, it is
94 # always possible to override the location of $0 by the calling
95 # program, so we can't really tell for sure that this is where we
96 # expect it to be. :/
97
98 my $new_env   = 0;
99 my $exec_path = $0;
100 if($0 !~ m!^/!)
101 {
102     $exec_path = abs_path($0);
103 }
104 $exec_path = dirname($exec_path);
105
106 my $root_path = getcwd();
107
108 # Search for the root dali-env directory
109 if($exec_path =~ m!dali-env/opt/bin!)
110 {
111     # We are using the installed dali_env script
112
113     $root_path = $exec_path;
114     while(basename($root_path) ne "dali-env" && $root_path ne "")
115     {
116         $root_path = dirname($root_path);
117     }
118 }
119 elsif($root_path =~ m!dali-env$! or $root_path =~ m!dali-env/!)
120 {
121     # We are NOT using the installed dali_env script
122     # Find dali-env root from current directory
123
124     while(basename($root_path) ne "dali-env" && $root_path ne "")
125     {
126         $root_path = dirname($root_path);
127     }
128 }
129 else
130 {
131     # dali-env root dir should be in the current directory
132
133     $root_path .= "/dali-env";
134
135     if(! -e $root_path)
136     {
137       # Creating a new dali-env
138
139       $new_env = 1;
140     }
141 }
142
143 my $src_path         = "$root_path/src-packages";
144 my $sbs_path         = "$root_path/target";
145 my $install_path     = "$root_path/opt";
146
147 my $opt_create=0;
148 my $opt_setenv=0;
149 my $opt_help=0;
150 my $opt_man=0;
151
152 GetOptions("create"     => \$opt_create,
153            "setenv"     => \$opt_setenv,
154            "help"       => \$opt_help,
155            "man"        => \$opt_man) or pod2usage(2);
156
157 pod2usage(1) if $opt_help;
158 pod2usage(-exitstatus => 0, -verbose => 2) if $opt_man;
159
160
161 ################################################################################
162
163 sub create_env
164 {
165     mkpath("$install_path/bin");
166     mkpath("$install_path/lib/pkgconfig");
167     mkpath("$install_path/include");
168     mkpath("$install_path/share/aclocal");
169     mkpath("$src_path");
170     mkpath("$sbs_path");
171
172     copy($0, "$install_path/bin/dali_env");
173     chmod(0755, "$install_path/bin/dali_env");
174 }
175
176 ################################################################################
177
178 sub in_dali_env
179 {
180     my $cwd = substr(getcwd(), 0, length($root_path));
181     #print "cwd = $cwd\nroot = $root_path\n";
182     return $cwd eq $root_path;
183 }
184
185 ################################################################################
186
187 sub create_setenv
188 {
189     print <<"EOF";
190 #
191 # To use the desktop libraries, please add the following lines to your .bashrc or
192 # create a setenv script from them, e.g. by running this command as follows
193 # \$ $install_path/bin/dali_env -s > setenv
194 #
195 # You can then source this script by using
196 # \$ . setenv
197 #
198 # Use DESKTOP_PREFIX when running configure or cmake in dali/build/tizen:
199 # \$ CXXFLAGS="-g -O0" ./configure --prefix=\$DESKTOP_PREFIX
200 # _OR_
201 # \$ CXXFLAGS="-g -O0" cmake -DCMAKE_INSTALL_PREFIX=\$DESKTOP_PREFIX
202
203 export DESKTOP_PREFIX=$install_path
204 export PATH=$install_path/bin:\$PATH
205 export LD_LIBRARY_PATH=$install_path/lib:\$LD_LIBRARY_PATH
206 export INCLUDEDIR=$install_path/include
207 export PKG_CONFIG_PATH=$install_path/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
208 export DOTNET_CLI_TELEMETRY_OPTOUT=1
209 export DALI_WINDOW_WIDTH=480
210 export DALI_WINDOW_HEIGHT=800
211
212 EOF
213 }
214
215 ################################################################################
216
217 sub check_system_package
218 {
219     my $package;
220     foreach $package (@_)
221     {
222         my @x=split(/\s+/, `dpkg -l $package 2> /dev/null|grep $package`);
223         if($x[0] ne "ii")
224         {
225             # Check if the package is available to install, exit-code is 0 if the package is found.
226             if(system("apt-cache show $package > /dev/null 2>&1") == 0)
227             {
228                 print "Attempting to install $package\n";
229                 system("sudo apt-get -y --force-yes install $package");
230             }
231         }
232     }
233 }
234
235 sub check_system_packages
236 {
237     print "Checking for required system packages (may require sudo password)\n";
238
239     check_system_package(@system_packages);
240
241     my $gnome_v =`dpkg -l gnome-common| tail -1| sed "s/ \\+/ /g" | cut -d' ' -f 3`;
242     my @am = split(/\./, `automake --version | head -1 | cut -f4 -d' '`);
243     if($gnome_v =~ /$2.24/ && $am[1]>10)
244     {
245         die "Gnome common and automake are not compatible - automake is too new\n";
246     }
247     my @gpp_v = (`g++ --version  | head -1` =~ /(\d+)\.(\d+)\.(\d+)/);
248
249     if(! (($gpp_v[0] > 4)
250           ||
251           ($gpp_v[0] == 4 && $gpp_v[1] > 4)
252           ||
253           ($gpp_v[0] == 4 && $gpp_v[1] == 4 && $gpp_v[2] >= 5)))
254     {
255         die "You need g++ 4.5.1 or greater to build dali\n";
256     }
257 }
258
259 sub check_source_packages
260 {
261     my $pkgref;
262
263     foreach $pkgref (@source_pkgs)
264     {
265         my $pkg = $pkgref->{"name"};
266         if($pkg eq "v8")
267         {
268             install_v8( $pkgref );
269         }
270         elsif ($pkg eq "gtest")
271         {
272             if(! -e "/usr/lib/libgtest.a")
273             {
274                 print "Attempting to build $pkg\n";
275                 # from https://www.eriksmistad.no/getting-started-with-google-test-on-ubuntu/
276                 run_command("cd /usr/src/gtest; sudo cmake CMakeLists.txt; sudo make; sudo cp *.a /usr/lib; cd -;");
277             }
278         }
279     }
280 }
281
282 ################################################################################
283
284 sub create_link
285 {
286     my $arch=`uname -i`;
287     $arch =~ s/\r|\n//g;
288
289     my $link = "/usr/lib/$arch-linux-gnu/libturbojpeg.so";
290
291     unless (-e $link)
292     {
293        print "Creating libjpegturbo symbolic link\n";
294        system("sudo ln -s $link.0 $link");
295     }
296 }
297
298 ################################################################################
299 # Helper to run and print out the command being run and quit if it fails
300 #
301 sub run_command
302 {
303   my $command = $_[0];
304   my $ret;
305   print("Running: $command\n");
306   $ret = system("$command");
307   if($ret >> 8) { die "$command failed \n"; }
308 }
309
310 ################################################################################
311 # later versions of v8 (post mid 2014) require googles depot_tools to build.
312 #
313 sub install_google_depot_tools
314 {
315
316 ####
317 # clone the depo_tools into the source directory and set the path up
318 ####
319     my $v8 = $_[0];
320
321     my $depot_tools_directory = $src_path . "/depot_tools";
322     my $depot_tools_repo = $v8->{"depot_tools_repo"};
323
324     # clear the directory if exists
325     rmtree( $depot_tools_directory );
326
327     # clone the depot tools
328     run_command( "git clone " . $depot_tools_repo. " " . $depot_tools_directory );
329
330     # add it the the path
331     $ENV{PATH} = "$ENV{PATH}:$depot_tools_directory";
332
333     # need to setup a config file for the proxy
334     create_boto_config_file( $v8 , $depot_tools_directory );
335
336     # set the config location as an environment variable ( used by scripts depot_tools)
337     $ENV{NO_AUTH_BOTO_CONFIG}="$src_path/depot_tools/.boto";
338
339     # change to depot tools directory
340     chdir( $depot_tools_directory );
341
342     # fetch v8
343     run_command("fetch --nohooks v8");
344
345 }
346
347
348 ################################################################################
349 # later versions of v8 use boto, which currently requires having proxy manually set
350 #
351 sub create_boto_config_file
352 {
353     my $v8 = $_[0];
354     my $depot_tools_directory = $_[1];
355     print(" depot_tools directory = $depot_tools_directory\n");
356
357     print("Configuring boto with http proxy IP = ". $http_proxy_ip . ", Port = " . $http_proxy_port . "\n");
358
359 # Create the proxy info for the boto file
360 my $fileContents = <<"END";
361 [Boto]
362 debug = 0
363 num_retries = 2
364
365 proxy = $http_proxy_ip
366 proxy_port = $http_proxy_port
367 END
368       # Place the config file in the depot tools folder
369     my $filename = $depot_tools_directory . "/" . ".boto";
370     print("Creating Boto config file with proxy settings to file ". $filename . "\n");
371     my $fh;
372     open( $fh, '>',  $filename );
373     print { $fh } $fileContents;
374     close( $fh );
375
376     # export the environment variable
377     run_command("gclient config https://gclient.googlecode.com/svn/trunk/gclient");
378
379     run_command("gclient runhooks");
380
381
382
383 }
384 ################################################################################
385 # We need a specific version of V8 to work with DALi
386 # - Check a txt file in dali-env to see if v8 needs upgrading (checks gcc version too)
387 # - Clones the source
388 # - builds dependencies (v8 automatically clones it's GYP build system)
389 # - Builds it
390 # - Create a package file
391 # It is cloned, then built from source, we create a package file for it, then
392 # it's copied into dali-env
393 sub install_v8
394 {
395     my $v8 = $_[0];
396     my $ret;
397     my $v8Version = $v8->{"version"};
398     print( "Checking if V8 ". $v8Version. " is installed \n");
399
400 ####
401 # Check currently installed version
402 # We create a text file with v8 and gcc version in the filename to compare with
403 # Version file is stored as "v8_2.3.4_installed_built_with_gcc_4_8_3.txt"
404 ####
405     # get the gcc version, so if the compiler is updated v8 is re-built
406     # note: v8 requires gcc version GCC >= 4.6
407     my $gccVersion = `gcc --version | grep ^gcc | sed 's/^.* //g'`;
408     chomp( $gccVersion );
409     my $versionTextFile = $src_path . "/v8_" . $v8Version. "_" . $v8->{"build-mode"} . "_installed_built_with_gcc_". $gccVersion .".txt";
410
411     # use stat to see if file exists
412     my @install_stats = stat $versionTextFile;
413     if( (scalar(@install_stats)) && $v8->{"force-rebuild"} != 1 )
414     {
415       print("Correct V8 version installed\n");
416       return;
417     }
418     else
419     {
420       # delete older versions of the version file first ( otherwise when downgrading it thinks version is still installed)
421       system( "rm " . $src_path . "/v8_*.txt  >/dev/null 2>&1");
422     }
423
424
425 ####
426 # Clone the v8 source repository and checkout the version we want
427 ####
428     # Need to clone it from repo
429     my $v8_source_directory;
430
431
432
433     # newer version of v8 use depot_tools with gclient, git cloned builds do not work
434     if( $v8->{"use_depot_tools"} == 1)
435     {
436       install_google_depot_tools( $v8 );
437
438       # v8 is checkout out under depot_tools path
439       $v8_source_directory = $src_path . "/depot_tools/v8";
440     }
441     else
442     {
443       $v8_source_directory = $src_path . "/v8";
444
445       # delete the old v8 source directpry if exists
446       rmtree( $v8_source_directory );
447
448       # clone the repository
449       run_command( "git clone " . $v8->{"repo"} . " " . $v8_source_directory );
450     }
451
452     # change to the source directoy for the checkout
453     chdir( $v8_source_directory );
454
455     # checkout the version DALi is compatible with
456     run_command( "git checkout ". $v8Version );
457
458 ####
459 # Run make dependencies then make for the specific target
460 ####
461     if( $v8->{"use_depot_tools"} == 1)
462     {
463       run_command("gclient sync");
464     }
465     else
466     {
467       run_command("make dependencies");
468     }
469
470     # assemble the make command
471     my $makeCommand = $v8->{"make"};
472
473     # need to append architecture and build mode, e.g. x64.debug
474     my $buildTarget;
475     if( $Config{use64bitint} ) {
476        print("Building 64 bit version of V8\n");
477        $buildTarget= "x64." . $v8->{"build-mode"}
478     }
479     else{
480       print("Building 32 bit version of V8\n");
481        $buildTarget= "ia32." . $v8->{"build-mode"}
482     }
483     $makeCommand .= " " . $buildTarget;
484     print("Running: $makeCommand\n");
485     run_command( $makeCommand );
486
487 ####
488 # Manually install the library / header files
489 ####
490
491     # Need to manually install (make install not available on v8 )
492     my $libSourceDir = "$v8_source_directory/out/$buildTarget/lib.target/";
493     my $headerSourceDir = "$v8_source_directory/include/";
494
495     my $libDestinationDir = $install_path . "/lib/";
496     my $headerDestinationDir = $install_path . "/include/v8/";
497
498     # delete any current v8 libs
499     system( "rm " . $libDestinationDir . "libv8*");
500     system( "rm " . $libDestinationDir . "libicu*");
501
502
503     # copy the library and header files
504     dircopy( $libSourceDir, $libDestinationDir);
505     dircopy( $headerSourceDir, $headerDestinationDir);
506
507
508     # Copy libv8.so to libv8.so.version (  e.g. libv8.so.1.2.4)
509     my $v8SoFile = $libDestinationDir . "libv8.so";
510     my $v8SoVersionFile = $libDestinationDir . "libv8.so." . $v8Version;
511     move( $v8SoFile, $v8SoVersionFile );
512
513     # symlink the libv8.so.1.2.3 to libv8.so
514     symlink( $v8SoVersionFile, $v8SoFile );
515     print( "source dir = " . $libSourceDir . " dest dir ". $libDestinationDir . " \n" );
516
517
518 ####
519 # Create the package file in,
520 # we keep the library files and header files in v8 sub-directories
521 ####
522 my $fileContents = <<"END";
523 prefix=$install_path
524 exec_prefix=\${prefix}
525 apiversion=$v8Version
526 libdir=\${exec_prefix}/lib
527 includedir=\${prefix}/include/v8
528
529 Name: v8 JavaScript engine - runtime library
530 Description: V8 is Google's open source JavaScript engine.
531 Version: \${apiversion}
532 Libs: -L\${libdir} -lv8 -licuuc -licui18n
533 Cflags: -I\${includedir}
534 END
535
536   my $filename = $install_path . "/lib/pkgconfig/" . "v8.pc";
537   print("writing to file ". $filename . "\n");
538   my $fh;
539   if( open( $fh, '>',  $filename ) )
540   {
541     print { $fh } $fileContents;
542     close( $fh );
543   }
544   else
545   {
546     die "failed to create " . $filename ."\n";
547   }
548
549   print("Installed V8 " .$v8Version . " OK\n");
550
551 #####
552 #
553 ####
554       my $versionFile;
555       open( $versionFile, '>',  $versionTextFile );
556       close( $versionFile );
557       print("Installing V8 version $v8Version\n");
558
559 }
560
561 ################################################################################
562 #                                       MAIN
563 ################################################################################
564
565
566 if($opt_create)
567 {
568     my $new_root = getcwd() . "/dali-env";
569
570     if($exec_path =~ m!dali-env/opt/bin!)
571     {
572         die "Already in a dali-env directory\n";
573         # Could query if user wants to re-create?
574     }
575     elsif(-e $root_path)
576     {
577         die "$root_path already exists\n";
578     }
579     elsif(-e $new_root)
580     {
581         die "A dali-env directory already exists here\n";
582     }
583
584     check_system_packages();
585
586     create_link();
587
588     create_env();
589
590     # do this after source directory structure created in create_env
591     check_source_packages();
592
593     create_setenv();
594 }
595 elsif($opt_setenv)
596 {
597     if(! -d $root_path)
598     {
599         die "$root_path does not exist\n";
600     }
601     elsif($new_env)
602     {
603         die "$root_path is not an existing environment\n";
604     }
605     create_setenv();
606 }
607 else
608 {
609     pod2usage(1);
610 }
611
612 __END__
613
614 =head1 NAME
615
616 dali_env - Create the DALi environment for Ubuntu
617
618 =head1 SYNOPSIS
619
620 dali_env [-c] [-s] [-h|-m]
621
622 =head1 OPTIONS
623
624 =over 28
625
626 =item B<-c|--create>
627
628 Create a DALi environment directory in the current directory.
629
630 =item B<-s|--setenv>
631
632 Display environment variables to setup.
633
634 =item B<-h|--help>
635
636 Display this help
637
638 =item B<-m|--man>
639
640 Display the manual page
641
642 =back
643
644 =head1 DESCRIPTION
645
646 B<dali_env>
647
648 Gets the required dependencies for DALi and them to a local directory. Can also create a setenv script to point to the installation.
649
650 =cut