Kompilowanie kodu z apue

12

Właśnie zacząłem czytać książkę: Programowanie zaawansowane w środowisku UNIX® . Chciałem spróbować uruchomić pierwszy przykład kodu. Używam Scientific Linux 6.4.

Pobrałem kod źródłowy i jak mówi w swoim README, wpadłem makew pliku nieskompresowanego.

Napisałem pierwszy program (próbne lspolecenie)

#include "./include/apue.h"
#include <dirent.h>

int
main(int argc, char *argv[])
{
    DIR           *dp;
    struct dirent *dirp;

    if(argc!=2)
        err_quit("usage: test directory_name");

    if((dp=opendir(argv[1]))==NULL)
        err_sys("Can't open %s", argv[1]);

    while((dirp=readdir(dp))!=NULL)
        printf("%s\n", dirp->d_name);

    closedir(dp);
    return 0;
}

i umieść go w nieskompresowanym pliku. Ponieważ książka poradził mi potem pobiegł: gcc myls.c. Ale pojawia się ten błąd:

# gcc myls.c
/tmp/ccWTWS2I.o: In function `main':
test.c:(.text+0x20): undefined reference to `err_quit'
test.c:(.text+0x5b): undefined reference to `err_sys'
collect2: ld returned 1 exit status

Chciałem wiedzieć, jak mogę rozwiązać ten problem. Chcę też móc uruchomić kod, który piszę w dowolnym katalogu.

makhlaghi
źródło
Skąd spodziewasz err_{quit,sys}się pochodzić?
Chris Down,
W nieskompresowanym kodzie źródłowym znajduje się katalog: includezawierający plik nagłówka apue.h. Ale to jest jedyny plik w tym katalogu. Nie rozumiem, gdzie są rzeczywiste definicje funkcji! Myślałem, że ktoś może tutaj znać strukturę pliku kodu źródłowego tej książki.
makhlaghi
Te .hpliki zawierają protypes dla funkcji. Ich implementacje są w .solub .apliki, które muszą być obecne na pudełku. Są to biblioteki dynamiczne i statyczne, które zawierają funkcje.
slm
Co to w ogóle jest apue.h?
głosy

Odpowiedzi:

13

Krótki przegląd pisania i kompilacji programów w Advanced Programming in UNIX® Environment , dzięki SLM za pomoc w zrozumieniu kroków. Możesz pobrać kod źródłowy stąd . Chciałbym, aby ta informacja została dołączona jako część dodatku b książki, w której wyjaśniono plik nagłówka.

Nieskompresowany plik zawiera katalogi z nazwami rozdziałów i dwoma innymi nazwanymi includei lib. Te z nazwami rozdziałów zawierają wszystkie programy z tego rozdziału.

includeKatalog zawiera plik nagłówka, który jest używany w większości programów w książce: apue.h. libKatalog ma kod źródłowy wdrożeń dla tego cel.

Załóżmy, że nieskompresowany plik znajduje się w:, SCADDRESS/na przykład może to być: /home/yourid/Downloads/apue.3e/

Po rozpakowaniu kodu źródłowego przejdź do katalogu i uruchom make:

$ cd SCADDRESS
$ make

makeskompiluje wszystkie programy we wszystkich rozdziałach. Ale ważne jest to, że wcześniej sprawi, że biblioteka będzie zawierać implementacje funkcji w apue.h.

Aby skompilować przykładowy program napisany z książki, uruchom następującą komendę GCC (zakładając, że nazwa twojego programu myls.cjest pierwsza w książce):

gcc -o myls myls.c -I SCADDRESS/include/ -L SCADDRESS/lib/ -lapue

-Iinformuje, gccktóry katalog ma szukać pliku dołączanego. -Linformuje o lokalizacji katalogu biblioteki i -lapueinformuje o nazwie pliku biblioteki, którego ma szukać w tym katalogu. Taki sposób, że -LXXX oznacza poszukiwanie pliku w katalogu biblioteki o nazwie: libXXX.a lub libXXX.so.

makhlaghi
źródło
Czasami może być pouczające dodanie -Walldo gccpolecenia, aby częściej ostrzegało.
MattBianco,
3

Myślę, że ten przepływ pytań i odpowiedzi zatytułowany: Gdzie jest zdefiniowana funkcja err_sys ()? ma to, czego potrzebujesz. W 2 odpowiedziach w tym wątku było powiedziane:

A1

err_sys () to funkcja używana w kilku książkach napisanych przez W. Richarda Stevensa. Ta funkcja służy do drukowania, jaki rodzaj błędu wystąpił.

Funkcja jest używana w programach w tekstach z niestandardowym plikiem nagłówka „ourhdr.h” (lub czymś innym). Sprawdź w załączniku listę nagłówków lub definicję funkcji.

A2

Źródło tej funkcji (z Advanced Programming in the UNIX® Environment, autorstwa W. Richarda Stevensa) można znaleźć na stronie internetowej książki: http://www.apuebook.com/ .

Bibliografia

slm
źródło
Dzięki, ale mój problem polega na tym, jak go skompilować, aby te błędy się nie pojawiały. To err_systylko przykład, w tym pliku nagłówkowym znajdują się inne funkcje. Szukam więc ogólnej odpowiedzi na ten problem (jak dołączyć plik nagłówka i pomyślnie go skompilować), nie przepisując tej konkretnej funkcji.
makhlaghi
1
@makhlaghi - błędy są b / c brakuje podstawowych implementacji. Zazwyczaj dołączasz je gccza pomocą -Largumentów odwołujących się do bibliotek, których chcesz użyć. Biblioteki to pliki .solub .a. Ten samouczek może być pomocny w zapoznaniu się z / gcc, ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html . W szczególności ta sekcja: „Wyszukiwanie plików nagłówkowych i bibliotek (-I, -L i -l)”
slm
Bardzo dziękuję za cierpliwość w kontaktach ze mną (brak doświadczenia!). Zrozumiałem, jak to skompilować. Muszę użyć tego polecenia: gcc -o myls myls.c -L LIBPOSITION -lapue. Gdzie LIBPOSITION znajduje się w libkatalogu nieskompresowanego katalogu. Dzięki jeszcze raz.
makhlaghi
@makhlaghi - nie wspominaj o tym. Lubię pomagać innym zrozumieć, jak działają rzeczy. Wierzcie lub nie, ponieważ muszę wyjaśniać różne rzeczy, co pomaga mi lepiej je rozumieć. Dzięki za Q i powodzenia w / gcc podróży!
slm
2

Dla mnie zadziałały następujące kroki (Ubuntu 14.04 64bit):

  1. wget http://www.apuebook.com/src.3e.tar.gzPobierz spakowane archiwum tar z oficjalnej strony książki
  2. tar xzf src.3e.tar.gzSpowoduje to apue.3edomyślnie utworzenie rozpakowanego folderu o nazwie pod bieżącym katalogiem
  3. cd apue.3e
  4. sudo apt-get install libbsd-dev. To jest dla łącza -lbsd w / wątkach
  5. make Spowoduje to automatyczne skompilowanie całego kodu źródłowego we wszystkich folderach
  6. cd intronastępnie ./ls1 ..działa zgodnie z oczekiwaniami (wyświetla listę plików z katalogu nadrzędnego)

Być może będziesz musiał się rozejrzeć, aby znaleźć inne fragmenty kodu z książki, ale powinno to być proste.

Yibo Yang
źródło
1

To, co makhlighi wyjaśnił w swoim ostatnim komentarzu, zadziałało dla mnie, ale musiałem użyć innego kodu źródłowego niż ten z oficjalnej strony www.apuebook.com.

Ten, którego użyłem, można znaleźć na https://github.com/roktas/apue2e . Jak ktoś wyjaśnił, ten został zaimplementowany w celu współpracy z nowoczesnym systemem Linux.

Bilal Korir
źródło
Może mógłbyś to trochę rozwinąć?
slm
0

Udało mi się zbudować bibliotekę, korzystając z podanej tutaj instrukcji wiersza poleceń. Miałem trudności z budowaniem próbki w Xcode. Aby to zrobić, zdefiniowałem ścieżki wyszukiwania plików nagłówków i bibliotek (panel „Ustawienia kompilacji”). Następnie zdefiniowałem samą bibliotekę w okienku „Fazy budowania” niż w panelu „Połącz binarne z bibliotekami”. Po tym wszystko jest proste.

Thierry Jeanneret
źródło
0

Jeśli apue.3e jest zainstalowany, możesz spróbować umieścić apue w domyślnym katalogu systemu operacyjnego, np .:

code@lab:~/src/code$ sudo cp ../apue.3e/include/apue.h /usr/include/
code@lab:~/src/code$ sudo cp ../apue.3e/lib/libapue.a /usr/lib/

Po skompilowaniu kodu dodaj argument: -lapue

code@lab:~/src/code$ gcc -o myls myls.c -lapue
code@lab:~/src/code$ ./myls
Usage: ls <dir>
odpluskwić
źródło
0

„err_sys” i „err_quit” znajdują się w pliku o nazwie „errno.c”, który nie znajduje się w bieżącym katalogu roboczym. Przede wszystkim otwórz folder „apue”, który pobrałeś i rozpakowałeś, i skopiuj wszystkie elementy w tym folderze, na przykład advio, demony itp., Wszystko do bieżącego katalogu roboczego. za pomocą polecenia „pwd”. Teraz w folderze „include” znajdziesz plik nagłówka apue. Skopiuj go również do bieżącego katalogu roboczego. W skrócie, każdy plik .c, którego będziesz używać w swoim programie, musi znajdować się w bieżącym katalogu roboczym. Skopiuj wszystkie pliki do bieżącego katalogu roboczego.

Teraz, aby rozwiązać problem. Plik errno.c znajduje się w folderze lib w folderze apue. Skopiuj go do bieżącego katalogu roboczego. To rozwiąże problem.

Shanif Ansari
źródło