Skip to content

Instantly share code, notes, and snippets.

@martijnvermaat
Created September 7, 2011 21:15
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save martijnvermaat/1201757 to your computer and use it in GitHub Desktop.
Save martijnvermaat/1201757 to your computer and use it in GitHub Desktop.
The GPL in combination with closed source software

The GPL in combination with closed source software

Here are a few issues concerning GPL-licensed software in combination with closed source software. We assume [version 2 of the GPL] 1 in the following discussion.

What exactly is a work "derived from" the Program?

The "viral" clause of the GPL speaks of works "derived from" the Program. This is our main source of confusion in understanding the GPL.

Let's have a look at a few specific cases:

  1. A modified version of the original program.
  2. Code that calls the original program via fork and exec.
  3. Code that is linked with the original program (read: library).

Reading the license text, the first case is clearly a work "derived from" the original program. The second clearly is not.

What about the third? Several interpretations exist, some of them making a difference between static and dynamic linking. See for example [Wikipedia] 3. For The FSF maintains a [FAQ on the GPL] 2, from which it becomes clear that they view any code linking to a GPL-licensed library to be "derived from" that library:

If a library is released under the GPL (not the LGPL), does that mean that any program which uses it has to be under the GPL? Yes, because the program as it is actually run includes the library.

Most of the more specific questions below revolve around this issue.

Is Python code using MySQLdb subject to the GPL?

At first sight, this seems to be just an instance of case three above. The Python code links (dynamically) to the [MySQLdb library] 4 which is GPL-licensed.

However, while most distributions state MySQLdb's license as [being the GPL] 5, the [README file] 6 in the root of its source code states:

GPL or the original license based on Python 1.5.2's license.

So it seems we can choose. Python 1.5.2 was licensed under something close to the MIT license and the header of MySQLdb's _mysql.c file confirms this:

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, or (at your option)
any later version. Alternatively, you may use the original license
reproduced below.

Copyright 1999 by Comstar.net, Inc., Atlanta, GA, US.

                       All Rights Reserved

Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and
that both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Comstar.net, Inc. or
COMSTAR not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

COMSTAR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
NO EVENT SHALL COMSTAR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

(This is taken from the MySQLdb 1.2.3 release tarball, unfortunately I cannot find it in the current Subversion source tree since some restructuring seems to have taken place.)

Case closed, we can just us MySQLdb's original license (Python 1.5.2, or MIT-like) and our Python code is not subject to the GPL.

Except that MySQLdb of course links to [libmysql] 7, a GPL-licensed library, part of the MySQL distribution. Does that mean that MySQLdb's original non-GPL license violates libmysql's GPL license? No, because there's yet another twist in this story.

The libmysql source code contains a file EXCEPTIONS-CLIENT. It starts with:

MySQL FLOSS License Exception

The MySQL AB Exception for Free/Libre and Open Source
Software-only Applications Using MySQL Client Libraries (the
"FLOSS Exception").

Version 0.6, 7 March 2007

Exception Intent

We want specified Free/Libre and Open Source Software ("FLOSS")
applications to be able to use specified GPL-licensed MySQL client
libraries (the "Program") despite the fact that not all FLOSS
licenses are compatible with version 2 of the GNU General Public
License (the "GPL").

The file continues with legal terms and conditions, including a list of FLOSS licenses covered by this exception. The MIT license is in this list, but the Python 1.5.2 license is not explicitely mentioned (note that the included "CNRI Python License" and "Python Software Foundation License 2.1.1" are other licenses).

Let's assume MySQLdb's original non-GPL license is covered by this exception. This would mean we can use MySQLdb under this non-GPL license. But our own Python code by proxy also links to libmysql and thus, depending on the answer to the first question above, is subject to the GPL.

Is PHP code using the PHP MySQL extension subject to the GPL?

See the previous question. This case is a bit simpler, because PHP is not dual-licensed (like MySQLdb is) and its license (the [PHP License] 8), is explicitely mentioned in libmysql's EXCEPTIONS-CLIENT file. Note that PHP's MySQL extension of course links to libmysql.

Is code interfacing with a MySQL server via TCP subject to the GPL?

MySQL server is GPL software. For this question, assume the code is not subject to the GPL due to linking with a GPL library (this case is covered by the previous two questions).

The question here is how intricate communication by exchanging SQL statements and MySQL result sets over TCP must be considered. This is not covered by the second case of the first question above (using fork and exec to communicate). However, one might say it is covered by the following description from the GPL FAQ:

If the program dynamically links plug-ins, and they make function calls to each other and share data structures, we believe they form a single program, which must be treated as an extension of both the main program and the plug-ins. This means the plug-ins must be released under the GPL or a GPL-compatible free software license, and that the terms of the GPL must be followed when those plug-ins are distributed.

Can GPL software and closed source software be distributed on one CD?

The GPL seems to be quite clear on this:

[...] mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.

Do the answers to the above questions change for version 3 of the GPL?

We have not studied the [GPL 3] 9, but think both versions are pretty much interchangeable on these points.

@martijnvermaat
Copy link
Author

Now that there is MySQL Native Driver (part of the PHP source code), this problem seems to be solved for PHP applications (they can no longer be considered a derived work from libmysql since they can function without it).

It looks like something similar was done for Python with MySQL Connector/Python. However, it kind of misses the point since it is GPL-licensed.

See also Monty's Licensing FAQ.

@martijnvermaat
Copy link
Author

Another solution for Python would be to use a client based on libdrizzle, which is BSD-licensed and aims to be MySQL-compatible.

My current findings are not satisfactory. With MySQL server 5.1.41-3ubuntu12, libdrizzle 0.7-1 and python-libdrizzle 0.08.2 on Ubuntu 10.04 I can connect but not retrieve data:

>>> from drizzle import db
>>> connection = db.connect(host='localhost', username='mutalyzer', password='', port=3306, database='hg19')
>>> cursor = connection.cursor()
>>> cursor.execute('show tables;')
>>> cursor.fetchone()
(<read-only buffer for 0x22f81e0, size -1, offset 0 at 0x22da7f0>,)

Where we should get a readable table name in a string.

Also, to be able to connect with a username at all, I had to uncomment

#self._drizzle_connection.set_auth(self.username, self.password)

on line 81 in db.py (from python-libdrizzle).

@martijnvermaat
Copy link
Author

Also, the Python MySQLdb library implements PEP 249 (Python Database API Specification v2.0), so I'm quite confident we can use another library only be changing the

import MySQLdb

line. I assume this will work at least with python-libdrizzle connecting to a Drizzle server. Depending on the MySQL-specificity of our queries, it will also easily work with other database systems. For example, the psycopg2 library implements PEP 249 and connects to a PostgreSQL server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment