jej lokalizację (w podrozdziale poniżej, pokazano jak to zrobić).
</p>
<h4>Konsolidacja programów z bibliotekami współużytkowanymi</h4>
+ <p>
+ Jeśli w kompilowanym programie używaliśmy jakiś niestandardowych
+ bibliotek współużytkowanych, których próżno szukać w zasobach
+ systemowych musimy podczas konsolidacji wskazać scieżkę oraz nazwę
+ biblioteki podczas uruchamiania kompilatora (tak jak robiliśmy to
+ wcześniej - w przypadku bibliotek statycznych). Tutaj niezbędne
+ będzie również wskazanie katalogu w celu dodania go do ścieżki
+ wyszukiwania bibliotek. W tego typu przypadkach nie należy posługiwać
+ się ustawieniemi konsolidatora dynamicznego.
+ </p>
+ </p>
+ Opcja, o której mowa to: <code class="code-inline">-Wl,-rpath</code>.
+ Przykład poniżej może to zobrazować:
+ </p>
+<pre class="code-inline">
+xf0r3m@laptop-5cfe659:~$ cc -o myprog myprog.o -Wl,rpath=/opt/pt/lib -L/opt/pt/lib -lnetstats
+</pre>
+ <p>
+ Domyślny standardem dla plików wykonywalnych oraz bibliotek w
+ dystrybucjach Linuksa jest <strong>ELF</strong> - <em>Executable and
+ Linkable Format</em>, dzięki czemu możemy zmienić ścieżkę
+ wyszukiwania bibliotek dla środowiska wykonawczego. Możemy tego
+ dokonać za pomocą polecenia <em>patchelf</em>.
+ </p>
+ <h4>Problemy związane z bibliotekami współdzielonymi</h4>
+ <p>
+ Najczęściej występującym problemem związanym z bibliotekami
+ współdzielonymi jest ich potencjalny brak w naszym systemie. Wówczas
+ musimy szukać pakietów z końcówką <em>-dev</em> w nazwie i
+ ześmiecać system gigabajtami niepotrzebnych plików.
+ </p>
+ <p>
+ Kolejną rzeczą może być, za długa wartość zmiennej
+ <code class="code-inline">LD_LIBRARY_PATH</code>. Zawartość tej
+ zmiennej jest odczytywana przez konsolidator, który następnie
+ przeszukuje podane ścieżki pod kątem występowania bibliotek. Ta
+ zmianna ma pierwszeństwo przez pozostałymi lokalizacjami, w których
+ mogą wystąpić biblioteki w systemie. Dlatego też ustawienie jej
+ globalnie gdzieś w systemie (np. w plikach konfiguracyjnych powłoki)
+ może spowodować znaczy spadek wydajności systemu. Jeśli już musimy
+ wskazać inną lokalizację bibliotek dla programów a nie chcemy
+ ponownie kompilować (lub nie mamy takiej możliwości, brak kodu
+ źródłowego), możemy utworzyć tzw. skrypt <em>opakowywujący</em> -
+ manipulujący zawartością zmiennej
+ <code class="code-inline">LD_LIBRARY_PATH</code> oraz uruchamiający
+ żądany program. Przy czym zmienna zostanie zmieniona wyłącznie
+ w obrębie procesu podpowłoki uruchomionego na potrzeby skryptu
+ (Więcej o skryptach znajduje się w dodatku A).
+ </p>
+ <p>
+ Nie mniej jednak najlepszą ucieczką przez problemami związanymi z
+ bibliotekami jest ich wskazanie w procesie konsolidacji lub użycie
+ bibliotek statycznych.
+ </p>
+ <h3 id="14.1.4.headersfiles">14.1.4. Pliki nagłówkowe</h3>
+ <p>
+ Aby programiści mogi skorzystać z bibliotek w swoich programach muszą
+ się do nich w jakiś sposób odwołać. W języku C mogą wykorzystać do
+ tego <strong>pliki nagłówkowe</strong> zawierający deklaracje typów
+ oraz funkcji bibliotecznych. Jednym z takich plików, był <em>stdio.h</em>
+ przedstawiany we wcześniejszych przykładach - ten plik nagłówkowy
+ udostępniał nam funkcję <code class="code-inline">printf()</code>.
+ </p>
+ <p>
+ Do wskazywania plików nagłówkowych służy dyrektywa
+ <code class="code-inline">#include</code>. Czasami zdarza się, że
+ programiści dodają omyłkowo jakiś plik nagłówkowy, który nie
+ istnieje. Tego typu błędy zostają wyłapane już na poziomie kompilacji
+ gdzie kod jest wstępnie analizowany.
+ </p>
+ <p>
+ Oczywiście, może tak być, że wykorzystywane przez programistów
+ pliki nagłówkowe nie znajdują się w standardowej lokalizacji dla
+ tego rozdzaju plików w systemie (<em>/usr/include</em>). Jeśli tak
+ jest to, możemy skorzystać z opcji kompliatora pozwalającą dodać
+ podany katalog do ścieżki wyszukiwania plików nagłówkowych.
+ </p>
+<pre class="code-block">
+xf0r3m@laptop-5cfe659:~$ cc -c -I/opt/pt/include netstats.c
+</pre>
+ <p>
+ Istnieją dwie metody na dołączenie plików nagłówkowych do kodu
+ programu. Różnice te są dość subtelne jednak mają dość duże
+ znaczenie.
+ </p>
+<pre class="code-block">
+#include <stdio.h>
+</pre>
+ <p>
+ Klasyczne dołączenie pliku nagłówkowego. Mówi on nam, że kompilator
+ będzie przeszukiwać zasoby systemowego, aby użyć tego pliku na
+ potrzeby kompilacji.
+ </p>
+<pre class="code-block">
+#include "ip.h"
+</pre>
+ <p>
+ Użycie podwójnych apostrofofów zamiast ostych nawiasów, spowoduje że
+ kompilator przeszuka katalog z podanym kodem źródłowym w poszukiwaniu
+ tak załączonego pliku nagłówkowego. Tak załączone pliki nagłówkowe
+ muszą występować w tym samym folderze do kompilowany kod źródłowy.
+ Jest to przydatne w przypadku, gdy korzystamy z własnych plików tego
+ rodzaju.
+ </p>
+ <h4>Preprocesor języka C</h4>
+ <p>
+ Wcześnie mówiliśmy o kompilatorze w kontekście odnajdywania plików
+ nagłówkowych, jednak nie jest do dokońca prawdą. Preprocesor w
+ przypadku języka C, zajmuje się dostoswaniem kodu pisanego przez
+ człowiek dla kompilatora. Wykonuje on swoje działania na podstawie
+ <strong>dyrektyw</strong> zapisywanych przez ludzi w kodzie dodając
+ do niego kilka uproszczeń oraz skrótów.
+ </p>
+ <p>
+ Dyrektywy to nic innego jak instrukcje. Jednak, aby odróżniały się
+ do instrukcji właściwego języka w C, poprzedza się znakiem
+ krzyżyka (<strong>#</strong>). Taką dyrektywę poznaliśmy już, a jest
+ nią dyrektywa <code class="code-inline">#include</code>. W języku C
+ dostępne są trzy rodzaje dyrektyw:
+ </p>
+ <ul>
+ <li><strong>Dołaczenia plików nagłówkowych</strong> - <em>#include</em>
+ - nakazuja preprocesorowi dołaczyć do kodu źródłowego cały plik
+ nagłówkowy.</li>
+ <li><strong>Makra</strong> - <em>#define</em> - makra nakazują
+ zmianę w kodzie nazwy makra np. <em>PI</em> na jej wartość np.
+ <em>3.14</em>. Konwencja mówi, że nazwy makr zapisujemy wielkimi
+ literami i nie należy przesadzać z ich stosowaniem. Nie są one
+ również tożsame ze stałymi, które możemy znać innych języków
+ programowania. Przykładem makra może być np.:
+<pre class="code-block">
+#define PI 3.14
+</pre>
+</li>
+ <li><strong>Kompilacja warunkowa</strong> - <em>#ifdef</em>,
+ <em>#if</em>, <em>#endif</em> - zwane rownież dyrektywami
+ warunkowymi. Pozwalaja one kontrolować kompilację kodu źródłowego
+ na podstawie występowania makr w preprocesorze
+ (dyrektywa <em>#ifdef</em>) lub niezerowego <em>warunku</em>
+ (dyrektywa <em>#if</em>). W przypadku gdy warunek nie jest
+ spełniony, kod źródłowy między dyrektywami <em>#ifdef</em> oraz
+ <em>#if</em> a <em>#endif</em> nie zostanie w ogóle skompilowany.
+ </li>
+ </ul>
+ <p>
+ Istotnym czynnikiem w wykorzystaniu makr a co za tym idzie kompilacji
+ warunkowej jest możliwość przekazania makra do preprocesora za pomocą
+ opcji <em>-D</em> kompilatora. Taka możliwość interakcji, na pewno
+ bardziej wyjaśnia sens istnienia dyrektyw oraz samego preprocesora.
+ </p>
+ <p>
+ Odnośnie samego preprocesora, to nie zna on żadnych elementów języka
+ C. Jest on skupiony wyłącznie na makrach oraz pozostałych dyrektywach.
+ </p>
+ <h2 id="14.2.make">14.2. Narzędzie make</h2>
</div>
<p style="margin: 15px; padding: 0; outline: 0;">
2024; COPYLEFT; ALL RIGHTS REVERSED;