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.


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.


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


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.


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.


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.


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>

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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.