eaa46773f70f10268e278b22b1ad88562099394c
[platform/core/uifw/dali-core.git] / build / scripts / dali_env
1 #!/usr/bin/perl
2
3 # Copyright (c) 2016 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     "libfribidi-dev",
47     "libharfbuzz-dev",
48     "doxygen",
49     "lcov",
50     "libcurl4-gnutls-dev",
51 );
52
53 my @emscripten_system_packages = (
54     "gnome-common",
55     "curl",
56     "tar",
57     "build-essential",
58     "cmake",
59     "nodejs",
60     "default-jre",
61     "python2.7"
62 );
63
64 # Some packages like require building from source
65 # v8 is currently disabled until we can get it working without a http proxy being setup
66 my @source_pkgs = (
67
68     {"name" => "disabled-v8",
69      "force-rebuild" => 0,
70      "use_depot_tools" => 1,
71      "repo" => "https://chromium.googlesource.com/v8/v8.git",
72      "depot_tools_repo" => "https://chromium.googlesource.com/chromium/tools/depot_tools.git",
73
74      # original version used with DALi is 3.25.19. 3.32.7 is the latest we can use before
75      # upgrading DALi to use  c++0x or c++11
76      "version" => " 3.32.7", "make" => "make -j8 library=shared", "build-mode" =>"debug" },
77
78     {"name" => "emscripten",
79      "portable" => "https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz"
80     }
81 );
82
83 ### Detect any http proxy, part of v8 installation requires this information
84 my $http_proxy_port;
85 my $http_proxy_ip;
86
87 if( exists $ENV{http_proxy} )
88 {
89   # string  split into 3 items  http, //ip, port
90   my @http_proxy_info =  split( /:/,$ENV{http_proxy}, );
91
92   $http_proxy_ip =  @http_proxy_info[1];
93   $http_proxy_ip =~ s/[\/]//g;;  # remove forward slashes
94   $http_proxy_port =  @http_proxy_info[2];
95 }
96
97 # Make best guess as to where this program was run from (note, it is
98 # always possible to override the location of $0 by the calling
99 # program, so we can't really tell for sure that this is where we
100 # expect it to be. :/
101
102 my $new_env   = 0;
103 my $exec_path = $0;
104 if($0 !~ m!^/!)
105 {
106     $exec_path = abs_path($0);
107 }
108 $exec_path = dirname($exec_path);
109
110 my $root_path = getcwd();
111
112 # Search for the root dali-env directory
113 if($exec_path =~ m!dali-env/opt/bin!)
114 {
115     # We are using the installed dali_env script
116
117     $root_path = $exec_path;
118     while(basename($root_path) ne "dali-env" && $root_path ne "")
119     {
120         $root_path = dirname($root_path);
121     }
122 }
123 elsif($root_path =~ m!dali-env$! or $root_path =~ m!dali-env/!)
124 {
125     # We are NOT using the installed dali_env script
126     # Find dali-env root from current directory
127
128     while(basename($root_path) ne "dali-env" && $root_path ne "")
129     {
130         $root_path = dirname($root_path);
131     }
132 }
133 else
134 {
135     # dali-env root dir should be in the current directory
136
137     $root_path .= "/dali-env";
138
139     if(! -e $root_path)
140     {
141       # Creating a new dali-env
142
143       $new_env = 1;
144     }
145 }
146
147 my $src_path         = "$root_path/src-packages";
148 my $sbs_path         = "$root_path/target";
149 my $install_path     = "$root_path/opt";
150 my $emscripten_path  = "$root_path/emsdk_portable";
151
152 my $opt_create=0;
153 my $opt_setenv=0;
154 my $opt_help=0;
155 my $opt_man=0;
156 my $opt_emscripten=0;
157
158 GetOptions("create"     => \$opt_create,
159            "setenv"     => \$opt_setenv,
160            "emscripten" => \$opt_emscripten,
161            "help"       => \$opt_help,
162            "man"        => \$opt_man) or pod2usage(2);
163
164 pod2usage(1) if $opt_help;
165 pod2usage(-exitstatus => 0, -verbose => 2) if $opt_man;
166
167
168 ################################################################################
169
170 sub create_env
171 {
172     mkpath("$install_path/bin");
173     mkpath("$install_path/lib/pkgconfig");
174     mkpath("$install_path/include");
175     mkpath("$install_path/share/aclocal");
176     mkpath("$src_path");
177     mkpath("$sbs_path");
178
179     copy($0, "$install_path/bin/dali_env");
180     chmod(0755, "$install_path/bin/dali_env");
181 }
182
183 ################################################################################
184
185 sub in_dali_env
186 {
187     my $cwd = substr(getcwd(), 0, length($root_path));
188     #print "cwd = $cwd\nroot = $root_path\n";
189     return $cwd eq $root_path;
190 }
191
192 ################################################################################
193
194 sub create_setenv
195 {
196     if( ( -d $emscripten_path ) || $opt_emscripten )
197     {
198         print <<"EOF";
199 #
200 # Emscripten environment
201 #  - which brazenly overwrites PATH so we set this first
202 #  - NB: If you change the tools within emsdk then you'll need to recreate this file
203 #
204
205 EOF
206         my $emsdk_env_file = $emscripten_path . '/emsdk_set_env.sh';
207         open(FILE, $emsdk_env_file) or die "Can't read file enscripten env file" . $emsdk_env_file;
208         my @emsdk_env = <FILE>;
209         close (FILE);
210         print @emsdk_env;
211     }
212
213     print <<"EOF";
214 #
215 # To use the desktop libraries, please add the following lines to your .bashrc or
216 # create a setenv script from them, e.g. by running this command as follows
217 # \$ $install_path/bin/dali_env -s > setenv
218 #
219 # You can then source this script by using
220 # \$ . setenv
221 #
222 # Use DESKTOP_PREFIX when running configure in dali/build/tizen:
223 # \$ CXXFLAGS="-g -O0" ./configure --prefix=\$DESKTOP_PREFIX
224
225 export DESKTOP_PREFIX=$install_path
226 export PATH=$install_path/bin:\$PATH
227 export LD_LIBRARY_PATH=$install_path/lib:\$LD_LIBRARY_PATH
228 export INCLUDEDIR=$install_path/include
229 export PKG_CONFIG_PATH=$install_path/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
230
231 export DALI_WINDOW_WIDTH=480
232 export DALI_WINDOW_HEIGHT=800
233
234 EOF
235 }
236
237 ################################################################################
238
239 sub check_system_package
240 {
241     my $package;
242     foreach $package (@_)
243     {
244         my @x=split(/\s+/, `dpkg -l $package|grep $package`);
245         if($x[0] ne "ii")
246         {
247             print "Attempting to install $package\n";
248             system("sudo apt-get -y --force-yes install $package");
249         }
250     }
251 }
252
253 sub check_system_packages
254 {
255     print "Checking for required system packages (may require sudo password)\n";
256
257     check_system_package(@system_packages);
258
259     if($opt_emscripten)
260     {
261         check_system_package(@emscripten_system_packages);
262     }
263
264     my $gnome_v =`dpkg -l gnome-common| tail -1| sed "s/ \\+/ /g" | cut -d' ' -f 3`;
265     my @am = split(/\./, `automake --version | head -1 | cut -f4 -d' '`);
266     if($gnome_v =~ /$2.24/ && $am[1]>10)
267     {
268         die "Gnome common and automake are not compatible - automake is too new\n";
269     }
270     my @gpp_v = (`g++ --version  | head -1` =~ /(\d+)\.(\d+)\.(\d+)/);
271
272     if(! (($gpp_v[0] > 4)
273           ||
274           ($gpp_v[0] == 4 && $gpp_v[1] > 4)
275           ||
276           ($gpp_v[0] == 4 && $gpp_v[1] == 4 && $gpp_v[2] >= 5)))
277     {
278         die "You need g++ 4.5.1 or greater to build dali\n";
279     }
280 }
281
282 sub check_source_packages
283 {
284     my $pkgref;
285
286     foreach $pkgref (@source_pkgs)
287     {
288         my $pkg = $pkgref->{"name"};
289         if($pkg eq "v8")
290         {
291             install_v8( $pkgref );
292         }
293         elsif($pkg eq "emscripten" && $opt_emscripten)
294         {
295             install_emscripten( $pkgref );
296         }
297     }
298 }
299
300 ################################################################################
301
302 sub create_link
303 {
304     my $arch=`uname -i`;
305     $arch =~ s/\r|\n//g;
306
307     my $link = "/usr/lib/$arch-linux-gnu/libturbojpeg.so";
308
309     unless (-e $link)
310     {
311        print "Creating libjpegturbo symbolic link\n";
312        system("sudo ln -s $link.0 $link");
313     }
314 }
315
316 ################################################################################
317 # Helper to run and print out the command being run and quit if it fails
318 #
319 sub run_command
320 {
321   my $command = $_[0];
322   my $ret;
323   print("Running: $command\n");
324   $ret = system("$command");
325   if($ret >> 8) { die "$command failed \n"; }
326 }
327
328 ################################################################################
329 # later versions of v8 (post mid 2014) require googles depot_tools to build.
330 #
331 sub install_google_depot_tools
332 {
333
334 ####
335 # clone the depo_tools into the source directory and set the path up
336 ####
337     my $v8 = $_[0];
338
339     my $depot_tools_directory = $src_path . "/depot_tools";
340     my $depot_tools_repo = $v8->{"depot_tools_repo"};
341
342     # clear the directory if exists
343     rmtree( $depot_tools_directory );
344
345     # clone the depot tools
346     run_command( "git clone " . $depot_tools_repo. " " . $depot_tools_directory );
347
348     # add it the the path
349     $ENV{PATH} = "$ENV{PATH}:$depot_tools_directory";
350
351     # need to setup a config file for the proxy
352     create_boto_config_file( $v8 , $depot_tools_directory );
353
354     # set the config location as an environment variable ( used by scripts depot_tools)
355     $ENV{NO_AUTH_BOTO_CONFIG}="$src_path/depot_tools/.boto";
356
357     # change to depot tools directory
358     chdir( $depot_tools_directory );
359
360     # fetch v8
361     run_command("fetch --nohooks v8");
362
363 }
364
365
366 ################################################################################
367 # later versions of v8 use boto, which currently requires having proxy manually set
368 #
369 sub create_boto_config_file
370 {
371     my $v8 = $_[0];
372     my $depot_tools_directory = $_[1];
373     print(" depot_tools directory = $depot_tools_directory\n");
374
375     print("Configuring boto with http proxy IP = ". $http_proxy_ip . ", Port = " . $http_proxy_port . "\n");
376
377 # Create the proxy info for the boto file
378 my $fileContents = <<"END";
379 [Boto]
380 debug = 0
381 num_retries = 2
382
383 proxy = $http_proxy_ip
384 proxy_port = $http_proxy_port
385 END
386       # Place the config file in the depot tools folder
387     my $filename = $depot_tools_directory . "/" . ".boto";
388     print("Creating Boto config file with proxy settings to file ". $filename . "\n");
389     my $fh;
390     open( $fh, '>',  $filename );
391     print { $fh } $fileContents;
392     close( $fh );
393
394     # export the environment variable
395     run_command("gclient config https://gclient.googlecode.com/svn/trunk/gclient");
396
397     run_command("gclient runhooks");
398
399
400
401 }
402 ################################################################################
403 # We need a specific version of V8 to work with DALi
404 # - Check a txt file in dali-env to see if v8 needs upgrading (checks gcc version too)
405 # - Clones the source
406 # - builds dependencies (v8 automatically clones it's GYP build system)
407 # - Builds it
408 # - Create a package file
409 # It is cloned, then built from source, we create a package file for it, then
410 # it's copied into dali-env
411 sub install_v8
412 {
413     my $v8 = $_[0];
414     my $ret;
415     my $v8Version = $v8->{"version"};
416     print( "Checking if V8 ". $v8Version. " is installed \n");
417
418 ####
419 # Check currently installed version
420 # We create a text file with v8 and gcc version in the filename to compare with
421 # Version file is stored as "v8_2.3.4_installed_built_with_gcc_4_8_3.txt"
422 ####
423     # get the gcc version, so if the compiler is updated v8 is re-built
424     # note: v8 requires gcc version GCC >= 4.6
425     my $gccVersion = `gcc --version | grep ^gcc | sed 's/^.* //g'`;
426     chomp( $gccVersion );
427     my $versionTextFile = $src_path . "/v8_" . $v8Version. "_" . $v8->{"build-mode"} . "_installed_built_with_gcc_". $gccVersion .".txt";
428
429     # use stat to see if file exists
430     my @install_stats = stat $versionTextFile;
431     if( (scalar(@install_stats)) && $v8->{"force-rebuild"} != 1 )
432     {
433       print("Correct V8 version installed\n");
434       return;
435     }
436     else
437     {
438       # delete older versions of the version file first ( otherwise when downgrading it thinks version is still installed)
439       system( "rm " . $src_path . "/v8_*.txt  >/dev/null 2>&1");
440     }
441
442
443 ####
444 # Clone the v8 source repository and checkout the version we want
445 ####
446     # Need to clone it from repo
447     my $v8_source_directory;
448
449
450
451     # newer version of v8 use depot_tools with gclient, git cloned builds do not work
452     if( $v8->{"use_depot_tools"} == 1)
453     {
454       install_google_depot_tools( $v8 );
455
456       # v8 is checkout out under depot_tools path
457       $v8_source_directory = $src_path . "/depot_tools/v8";
458     }
459     else
460     {
461       $v8_source_directory = $src_path . "/v8";
462
463       # delete the old v8 source directpry if exists
464       rmtree( $v8_source_directory );
465
466       # clone the repository
467       run_command( "git clone " . $v8->{"repo"} . " " . $v8_source_directory );
468     }
469
470     # change to the source directoy for the checkout
471     chdir( $v8_source_directory );
472
473     # checkout the version DALi is compatible with
474     run_command( "git checkout ". $v8Version );
475
476 ####
477 # Run make dependencies then make for the specific target
478 ####
479     if( $v8->{"use_depot_tools"} == 1)
480     {
481       run_command("gclient sync");
482     }
483     else
484     {
485       run_command("make dependencies");
486     }
487
488     # assemble the make command
489     my $makeCommand = $v8->{"make"};
490
491     # need to append architecture and build mode, e.g. x64.debug
492     my $buildTarget;
493     if( $Config{use64bitint} ) {
494        print("Building 64 bit version of V8\n");
495        $buildTarget= "x64." . $v8->{"build-mode"}
496     }
497     else{
498       print("Building 32 bit version of V8\n");
499        $buildTarget= "ia32." . $v8->{"build-mode"}
500     }
501     $makeCommand .= " " . $buildTarget;
502     print("Running: $makeCommand\n");
503     run_command( $makeCommand );
504
505 ####
506 # Manually install the library / header files
507 ####
508
509     # Need to manually install (make install not available on v8 )
510     my $libSourceDir = "$v8_source_directory/out/$buildTarget/lib.target/";
511     my $headerSourceDir = "$v8_source_directory/include/";
512
513     my $libDestinationDir = $install_path . "/lib/";
514     my $headerDestinationDir = $install_path . "/include/v8/";
515
516     # delete any current v8 libs
517     system( "rm " . $libDestinationDir . "libv8*");
518     system( "rm " . $libDestinationDir . "libicu*");
519
520
521     # copy the library and header files
522     dircopy( $libSourceDir, $libDestinationDir);
523     dircopy( $headerSourceDir, $headerDestinationDir);
524
525
526     # Copy libv8.so to libv8.so.version (  e.g. libv8.so.1.2.4)
527     my $v8SoFile = $libDestinationDir . "libv8.so";
528     my $v8SoVersionFile = $libDestinationDir . "libv8.so." . $v8Version;
529     move( $v8SoFile, $v8SoVersionFile );
530
531     # symlink the libv8.so.1.2.3 to libv8.so
532     symlink( $v8SoVersionFile, $v8SoFile );
533     print( "source dir = " . $libSourceDir . " dest dir ". $libDestinationDir . " \n" );
534
535
536 ####
537 # Create the package file in,
538 # we keep the library files and header files in v8 sub-directories
539 ####
540 my $fileContents = <<"END";
541 prefix=$install_path
542 exec_prefix=\${prefix}
543 apiversion=$v8Version
544 libdir=\${exec_prefix}/lib
545 includedir=\${prefix}/include/v8
546
547 Name: v8 JavaScript engine - runtime library
548 Description: V8 is Google's open source JavaScript engine.
549 Version: \${apiversion}
550 Libs: -L\${libdir} -lv8 -licuuc -licui18n
551 Cflags: -I\${includedir}
552 END
553
554   my $filename = $install_path . "/lib/pkgconfig/" . "v8.pc";
555   print("writing to file ". $filename . "\n");
556   my $fh;
557   if( open( $fh, '>',  $filename ) )
558   {
559     print { $fh } $fileContents;
560     close( $fh );
561   }
562   else
563   {
564     die "failed to create " . $filename ."\n";
565   }
566
567   print("Installed V8 " .$v8Version . " OK\n");
568
569 #####
570 #
571 ####
572       my $versionFile;
573       open( $versionFile, '>',  $versionTextFile );
574       close( $versionFile );
575       print("Installing V8 version $v8Version\n");
576
577 }
578
579 ################################################################################
580 #
581 # install the latest emscripten in a portable directory
582 #
583 ################################################################################
584 sub install_emscripten
585 {
586     my $info = $_[0];
587     my $ret;
588     print( "Checking if Emscripten is up to date\n");
589
590     my $portable = $info->{"portable"};
591
592     my $current_dir = getcwd();
593
594     print( "\n");
595     print( "Installing or updating Emscripten.\n");
596     print( ".....You may need a cup of tea.\n");
597     print( ".......... In fact, take the afternoon off.\n");
598     print( "\n");
599
600     if(-e $emscripten_path)
601     {
602         chdir( $emscripten_path );
603     }
604     else
605     {
606         chdir( $root_path );
607
608         system("curl -O " . $portable) == 0
609             or die "curl failed with error $?. :" . $portable;
610
611         my($filename, $dirs, $suffix) = fileparse($portable);
612
613         system("tar -xvf " . $filename . $suffix) == 0
614             or die "tar unpack failed (nb tar.gz is the presumed downloaded format):" . $filename . $suffix;
615
616         system("rm " . $filename . $suffix) == 0
617             or die "Cannot remove emsdk portable tar file:" . $filename . $suffix;
618
619         chdir( $emscripten_path );
620     }
621
622     system("./emsdk update") == 0
623         or die "Cannot run emsdk? Did the install fail?";
624
625     system("./emsdk install latest");
626     system("./emsdk activate latest");
627     system("bash -c \"source ./emsdk_env.sh\""); # emsdk uses popd ie expects bash
628
629     system("emsdk list");
630
631     chdir($current_dir);
632 }
633
634
635 ################################################################################
636 #                                       MAIN
637 ################################################################################
638
639
640 if($opt_create)
641 {
642     my $new_root = getcwd() . "/dali-env";
643
644     if($exec_path =~ m!dali-env/opt/bin!)
645     {
646         die "Already in a dali-env directory\n";
647         # Could query if user wants to re-create?
648     }
649     elsif(-e $root_path)
650     {
651         die "$root_path already exists\n";
652     }
653     elsif(-e $new_root)
654     {
655         die "A dali-env directory already exists here\n";
656     }
657
658     check_system_packages();
659
660     create_link();
661
662     create_env();
663
664     # do this after source directory structure created in create_env
665     check_source_packages();
666
667     create_setenv();
668 }
669 elsif($opt_setenv)
670 {
671     if(! -d $root_path)
672     {
673         die "$root_path does not exist\n";
674     }
675     elsif($new_env)
676     {
677         die "$root_path is not an existing environment\n";
678     }
679     create_setenv();
680 }
681 else
682 {
683     pod2usage(1);
684 }
685
686 __END__
687
688 =head1 NAME
689
690 dali_env - Create the DALi environment for Ubuntu
691
692 =head1 SYNOPSIS
693
694 dali_env [-c] [-s] [-h|-m]
695
696 =head1 OPTIONS
697
698 =over 28
699
700 =item B<-c|--create>
701
702 Create a DALi environment directory in the current directory.
703
704 =item B<-s|--setenv>
705
706 Display environment variables to setup.
707
708 =item B<-e|--emscripten>
709
710 Include emscripten (use with -c to install with emscripten or -s to setup env vars with emscripten).
711
712 =item B<-h|--help>
713
714 Display this help
715
716 =item B<-m|--man>
717
718 Display the manual page
719
720 =back
721
722 =head1 DESCRIPTION
723
724 B<dali_env>
725
726 Gets the required dependencies for DALi and them to a local directory. Can also create a setenv script to point to the installation.
727
728 =cut