10

I am developing a commerical clock application ("JJClock"), which is written in Python. What I will deliver to my customers will either be a .pyc file or a .so file ("compiled") with Cython -- the fact that a .pyc is reversible doesn't matter, just that I am not giving my customers the source code.

My clock application has a dedicated "backend" that allows me to use two, alternative "get time" libraries: gplclock (GPL licensed) and mitclock (MIT licensed). The core code of JJClock is completely agnostic to which time library is being used (this is controlled via an environment variable).

For example, here is something that looks like my main application:

# jjclock.py

import sys
import clock_api

if __name__ == "__main__":
    clock = clock_api.get_clock()
    time_now = clock.time()
    #
    # do something propetary with time_now
    #
    print time_now

# EOF

and here is the implementation of clock_api:

# clock_api.py

import os
import importlib

class MITClock(object):

    def __init__(self):
        self.mit_clock = importlib.import_module("mitclock")

    def time(self):
        return self.mit_clock.getTheTime()

class GPLClock(object):

    def __init__(self):
        self.gpl_clock = importlib.import_module("gplclock")

    def time(self):
        #
        # IMPORTANT: this API call is different!
        # API calls were found via `dir` and the man pages
        #
        return self.gpl_clock.get_time()

def get_clock():
    if os.environ.get("CLOCK", "mit") == "mit":
        return MITClock()
    elif os.environ["CLOCK"] == "gpl":
        return GPLClock()

# EOF

To develop my clock_api file, I utilised the shared objects for gplclock.so and mitclock.so can be obtained via apt-get with Ubuntu. Furthermore, both gplclock and mitclock have publicsed Python API examples, which allowed me to develop both of my clock classes without seeing any of the internal code of either gplclock or mitclock.

If we consider developing an application in C, then we need to #includea header for given library, and therefore it is clear that my commercial object code contains GPL object code (via the #include), then therefore the GPL applies. However, in the above, there is no "code" from gplclock in my application -- only the use of its dynamic API, which could be discoverable by interrogating gplclock via dir in Python.

Furthermore, my application is 100% functional without gplclock. It is completely at the discression of the end user to a) obtain gplclock.so and b) explicitly set the non-default environment variable CLOCK to be gpl.

How JJClock works and runs is completely abstracted from the selected clock -- all of this logic exists inside of the clock_api (e.g., we might want to implement an add method between two clocks, and therefore GPLClock and MITClock would implement the logic to do this operation). Again, this would be developed by not looking or obtaining the source for either: it can all be done via (e.g.,) dir in Python, or maybe even the man pages for both libraries.

It is my understanding that, at the shared object level, there isn't even dynamic linking between JJClock and gplclock. There is just a Python call with the string gplclock and then method invocations are made via getattr, with string of the method name.

So, my questions are:

  • Even if JJClock's dependancy on gplclock is optional (and no GPL code exists in my code, beyond API calls found via documentation), does this mean that gplclock must be licensed as GPL?

  • There exists an alternative clock API (pyclock), which is Apache licensed (???) and supports both gplclock and mitclock -- how does this work? Can JJClock use this library and remain commercial (without using clock_api)? What does it mean for pyclock to "wrap" the GPL library gplclock and provide it under an Apache license?

  • If JJClock can use pyclock, could I release clock_api under MIT, and keep JJClock as commercial?

  • What would the implications be here if I distributed JJClock alongside with gplclock.so? Does this change anything?

5
  • 1
    Relevant GPL FAQ entries: Can I release a nonfree program that's designed to load a GPL-covered plug-in? If they form a single combined program then the main program must be released under the GPL or a GPL-compatible [license]. When is a program and its plug-ins considered a single combined program? It depends on how the main program invokes its plug-ins. […] If the main program dynamically links plug-ins, and they make function calls to each other and share data structures, we believe they form a single combined program.
    – amon
    Commented Aug 28, 2018 at 12:24
  • Okay, sure, but is JJClock "dynamically linking" against "gplclock" (stackoverflow.com/questions/40492518/…)? Does dlopen count as "dynamic linking" (stackoverflow.com/questions/21214902/…)? Commented Aug 28, 2018 at 14:12
  • Also, if gplclock's "API" is GPL, what does that mean for pyclock being Apache licensed? Is pyclock "licensed incorrectly"? Commented Aug 28, 2018 at 14:13
  • "If we consider developing an application in C, then we need to #includea header for given library, and therefore it is clear that my commercial object code contains GPL object code (via the #include), then therefore the GPL applies." No. GPL software routinely #include's headers from, say, Microsoft Windows, and that does not generally require that such software accept Microsoft's licenses. You would need to look at what is actually being copied by the #include lines to say for certain. If it is only instructions on how to call a particular library, then that would preclude copyrightability.
    – Brandin
    Commented Aug 29, 2018 at 13:53
  • If you don't distribute the GPL library with your code, then you avoid the whole issue, dlopen or otherwise. E.g. I can write some code that links with Microsoft's runtime libraries which are included on Microsoft Windows systems (as is standard practice). But when I distribute it, I don't actually distribute those libraries (unless I am using the Microsoft redistributable library versions; then I have to follow the license for that). Did I have to write an #include line in my code in order to accomplish this linking compatibility? Probably. Does that make my code beholden to Microsoft? Nope.
    – Brandin
    Commented Aug 29, 2018 at 14:07

1 Answer 1

8

How GPL interacts with various kinds of linking is a tricky and not completely settled question. First, a few facts:

  • The GPL license is copyright-based. The GPL license only becomes relevant for you if your actions would otherwise be copyright infringement.

  • Copyright infringement definitively occurs if you copy the library, if your software includes the library, or if your software is a derived work in the sense of copyright.

  • It is the opinion of the FSF (the GPL authors) that dynamically linking a library creates a derived work at runtime and therefore requires permission from the copyright holders.

  • Here, dynamically linking means any mechanism that loads the library into a process, including .so shared objects, dlopen(), and Python's import facilities. Copyright is technology-agnostic.

  • Many people disagree with the FSF's interpretation, for example Lawrence Rosen. Under Rosen's interpretation the GPL license would be no more restrictive than the LGPL.

  • The FSF's theory has not been tested in court, but is generally accepted in the industry. Because this is a legal grey area, you too should assume the FSF's opinion is correct, just to be on the safe side.

  • The GPL includes a permission by the copyright holders to use the GPL'ed software in any way, which includes linking it to non-GPL software (!). However, you may not distribute the result except under a GPL-compatible license (which given non-free components is impossible).

So the tricky question: who is effectively creating the derived work? You are supplying all the pieces, but the end user has to put them together.

In a simple scenario, the user takes your software and replaces some dynamically linked dependency with an ABI-compatible GPL'ed version. Does this make your software subject to the GPL? Absolutely not. The user combined your proprietary software with the GPL'ed library, and is not allowed to distribute the result.

But that is not your scenario. Your software explicitly anticipates and suggests using a GPL library. It includes code with the sole purpose to interface with the GPL library. I see no reason why an optional dependency should be treated differently from a hard dependency for the purpose of determining whether copyright infringement has occurred.

I therefore find it hard to argue that your usage of the GPL'ed library would be fine:

  • You are definitively violating the intent of the GPL.
  • Because your software is designed to load a specific GPL'ed library, it might already be a derived work.
  • At best, you are skirting direct copyright infringement by deferring the final step of potential infringement to the end users. Courts tend to dislike clever “loopholes” like this. There might still be secondary liability.

Up to your remaining questions:

  • How can a wrapper of a GPL library be licensed under the Apache license?

    The GPL requires that derived works are published under a GPL-compatible license. E.g. the Apache 2 is compatible with GPLv3.

    This means that you cannot depend solely on the declared license of some library, but must consider your complete dependency graph. You must comply with the licenses of all directly and indirectly used components of your software.

  • Could you just introduce a MIT-licensed wrapper for the GPL dependency, while keeping your main code proprietary?

    No, because you have to consider all components. If your system includes GPL components, then it must be available under the GPL, which means that all other components (including your proprietary software) would have to be available under GPL-compatible licenses.

  • Would you be allowed to distribute the GPL library alongside your proprietary software?

    The GPL allows GPL software to be distributed alongside other software (“mere aggregation”) if it is clearly marked as such and does not deprive users from their rights under the GPL.

    But in this specific case, doing so would confirm the appearance that the GPL library is part of your software, and that not publishing your software under the GPL would be copyright infringement.

To summarize: stop looking for GPL loopholes. Either comply with the licenses of the software you are using, or stop using that software in your system. If you nevertheless want to proceed with your current design, at least get advice from a lawyer to reduce your liability in applicable jurisdictions.

1
  • 1
    I found this answer extremely helpful but I think that one statement got the direction wrong: "The GPL requires that derived works are published under a GPL-compatible license. E.g. the Apache 2 is compatible with GPLv3." You cannot license a GPLv3-derived work under the Apache 2 license; it only works in the other direction. So to me it seems that an Apache 2 licensed wrapper for a GPLv3 library is against the intent of the GPL.
    – saraedum
    Commented Oct 31, 2020 at 18:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.