[Qt] [C++] Compiler dans un seul .exe

Bonjour,

Suite à la discussion précédente, mon programme fonctionne désormais, mais comme j’aimerais le partager, j’ai cherché (en vain) sur Internet comment mettre les dll, les fichiers images, etc. (heureusement il n’y en a pas dans mon cas), tout cela dans un seul fichier .exe. Cependant, la plupart des sujets datent de plusieurs années, et donc les liens donnés sont obsolètes. Faut-il configurer le compilateur pour tout rentrer dans un fichier ou comment faut-il faire ?

Merci.

Re

Attention aux licences:

The open source version of Qt is mainly distributed under the LGPL, version 3 and GPLv2/v3. You will need to fulfill the license obligations for these licenses when using Qt in your product.

Par ailleurs, ce que tu demandes à faire c’est du « static build » ou « static linking ». Peut-être un début d’info ici: Qt: Static Builds Under Windows » Tadeu Bento Mais avec Qt, tu risques de devoir rabaisser les manches et mettre des gants…

Renseigne-toi, tout de même, auprès de Qt en ce qui concerne les licences. Tout autant du point de vue de ton code, que de tes ressources annexes (images, son, icônes, …). Mais également du point de vue des contraintes formative de ton package (ce que doit contenir le readme, les références obligatoires à Qt, etc.). Tout en prenant compte également du dépôt de tes sources (acceptation de la licence du logiciel par le dépôt, etc.). Pareil pour le store où tu déposeras ton binaire.

Je pense que le mieux, comme c’est un petit projet qui n’a pas une vocation commerciale, ce serait de mettre ton code avec les licence GPL sur un dépôt de source (GitLab ou autre). Tu crées les fichiers nécessaires pour correspondre à la nomenclature GPL avec les référence à Qt et au travers desquels tu donnes la démarche pour compiler l’application.

J’ai sûrement oublié plein de truc. Peut-être que quelqu’un ici pourrait te donner une orientation de réflexion plus pertinente et moins sommaire. @ericb

Oui effectivement, je publie toujours en GPL (et maintenant sur GitHub), mais étant donné que Qt était de KDE, je pensais qu’il n’y avait pas de problèmes en matière de licence.

KDE se base sur Qt. Qt est sous l’égide de la Qt Company :wink:

Si j’ai bien compris la compilation statique, c’est-à-dire le truc le plus pratique pour partager, est interdite en open-source. Faut pas chercher la logique… :thinking:

Et donc si j’ai bien compris, si je veux publier en GPL, je dois publier avec tous les fichiers séparés ?

Hé bien, en ce qui concerne une build statique et un code en open-source, je ne sais pas.

Et ce n’est pas très clair au niveau des licences libres. Chez Qt, quand il est fait référence à la GPL, j’aurai tendance à dire que c’est la v3. Bien que parfois il parle de la v2. En tout cas, ils mettent en avant la v3. Mais il est aussi question de la LGPL. Et si je lis d’autres commentaires sur le web, ce serait la LGPL qui ne permettrait pas (aisément?) de faire une build statique (sous conditions).

Donc, il faudrait regarder un peu partout pour démêler la vérité ou la demander directement aux concernés. :slight_smile:

D’où ma proposition de ne mettre que le source et pas le binaire. La décision du mode de « linkage » sera à charge de l’utilisateur final.

Et, entre nous, je préfère avoir des DLL packagées avec l’application qu’un gros binaire. Parce que parfois, on peut « patcher » une application rien qu’en copiant une nouvelle version de la DLL sans avoir à la recompiler.

OK, c’est juste que je suis en train de prépare un gros projet à plusieurs, et ça serait dommage de le télécharger avec 50 fichiers différents.

En fait, tu peux, je pense, distribuer ton binaire accompagné des DLL propres à Qt (mais je crois qu’il faut également celles de MSVC). Ou alors utiliser l’outil windeployqt

OK, de toute façon, c’est bien connu, un problème s’est à nouveau créé, donc existe-t-il des dll qui marchent à la fois pour 32 et 64 bits ?

Non, il n’existe pas, à ma connaissance, des DLL qui fonctionnent à la fois pour 32 et 64 bits. Le format exécutable binaire PE ne le permet pas, il me semble.

Mais l’outil windeployqt pourrait faire la différence

1 « J'aime »

@PaliPalo : si si, ça existe depuis longtemps même : sur Mac OS X j’ai même compilé OpenOffice de cette façon pendant longtemps :slight_smile: (le binaire dédié s’appelait « lippo », je m’en souviens encore). La propriété remarquable : ça permettait de fonctionner sur 2 archtectures différentes, et pas besoin de maintenir 2 versions. L’inconvénient : 2 fois la taille initiale (puisque contient les instructions pour les 2 architectures, par exemple PowerPC et Intel 32 ou 64 bits)

Le binaire créé était de type UB (pour universal binary). Et ça peut aussi se faire pour (par exemple) ARM et x86_64. ou « cequetuveux » :wink:

Mais c’est un peu compliqué à expliqueer ici : la méthode demande 2 « toolchains » , et ensuite d’associer les 2 binaires en un seul, de type UB.

Ah bah cool tu les as trouvées où alors ?

J’ai quand même des interrogations @ericb. Avais-tu fait cela sur Mac uniquement ou avais-tu réussi également l’opération sur Windows (et Linux ?) ? Car je pense que @AirSThib veut pouvoir faire la même chose quelque soit le système d’exploitation d’où son usage de Qt.

De plus, j’ai l’impression que c’était ton binaire exécutable qui était multi-architecture et non pas les DLL. Or c’est ce qui est demandé: soit pouvoir lier statiquement des librairies dans l’exécutable (et là ta proposition pourrait fonctionner) ; soit utiliser des DLL qui sont 32 et 64 bits en même temps (ce qui ne me semble par possible)

Si je ne me trompe pas, une DLL (ainsi qu’un exécutable) sous Windows est de type PE et le header définit soit une DLL 32 bits soit une DLL 64 bits. En outre, je ne crois pas que Microsoft ait développé un binaire tel que UB pour le monde Apple (ce que j’apprends au travers toi :wink:). D’ailleurs, je m’appuie également sur le fait qu’un Windows 64 bits place les DLL 32bits dans un dossier différent d’un dossier 64 bits. Ce qui me tend à dire que Microsoft l’aurait déjà utilisé la bi-architecture pour ses propres DLL système.

Sous Linux, il me semble également que les shared libraries sont scindées entre 32 et 64 bits. Je t’avoue que je ne sais pas si le format actuel elf permet la coexistence du 32 et 64 bits dans le même binaire; mais de ce que je lis, le header fait également la distinction entre 64 et 32 bits.

Mais bon, je peux toujours me tromper :slight_smile:

@PaliPalo

Dans l’ordre :

@AirSThib veut écrire un seul code source, a priori portable sur d’autres OS, et qu’on doit compiler sur chaque OS. C’est le plus gros intérêt de Qt à mon avis.

Les binaires pour Windows sont compilés sous Windows (avec les outils Microsoft ou mingw), ou sous Linux pour Windows avec mingw, qui utilise une toolchain gcc / c++ dédiée (par exemple)

En ce qui me concerne, je n’ai utilisé ce genre de binaire (multi-architecture) sur Mac OS X uniquement quand je m’occupais du port OpenOffice. C’est Pavel Janik qui m’avait initié, et on produisait des gros blobs qui fonctionnaient partout.

Pour les dll : la différence entre un binaire exécutable et une bibliothèques (partagée = dll sous Windows), c’est que dans le binaire exécutable il y a une fonction main, qui est LA SEULE à pouvoir intéragir avec le système d’exploitation -c’est la raison pour laquelle il n’y a qu’une fonction main) + les points d’entrée des bibliothèques « liées » (lors de l’édition de lien, dernière étape de la compilation. Cela signifie que l’on peut linker une partie du binaire (préfixée par exemple) avec une architecture et une autre partie avec une autre. ça devrait pouvoir se faire amha. Que ce soit pour le binaire exacutbale ou une bibliothèque partagée, peu importe.

En ce qui concerne la création de bibliothèques (aka library en anglais) 32 et 64 bits, je n’ai pas vérifié si lipo le permet sur Mac OS X. Les sources sont là : sources de lipo. Pour l’adapter à Linux, je pense qu’il faut modifier le code de lipo.c car l’ABI sous Linux n’est pas la même que sur Mac OS X, et le problème de l’alignement risque de poser quelques problèmes aussi. AMHA : rien ne l’interdit a priori sous Linux, mais peut-être que cela n’a jamais été fait. On parle aussi de lipo sur StackOverflow. Et si vous avez les outils développeur sur Mac OS X, essayez de faire man lipo dans un terminal.

Une dernière chose à propos de Mac OS X : je parie qu’on doit pouvoir compiler des binaires utilisables sur x86_64 ET sur aarch64 (je serais étonné qu’on soit seulement en 32 bits sur les M1, car bonjour la manipulation de grosses images dans ce cas :-/

Sous Windows (je ne suis pas un spécialiste toutefois) : après vérification, Microsoft a deux répertoires distincts ce qui permet la rétro-compatibilité : on peut faire tourner n’importe quoi sous Windows, même des vieux binaires (je n’ai que wine sous Linux, et la cross-compilation marche pas mal du tout). Mais les binaires ne sont pas des « fat binaries », en effet.

Donc en effet, sous Windows, ils ont apparemment choisi de séparer. Cela n’interdit pourtant pas de créer ce type de binaires (mais je peux me tromper aussi).

Enfin, si je n’ai rien oublié, sous Linux, tout est séparé, et je n’ai pas la réponse. Le reproche qu’on faisait aux archives UB, c’était leur lourdeur, et c’est peut-être la raison pour laquelle tout le monde a laissé tomber. Toutefois, la documentation Debian laisse penser que c’est pensable (possible, je ne pense pas, car c’est assez crade et coûte cher en stockage pour des gains moindres).

Pour plus d’informations je suggère de voir la documentation Debian , où le choix de séparer a clairement été fait.

Avis personnel : je continue de penser que c’est possible de tout mettre dans le même binaire, exécutable comme bibliothèque (library en anglais) sous Linux, mais avec modification de lipo.c obligatoire, ABI, alignement, éditions de liens à faire en double.

En espérant avoir répondu plus précisément :slight_smile:

EDIT : ajout d’un lien important sur les UB

EDIT2 : on pourrait utiliser des applis 32 bits sur Mac OS X

EDIT3 : La réponse est OUI sur Mac OS X: mélanger 32 bits et 64 bits avec lipo

C’est ça je veux tout compiler depuis le même code source, mais moi quand je compile sous GNU/Linux je n’ai pas besoin de dll, tout est dans le fichier d’appli (qui est sans extension je crois bien).