bb9db7c9f2d398d0632991cb59822752b46f4e52
[platform/core/uifw/dali-core.git] / build / scripts / dali_env
1 #!/usr/bin/perl
2
3 # Copyright (c) 2014 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 EOF
232 }
233
234 ################################################################################
235
236 sub check_system_package
237 {
238     my $package;
239     foreach $package (@_)
240     {
241         my @x=split(/\s+/, `dpkg -l $package|grep $package`);
242         if($x[0] ne "ii")
243         {
244             print "Attempting to install $package\n";
245             system("sudo apt-get -y --force-yes install $package");
246         }
247     }
248 }
249
250 sub check_system_packages
251 {
252     print "Checking for required system packages (may require sudo password)\n";
253
254     check_system_package(@system_packages);
255
256     if($opt_emscripten)
257     {
258         check_system_package(@emscripten_system_packages);
259     }
260
261     my $gnome_v =`dpkg -l gnome-common| tail -1| sed "s/ \\+/ /g" | cut -d' ' -f 3`;
262     my @am = split(/\./, `automake --version | head -1 | cut -f4 -d' '`);
263     if($gnome_v =~ /$2.24/ && $am[1]>10)
264     {
265         die "Gnome common and automake are not compatible - automake is too new\n";
266     }
267     my @gpp_v = (`g++ --version  | head -1` =~ /(\d+)\.(\d+)\.(\d+)/);
268
269     if(! (($gpp_v[0] > 4)
270           ||
271           ($gpp_v[0] == 4 && $gpp_v[1] > 4)
272           ||
273           ($gpp_v[0] == 4 && $gpp_v[1] == 4 && $gpp_v[2] >= 5)))
274     {
275         die "You need g++ 4.5.1 or greater to build dali\n";
276     }
277 }
278
279 sub check_source_packages
280 {
281     my $pkgref;
282
283     foreach $pkgref (@source_pkgs)
284     {
285         my $pkg = $pkgref->{"name"};
286         if($pkg eq "v8")
287         {
288             install_v8( $pkgref );
289         }
290         elsif($pkg eq "emscripten" && $opt_emscripten)
291         {
292             install_emscripten( $pkgref );
293         }
294     }
295 }
296
297 ################################################################################
298
299 sub create_link
300 {
301     my $arch=`uname -i`;
302     $arch =~ s/\r|\n//g;
303
304     my $link = "/usr/lib/$arch-linux-gnu/libturbojpeg.so";
305
306     unless (-e $link)
307     {
308        print "Creating libjpegturbo symbolic link\n";
309        system("sudo ln -s $link.0 $link");
310     }
311 }
312
313 ################################################################################
314 # Helper to run and print out the command being run and quit if it fails
315 #
316 sub run_command
317 {
318   my $command = $_[0];
319   my $ret;
320   print("Running: $command\n");
321   $ret = system("$command");
322   if($ret >> 8) { die "$command failed \n"; }
323 }
324
325 ################################################################################
326 # later versions of v8 (post mid 2014) require googles depot_tools to build.
327 #
328 sub install_google_depot_tools
329 {
330
331 ####
332 # clone the depo_tools into the source directory and set the path up
333 ####
334     my $v8 = $_[0];
335
336     my $depot_tools_directory = $src_path . "/depot_tools";
337     my $depot_tools_repo = $v8->{"depot_tools_repo"};
338
339     # clear the directory if exists
340     rmtree( $depot_tools_directory );
341
342     # clone the depot tools
343     run_command( "git clone " . $depot_tools_repo. " " . $depot_tools_directory );
344
345     # add it the the path
346     $ENV{PATH} = "$ENV{PATH}:$depot_tools_directory";
347
348     # need to setup a config file for the proxy
349     create_boto_config_file( $v8 , $depot_tools_directory );
350
351     # set the config location as an environment variable ( used by scripts depot_tools)
352     $ENV{NO_AUTH_BOTO_CONFIG}="$src_path/depot_tools/.boto";
353
354     # change to depot tools directory
355     chdir( $depot_tools_directory );
356
357     # fetch v8
358     run_command("fetch --nohooks v8");
359
360 }
361
362
363 ################################################################################
364 # later versions of v8 use boto, which currently requires having proxy manually set
365 #
366 sub create_boto_config_file
367 {
368     my $v8 = $_[0];
369     my $depot_tools_directory = $_[1];
370     print(" depot_tools directory = $depot_tools_directory\n");
371
372     print("Configuring boto with http proxy IP = ". $http_proxy_ip . ", Port = " . $http_proxy_port . "\n");
373
374 # Create the proxy info for the boto file
375 my $fileContents = <<"END";
376 [Boto]
377 debug = 0
378 num_retries = 2
379
380 proxy = $http_proxy_ip
381 proxy_port = $http_proxy_port
382 END
383       # Place the config file in the depot tools folder
384     my $filename = $depot_tools_directory . "/" . ".boto";
385     print("Creating Boto config file with proxy settings to file ". $filename . "\n");
386     my $fh;
387     open( $fh, '>',  $filename );
388     print { $fh } $fileContents;
389     close( $fh );
390
391     # export the environment variable
392     run_command("gclient config https://gclient.googlecode.com/svn/trunk/gclient");
393
394     run_command("gclient runhooks");
395
396
397
398 }
399 ################################################################################
400 # We need a specific version of V8 to work with DALi
401 # - Check a txt file in dali-env to see if v8 needs upgrading (checks gcc version too)
402 # - Clones the source
403 # - builds dependencies (v8 automatically clones it's GYP build system)
404 # - Builds it
405 # - Create a package file
406 # It is cloned, then built from source, we create a package file for it, then
407 # it's copied into dali-env
408 sub install_v8
409 {
410     my $v8 = $_[0];
411     my $ret;
412     my $v8Version = $v8->{"version"};
413     print( "Checking if V8 ". $v8Version. " is installed \n");
414
415 ####
416 # Check currently installed version
417 # We create a text file with v8 and gcc version in the filename to compare with
418 # Version file is stored as "v8_2.3.4_installed_built_with_gcc_4_8_3.txt"
419 ####
420     # get the gcc version, so if the compiler is updated v8 is re-built
421     # note: v8 requires gcc version GCC >= 4.6
422     my $gccVersion = `gcc --version | grep ^gcc | sed 's/^.* //g'`;
423     chomp( $gccVersion );
424     my $versionTextFile = $src_path . "/v8_" . $v8Version. "_" . $v8->{"build-mode"} . "_installed_built_with_gcc_". $gccVersion .".txt";
425
426     # use stat to see if file exists
427     my @install_stats = stat $versionTextFile;
428     if( (scalar(@install_stats)) && $v8->{"force-rebuild"} != 1 )
429     {
430       print("Correct V8 version installed\n");
431       return;
432     }
433     else
434     {
435       # delete older versions of the version file first ( otherwise when downgrading it thinks version is still installed)
436       system( "rm " . $src_path . "/v8_*.txt  >/dev/null 2>&1");
437     }
438
439
440 ####
441 # Clone the v8 source repository and checkout the version we want
442 ####
443     # Need to clone it from repo
444     my $v8_source_directory;
445
446
447
448     # newer version of v8 use depot_tools with gclient, git cloned builds do not work
449     if( $v8->{"use_depot_tools"} == 1)
450     {
451       install_google_depot_tools( $v8 );
452
453       # v8 is checkout out under depot_tools path
454       $v8_source_directory = $src_path . "/depot_tools/v8";
455     }
456     else
457     {
458       $v8_source_directory = $src_path . "/v8";
459
460       # delete the old v8 source directpry if exists
461       rmtree( $v8_source_directory );
462
463       # clone the repository
464       run_command( "git clone " . $v8->{"repo"} . " " . $v8_source_directory );
465     }
466
467     # change to the source directoy for the checkout
468     chdir( $v8_source_directory );
469
470     # checkout the version DALi is compatible with
471     run_command( "git checkout ". $v8Version );
472
473 ####
474 # Run make dependencies then make for the specific target
475 ####
476     if( $v8->{"use_depot_tools"} == 1)
477     {
478       run_command("gclient sync");
479     }
480     else
481     {
482       run_command("make dependencies");
483     }
484
485     # assemble the make command
486     my $makeCommand = $v8->{"make"};
487
488     # need to append architecture and build mode, e.g. x64.debug
489     my $buildTarget;
490     if( $Config{use64bitint} ) {
491        print("Building 64 bit version of V8\n");
492        $buildTarget= "x64." . $v8->{"build-mode"}
493     }
494     else{
495       print("Building 32 bit version of V8\n");
496        $buildTarget= "ia32." . $v8->{"build-mode"}
497     }
498     $makeCommand .= " " . $buildTarget;
499     print("Running: $makeCommand\n");
500     run_command( $makeCommand );
501
502 ####
503 # Manually install the library / header files
504 ####
505
506     # Need to manually install (make install not available on v8 )
507     my $libSourceDir = "$v8_source_directory/out/$buildTarget/lib.target/";
508     my $headerSourceDir = "$v8_source_directory/include/";
509
510     my $libDestinationDir = $install_path . "/lib/";
511     my $headerDestinationDir = $install_path . "/include/v8/";
512
513     # delete any current v8 libs
514     system( "rm " . $libDestinationDir . "libv8*");
515     system( "rm " . $libDestinationDir . "libicu*");
516
517
518     # copy the library and header files
519     dircopy( $libSourceDir, $libDestinationDir);
520     dircopy( $headerSourceDir, $headerDestinationDir);
521
522
523     # Copy libv8.so to libv8.so.version (  e.g. libv8.so.1.2.4)
524     my $v8SoFile = $libDestinationDir . "libv8.so";
525     my $v8SoVersionFile = $libDestinationDir . "libv8.so." . $v8Version;
526     move( $v8SoFile, $v8SoVersionFile );
527
528     # symlink the libv8.so.1.2.3 to libv8.so
529     symlink( $v8SoVersionFile, $v8SoFile );
530     print( "source dir = " . $libSourceDir . " dest dir ". $libDestinationDir . " \n" );
531
532
533 ####
534 # Create the package file in,
535 # we keep the library files and header files in v8 sub-directories
536 ####
537 my $fileContents = <<"END";
538 prefix=$install_path
539 exec_prefix=\${prefix}
540 apiversion=$v8Version
541 libdir=\${exec_prefix}/lib
542 includedir=\${prefix}/include/v8
543
544 Name: v8 JavaScript engine - runtime library
545 Description: V8 is Google's open source JavaScript engine.
546 Version: \${apiversion}
547 Libs: -L\${libdir} -lv8 -licuuc -licui18n
548 Cflags: -I\${includedir}
549 END
550
551   my $filename = $install_path . "/lib/pkgconfig/" . "v8.pc";
552   print("writing to file ". $filename . "\n");
553   my $fh;
554   if( open( $fh, '>',  $filename ) )
555   {
556     print { $fh } $fileContents;
557     close( $fh );
558   }
559   else
560   {
561     die "failed to create " . $filename ."\n";
562   }
563
564   print("Installed V8 " .$v8Version . " OK\n");
565
566 #####
567 #
568 ####
569       my $versionFile;
570       open( $versionFile, '>',  $versionTextFile );
571       close( $versionFile );
572       print("Installing V8 version $v8Version\n");
573
574 }
575
576 ################################################################################
577 #
578 # install the latest emscripten in a portable directory
579 #
580 ################################################################################
581 sub install_emscripten
582 {
583     my $info = $_[0];
584     my $ret;
585     print( "Checking if Emscripten is up to date\n");
586
587     my $portable = $info->{"portable"};
588
589     my $current_dir = getcwd();
590
591     print( "\n");
592     print( "Installing or updating Emscripten.\n");
593     print( ".....You may need a cup of tea.\n");
594     print( ".......... In fact, take the afternoon off.\n");
595     print( "\n");
596
597     if(-e $emscripten_path)
598     {
599         chdir( $emscripten_path );
600     }
601     else
602     {
603         chdir( $root_path );
604
605         system("curl -O " . $portable) == 0
606             or die "curl failed with error $?. :" . $portable;
607
608         my($filename, $dirs, $suffix) = fileparse($portable);
609
610         system("tar -xvf " . $filename . $suffix) == 0
611             or die "tar unpack failed (nb tar.gz is the presumed downloaded format):" . $filename . $suffix;
612
613         system("rm " . $filename . $suffix) == 0
614             or die "Cannot remove emsdk portable tar file:" . $filename . $suffix;
615
616         chdir( $emscripten_path );
617     }
618
619     system("./emsdk update") == 0
620         or die "Cannot run emsdk? Did the install fail?";
621
622     system("./emsdk install latest");
623     system("./emsdk activate latest");
624     system("bash -c \"source ./emsdk_env.sh\""); # emsdk uses popd ie expects bash
625
626     system("emsdk list");
627
628     chdir($current_dir);
629 }
630
631
632 ################################################################################
633 #                                       MAIN
634 ################################################################################
635
636
637 if($opt_create)
638 {
639     my $new_root = getcwd() . "/dali-env";
640
641     if($exec_path =~ m!dali-env/opt/bin!)
642     {
643         die "Already in a dali-env directory\n";
644         # Could query if user wants to re-create?
645     }
646     elsif(-e $root_path)
647     {
648         die "$root_path already exists\n";
649     }
650     elsif(-e $new_root)
651     {
652         die "A dali-env directory already exists here\n";
653     }
654
655     check_system_packages();
656
657     create_link();
658
659     create_env();
660
661     # do this after source directory structure created in create_env
662     check_source_packages();
663
664     create_setenv();
665 }
666 elsif($opt_setenv)
667 {
668     if(! -d $root_path)
669     {
670         die "$root_path does not exist\n";
671     }
672     elsif($new_env)
673     {
674         die "$root_path is not an existing environment\n";
675     }
676     create_setenv();
677 }
678 else
679 {
680     pod2usage(1);
681 }
682
683 __END__
684
685 =head1 NAME
686
687 dali_env - Create the DALi environment for Ubuntu
688
689 =head1 SYNOPSIS
690
691 dali_env [-c] [-s] [-h|-m]
692
693 =head1 OPTIONS
694
695 =over 28
696
697 =item B<-c|--create>
698
699 Create a DALi environment directory in the current directory.
700
701 =item B<-s|--setenv>
702
703 Display environment variables to setup.
704
705 =item B<-e|--emscripten>
706
707 Include emscripten (use with -c to install with emscripten or -s to setup env vars with emscripten).
708
709 =item B<-h|--help>
710
711 Display this help
712
713 =item B<-m|--man>
714
715 Display the manual page
716
717 =back
718
719 =head1 DESCRIPTION
720
721 B<dali_env>
722
723 Gets the required dependencies for DALi and them to a local directory. Can also create a setenv script to point to the installation.
724
725 =cut