Wie mache ich eine C ++ (shared) library kompatibel mit clang und GCC?

9

Ich habe eine ziemlich umfangreiche C ++ 11-Bibliothek geschrieben, und ich plane den Download von vorkompilierten Versionen von meiner Website zu erlauben.

Also habe ich einen automatisierten Build eingerichtet, der die Bibliothek mit clang kompiliert und zum Download verfügbar macht, aber das hat ein Problem ergeben: Wenn ich versuche, die clang-kompilierte Bibliothek mit GCC zu verwenden, bekomme ich undefinierte Referenzen (hauptsächlich verwandt mit std::string ). Ich denke, das hängt mit den GCC-Dual-ABI-Änderungen in GCC 5.1 zusammen, aber ich bin mir nicht sicher, wie ich das beheben soll.

Meine Frage ist, welche Flags sollte ich setzen oder Praktiken sollte ich folgen, um eine C ++ - Bibliothek sowohl mit Clang und GCC kompatibel?

Oder sollte ich zwei getrennte Bibliotheken aufgeben und kompilieren?

    
Kazade 03.01.2018, 07:16
quelle

3 Antworten

3

Wie bereits an mehreren Stellen erwähnt (zB hier ) libc ++ ist nicht vollständig binärkompatibel mit libstdc ++. Es gibt mehrere Möglichkeiten, aber einige von ihnen sind nicht so einfach.

  1. Kompilieren Sie zwei separate Bibliotheken - immer funktionierende Lösung.
  2. Entfernen Sie inkompatible Container von Ihrer Schnittstelle (zB std :: string) - aber das könnte viel Arbeit sein und manchmal keine gute Idee.
  3. Weisen Sie Ihre Bibliothek GCC-Benutzer an, die Sie mit libc ++ verknüpfen und dieselben grundlegenden Schritte ausführen müssen hier . Aber ich denke, die meisten GCC-Benutzer wollen das nicht tun.
  4. Verwenden Sie clang mit libstdc ++, indem Sie -stdlib=libstdc++ flag verwenden, um mit libstdc ++ kompatibel zu sein (wie in anderen Antworten vorgeschlagen). Diese Lösung ist jedoch möglicherweise auf einigen Plattformen schwieriger einzurichten.

Ich würde vorschlagen, wie bereits in den Kommentaren erwähnt, mit Option 1 zu gehen.

    
pe3k 03.01.2018, 14:19
quelle
2

Es gibt mehrere Möglichkeiten:

  1. Verteile es nicht in binärer Form. Machen Sie es stattdessen einfach, überall zu bauen (z. B. mit CMake oder Autotools oder ...)

  2. Machen Sie es nur Kopfzeile. Dies ist bei weitem die einfachste Lösung, aber möglicherweise nicht das, was Sie wollen. Es ist nur sinnvoll für Vorlagencode und hat einen großen Einfluss auf die Leistung der Kompilierung Ihrer Bibliothek.

  3. Sagen Sie den Leuten, dass sie mit libstdc ++ verlinken sollen, wenn Sie Clang und Ihre Bibliothek benutzen. Suboptimale Lösung (Ich möchte meinen Code sowohl gegen libc ++ als auch gegen libstdc ++ überprüfen), aber (virtuell) jeder Linux-Benutzer hat sowieso libstdc ++ installiert. Stellen Sie sicher, dass Sie eine etwas ältere Version wählen (die Version, die in der neuesten Debian Stable-Distribution geliefert wird, ist eine gute Wahl), da neuere Versionen möglicherweise neue Symbole einführen. Ältere Versionen fehlen. Neue Versionen sollten sowieso ABI-kompatibel sein.

Beachten Sie, dass die Situation für Visual Studio-Benutzer noch schlimmer ist, wo jede einzelne Compiler-Version eine neue Binärdatei verlangt, weil sie absolut nichts in Bezug auf die ABI der C ++ - Bibliotheken oder des Compilers garantiert.

    
rubenvb 03.01.2018 13:43
quelle
1

Eine weitere Option besteht darin, dass Ihre gemeinsam genutzte Bibliothek keine C ++ - Standardbibliothekstypen in ihrer Schnittstelle verfügbar macht. Außerdem muss eine Headerdatei mit Ihrer gemeinsam genutzten Bibliothek bereitgestellt werden, die std::string in Typen konvertiert, die von Ihrer Bibliothek verwendet werden, z. B. struct my_string_span { char const *begin, *end; }; und andere Standardcontainer.

    
Maxim Egorushkin 03.01.2018 14:53
quelle

Tags und Links