3 # Copyright (c) 2024 Samsung Electronics Co., Ltd.
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
9 # http://www.apache.org/licenses/LICENSE-2.0
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.
23 use File::Copy::Recursive qw(dircopy);
28 ################################################################################
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 = (
51 "libcurl4-gnutls-dev",
64 my $ubuntu_version = (split(/\s+/, `lsb_release -d`))[2];
65 if (${ubuntu_version} > 20)
67 # Add unique packages for 20.04 and above
68 push @system_packages, "libefl-all-dev";
72 # Add unique packages for Ubuntu releases before 20.04
73 push @system_packages, "libelementary-dev";
76 # Some packages like require building from source
77 # v8 is currently disabled until we can get it working without a http proxy being setup
80 {"name" => "disabled-v8",
82 "use_depot_tools" => 1,
83 "repo" => "https://chromium.googlesource.com/v8/v8.git",
84 "depot_tools_repo" => "https://chromium.googlesource.com/chromium/tools/depot_tools.git",
86 # original version used with DALi is 3.25.19. 3.32.7 is the latest we can use before
87 # upgrading DALi to use c++0x or c++11
88 "version" => " 3.32.7", "make" => "make -j8 library=shared", "build-mode" =>"debug" },
92 ### Detect any http proxy, part of v8 installation requires this information
96 if( exists $ENV{http_proxy} )
98 # string split into 3 items http, //ip, port
99 my @http_proxy_info = split( /:/,$ENV{http_proxy}, );
101 $http_proxy_ip = @http_proxy_info[1];
102 $http_proxy_ip =~ s/[\/]//g;; # remove forward slashes
103 $http_proxy_port = @http_proxy_info[2];
106 # Make best guess as to where this program was run from (note, it is
107 # always possible to override the location of $0 by the calling
108 # program, so we can't really tell for sure that this is where we
109 # expect it to be. :/
115 $exec_path = abs_path($0);
117 $exec_path = dirname($exec_path);
119 my $root_path = getcwd();
121 # Search for the root dali-env directory
122 if($exec_path =~ m!dali-env/opt/bin!)
124 # We are using the installed dali_env script
126 $root_path = $exec_path;
127 while(basename($root_path) ne "dali-env" && $root_path ne "")
129 $root_path = dirname($root_path);
132 elsif($root_path =~ m!dali-env$! or $root_path =~ m!dali-env/!)
134 # We are NOT using the installed dali_env script
135 # Find dali-env root from current directory
137 while(basename($root_path) ne "dali-env" && $root_path ne "")
139 $root_path = dirname($root_path);
144 # dali-env root dir should be in the current directory
146 $root_path .= "/dali-env";
150 # Creating a new dali-env
156 my $src_path = "$root_path/src-packages";
157 my $sbs_path = "$root_path/target";
158 my $install_path = "$root_path/opt";
162 my $opt_envfile="setenv";
166 my $opt_vk_version="1.3.280.1";
167 my $opt_vulkan=undef;
170 GetOptions("create" => \$opt_create,
171 "envfile=s" => \$opt_envfile,
172 "force" => \$opt_force,
173 "setenv" => \$opt_setenv,
174 "help" => \$opt_help,
175 "vulkan:s" => \$opt_vulkan,
177 "man" => \$opt_man) or pod2usage(2);
179 pod2usage(1) if $opt_help;
180 pod2usage(-exitstatus => 0, -verbose => 2) if $opt_man;
182 if($opt_vulkan ne "")
184 $opt_vk_version=$opt_vulkan;
187 ################################################################################
189 # Taken from IO::Interactive (to avoid yet more perl dependencies!)
191 my ($out_handle) = (@_, select); # Default to default output handle
193 # Not interactive if output is not to terminal...
194 return 0 if not -t $out_handle;
196 # If *ARGV is opened, we're interactive if...
197 if ( tied(*ARGV) or defined(fileno(ARGV)) ) { # this is what 'Scalar::Util::openhandle *ARGV' boils down to
199 # ...it's currently opened to the magic '-' file
200 return -t *STDIN if defined $ARGV && $ARGV eq '-';
202 # ...it's at end-of-file and the next file is the magic '-' file
203 return @ARGV>0 && $ARGV[0] eq '-' && -t *STDIN if eof *ARGV;
205 # ...it's directly attached to the terminal
209 # If *ARGV isn't opened, it will be interactive if *STDIN is attached
216 ################################################################################
220 mkpath("$install_path/bin");
221 mkpath("$install_path/lib/pkgconfig");
222 mkpath("$install_path/include");
223 mkpath("$install_path/share/aclocal");
227 copy($0, "$install_path/bin/dali_env");
228 chmod(0755, "$install_path/bin/dali_env");
231 ################################################################################
235 my $cwd = substr(getcwd(), 0, length($root_path));
236 #print "cwd = $cwd\nroot = $root_path\n";
237 return $cwd eq $root_path;
240 ################################################################################
244 # Setup vulkan environment if necessary
246 if(defined($opt_vulkan))
249 export VULKAN_VERSION=${opt_vk_version}
250 export VULKAN_ROOT=${root_path}/vulkan/\${VULKAN_VERSION}
251 . \${VULKAN_ROOT}/setup-env.sh
257 if($opt_envfile && is_interactive())
259 print "Writing environment script to $opt_envfile\n";
260 open($fh, ">", $opt_envfile)|| die "Can't open $opt_envfile for writing:$!\n";
261 $oldfh = select($fh);
265 # To use the desktop libraries, please add the following lines to your .bashrc or
266 # create a setenv script from them, e.g. by running this command as follows
267 # \$ $install_path/bin/dali_env -s
269 # You can then source this script by using
272 # Use DESKTOP_PREFIX when running configure or cmake in dali/build/tizen:
273 # \$ CXXFLAGS="-g -O0" ./configure --prefix=\$DESKTOP_PREFIX
275 # \$ CXXFLAGS="-g -O0" cmake -DCMAKE_INSTALL_PREFIX=\$DESKTOP_PREFIX
278 export DESKTOP_PREFIX=$install_path
279 export PATH=$install_path/bin:\$PATH
280 export LD_LIBRARY_PATH=$install_path/lib:\$LD_LIBRARY_PATH
281 export INCLUDEDIR=$install_path/include
282 export PKG_CONFIG_PATH=$install_path/lib/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig
283 export DOTNET_CLI_TELEMETRY_OPTOUT=1
284 export DALI_MULTI_SAMPLING_LEVEL=4
285 export DALI_WINDOW_WIDTH=480
286 export DALI_WINDOW_HEIGHT=800
296 ################################################################################
299 my ($archive, $url, $download_info) = @_;
301 # Avoid excessive downloading of the same file
302 if(! -e "/tmp/$archive")
304 print "Downloading $download_info\nfrom: $url\n";
305 system('wget','-P','/tmp',$url);
306 die "Can't download archive" if(! -e "/tmp/$archive");
313 system('tar','-xf',"/tmp/$archive", '--checkpoint=5000', '--checkpoint-action=ttyout=.');
318 if(defined($opt_vulkan))
320 my $archive="vulkansdk-linux-x86_64-${opt_vk_version}.tar.xz";
321 my $url="https://sdk.lunarg.com/sdk/download/${opt_vk_version}/linux/$archive";
322 download_archive($archive, $url, "Vulkan SDK version ${opt_vk_version}");
324 my $vulkan_install_path="$root_path/vulkan";
325 print "Unpacking vulkan archive\n";
326 mkpath($vulkan_install_path);
327 chdir($vulkan_install_path);
328 untar_archive($archive);
330 chdir("$root_path/..");
333 open($fh, ">", "$install_path/lib/pkgconfig/vulkan.pc") || die "Can't open vulkan.pc for writing: $!\n";
335 $vulkan_install_path .= "/${opt_vk_version}";
337 prefix=${vulkan_install_path}/x86_64
338 exec_prefix=${vulkan_install_path}/x86_64
339 libdir=\${prefix}/lib
340 includedir=\${prefix}/include
343 Description: Vulkan Loader
344 Version: ${opt_vk_version}
345 Libs: -L\${libdir} -lvulkan
346 Libs.private: -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
347 Cflags: -I\${includedir}
351 open($fh, ">", "$install_path/lib/pkgconfig/glslang.pc") || die "Can't open glslang.pc for writing: $!\n";
353 prefix=${vulkan_install_path}/x86_64
354 exec_prefix=${vulkan_install_path}/x86_64
355 libdir=\${prefix}/lib
356 includedir=\${prefix}/include
359 Description: OpenGL and OpenGL ES shader front end and validator
360 Version: ${opt_vk_version}
361 Libs: -L\${libdir} -lglslang -lOSDependent -lSPVRemapper -lshaderc -lshaderc_combined
362 Cflags: -I\${includedir}
366 open($fh, ">", "$install_path/lib/pkgconfig/SPIRV-Tools.pc") || die "Can't open SPIRV-Tools.pc for writing: $!\n";
368 prefix=${vulkan_install_path}/x86_64
369 exec_prefix=${vulkan_install_path}/x86_64
370 libdir=\${prefix}/lib
371 includedir=\${prefix}/include
374 Description: Tools for SPIR-V
375 Version: ${opt_vk_version}
376 Libs: -L\${libdir} -lSPIRV-Tools -lSPIRV-Tools-link -lSPIRV-Tools-opt
377 Cflags: -I\${includedir}
381 print "Written pkg-config files to $install_path/lib/pkg-config\n";
389 my $boost_archive="boost-1.84.0.tar.gz";
390 my $boost_url="https://github.com/boostorg/boost/releases/download/boost-1.84.0/$boost_archive";
391 download_archive($boost_archive, $boost_url, "Boost");
393 my $tbb_archive="2019_U9.tar.gz";
394 my $tbb_url="https://github.com/oneapi-src/oneTBB/archive/refs/tags/$tbb_archive";
395 download_archive($tbb_archive, $tbb_url, "LibTBB");
397 my $openusd_archive="32-bit-arm-and-tizen-support.tar.gz";
398 my $openusd_url="https://github.com/dalihub/OpenUSD/archive/refs/tags/$openusd_archive";
399 download_archive($openusd_archive, $openusd_url, "OpenUSD");
401 my $usd_install_path=$install_path;
402 my $usd_source_path="$src_path/usd";
404 print "Unpacking Boost, TBB & OpenUSD archives\n";
405 mkpath($usd_source_path);
406 chdir($usd_source_path);
407 untar_archive($boost_archive);
408 untar_archive($tbb_archive);
409 untar_archive($openusd_archive);
411 mkpath("$usd_install_path/lib");
412 mkpath("$usd_install_path/include");
414 my $boost_source_path="$usd_source_path/boost-1.84.0";
415 print "Building Boost\n";
416 chdir("$boost_source_path");
417 system('cmake',"-DCMAKE_INSTALL_PREFIX=$usd_install_path", '.');
418 system('make','-j8','install');
420 my $tbb_source_path="$usd_source_path/oneTBB-2019_U9";
421 print "Building TBB\n";
422 chdir("$tbb_source_path");
423 system('make','-j8');
424 my $tbbBuildFolder=`make info | grep tbb_build_prefix | cut -d= -f 2`;
425 chomp($tbbBuildFolder);
426 $tbbBuildFolder=$tbbBuildFolder . "_release";
427 print "$tbbBuildFolder Hello";
428 system("install -m 644 ./build/$tbbBuildFolder/*.so* $usd_install_path/lib/");
429 system('cp','-rf','include/tbb',"$usd_install_path/include/");
431 my $openusd_source_path="$usd_source_path/OpenUSD-32-bit-arm-and-tizen-support";
432 print "Building USD\n";
433 chdir("$openusd_source_path");
435 '-DPXR_ENABLE_PYTHON_SUPPORT=OFF',
436 '-DPXR_ENABLE_PTEX_SUPPORT=OFF',
437 '-DPXR_ENABLE_OPENVDB_SUPPORT=OFF',
438 '-DPXR_ENABLE_HDF5_SUPPORT=OFF',
439 '-DPXR_ENABLE_MATERIALX_SUPPORT=OFF',
440 '-DPXR_BUILD_IMAGING=OFF',
441 '-DPXR_BUILD_USD_IMAGING=OFF',
442 '-DPXR_BUILD_USDVIEW=OFF',
443 '-DPXR_BUILD_DOCUMENTATION=OFF',
444 '-DPXR_BUILD_HTML_DOCUMENTATION=OFF',
445 '-DPXR_BUILD_PYTHON_DOCUMENTATION=OFF',
446 '-DPXR_BUILD_TESTS=OFF',
447 '-DPXR_BUILD_EXAMPLES=OFF',
448 '-DPXR_BUILD_TUTORIALS=OFF',
449 '-DPXR_BUILD_USD_TOOLS=OFF',
450 '-DPXR_BUILD_MAYAPY_TESTS=OFF',
451 '-DPXR_BUILD_ANIMX_TESTS=OFF',
452 "-DTBB_ROOT_DIR=$usd_install_path",
453 "-DBOOST_ROOT=$usd_install_path",
454 "-DCMAKE_INSTALL_PREFIX=$usd_install_path",
457 system('make','-j8','install');
460 chdir("$root_path/..");
464 sub check_system_package
467 foreach $package (@_)
469 my @x=split(/\s+/, `dpkg -l $package 2> /dev/null|grep $package`);
472 # Check if the package is available to install, exit-code is 0 if the package is found.
473 if(system("apt-cache show $package > /dev/null 2>&1") == 0)
475 print "Attempting to install $package\n";
476 system("sudo apt-get -y --allow-change-held-packages --allow-downgrades install $package");
482 sub check_system_packages
484 print "Checking for required system packages (may require sudo password)\n";
486 check_system_package(@system_packages);
488 my $gnome_v =`dpkg -l gnome-common| tail -1| sed "s/ \\+/ /g" | cut -d' ' -f 3`;
489 my @am = split(/\./, `automake --version | head -1 | cut -f4 -d' '`);
490 if($gnome_v =~ /$2.24/ && $am[1]>10)
492 die "Gnome common and automake are not compatible - automake is too new\n";
494 my @gpp_v = (`g++ --version | head -1` =~ /(\d+)\.(\d+)\.(\d+)/);
496 if(! (($gpp_v[0] > 4)
498 ($gpp_v[0] == 4 && $gpp_v[1] > 4)
500 ($gpp_v[0] == 4 && $gpp_v[1] == 4 && $gpp_v[2] >= 5)))
502 die "You need g++ 4.5.1 or greater to build dali\n";
506 sub check_source_packages
510 foreach $pkgref (@source_pkgs)
512 my $pkg = $pkgref->{"name"};
515 install_v8( $pkgref );
517 elsif ($pkg eq "gtest")
519 if(! -e "/usr/lib/libgtest.a")
521 print "Attempting to build $pkg\n";
522 # from https://www.eriksmistad.no/getting-started-with-google-test-on-ubuntu/
523 run_command("cd /usr/src/gtest; sudo cmake CMakeLists.txt; sudo make; sudo cp lib/*.a /usr/lib; cd -;");
529 ################################################################################
536 my $link = "/usr/lib/$arch-linux-gnu/libturbojpeg.so";
540 print "Creating libjpegturbo symbolic link\n";
541 system("sudo ln -s $link.0 $link");
545 ################################################################################
546 # Helper to run and print out the command being run and quit if it fails
552 print("Running: $command\n");
553 $ret = system("$command");
554 if($ret >> 8) { die "$command failed \n"; }
557 ################################################################################
558 # later versions of v8 (post mid 2014) require googles depot_tools to build.
560 sub install_google_depot_tools
564 # clone the depo_tools into the source directory and set the path up
568 my $depot_tools_directory = $src_path . "/depot_tools";
569 my $depot_tools_repo = $v8->{"depot_tools_repo"};
571 # clear the directory if exists
572 rmtree( $depot_tools_directory );
574 # clone the depot tools
575 run_command( "git clone " . $depot_tools_repo. " " . $depot_tools_directory );
577 # add it the the path
578 $ENV{PATH} = "$ENV{PATH}:$depot_tools_directory";
580 # need to setup a config file for the proxy
581 create_boto_config_file( $v8 , $depot_tools_directory );
583 # set the config location as an environment variable ( used by scripts depot_tools)
584 $ENV{NO_AUTH_BOTO_CONFIG}="$src_path/depot_tools/.boto";
586 # change to depot tools directory
587 chdir( $depot_tools_directory );
590 run_command("fetch --nohooks v8");
595 ################################################################################
596 # later versions of v8 use boto, which currently requires having proxy manually set
598 sub create_boto_config_file
601 my $depot_tools_directory = $_[1];
602 print(" depot_tools directory = $depot_tools_directory\n");
604 print("Configuring boto with http proxy IP = ". $http_proxy_ip . ", Port = " . $http_proxy_port . "\n");
606 # Create the proxy info for the boto file
607 my $fileContents = <<"END";
612 proxy = $http_proxy_ip
613 proxy_port = $http_proxy_port
615 # Place the config file in the depot tools folder
616 my $filename = $depot_tools_directory . "/" . ".boto";
617 print("Creating Boto config file with proxy settings to file ". $filename . "\n");
619 open( $fh, '>', $filename );
620 print { $fh } $fileContents;
623 # export the environment variable
624 run_command("gclient config https://gclient.googlecode.com/svn/trunk/gclient");
626 run_command("gclient runhooks");
631 ################################################################################
632 # We need a specific version of V8 to work with DALi
633 # - Check a txt file in dali-env to see if v8 needs upgrading (checks gcc version too)
634 # - Clones the source
635 # - builds dependencies (v8 automatically clones it's GYP build system)
637 # - Create a package file
638 # It is cloned, then built from source, we create a package file for it, then
639 # it's copied into dali-env
644 my $v8Version = $v8->{"version"};
645 print( "Checking if V8 ". $v8Version. " is installed \n");
648 # Check currently installed version
649 # We create a text file with v8 and gcc version in the filename to compare with
650 # Version file is stored as "v8_2.3.4_installed_built_with_gcc_4_8_3.txt"
652 # get the gcc version, so if the compiler is updated v8 is re-built
653 # note: v8 requires gcc version GCC >= 4.6
654 my $gccVersion = `gcc --version | grep ^gcc | sed 's/^.* //g'`;
655 chomp( $gccVersion );
656 my $versionTextFile = $src_path . "/v8_" . $v8Version. "_" . $v8->{"build-mode"} . "_installed_built_with_gcc_". $gccVersion .".txt";
658 # use stat to see if file exists
659 my @install_stats = stat $versionTextFile;
660 if( (scalar(@install_stats)) && $v8->{"force-rebuild"} != 1 )
662 print("Correct V8 version installed\n");
667 # delete older versions of the version file first ( otherwise when downgrading it thinks version is still installed)
668 system( "rm " . $src_path . "/v8_*.txt >/dev/null 2>&1");
673 # Clone the v8 source repository and checkout the version we want
675 # Need to clone it from repo
676 my $v8_source_directory;
680 # newer version of v8 use depot_tools with gclient, git cloned builds do not work
681 if( $v8->{"use_depot_tools"} == 1)
683 install_google_depot_tools( $v8 );
685 # v8 is checkout out under depot_tools path
686 $v8_source_directory = $src_path . "/depot_tools/v8";
690 $v8_source_directory = $src_path . "/v8";
692 # delete the old v8 source directpry if exists
693 rmtree( $v8_source_directory );
695 # clone the repository
696 run_command( "git clone " . $v8->{"repo"} . " " . $v8_source_directory );
699 # change to the source directoy for the checkout
700 chdir( $v8_source_directory );
702 # checkout the version DALi is compatible with
703 run_command( "git checkout ". $v8Version );
706 # Run make dependencies then make for the specific target
708 if( $v8->{"use_depot_tools"} == 1)
710 run_command("gclient sync");
714 run_command("make dependencies");
717 # assemble the make command
718 my $makeCommand = $v8->{"make"};
720 # need to append architecture and build mode, e.g. x64.debug
722 if( $Config{use64bitint} ) {
723 print("Building 64 bit version of V8\n");
724 $buildTarget= "x64." . $v8->{"build-mode"}
727 print("Building 32 bit version of V8\n");
728 $buildTarget= "ia32." . $v8->{"build-mode"}
730 $makeCommand .= " " . $buildTarget;
731 print("Running: $makeCommand\n");
732 run_command( $makeCommand );
735 # Manually install the library / header files
738 # Need to manually install (make install not available on v8 )
739 my $libSourceDir = "$v8_source_directory/out/$buildTarget/lib.target/";
740 my $headerSourceDir = "$v8_source_directory/include/";
742 my $libDestinationDir = $install_path . "/lib/";
743 my $headerDestinationDir = $install_path . "/include/v8/";
745 # delete any current v8 libs
746 system( "rm " . $libDestinationDir . "libv8*");
747 system( "rm " . $libDestinationDir . "libicu*");
750 # copy the library and header files
751 dircopy( $libSourceDir, $libDestinationDir);
752 dircopy( $headerSourceDir, $headerDestinationDir);
755 # Copy libv8.so to libv8.so.version ( e.g. libv8.so.1.2.4)
756 my $v8SoFile = $libDestinationDir . "libv8.so";
757 my $v8SoVersionFile = $libDestinationDir . "libv8.so." . $v8Version;
758 move( $v8SoFile, $v8SoVersionFile );
760 # symlink the libv8.so.1.2.3 to libv8.so
761 symlink( $v8SoVersionFile, $v8SoFile );
762 print( "source dir = " . $libSourceDir . " dest dir ". $libDestinationDir . " \n" );
766 # Create the package file in,
767 # we keep the library files and header files in v8 sub-directories
769 my $fileContents = <<"END";
771 exec_prefix=\${prefix}
772 apiversion=$v8Version
773 libdir=\${exec_prefix}/lib
774 includedir=\${prefix}/include/v8
776 Name: v8 JavaScript engine - runtime library
777 Description: V8 is Google's open source JavaScript engine.
778 Version: \${apiversion}
779 Libs: -L\${libdir} -lv8 -licuuc -licui18n
780 Cflags: -I\${includedir}
783 my $filename = $install_path . "/lib/pkgconfig/" . "v8.pc";
784 print("writing to file ". $filename . "\n");
786 if( open( $fh, '>', $filename ) )
788 print { $fh } $fileContents;
793 die "failed to create " . $filename ."\n";
796 print("Installed V8 " .$v8Version . " OK\n");
802 open( $versionFile, '>', $versionTextFile );
803 close( $versionFile );
804 print("Installing V8 version $v8Version\n");
808 ################################################################################
810 ################################################################################
815 my $new_root = getcwd() . "/dali-env";
817 if($exec_path =~ m!dali-env/opt/bin!)
819 die "Already in a dali-env directory\n";
820 # Could query if user wants to re-create?
822 elsif(-e $root_path && !$opt_force)
824 die "$root_path already exists\n";
826 elsif(-e $new_root && !$opt_force)
828 die "A dali-env directory already exists here\n";
832 system('rm','-rf',"$root_path");
835 check_system_packages();
841 # do this after source directory structure created in create_env
842 check_source_packages();
852 die "$root_path does not exist\n";
856 die "$root_path is not an existing environment\n";
869 dali_env - Create the DALi environment for Ubuntu
873 dali_env [-c] [-s] [-h|-m]
881 Create a DALi environment directory in the current directory.
885 Removes any existing dali-env directory before creating a new one.
889 If run interactively, then writes environment variables to environment file.
890 If non-interactive, then outputs environment to STDOUT.
892 =item B<-e|--envfile> environment-file
894 Set the filename for the environment settings, defaults to "setenv"
896 =item B<-v|--vulkan> [vulkan-option]
898 Install the Vulkan SDK (By default, uses 1.3.280.1) with the optional version
899 number. Adds several .pc files into dali-env/opt/lib/pkg-config directory,
900 and requires a new environment file to be written.
904 Installs the OpenUSD library and its dependencies.
912 Display the manual page
920 Gets the required dependencies for DALi and installs them to a local directory. Can also create a setenv script to point to the installation.