Comprendre l'implication de la LGPL sur #include
J'ai posé des questions sur la liaison dynamique en C ++ dans stackoverflow (https://stackoverflow.com/q/64039902/14321464), cependant, j'ai été intrigué par les réponses concernant mon désir de garder mon code source découvert par le copyleft LGPL. Je pose également cette question moi-même et je le recherche depuis des jours ici dans stackexchange, en lisant de nombreuses clarifications apportées par diverses équipes (comme celles de Teems:http://teem.sourceforge.net/lgpl.html) et googler. Voici ce que je comprends jusqu'à présent:
Si j'écris et compile mon code source et lie la bibliothèque LGPL de manière statique (via .a sous Linux ou .lib sous Windows (... peut-être? Je ne sais pas quel est l'équivalent d'un fichier .a sous Windows)), je suis lié à au moins fournir le fichier de sortie (.o) de la compilation de mon code source afin que les gens puissent utiliser l'éditeur de liens de leur choix pour relier et compiler le fichier .o en exécutable final en utilisant la bibliothèque de leur choix.
Si j'écris et compile votre code source et lie dynamiquement la bibliothèque LGPL (via .so sous Linux, ou .dll sous Windows), et si je décide de redistribuer le fichier .SO dans le cadre de ma distribution logicielle, alors je dois fournir la source code de la bibliothèque LGPL qui est utilisée et distribuée (je suppose qu'en auto-hébergement uniquement, je pourrais même être enclin à simplement emballer le code source dans le cadre de la distribution).
Si j'écris et compile mon code source et lie dynamiquement la bibliothèque LGPL (via .so sous Linux ou .dll sous Windows), et que je déclare uniquement que pour exécuter ce programme, les utilisateurs doivent acquérir eux-mêmes les bibliothèques LGPL, aucun code source ne doit être fourni à l'utilisateur final. J'ai juste besoin d'indiquer comment et où ces fichiers doivent être placés pour que le programme puisse fonctionner.
Et après avoir lu les LGPL v2.1 et LGPL v3 dans les deux sens, j'ai encore 2 questions dans ma tête:
- Considérez ce cas: une bibliothèque LGPL v2.1 fournit un ensemble de fichiers .so / .dll, ainsi qu'un dossier d'inclusion contenant tous les fichiers .h (en-tête) relatifs à .so / .dll (décrivant toutes les structures, classes, constructeurs et destructeurs, et toutes les déclarations de fonction dans le fichier .so / .dll compilé).
Pour autant que je sache, la liaison dynamique signifie que le programme doit pouvoir être exécuté (soit via le terminal en utilisant ./( nom de l'exécutable), en double-cliquant sur l'exécutable, ou sur certaines autres formes d'exécution de l'exécutable comme prévu par l'hôte. System) et toujours capable de fonctionner même sans le .so / .dll présent (en affichant un écran d'erreur ou même en forçant simplement à se fermer).
Donc, dans ce cas, considérez cet exemple:
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;
}
et ces 2 sont compilés pour devenir libsampleso.so (g ++ sampleso.cpp -fPIC -shared -Wall -ldl -o libsampleso.so). Je distribue ensuite ce code en tant que LGPL v2.1 avec à la fois libsampleso.so et sampleso.hpp. Si, plus tard, j'utilise libsampleso.so par:
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;
}
et compilez-le par liaison dynamique (g ++ main.cpp -Wall -Wextra -std = c ++ 17 -L. -ldl -lsampleso -o main), est l'ajout de #include "sampleso.h"rend mon main.cpp (V1) compté comme des travaux dérivés , d'où le fait que le code source de main.cpp soit divulgué comme copyleft, ou pas? Ou dois-je aller jusqu'à utiliser dlopen, dlsym et dlclose pour être considéré comme un lien dynamique (voir main.cpp V2)? Dans quelle mesure FSF et LGPL comptent-ils un programme comme liaison dynamique (en le mentionnant simplement dans le cadre de -l param? Ou dois-je littéralement appeler la bibliothèque en utilisant dlopen et supprimer tout #include "sampleso.h"n'importe où dans mon code pour être considéré comme suffisamment dynamique? ). Tout le monde a parlé de .so et .dll, mais personne ne parle de l'inclusion du fichier d'en-tête LGPL et de la compilation de tout code avec l'en-tête LGPL inclus.
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;
}
- Étant donné que LGPL v2.1 et v3 exige la possibilité pour l'utilisateur de mettre à niveau / rétrograder la bibliothèque partagée comme bon lui semble, tout en conservant la capacité de l'exécutable à s'exécuter, qu'en est-il d'un exécutable qui nécessite une version de bibliothèque spécifique (toujours avec une liaison dynamique, mais une version spécifique du fichier .so / .dll est rendu obligatoire par le programmeur)? Cela rend l'utilisateur incapable de mettre à niveau ou de rétrograder comme bon lui semble, car les utilisateurs sont limités à cette version de bibliothèque spécifique, et s'ils mettent à niveau ou rétrogradent, le programme tomberait également en panne.
Je suis vraiment désolé si cette question ressemble plus à un essai, mais venant d'un pays autre que les États-Unis, il est très difficile d'interpréter clairement ce que constitue la LGPL et où sont les limites où la LGPL s'applique ou non aux applications.
EDIT: Je connais tous les autres éléments juridiques requis par la licence LGPL (en mentionnant son utilisation dans ma licence, en fournissant le texte de la licence LGPL dans son intégralité et en hébergeant les codes LGPL, etc.) Je veux juste me concentrer sur la section 4, 5 et 6 qui est encore débattue par beaucoup quant à savoir jusqu'où quelqu'un peut dire que quelque chose est un travail dérivé.
Réponses
Le LGPLv2.1 contient ces paragraphes qui sont directement pertinents pour votre question
Lorsqu'un «travail qui utilise la bibliothèque» utilise du matériel d'un fichier d'en-tête qui fait partie de la bibliothèque, le code objet de l'œuvre peut être un travail dérivé de la bibliothèque même si le code source ne l'est pas. Que cela soit vrai est particulièrement important si l'œuvre peut être liée sans la bibliothèque, ou si l'œuvre est elle-même une bibliothèque. Le seuil pour que cela soit vrai n'est pas précisément défini par la loi.
Si un tel fichier objet utilise uniquement des paramètres numériques, des dispositions et des accesseurs de structure de données, ainsi que de petites macros et de petites fonctions en ligne (dix lignes ou moins de longueur), alors l'utilisation du fichier objet est illimitée, qu'il soit légalement un dérivé travail.
Le LGPLv3 a une section similaire:
3. Code objet incorporant le matériel des fichiers d'en-tête de bibliothèque.
La forme de code objet d'une application peut incorporer des éléments d'un fichier d'en-tête qui fait partie de la bibliothèque. Vous pouvez transmettre un tel code objet selon les termes de votre choix, à condition que, si le matériel incorporé ne se limite pas à des paramètres numériques, des dispositions et des accesseurs de structure de données, ou de petites macros, des fonctions en ligne et des modèles (dix lignes ou moins de longueur), vous effectuez les deux opérations suivantes: [...]
Dans des termes qui peuvent également être compris par les humains normaux, si vous utilisez un fichier d'en-tête d'une bibliothèque LGPL qui ne contient que
- paramètres numériques
- dispositions de structure de données
- accesseurs pour cette structure de données
- petites macros (moins de 10 lignes chacune)
- petites fonctions en ligne (moins de 10 lignes chacune)
alors votre code n'est pas «infecté» par les termes de la LGPL et vous pouvez distribuer votre code sous n'importe quelle licence de votre choix, y compris une licence source fermée.
Il est admis par la FSF qu'il n'y a aucune garantie que ces parties de la bibliothèque puissent être remplacées par les utilisateurs finaux.