Add the tar.bz2 archive
[dvb-osmc.git] / build
blobd67f37cbdd98307ae09ccf9850f727eddbca1a86
1 #!/usr/bin/perl
2 use strict;
3 use Getopt::Long;
4 use Pod::Usage;
6 #####################
7 # Parameters handling
8 #####################
10 my $level = 0;
11 my $help = 0;
12 my $man = 0;
13 my $check_only = 0;
14 my $main_git = 0;
15 my @git;
17 my $main_git_url = "git://linuxtv.org/media_tree.git";
18 my $main_branch = "master";
19 my $firmware_url = "http://www.linuxtv.org/downloads/firmware/";
20 my $firmware_tarball = "dvb-firmwares.tar.bz2";
22 GetOptions('v|verbose' => \$level,
23 'help|?' => \$help,
24 man => \$man,
25 'check_only|check-only' => \$check_only,
26 'main_git|main-git' => \$main_git,
27 'git=s{2}' => \@git,
28 ) or pod2usage(2);
29 pod2usage(1) if $help;
30 pod2usage(-exitstatus => 0, -verbose => 2) if $man;
32 #############
33 # Static vars
34 #############
36 my @missing;
37 my $system_release;
39 ##################################################
40 # Subroutines used at the check missing deps logic
41 ##################################################
43 sub catcheck($)
45 my $res = "";
46 $res = qx(cat $_[0]) if (-r $_[0]);
47 return $res;
50 sub give_redhat_hints()
52 my $install;
54 my %map = (
55 "wget" => "wget",
56 "lsdiff" => "patchutils",
57 "Digest::SHA" => "perl-Digest-SHA",
58 "Proc::ProcessTable" => "perl-Proc-ProcessTable",
61 foreach my $prog (@missing) {
62 print "ERROR: please install \"$prog\", otherwise, build won't work.\n";
63 if (defined($map{$prog})) {
64 $install .= " " . $map{$prog};
65 } else {
66 $install .= " " . $prog;
70 printf("You should run:\n\tyum install -y $install\n");
73 sub give_ubuntu_hints()
75 my $install;
77 my %map = (
78 "lsdiff" => "patchutils",
79 "Digest::SHA" => "libdigest-sha1-perl",
80 "Proc::ProcessTable" => "libproc-processtable-perl",
83 foreach my $prog (@missing) {
84 print "ERROR: please install \"$prog\", otherwise, build won't work.\n";
85 if (defined($map{$prog})) {
86 $install .= " " . $map{$prog};
87 } else {
88 $install .= " " . $prog;
92 printf("You should run:\n\tsudo apt-get install $install\n");
95 sub give_opensuse_hints()
97 my $install;
99 my %map = (
100 "lsdiff" => "patchutils",
101 "Digest::SHA" => "perl-Digest-SHA1",
102 "Proc::ProcessTable" => "perl-Proc-ProcessTable",
105 my $need_perl_repo = 0;
107 foreach my $prog (@missing) {
108 print "ERROR: please install \"$prog\", otherwise, build won't work.\n";
109 if (defined($map{$prog})) {
110 $install .= " " . $map{$prog};
111 } else {
112 $install .= " " . $prog;
114 if ($prog eq "Proc::ProcessTable") {
115 $need_perl_repo = 1;
119 printf("You should run:\n\tsudo zypper install $install\n");
121 if ($need_perl_repo) {
122 printf("\nThe Proc::ProcessTable perl module can be found in the perl buildservice repository. ");
123 printf("Add with the command (replacing 12.1 with your openSUSE release version):\n");
124 printf("\tsudo zypper ar http://download.opensuse.org/repositories/devel:/languages:/perl/openSUSE_12.1/ perl\n");
128 sub give_arch_linux_hints()
130 my $install;
132 my %map = (
133 "lsdiff" => "community/patchutils",
134 "Digest::SHA" => "extra/perl-digest-sha1",
135 "Proc::ProcessTable" => "aur/perl-proc-processtable",
138 foreach my $prog (@missing) {
139 print "ERROR: please install \"$prog\", otherwise, build won't work.\n";
140 if (defined($map{$prog})) {
141 $install .= " " . $map{$prog};
142 } else {
143 $install .= " " . $prog;
147 printf("You should install those package(s) (repository/package): $install\n");
150 sub give_gentoo_hints()
152 my $install;
154 my %map = (
155 "lsdiff" => "dev-util/patchutils",
156 "Digest::SHA" => "dev-perl/Digest-SHA1",
157 "Proc::ProcessTable" => "dev-perl/Proc-ProcessTable",
160 foreach my $prog (@missing) {
161 print "ERROR: please install \"$prog\", otherwise, build won't work.\n";
162 if (defined($map{$prog})) {
163 $install .= " " . $map{$prog};
164 } else {
165 $install .= " " . $prog;
169 printf("You should emerge those package(s): $install\n");
172 sub give_hints()
175 # Distro-specific hints
176 if ($system_release =~ /Red Hat Enterprise Linux/) {
177 give_redhat_hints;
178 return;
180 if ($system_release =~ /Fedora/) {
181 give_redhat_hints;
182 return;
184 if ($system_release =~ /Ubuntu/) {
185 give_ubuntu_hints;
186 return;
188 if ($system_release =~ /openSUSE/) {
189 give_opensuse_hints;
190 return;
192 if ($system_release =~ /Arch Linux/) {
193 give_arch_linux_hints;
194 return;
196 if ($system_release =~ /Debian/) {
197 give_ubuntu_hints;
198 return;
200 if ($system_release =~ /Gentoo/) {
201 give_gentoo_hints;
202 return;
204 # Fall-back to generic hint code
205 foreach my $prog (@missing) {
206 print "ERROR: please install \"$prog\", otherwise, build won't work.\n";
208 print "I don't know distro $system_release. So, I can't provide you a hint with the package names.\n";
209 print "Be welcome to contribute with a patch for media-build, by submitting a distro-specific hint\n";
210 print "to linux-media\@vger.kernel.org\n";
213 my $need = 0;
214 sub findprog($)
216 foreach(split(/:/, $ENV{PATH})) {
217 return "$_/$_[0]" if(-x "$_/$_[0]");
221 sub need_program($)
223 my $prog = shift;
225 return if findprog($prog);
227 push @missing, $prog;
229 $need++;
232 sub need_perl_module($)
234 my $prog = shift;
236 my $err = system("perl -M$prog -e 1 2>/dev/null /dev/null");
237 return if ($err == 0);
239 push @missing, $prog;
241 $need++;
244 sub check_needs()
246 if ($system_release) {
247 print "Checking if the needed tools for $system_release are available\n";
248 } else {
249 print "Checking if the needed tools are present\n";
252 # Check for needed programs/tools
253 need_program "git";
254 need_program "make";
255 need_program "gcc";
256 need_program "patch";
257 need_program "lsdiff";
258 need_program "wget";
260 # Check for needed perl modules
261 need_perl_module "Digest::SHA";
262 need_perl_module "Proc::ProcessTable";
264 give_hints if ($need);
266 die "Build can't procceed as $need dependency is missing" if ($need == 1);
267 die "Build can't procceed as $need dependencies are missing" if ($need);
269 print "Needed package dependencies are met.\n";
272 ######
273 # Git
274 ######
276 sub get_remote_name()
278 if ($git[0] =~ m,^(http|git|git\+ssh|ssh):\/\/linuxtv.org\/(.*),) {
279 my $name = $2;
280 $name =~ s,^/git,,;
281 $name =~ s,\.git$,,g;
282 $name =~ s,/,_,g;
284 return ($name, 0);
286 if (!($git[0] =~ m,^(http|git|git\+ssh|ssh):\/\/,)) {
287 my $name = $git[0];
288 $name =~ s,\s*$,,;
289 $name =~ s,/$,,;
290 $name =~ s,/,_,g;
292 return ($name, 1);
294 die "Invalid URL. Need to use one from linuxtv.org site or a local one\n";
297 sub check_git($$)
299 my $cmd = shift;
300 my $remote = shift;
302 print "\$ git --git-dir media/.git $cmd\n" if ($level);
303 open IN, "git --git-dir media/.git $cmd|" or die "can't run git --git-dir media/.git $cmd";
304 while (<IN>) {
305 return 1 if (m/^[\*]*\s*($remote)\n$/);
307 close IN;
308 return 0;
311 ####################
312 # Other aux routines
313 ####################
314 sub license ()
316 print "************************************************************\n";
317 print "* All drivers and build system are under GPLv2 License *\n";
318 print "* Firmware files are under the license terms found at: *\n";
319 printf "* %-56s *\n", $firmware_url;
320 print "* Please abort in the next 5 secs if you don't agree with *\n";
321 print "* the license *\n";
322 print "************************************************************\n";
323 print "\n";
324 sleep 5;
325 print "Not aborted. It means that the licence was agreed. Proceeding...\n\n";
328 sub which($)
330 my $file = shift;
331 my @path = split ":", $ENV{PATH};
333 foreach my $dir(@path) {
334 my $name = $dir.'/'.$file;
335 return $name if (-x $name );
337 return undef;
340 ######
341 # Main
342 ######
344 # Determine the system type. There's no standard unique way that would
345 # work with all distros with a minimal package install. So, several
346 # methods are used here.
348 # By default, it will use lsb_release function. If not available, it will
349 # fail back to reading the known different places where the distro name
350 # is stored
352 $system_release = qx(lsb_release -d) if which("lsb_release");
353 $system_release =~ s/Description:\s*// if ($system_release);
354 $system_release = catcheck("/etc/system-release") if !$system_release;
355 $system_release = catcheck("/etc/redhat-release") if !$system_release;
356 $system_release = catcheck("/etc/lsb-release") if !$system_release;
357 $system_release = catcheck("/etc/gentoo-release") if !$system_release;
358 $system_release = catcheck("/etc/issue") if !$system_release;
359 $system_release =~ s/\s+$//;
361 check_needs;
363 exit (0) if ($check_only);
365 if ($main_git) {
366 $git[0] = $main_git_url;
367 $git[1] = $main_branch;
370 if (@git == 2) {
371 my $name;
372 my $workdir;
374 my ($rname,$local) = get_remote_name();
376 if ($local) {
377 $name = "l_" . $rname;
378 } else {
379 $name = "r_" . $rname;
382 if ($git[0] ne $main_git_url) {
383 print "\n";
384 print "************************************************************\n";
385 print "* WARNING: This script will use a git tree as reference for*\n";
386 print "* the media drivers. This build system takes into accont *\n";
387 print "* only the main repository, and the latest staging branch. *\n";
388 print "* Trying to compile an old experimental tree will likely *\n";
389 print "* fail, as the backport patches may not fit on the needs *\n";
390 print "************************************************************\n";
391 print "\n";
392 $workdir = qx(which git-new-workdir);
393 } else {
394 print "************************************************************\n";
395 printf "* building %-38s git tree *\n", $git[0];
396 print "************************************************************\n";
398 license;
400 if (!stat "./media/.git/config") {
401 if (!$local) {
402 print "Getting the latest Kernel tree. This will take some time\n";
403 system("git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git media") == 0
404 or die "Can't clone from the upstream tree";
405 system('git --git-dir media/.git config format.cc "Linux Media Mailing List <linux-media@vger.kernel.org>"');
406 system('git --git-dir media/.git config format.signoff true');
407 system('git --git-dir media/.git config format.numbered auto');
408 system('git --git-dir media/.git config sendemail.chainreplyto false');
409 } else {
410 if ($workdir ne "") {
411 print "Creating a new workdir from $git[0] at media\n";
412 system("git new-workdir $git[0] media") == 0
413 or die "Can't create a new workdir";
414 } else {
415 print "Creating a new clone\n";
416 system("git clone -l $git[0] media") == 0
417 or die "Can't create a new clone";
420 } elsif ($workdir eq "") {
421 system("git --git-dir media/.git remote update origin") == 0
422 or die "Can't update from the upstream tree";
425 if ($workdir eq "") {
426 if (!check_git("remote", "$name")) {
427 print "adding remote $name to track $git[0]\n";
428 printf "\$ git --git-dir media/.git remote add $name $git[0]\n" if ($level);
429 system ("git --git-dir media/.git remote add $name $git[0]") == 0
430 or die "Can't create remote $name";
432 print "updating remote $rname\n";
433 system ("git --git-dir media/.git remote update $name") == 0
434 or die "Can't update remote $name";
435 print "creating a local branch $rname\n";
436 if (!check_git("branch", "$rname/$git[1]")) {
437 print "\$ (cd media; git checkout -b $rname/$git[1] remotes/$name/$git[1])\n" if ($level);
438 system ("(cd media; git checkout -b $rname/$git[1] remotes/$name/$git[1])") == 0
439 or die "Can't create local branch $rname";
440 } else {
441 system ("(cd media; git checkout $rname/$git[1])") == 0
442 or die "Can't checkout to branch $rname";
443 system ("(cd media; git pull . remotes/$name/$git[1])") == 0
444 or die "Can't update local branch $name";
446 } else {
447 print "git checkout $git[1]\n";
448 system ("(cd media; git checkout $git[1])") == 0
449 or die "Can't checkout $git[1]";
453 system ("make -C linux dir DIR=../media/") == 0
454 or die "Can't link the building system to the media directory.";
455 } else {
456 print "\n";
457 print "************************************************************\n";
458 print "* This script will download the latest tarball and build it*\n";
459 print "* Assuming that your kernel is compatible with the latest *\n";
460 print "* drivers. If not, you'll need to add some extra backports,*\n";
461 print "* ./backports/<kernel> directory. *\n";
462 print "* It will also update this tree to be sure that all compat *\n";
463 print "* bits are there, to avoid compilation failures *\n";
464 print "************************************************************\n";
465 license;
467 print "****************************\n";
468 print "Updating the building system\n";
469 print "****************************\n";
470 system("git pull git://linuxtv.org/media_build.git master");
472 system ("make -C linux/ download") == 0 or die "Download failed";
473 system ("make -C linux/ untar") == 0 or die "Untar failed";
476 print "**********************************************************\n";
477 print "* Downloading firmwares from linuxtv.org. *\n";
478 print "**********************************************************\n";
480 if (!stat $firmware_tarball) {
481 system ("wget $firmware_url/$firmware_tarball -O $firmware_tarball") == 0 or die "Can't download $firmware_tarball";
483 system ("(cd v4l/firmware/; tar xvfj ../../$firmware_tarball)") == 0 or die "Can't extract $firmware_tarball";
486 print "******************\n";
487 print "* Start building *\n";
488 print "******************\n";
490 system ("make allyesconfig") == 0 or die "can't select all drivers";
491 system ("make") == 0 or die "build failed";
493 print "**********************************************************\n";
494 print "* Compilation finished. Use 'make install' to install them\n";
495 print "**********************************************************\n";
498 __END__
500 =head1 NAME
502 build - Builds the media drivers without needing to compile a new kernel
504 =head1 SYNOPSIS
506 build [--help] [--man] [--verbose] [--check-only] [<--git> [URL] [BRANCH]]
507 [--main-git]
509 =head1 OPTIONS
511 =over 8
513 =item B<--help>
515 Print a brief help message and exits.
517 =item B<--man>
519 Prints the manual page and exits.
521 =item B<--verbose>
523 Be more verbose.
525 =item B<--check-only>
527 Don't do anything, except for checking if the needed dependencies are there.
529 =item B<--git> [URL] [BRANCH]
531 Allows specifying a URL and a git branch, instead of the default ones.
532 Currently, only linuxtv.org git URL's are supported, as the build needs to
533 warrant an unique namespace for git remotes.
535 =item B<--main-git>
537 Use the main development git tree, as found at
538 L<http://git.linuxtv.org/media_tree.git>.
540 =back
542 =head1 DESCRIPTION
544 B<build> will download and compile the latest drivers from linuxtv.org,
545 allowing testing them before reaching the upstream kernels.
547 This is an experimental build system for media drivers.
548 All files on this tree are covered by GPLv2, as stated at COPYING file.
550 Usage:
552 Just call the build utility:
554 =over 8
556 ~/media_build $ B<./build>
558 =back
560 Then, install the drivers as root, with:
562 =over 8
564 ~/media_build # B<make install>
566 =back
568 In order to test, unload old drivers with:
570 =over 8
572 ~/media_build # B<make rmmod>
574 =back
576 Then modprobe the driver you want to test. For example, to load driver B<foo>:
578 =over 8
580 ~/media_build # B<modprobe foo>
582 =back
584 If you're developing a new driver or patch, it is better to use:
586 =over 8
588 ~/media_build $ B<./build --main-git>
590 =back
592 Then, install the drivers as root, with:
594 =over 8
596 ~/media_build # B<make install>
598 =back
600 In order to test, unload old drivers with:
602 =over 8
604 ~/media_build # B<make rmmod>
606 =back
608 Then modprobe the driver you want to test:
610 =over 8
612 ~/media_build # B<modprobe foo>
614 =back
616 In this case, in order to modify something, you should edit the file at
617 the media/ subdir.
619 For example, a typical procedure to develop a new patch would be:
621 =over 8
623 ~/media_build $ B<cd media>
625 ~/media $ B<gedit drivers/media/video/foo.c>
627 ~/media $ B<make -C ../v4l>
629 ~/media $ B<make -C .. rmmod>
631 ~/media $ B<modprobe foo>
633 (some procedure to test the "foo" driver)
635 ~/media $ B<git diff >/tmp/my_changes.patch>
637 (email /tmp/my_changes.patch inlined to <linux-media@vger.kernel.org>)
639 =back
641 =head1 BUGS
643 Report bugs to <linux-media@vger.kernel.org>
645 =head1 COPYRIGHT
647 Copyright (c) 2011 by Mauro Carvalho Chehab.
649 License GPLv2: GNU GPL version 2 L<http://gnu.org/licenses/gpl.html>.
651 This is free software: you are free to change and redistribute it.
652 There is NO WARRANTY, to the extent permitted by law.
654 =cut