[legal] Add licence.pl and %.licence make target
authorMichael Brown <mcb30@etherboot.org>
Wed, 29 Apr 2009 07:51:27 +0000 (08:51 +0100)
committerMichael Brown <mcb30@etherboot.org>
Mon, 18 May 2009 07:29:24 +0000 (08:29 +0100)
It is now possible to run e.g.

  make bin/rtl8139.dsk.licence

in order to see a licensing assessment for any given gPXE build.  The
assessment will either produce a single overall licence for the build
(based on combining all the licences used within the source files for
that build), or will exit with an error stating why a licence
assessment is not possible (for example, if there are files involved
that do not yet contain an explicit FILE_LICENCE() declaration).

src/Makefile
src/Makefile.housekeeping
src/util/licence.pl [new file with mode: 0755]

index 4e4fd8b..add582a 100644 (file)
@@ -36,6 +36,7 @@ MAKEROM               := $(PERL) ./util/makerom.pl
 SYMCHECK       := $(PERL) ./util/symcheck.pl
 SORTOBJDUMP    := $(PERL) ./util/sortobjdump.pl
 PADIMG         := $(PERL) ./util/padimg.pl
+LICENCE                := $(PERL) ./util/licence.pl
 NRV2B          := ./util/nrv2b
 ZBIN           := ./util/zbin
 ELF2EFI32      := ./util/elf2efi32
index 4502017..e886c4b 100644 (file)
@@ -672,13 +672,31 @@ $(BIN)/%.deps : $(BIN)/%.tmp
 # Get unneeded source files for the specified target
 #
 define nodeps_list
-       $(sort $(filter-out $(call deps_list,$<),\
+       $(sort $(filter-out $(call deps_list,$(1)),\
                 $(foreach BOBJ,$(BOBJS),\
                   $($(basename $(notdir $(BOBJ)))_DEPS))))
 endef
 $(BIN)/%.nodeps : $(BIN)/%.tmp
        $(Q)$(ECHO) $(call nodeps_list,$<)
 
+# Get licensing verdict for the specified target
+#
+define unlicensed_deps_list
+       $(shell grep -L FILE_LICENCE $(call deps_list,$(1)))
+endef
+define licence_list
+       $(patsubst __licence_%,%,\
+         $(filter __licence_%,$(shell $(NM) $(1) | cut -d" " -f3)))
+endef
+$(BIN)/%.licence : $(BIN)/%.tmp
+       $(QM)$(ECHO) "  [LICENCE] $@"
+       $(Q)$(if $(strip $(call unlicensed_deps_list,$<)),\
+               echo -n "Unable to determine licence because the following " ;\
+               echo "files are missing a licence declaration:" ;\
+               echo $(call unlicensed_deps_list,$<);\
+               exit 1,\
+               $(LICENCE) $(call licence_list,$<))
+
 # Extract compression information from intermediate object file
 #
 $(BIN)/%.zinfo : $(BIN)/%.tmp
diff --git a/src/util/licence.pl b/src/util/licence.pl
new file mode 100755 (executable)
index 0000000..aca6718
--- /dev/null
@@ -0,0 +1,124 @@
+#!/usr/bin/perl -w
+#
+# Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+use strict;
+use warnings;
+use Getopt::Long;
+
+# List of licences we can handle
+my $known_licences = {
+  gpl_any => {
+    desc => "GPL (any version)",
+    can_subsume => {
+      public_domain => 1,
+      bsd3 => 1,
+      bsd2 => 1,
+    },
+  },
+  gpl2_or_later => {
+    desc => "GPL version 2 (or, at your option, any later version)",
+    can_subsume => {
+      gpl_any => 1,
+      public_domain => 1,
+      bsd3 => 1,
+      bsd2 => 1,
+    },
+  },
+  gpl2_only => {
+    desc => "GPL version 2 only",
+    can_subsume => {
+      gpl_any => 1,
+      gpl2_or_later => 1,
+      public_domain => 1,
+      bsd3 => 1,
+      bsd2 => 1,
+    },
+  },
+  public_domain => {
+    desc => "Public Domain",
+    can_subsume => {},
+  },
+  bsd4 => {
+    desc => "BSD Licence (with advertising clause)",
+    can_subsume => {
+      public_domain => 1,
+      bsd3 => 1,
+      bsd2 => 1,
+    },
+  },
+  bsd3 => {
+    desc => "BSD Licence (without advertising clause)",
+    can_subsume => {
+      public_domain => 1,
+      bsd2 => 1,
+    },
+  },
+  bsd2 => {
+    desc => "BSD Licence (without advertising or endorsement clauses)",
+    can_subsume => {
+      public_domain => 1,
+    },
+  },
+};
+
+# Parse command-line options
+my $verbosity = 1;
+Getopt::Long::Configure ( 'bundling', 'auto_abbrev' );
+GetOptions (
+  'verbose|v+' => sub { $verbosity++; },
+  'quiet|q+' => sub { $verbosity--; },
+) or die "Could not parse command-line options\n";
+
+# Parse licence list from command line
+my $licences = {};
+foreach my $licence ( @ARGV ) {
+  die "Unknown licence \"$licence\"\n"
+      unless exists $known_licences->{$licence};
+  $licences->{$licence} = $known_licences->{$licence};
+}
+die "No licences specified\n" unless %$licences;
+
+# Dump licence list
+if ( $verbosity >= 1 ) {
+  print "The following licences appear within this file:\n";
+  foreach my $licence ( keys %$licences ) {
+    print "  ".$licences->{$licence}->{desc}."\n"
+  }
+}
+
+# Apply licence compatibilities to reduce to a single resulting licence
+foreach my $licence ( keys %$licences ) {
+  # Skip already-deleted licences
+  next unless exists $licences->{$licence};
+  # Subsume any subsumable licences
+  foreach my $can_subsume ( keys %{$licences->{$licence}->{can_subsume}} ) {
+    if ( exists $licences->{$can_subsume} ) {
+      print $licences->{$licence}->{desc}." subsumes ".
+         $licences->{$can_subsume}->{desc}."\n"
+         if $verbosity >= 1;
+      delete $licences->{$can_subsume};
+    }
+  }
+}
+
+# Print resulting licence
+die "Cannot reduce to a single resulting licence!\n"
+    if ( keys %$licences ) != 1;
+( my $licence ) = keys %$licences;
+print "The overall licence for this file is:\n  " if $verbosity >= 1;
+print $licences->{$licence}->{desc}."\n";