Comprender la implicación de LGPL en #include
Pregunté sobre la vinculación dinámica en C ++ en stackoverflow (https://stackoverflow.com/q/64039902/14321464), sin embargo, me intrigaron las respuestas sobre mi deseo de mantener mi código fuente descubierto por el copyleft de LGPL. También he estado preguntando esto y buscándolo durante días aquí en stackexchange, leyendo muchas aclaraciones hechas por varios equipos (como de Teems:http://teem.sourceforge.net/lgpl.html) y buscar en Google. Esto es lo que entiendo hasta ahora:
Si escribo y compilo mi código fuente y vinculo la biblioteca LGPL de forma estática (a través de .a en Linux o .lib en Windows (... ¿tal vez? No estoy seguro de cuál es el equivalente de un archivo .a en Windows)), estoy obligado a proporcionar al menos el archivo de salida (.o) de la compilación de mi código fuente para que las personas puedan usar el enlazador de su elección para volver a vincular y compilar el archivo .o en el ejecutable final utilizando la biblioteca de su elección.
Si escribo y compilo su código fuente y vinculo la biblioteca LGPL dinámicamente (a través de .so en Linux o .dll en Windows), y si decido redistribuir el archivo .SO como parte de mi distribución de software, entonces debo proporcionar la fuente. código de la biblioteca LGPL que está en uso y distribuido (supongo que, solo por autohospedaje, podría incluso estar inclinado a empaquetar el código fuente como parte de la distribución).
Si escribo y compilo mi código fuente y vinculo la biblioteca LGPL dinámicamente (a través de .so en Linux o .dll en Windows), y solo declaro que para ejecutar este programa los usuarios deben adquirir las bibliotecas LGPL ellos mismos, entonces no es necesario que el código fuente sea proporcionado al usuario final. Solo necesito indicar cómo y dónde deben colocarse esos archivos para que el programa pueda ejecutarse.
Y después de leer LGPL v2.1 y LGPL v3 de un lado a otro, todavía tengo 2 preguntas en mi cabeza:
- Considere este caso: una biblioteca LGPL v2.1 proporciona un conjunto de archivos .so / .dll, así como una carpeta de inclusión que contiene todos los archivos .h (encabezado) relacionados con .so / .dll (que describen todas las estructuras, clases, constructores y destructores, y todas las declaraciones de funciones en el .so / .dll compilado).
Por lo que tengo entendido, la vinculación dinámica significa que el programa debe poder ejecutarse (ya sea a través de la terminal usando ./(nombre del ejecutable), haciendo doble clic en el ejecutable o algunas otras formas de ejecutar el ejecutable según lo previsto por el host Operativo System) y aún puede ejecutarse incluso sin el .so / .dll presente (mostrando una pantalla de error o incluso forzando el cierre).
Entonces, en ese caso, considere este ejemplo:
sampleso.hpp
#IFNDEF SAMPLESO_HPP__
#DEFINE SAMPLESO_HPP__
struct carDesc
{
const char *model;
int prod_year;
int wheel_num;
const char *license_plate;
const char *colour;
} car;
carDesc fillCarID(void);
sampleso.cpp
#include "sampleso.hpp"
carDesc fillCarID(void)
{
car.name = "Ford Fiesta";
car.prod_year = 2014;
car.wheel_num = 4;
car.license_plate = "D 1234 ABC";
car.colour = "Midnight blue";
return car;
}
y esos 2 se compilan para convertirse en libsampleso.so (g ++ sampleso.cpp -fPIC -shared -Wall -ldl -o libsampleso.so). Luego distribuyo este código como LGPL v2.1 con libsampleso.so y sampleso.hpp. Si, más adelante, uso libsampleso.so por:
main.cpp (v1)
#include <iostream>
#include "sampleso.h" //<< THIS IS THE INTERESTING BIT
int main (void)
{
carDesc fordCar;
fordCar = fillCarID(); //I know this function will produce NOTHING USEFUL, but let's just pretend it is
...
return EXIT_SUCCESS;
}
y compilarlo por enlace dinámico (g ++ main.cpp -Wall -Wextra -std = c ++ 17 -L. -ldl -lsampleso -o main), es la adición de #include "sampleso.h"hace que mi main.cpp (V1) cuente como trabajos derivados , obligando a que el código fuente de main.cpp se divulgue como copyleft, ¿o no? ¿O tengo que ir tan lejos como para usar dlopen, dlsym y dlclose para ser considerado un enlace dinámico (ver main.cpp V2)? ¿Hasta qué punto FSF y LGPL cuentan un programa como enlace dinámico (con solo mencionarlo como parte de -l param lo suficiente? ¿O tengo que llamar literalmente a la biblioteca usando dlopen y eliminar cada #include "sampleso.h"parte de mi código para que se cuente como lo suficientemente dinámico? ). Todo el mundo hablaba de .so y .dll, pero nadie habla de la inclusión del archivo de encabezado LGPL y de la compilación de cualquier código con encabezado LGPL incluido.
main.cpp (v2)
#include <iostream>
#include <dlfcn.h> //Completely has no sampleso.hpp in it
int main (void)
{
//... some dlopen codes here to find the libsampleso.so, and handle the error if it failed to be found in the aformentioned location ...
struct carDesc * fordCar;
fordCar = reinterpret_cast<struct carDesc*>(dlsym(hHandler,"car"));
carDesc(*__fn_fillCarIDv)(void);
__fn_fillCarIDv = reinterpret_cast<carDesc(*)(void)>(dlsym(hHandler,"_Z9fillCarIDv"));
fordCar = __fn_fillCarIDv(); //doesn't work, error: function returns incomplete type "carDesc" C/C++(862), still working on how to make it work
return EXIT_SUCCESS;
}
- Dado que LGPL v2.1 y v3 exige la capacidad del usuario para actualizar / degradar la biblioteca compartida como mejor le parezca, mientras mantiene la capacidad del ejecutable para ejecutarse, ¿qué pasa con un ejecutable que requiere una versión de biblioteca específica (aún con enlaces dinámicos, pero una versión específica? del archivo .so / .dll es obligatorio por parte del programador)? Eso hace que el usuario ya no pueda actualizar o degradar como mejor le parezca, ya que los usuarios están limitados a esa versión de biblioteca específica, y si actualizan o degradan, el programa también se romperá.
Lo siento mucho si esta pregunta se parece más a un ensayo, pero viniendo de un país que no sea EE. UU., Es muy difícil interpretar claramente qué constituye LGPL y dónde están los límites donde se aplica o no LGPL a las aplicaciones.
EDITAR: Conozco todas las demás cosas legales requeridas por la licencia LGPL (mencionar el uso de la misma en mi licencia, proporcionar el texto completo de la licencia LGPL y el alojamiento de los códigos LGPL, etc.) Solo quiero centrarme en la sección 4, 5 y 6 que todavía es debatido por muchos sobre hasta qué punto alguien puede decir que algo es trabajo derivado.
Respuestas
La LGPLv2.1 contiene estos párrafos que son directamente relevantes para su pregunta
Cuando un "trabajo que usa la Biblioteca" usa material de un archivo de encabezado que es parte de la Biblioteca, el código objeto del trabajo puede ser un trabajo derivado de la Biblioteca aunque el código fuente no lo sea. Si esto es cierto es especialmente importante si el trabajo se puede vincular sin la biblioteca, o si el trabajo es en sí mismo una biblioteca. El umbral para que esto sea cierto no está definido con precisión por la ley.
Si dicho archivo de objeto utiliza solo parámetros numéricos, diseños de estructura de datos y accesos, y pequeñas macros y pequeñas funciones en línea (diez líneas o menos de longitud), entonces el uso del archivo de objeto no está restringido, independientemente de si es legalmente un derivado. trabajo.
El LGPLv3 tiene una sección similar:
3. Código de objeto que incorpora material de archivos de encabezado de biblioteca.
La forma de código objeto de una Aplicación puede incorporar material de un archivo de encabezado que forma parte de la Biblioteca. Puede transmitir dicho código de objeto en los términos que elija, siempre que, si el material incorporado no se limita a parámetros numéricos, diseños de estructura de datos y accesos, o pequeñas macros, funciones en línea y plantillas (diez o menos líneas de longitud), usted haz las dos siguientes: [...]
En términos que también pueden ser entendidos por humanos normales, si usa un archivo de encabezado de una biblioteca LGPL que contiene solo
- parámetros numéricos
- diseños de estructura de datos
- accesores para esa estructura de datos
- macros pequeñas (menos de 10 líneas cada una)
- pequeñas funciones en línea (menos de 10 líneas cada una)
entonces su código no se "infecta" por los términos LGPL y puede distribuir su código bajo cualquier licencia que desee, incluida una licencia de código cerrado.
La FSF acepta que no hay garantía de que esas partes de la biblioteca puedan ser reemplazadas por los usuarios finales.