erstellen und verwalten von ppas mit mehreren architekturen
<p>ich habe ein programm, das für jede ubuntu-version neu kompiliert werden muss.</p><p>momentan packe ich es mit ubuntus ppa nur für die aktuelle distribution.</p><p>schließlich muss ich pakete für die vorherige ubuntu-version bereitstellen.</p><p>ich bin mir nicht sicher, wie ich das erreichen soll.</p><p>wie funktioniert der ubuntu ppa build server? betrachtet man nur das verteilungsfeld im aktuellsten changelog-eintrag (in der debian/changelog-datei), um zu bestimmen, für welche distribution das paket erstellt werden soll?</p><p>die debian-spezifikation erlaubt es, mehrere distributionen in das distributionsfeld aufzunehmen. aber das hilft mir nicht weiter.</p><p> <a href="https://help.launchpad.net/packaging/ppa/buildingasourcepackage#versioning">einige ubuntu-dokumente</a> sprechen über das kodieren des distributionsnamens in die versionsnummer (in der debian-changelog-datei).</p><p>aber wie funktioniert das in der praxis? eine neue version des programms ist verfügbar. was dann? füge ich für jede distribution einen neuen changelog-eintrag hinzu und der ppa-buildserver erstellt nach dem einspielen automatisch für jede distribution neue pakete? oder schaut sich der ppa-buildserver nur den ersten changelog-eintrag an?</p>
<p>der weg zu gehen ist das hochladen <strong>einmal für jede ubunt</strong> version.</p><p>launchpad erstellt keine pakete für ubuntu-versionen, die nicht mehr unterstützt werden, und erstellt nur ein paket für eine bestimmte ubuntu-version. die zielversion wird (wie sie bereits wissen) in der datei <code>changelog</code> durch den neuesten eintrag angegeben!</p><p>denken sie daran, dass die pakete, von denen ihr programm abhängt, möglicherweise nicht in allen ubuntu-versionen in derselben version verfügbar sind.</p><p>sie sprechen auch von "multi-architektur" (architektur = cup-typ, z. b. x86, lpia, amd64). dies macht keinen unterschied, da jedes hochgeladene paket für alle verfügbaren architekturen erstellt wird, solange sie <code>architecture: any</code> in der paketdefinition (<code>debian/control</code>) datei, dies ermöglicht ihnen auch, das paket von verschiedenen paketen für verschiedene architekturen abhängig zu machen (das paket muss mehrmals definiert werden)</p>
<p>treiber werden im kernel verwaltet. wenn eine kerneländerung ein globales suchen und ersetzen (oder suchen und ändern) für alle benutzer einer funktion erfordert, wird dies von der person durchgeführt, die die änderung vornimmt. es ist ein sehr schöner vorteil, wenn ihr treiber von personen aktualisiert wird, die api-änderungen vornehmen, anstatt dies selbst tun zu müssen, wenn er nicht auf einem neueren kernel kompiliert wird.</p><p>die alternative (was bei treibern der fall ist, die außerhalb des baums gewartet werden) besteht darin, dass der patch von seinen betreuern erneut synchronisiert werden muss, um mit den änderungen schritt zu halten.</p><p>eine schnelle suche ergab sich <a href="http://lwn.net/articles/186854/">eine debatte über in-tree vs. out-of-tree</a> treiberentwicklung.</p><p>die art und weise, wie linux gewartet wird, besteht hauptsächlich darin, alles im mainline-repo zu belassen. das erstellen kleiner abgespeckter kernel wird durch konfigurationsoptionen zur steuerung von <code>#ifdef</code> unterstützt. sie können also absolut winzige, abgespeckte kernel erstellen, die nur einen winzigen teil des codes im gesamten repo kompilieren.</p><p>die weit verbreitete verwendung von linux in eingebetteten systemen hat zu einer <em> besseren </em> unterstützung für das auslassen von dingen geführt als linux jahre zuvor, als der kernel-quellbaum kleiner war. ein super-minimal-4.0-kernel ist wahrscheinlich kleiner als ein super-minimal-2.4.0-kernel.</p> <p>einfach. hier ist das beispiel aus meinem kopf:</p><h1>die oberste ebene <code>cmakelists.txt</code>:</h1><pre><code>cmake\_minimum\_required(version 2.8.10) # you can tweak some common (for all subprojects) stuff here. for example: set(cmake\_disable\_in\_source\_build on) set(cmake\_disable\_source\_changes on) if ("${cmake\_source\_dir}" strequal "${cmake\_binary\_dir}") message(send\_error "in-source builds are not allowed.") endif () set(cmake\_verbose\_makefile on) set(cmake\_color\_makefile on) # remove 'lib' prefix for shared libraries on windows if (win32) set(cmake\_shared\_library\_prefix "") endif () # when done tweaking common stuff, configure the components (subprojects). # note: the order matters! the most independent ones should go first. add\_subdirectory(components/b) # b is a static library (depends on boost) add\_subdirectory(components/c) # c is a shared library (depends on b and external xxx) add\_subdirectory(components/a) # a is a shared library (depends on c and b) add\_subdirectory(components/executable) # executable (depends on a and c) </code></pre><h1><code>cmakelists.txt</code> in <code>components/b</code>:</h1><pre><code>cmake\_minimum\_required(version 2.8.10) project(b c cxx) find\_package(boost 1.50.0 required) file(glob cpp\_files source/*.cpp) include\_directories(${boost\_include\_dirs}) add\_library(${project\_name} static ${cpp\_files}) # required on unix os family to be able to be linked into shared libraries. set\_target\_properties(${project\_name} properties position\_independent\_code on) target\_link\_libraries(${project\_name}) # expose b's public includes (including boost transitively) to other # subprojects through cache variable. set(${project\_name}\_include\_dirs ${project\_source\_dir}/include ${boost\_include\_dirs} cache internal "${project\_name}: include directories" force) </code></pre><h1><code>cmakelists.txt</code> in <code>components/c</code>:</h1><pre><code>cmake\_minimum\_required(version 2.8.10) project(c c cxx) find\_package(xxx required) file(glob cpp\_files source/*.cpp) add\_definitions(${xxx\_definitions}) # note: boost's includes are transitively added through b\_include\_dirs. include\_directories(${b\_include\_dirs} ${xxx\_include\_dirs}) add\_library(${project\_name} shared ${cpp\_files}) target\_link\_libraries(${project\_name} b ${xxx\_libraries}) # expose c's definitions (in this case only the ones of xxx transitively) # to other subprojects through cache variable. set(${project\_name}\_definitions ${xxx\_definitions} cache internal "${project\_name}: definitions" force) # expose c's public includes (including the ones of c's dependencies transitively) # to other subprojects through cache variable. set(${project\_name}\_include\_dirs ${project\_source\_dir}/include ${b\_include\_dirs} ${xxx\_include\_dirs} cache internal "${project\_name}: include directories" force) </code></pre><h1><code>cmakelists.txt</code> in <code>components/a</code>:</h1><pre><code>cmake\_minimum\_required(version 2.8.10) project(a c cxx) file(glob cpp\_files source/*.cpp) # xxx's definitions are transitively added through c\_definitions. add\_definitions(${c\_definitions}) # note: b's and boost's includes are transitively added through c\_include\_dirs. include\_directories(${c\_include\_dirs}) add\_library(${project\_name} shared ${cpp\_files}) # you could need `${xxx\_libraries}` here too, in case if the dependency # of a on c is not purely transitive in terms of xxx, but a explicitly requires # some additional symbols from xxx. however, in this example, i assumed that # this is not the case, therefore a is only linked against b and c. target\_link\_libraries(${project\_name} b c) # expose a's definitions (in this case only the ones of c transitively) # to other subprojects through cache variable. set(${project\_name}\_definitions ${c\_definitions} cache internal "${project\_name}: definitions" force) # expose a's public includes (including the ones of a's dependencies # transitively) to other subprojects through cache variable. set(${project\_name}\_include\_dirs ${project\_source\_dir}/include ${c\_include\_dirs} cache internal "${project\_name}: include directories" force) </code></pre><h1><code>cmakelists.txt</code> in <code>components/executable</code>:</h1><pre><code>cmake\_minimum\_required(version 2.8.10) project(executable c cxx) file(glob cpp\_files source/*.cpp) add\_definitions(${a\_definitions}) include\_directories(${a\_include\_dirs}) add\_executable(${project\_name} ${cpp\_files}) target\_link\_libraries(${project\_name} a c) </code></pre><hr><p>um es klar zu machen, hier ist die entsprechende quellbaumstruktur:</p><pre><code>root of the project ├───components │ ├───executable │ │ ├───resource │ │ │ └───icons │ │ ├───source | | └───cmakelists.txt │ ├───a │ │ ├───include │ │ │ └───a │ │ ├───source | | └───cmakelists.txt │ ├───b │ │ ├───include │ │ │ └───b │ │ ├───source | | └───cmakelists.txt │ └───c │ ├───include │ │ └───c │ ├───source | └───cmakelists.txt └───cmakelists.txt </code></pre><p>es gibt viele punkte, an denen dies angepasst/angepasst oder geändert werden kann, um bestimmte anforderungen zu erfüllen. dies sollte jedoch zumindest den einstieg erleichtern.</p><p><strong> hinweis: </strong>ich habe diese struktur in mehreren mittelgroßen und großen projekten erfolgreich eingesetzt.</p> <p>ja, es ist möglich.<br> solange das betriebssystem unterstützt wird, können sie mehrere cuda-toolkits installieren. um keine probleme zu haben, empfehle ich jedoch, <code>runfile</code> installer zu verwenden, da sie angeben können, welche und wo diese installiert werden sollen.<br> eine sache, um die man sich kümmern muss, ist der symlink, der für cuda erstellt wurde. bei der installation von cuda suchen in der regel viele apps und/oder frameworks nach dem symlink, der am häufigsten auf die neueste/einzige version von cuda verweist, die auf einem system verfügbar ist.<br> nehmen sie also die erforderlichen änderungen in ihrer anwendungsspezifischen konfigurationsdatei vor, um auf die richtige cuda-installationsversion zu verweisen. das installationsprogramm erstellt normalerweise immer einen ordner mit dem namen <code>cuda-x.x</code> (z. b. cuda-9.1), den sie auch anstelle des symlinks (<code>/usr/local/cuda</code>) verwenden können.<br> wenn eine anwendung von ihnen nur den symlink <code>/usr/local/cuda</code> überprüft und sie die konfiguration nicht ändern können, können sie diesen symlink auf die version von cuda verweisen lassen, die diese anwendung benötigt, und die konfigurieren sie die anderen apps so, dass ihre entsprechenden versionen über ihre konfigurationsdateien verwendet werden.</p> <p>nachdem ich wochenlang damit rumgespielt hatte, konnte ich es endlich zum laufen bringen. da ich viele offene fragen gefunden habe, werde ich meine eigenen beantworten, um anderen zu helfen.</p><p><strong> wann funktioniert es? </strong></p><p>zuerst war ich mir nicht sicher, wie dieser voreinstellungsprozess aussehen würde. wann wurde die datei abgeholt und was ist zu erwarten, wenn meine vordefinierte datei nicht vollständig oder falsch war? also habe ich zuerst eine manuelle installation durchgeführt und alle gestellten fragen aufgeschrieben. nach der voreinstellung stellte ich fest, dass einige fragen nicht mehr gestellt werden, die fehlgeschlagenen fragen jedoch weiterhin gestellt wurden. also habe ich danach alles versucht, um sie alle vorzuspielen</p><p><strong> server edition </strong></p><p>ich habe im internet gelesen, dass sie die server-edition von ubuntu benötigen, da sie mit der desktop-edition nicht funktioniert. ich bin mir nicht sicher, ob das zutrifft, aber ich habe gerade die serverversion installiert und die desktop-pakete (in meinem fall gnome) in den voreinstellungsdateien installiert.</p><p><strong> bootoptionen </strong></p><p>manchmal wird über die übergabe von parametern durch die startoptionen gesprochen. ich hatte keine ahnung, wie das geht, aber am ende ist es ganz einfach. booten sie einfach vom installationsmedium und wählen sie ihre installationssprache. drücken sie dann f6, um andere optionen zu öffnen, und die startparameter werden angezeigt. drücken sie einfach die esc-taste, um den anderen optionsdialog zu schließen. <a href="https://i.stack.imgur.com/ztu2n.png"><img src="https://i.stack.imgur.com/ztu2n.png" alt="boot options in ubuntu"></a> </p><p>ich wollte nicht jedes mal alle diese optionen in die boot-optionen eingeben, also habe ich die datei\isolinux\isolinux.cfg (von meinem usb-stick) geändert und in diese geändert:</p><pre><code># d-i config version 2.0 # search path for the c32 support libraries (libcom32, libutil etc.) path include menu.cfg default vesamenu.c32 prompt 0 timeout 0 ui gfxboot bootlogo label custom menu label ^belle custom installation kernel /install/vmlinuz append file=/cdrom/preseed/my.seed debian-installer/language=en debian-installer/country=nl console-setup/ask\_detect=false keyboard-configuration/layoutcode=us debian-installer/locale=en\_us.utf-8 localechooser/preferred-locale=en\_us.utf8 initrd=/install/initrd.gz quiet -- </code></pre><p><strong> wann wird die voreinstellungsdatei geladen? </strong></p><p>ich habe gerade meine voreinstellungsdatei auf den usb-stick gelegt. die offizielle dokumentation von ubuntu beschreibt, dass die verschiedenen voreinstellungsmethoden (datei, netzwerk usw.) während der verschiedenen phasen der installation geladen werden. sie beschreiben jedoch nicht, wann die datei vom usb-stick geladen wird. dies geschieht direkt nach all den fragen zu tastatur, sprache usw. sie müssen diese also durch die startoptionen voreinstellen.</p><p><strong> verspäteter befehl </strong></p><p>mit einer der vorbereiteten fragen (später befehl) können sie benutzerdefinierte befehle kurz vor abschluss der installation ausführen. wie viele andere hatte ich probleme, das zum laufen zu bringen. am ende habe ich ein skript auf die festplatte kopiert und /etc/rc.local geändert, damit dieses skript beim ersten start ausgeführt wird. ich tat dies, da ich alle befehle zur verfügung hatte, die ich brauchte. in dieser phase der installation sind leider einige befehle verfügbar.</p><p><strong> referenzen </strong></p><p>ich habe diese informationen aus vielen anderen foren und führern entnommen. ich erinnere mich nicht an alle, aber um dich auf den weg zu bringen:</p><ul> <li>offizielle ubuntu-dokumentation (enthält auch eine beispiel-vorabdatei): <a href="https://help.ubuntu.com/lts/installation-guide/armhf/apbs02.html">https://help.ubuntu.com/lts/installation-guide/armhf/apbs02.html</a> </li> <li>das offizielle ubuntu-server-buch (es beschreibt es detaillierter). diese site enthält einen teil des vorbereiteten themas online: <a href="http://searchitchannel.techtarget.com/feature/performing-an-automated-ubuntu-install-using-preseeding">http://searchitchannel.techtarget.com/feature/performing-an-automated-ubuntu-install-using-preseeding</a> </li> </ul> <p>hier ist die quelle ihres problems aus ihrer <code>parted</code> ausgabe:</p><pre><code>error: can't have overlapping partitions. </code></pre><p>die eine primäre partition ihrer festplatte (<code>/dev/sda1</code>) befindet sich vollständig in ihrer erweiterten partition (<code>/dev/sda2</code>). das ist illegal. dieses ungültige layout wurde wahrscheinlich von den windows-partitionierungstools erstellt, die dies häufig mit festplatten mit erweiterten und logischen partitionen tun.</p><p>wahrscheinlich kann mein <a href="http://www.rodsbooks.com/fixparts/">fixpart-dienstprogramm</a> , das mit ubuntu geliefert wird, das problem beheben. <em> sie müssen jedoch </em> vorsichtig sein, wie sie diese reparatur durchführen. speziell:</p><ul> <li>windows besteht normalerweise darauf, von einer primären partition zu booten. daher müssen sie sicherstellen, dass jede partition, die windows für diesen zweck verwendet, zu einer primären partition wird, wenn fixparts seine aufgabe erfüllt hat.</li> <li>um neue partitionen für ubuntu zu erstellen, müssen sie mindestens eine logische partition haben und diese muss so positioniert sein, dass die zukünftigen ubuntu-partitionen an die logischen partitionen angrenzen. (in diesem abschnitt wird davon ausgegangen, dass alle vorhandenen ntfs-partitionen windows-daten enthalten. wenn sie beabsichtigen, eine dieser partitionen vollständig in ubuntu zu konvertieren, bleiben sie möglicherweise unter dem mbr-limit für vier primäre partitionen.)</li> <li>sofern ich nichts verpasst habe, müssen sie mindestens eine partition in der größe ändern, um platz für mehr zu schaffen. fixparts können das nicht. normalerweise ist es ratsam, die größe der partition in windows zu ändern. wie ich bereits bemerkt habe, neigen die standard-windows-tools dazu, dinge durcheinander zu bringen, wenn logische partitionen vorhanden sind. verwenden sie daher möglicherweise ein tool eines drittanbieters oder das ubuntu-installationsprogramm, um diesen job auszuführen. (ich kann mich nicht ohne weiteres erinnern, wie gut das ubuntu-installationsprogramm die größe von partitionen ändert. gparted sollte dies können - aber stellen sie sicher, dass sie das problem der überlappenden partitionen beheben, bevor sie es versuchen!)</li> <li><em> erstellen sie </em> keine neuen partitionen für ubuntu mit den windows-tools. sie werden wahrscheinlich in ein <a href="https://en.wikipedia.org/wiki/logical\_disk\_manager">ldm-layout (logical disk manager)</a> konvertieren (auch bekannt als <em> dynamischer datenträger </em> setup), was eine neue reihe von problemen für die ubuntu-installation sein wird. wenn sie windows-tools zum verkleinern vorhandener partitionen verwenden, lassen sie den resultierenden speicherplatz unbelegt und lassen sie das ubuntu-installationsprogramm neue partitionen in diesem speicherplatz erstellen.</li> <li>es besteht immer die möglichkeit, dass beim erneuten partitionieren der festplatte ein schwerwiegender fehler auftritt. dies gilt in zweifacher hinsicht, wenn ihre festplatte bereits beschädigt ist, so wie es bei ihnen der fall ist. ich empfehle daher eine vollständige sicherung oder zumindest eine sicherung ihrer benutzerdateien, bevor sie etwas anderes tun.</li> </ul><p>auch wenn sie feststellen, dass der uefi-start in ihrer firmware angegeben ist, weist ihr festplattenlayout eindeutig auf eine installation von windows im bios-modus hin. beim dual-booten ist es fast immer am besten, sicherzustellen, dass beide betriebssysteme im gleichen modus booten. daher sollten sie ubuntu im bios-modus installieren. beachten sie, dass der in der firmware angegebene startmodus (bios/csm/legacy vs. efi/uefi) häufig eher als vorschlag als als befehl interpretiert wird. aus diesem grund können sie einen start im bios-modus durchführen, auch wenn sie dies festgelegt haben efi-modus booten in der firmware.</p><p>alternativ dazu können sie windows möglicherweise so konvertieren, dass es im efi-modus gestartet wird, wie in <a href="https://web.archive.org/web/20170306032145/http://sdnalloh.com/converting-win7-from-mbr-to-gpt/">dieses blogposts beschrieben.</a> wenn windows im efi-modus von einer gpt-festplatte gestartet wird, müssen sie ich muss mich nicht mit primären/erweiterten/logischen partitionsproblemen befassen, da gpt diesen unterschied nicht erkennt. normalerweise ist es einfacher, in einer dual-boot-konfiguration einen konsistenten efi-modus-start zu gewährleisten, als beide betriebssysteme auch im bios-modus einzurichten. (weitere informationen zu diesem thema finden sie auf <a href="http://www.rodsbooks.com/efi-bootloaders/csm-good-bad-ugly.html">meiner seite</a> .) wenn sie diesen weg gehen, ist es wahrscheinlich am sichersten, das aktuelle festplatten-setup mit fixparts als ersten schritt zu reparieren. wenn sie jedoch die größenänderung von partitionen erst nach der mbr-zu-gpt-konfiguration verschieben, sind fixparts nicht mehr erforderlich.</p> <p>dies ist eine <em> sehr </em> gute frage. oft können personen in einer organisation in der doku-historie herumschnüffeln, um zu sehen, was der autor über frühere revisionen gedacht hat.</p><p>eine möglichkeit, dies zu umgehen (nicht elegant), besteht darin, eine kopie des dokuments mit <strong>datei</strong> -&gt; <strong>kopie erstellen ...</strong> zu erstellen</p><p>diese kopie enthält den aktuellsten inhalt und startet den verlauf neu. dann können sie die ursprüngliche löschen, die neue umbenennen usw.</p> <p>wenn sie updates installieren als option haben, können sie besser verfolgen, wie oft ihre server für updates neu gestartet werden. aus it-sicht ist ein neustart eines servers normalerweise keine gute sache. so sehr, dass eine der verkaufsfunktionen von linux (ich nehme auch unix an?) immer darin bestand, dass weniger neustarts erforderlich sind.</p><p>dies ist wahrscheinlich eine dieser funktionen, bei denen eine gruppe innerhalb von microsoft dies für eine gute idee hielt, eine andere gruppe sich jedoch sorgen über die möglichen auswirkungen machte, wenn jemand sagen konnte: "ich musste meinen server diesen monat viermal neu starten, und ihr protokollierungssystem zeigt es mir." dass alle von ihnen update bezogen waren. "</p> <p>das problem liegt in ihrer gcc-installation. in den gcc 6+ -versionen ist pie (position independent executables) standardmäßig aktiviert. um es zu kompilieren, müssen sie es deaktivieren. sogar gcc 5 hat das problem. dies ist ein bekannter fehler für gcc. <a href="http://bugs.launchpad.net/bugs/1574982">bug link</a> .</p><p>bisher gibt es keinen offiziellen patch von gcc-seite, daher besteht die problemumgehung darin, das makefile der kernelquelle zu patchen.</p><p>wenn sie mit dem patchen der quelldatei vertraut sind, verwenden sie die codes aus diesem link, um die patchdatei zu erstellen, und versuchen sie dann zu kompilieren. <a href="https://lists.ubuntu.com/archives/kernel-team/2016-may/077178.html">patchdatei</a> </p><p>lassen sie mich wissen, wenn sie probleme bei der installation des patches haben.</p> <p>gehe zu <strong>datei</strong> -&gt; <strong>einstellungen</strong> -&gt; <strong>compiler</strong> überprüfe jetzt <strong>externes build verwenden</strong></p><p>dann das projekt neu erstellen</p> <p>in ihrer paste sehen wir einen microcode (firmware) fehler. wir fragen uns, ob ihre firmware-datei beschädigt ist. laden sie eine neue kopie herunter und installieren sie sie. vom terminal mit einer funktionierenden internetverbindung:</p><pre><code>wget http://mirrors.kernel.org/ubuntu/pool/main/l/linux-firmware/linux-firmware\_1.162\_all.deb sudo dpkg -i linux*.deb </code></pre><p>starten sie neu und lassen sie uns eine neue paste sehen:</p><pre><code>dmesg | grep iwl </code></pre><p>diese seite schlägt vor, dass die firmware für kernel-versionen 4.3 und neuer die -16-version ist. ihr fahrer lädt -22. lassen sie uns experimentieren, indem wir -21 und -22 umbenennen, um zu versuchen, -16 zu laden und zu sehen, ob es hilft.</p><pre><code>cd /lib/firmware sudo mv iwlwifi-8000c-21.ucode iwlwifi-8000c-21.bak sudo mv iwlwifi-8000c-22.ucode iwlwifi-8000c-21.bak </code></pre><p>starten sie neu und lassen sie uns eine paste haben.</p><pre><code>dmesg | grep iwl </code></pre>