Files
media_build/build
Mauro Carvalho Chehab 2ef208defa build: Add an option for developing new stuff against upstream
This may help new developers to use the media_build.git tree.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
2011-08-02 16:59:12 -03:00

458 lines
10 KiB
Perl
Executable File

#!/usr/bin/perl
use strict;
use Getopt::Long;
use Pod::Usage;
#####################
# Parameters handling
#####################
my $level = 0;
my $help = 0;
my $man = 0;
my $check_only = 0;
my $main_git = 0;
my @git;
my $main_git_url = "git://linuxtv.org/media_tree.git";
my $main_branch = "staging/for_v3.2";
GetOptions('v|verbose' => \$level,
'help|?' => \$help,
man => \$man,
'check_only|check-only' => \$check_only,
'main_git|main-git' => \$main_git,
'git=s{2}' => \@git,
) or pod2usage(2);
pod2usage(1) if $help;
pod2usage(-exitstatus => 0, -verbose => 2) if $man;
########################
# Check for missing deps
########################
my @missing;
my $system_release = catcheck("/etc/system-release");
$system_release = catcheck("/etc/redhat-release") if !$system_release;
$system_release = catcheck("/etc/lsb-release") if !$system_release;
sub catcheck($)
{
my $res = "";
$res = qx(cat $_[0]) if (-r $_[0]);
return $res;
}
sub give_redhat_hints()
{
my $install;
my %map = (
"lsdiff" => "patchutils",
"Digest::SHA1" => "perl-Digest-SHA1",
"Proc::ProcessTable" => "perl-Proc-ProcessTable",
);
foreach my $prog (@missing) {
print "ERROR: please install \"$prog\", otherwise, build won't work.\n";
if (defined($map{$prog})) {
$install .= " " . $map{$prog};
} else {
$install .= " " . $prog;
}
}
printf("You should run:\n\tyum install -y $install\n");
}
sub give_ubuntu_hints()
{
my $install;
my %map = (
"lsdiff" => "patchutils",
"Digest::SHA1" => "libdigest-sha1-perl",
"Proc::ProcessTable" => "libproc-processtable-perl",
);
foreach my $prog (@missing) {
print "ERROR: please install \"$prog\", otherwise, build won't work.\n";
if (defined($map{$prog})) {
$install .= " " . $map{$prog};
} else {
$install .= " " . $prog;
}
}
printf("You should run:\n\tsudo apt-get install $install\n");
}
sub give_hints()
{
# Distro-specific hints
if ($system_release =~ /Red Hat Enterprise Linux Workstation/) {
give_redhat_hints;
return;
}
if ($system_release =~ /Fedora/) {
give_redhat_hints;
return;
}
if ($system_release =~ /Ubuntu/) {
give_ubuntu_hints;
return;
}
# Fall-back to generic hint code
foreach my $prog (@missing) {
print "ERROR: please install \"$prog\", otherwise, build won't work.\n";
}
print "I don't know distro $system_release. So, I can't provide you a hint with the package names.\n";
print "Be welcome to contribute with a patch for media-build, by submitting a distro-specific hint\n";
print "to linux-media\@vger.kernel.org\n";
}
my $need = 0;
sub findprog($)
{
foreach(split(/:/, $ENV{PATH})) {
return "$_/$_[0]" if(-x "$_/$_[0]");
}
}
sub need_program($)
{
my $prog = shift;
return if findprog($prog);
push @missing, $prog;
$need++;
}
sub need_perl_module($)
{
my $prog = shift;
my $err = system("perl -M$prog -e 1 2>/dev/null /dev/null");
return if ($err == 0);
push @missing, $prog;
$need++;
}
sub check_needs()
{
print "Checking if the needed tools are present:\n";
# Check for needed programs/tools
need_program "git";
need_program "make";
need_program "gcc";
need_program "patch";
need_program "lsdiff";
# Check for needed perl modules
need_perl_module "Digest::SHA1";
need_perl_module "Proc::ProcessTable";
give_hints if ($need);
die "Build can't procceed as $need dependency is missing" if ($need == 1);
die "Build can't procceed as $need dependencies are missing" if ($need);
print "Needed package dependencies are met.\n";
}
######
# Git
######
sub get_remote_name()
{
if ($git[0] =~ m,^(http|git|git\+ssh|ssh):\/\/linuxtv.org\/(.*),) {
my $name = $2;
$name =~ s,^/git,,;
$name =~ s,\.git$,,g;
$name =~ s,/,_,g;
return $name;
}
die "Invalid URL. Need to use one from linuxtv.org site\n";
}
sub check_git($$)
{
my $cmd = shift;
my $remote = shift;
print "\$ git --git-dir media/.git $cmd\n" if ($level);
open IN, "git --git-dir media/.git $cmd|" or die "can't run git --git-dir media/.git $cmd";
while (<IN>) {
return 1 if (m/^[\*]*\s*($remote)\n$/);
}
close IN;
return 0;
}
######
# Main
######
check_needs;
exit (0) if ($check_only);
if ($main_git) {
$git[0] = $main_git_url;
$git[1] = $main_branch;
}
if (@git == 2) {
my $rname = get_remote_name();
if ($git[0] ne $main_git_url) {
print "\n";
print "**************************************************************\n";
print "* WARNING: This script will use a git tree as the reference *\n";
print "* for the media drivers. This build system takes into accont *\n";
print "* only the main repository, and the latest staging branch. *\n";
print "* Trying to compile an old experimental tree will likely *\n";
print "* fail, as the backport patches may not fit on the needs *\n";
print "**************************************************************\n";
print "\n";
} else {
print "**************************************************************\n";
printf "* building %-40s git tree *\n", $git[0];
print "**************************************************************\n";
}
sleep 3;
if (!stat "./media/.git/config") {
print "Getting the latest Kernel tree. This will take some time\n";
system("git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git media") == 0
or die "Can't clone from the upstream tree";
} else {
system("git --git-dir media/.git remote update origin") == 0
or die "Can't update from the upstream tree";
}
if (!check_git("remote", "r_$rname")) {
print "adding remote r_$rname to track $git[0], $git[1]\n";
printf "\$ git --git-dir media/.git remote add r_$rname $git[0] $git[1]\n" if ($level);
system ("git --git-dir media/.git remote add r_$rname $git[0] $git[1]") == 0
or die "Can't create remote r_$rname";
}
print "updating remote $rname\n";
system ("git --git-dir media/.git remote update r_$rname") == 0
or die "Can't update remote r_$rname";
print "creating a local branch $rname\n";
if (!check_git("branch", "$rname/$git[1]")) {
print "\$ (cd media; git checkout -b $rname/$git[1] remotes/r_$rname/$git[1])\n" if ($level);
system ("(cd media; git checkout -b $rname/$git[1] remotes/r_$rname/$git[1])") == 0
or die "Can't create local branch $rname";
} else {
system ("(cd media; git checkout $rname/$git[1])") == 0
or die "Can't checkout to branch $rname";
system ("(cd media; git pull . remotes/r_$rname/$git[1])") == 0
or die "Can't update local branch $rname";
}
system ("make -C linux dir DIR=../media/") == 0
or die "Can't link the building system to the media directory.";
} else {
print "\n";
print "************************************************************\n";
print "* This script will download the latest tarball and build it*\n";
print "* Assuming that your kernel is compatible with the latest *\n";
print "* drivers. If not, you'll need to add some extra backports,*\n";
print "* ./backports/<kernel> directory. *\n";
print "* It will also update this tree to be sure that all compat *\n";
print "* bits are there, to avoid compilation failures *\n";
print "************************************************************\n";
print "\n";
sleep 5;
print "****************************\n";
print "Updating the building system\n";
print "****************************\n";
system("git pull git://linuxtv.org/media_build.git master");
system ("make -C linux/ download") == 0 or die "Download failed";
system ("make -C linux/ untar") == 0 or die "Untar failed";
}
system ("make allyesconfig") == 0 or die "can't select all drivers";
system ("make") == 0 or die "build failed";
print "**********************************************************\n";
print "* Compilation finished. Use 'make install' to install them\n";
print "**********************************************************\n";
__END__
=head1 NAME
build - Builds the media drivers without needing to compile a new kernel
=head1 SYNOPSIS
build [--help] [--man] [--verbose] [--check-only] [<--git> [URL] [BRANCH]]
[--main-git]
=head1 OPTIONS
=over 8
=item B<--help>
Print a brief help message and exits.
=item B<--man>
Prints the manual page and exits.
=item B<--verbose>
Be more verbose.
=item B<--check-only>
Don't do anything, except for checking if the needed dependencies are there.
=item B<--git> [URL] [BRANCH]
Allows specifying a URL and a git branch, instead of the default ones.
Currently, only linuxtv.org git URL's are supported, as the build needs to
warrant an unique namespace for git remotes.
=item B<--main-git>
Use the main development git tree, as found at
L<http://git.linuxtv.org/media_tree.git>.
=back
=head1 DESCRIPTION
B<build> will download and compile the latest drivers from linuxtv.org,
allowing testing them before reaching the upstream kernels.
This is an experimental build system for media drivers.
All files on this tree are covered by GPLv2, as stated at COPYING file.
Usage:
Just call the build utility:
=over 8
~/media_build $ B<./build>
=back
Then, install the drivers as root, with:
=over 8
~/media_build # B<make install>
=back
In order to test, unload old drivers with:
=over 8
~/media_build # B<make rmmod>
=back
Then modprobe the driver you want to test. For example, to load driver B<foo>:
=over 8
~/media_build # B<modprobe foo>
=back
If you're developing a new driver or patch, it is better to use:
=over 8
~/media_build $ B<./build --main-git>
=back
Then, install the drivers as root, with:
=over 8
~/media_build # B<make install>
=back
In order to test, unload old drivers with:
=over 8
~/media_build # B<make rmmod>
=back
Then modprobe the driver you want to test:
=over 8
~/media_build # B<modprobe foo>
=back
In this case, in order to modify something, you should edit the file at
the media/ subdir.
For example, a typical procedure to develop a new patch would be:
=over 8
~/media_build $ B<cd media>
~/media $ B<gedit drivers/media/video/foo.c>
~/media $ B<make -C ../v4l>
~/media $ B<make -C .. rmmod>
~/media $ B<modprobe foo>
(some procedure to test the "foo" driver)
~/media $ B<git diff >/tmp/my_changes.patch>
(email /tmp/my_changes.patch inlined to <linux-media@vger.kernel.org>)
=back
=head1 BUGS
Report bugs to <linux-media@vger.kernel.org>
=head1 COPYRIGHT
Copyright (c) 2011 by Mauro Carvalho Chehab <mchehab@redhat.com>.
License GPLv2: GNU GPL version 2 L<http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
=cut