apueからコードをコンパイルする


12

たった今、私は本を読み始めました:UNIX®環境での高度なプログラミング。最初のコード例を実行してみました。Scientific Linux 6.4を実行しています。

ソースコードをダウンロードし、READMEにあるようmakeに、非圧縮ファイルで実行しました。

最初のプログラムを作成しました(モックlsコマンド)

#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;
}

それを非圧縮ファイルに入れます。本が助言したように、私は走りました:gcc myls.c。しかし、私はこのエラーを受け取ります:

# 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

この問題を解決する方法を知りたかった。また、任意のディレクトリで記述したコードを実行できるようにします。


どこerr_{quit,sys}から来ると思いますか?
クリスダウン

非圧縮ソースコードにincludeは、ヘッダーファイルがあるディレクトリがありますapue.h。しかし、これはそのディレクトリ内の唯一のファイルです。実際の関数定義がどこにあるのかわかりません!誰かがこの本のソースコードファイルの構造に精通していると思います。
マクラギ

.hファイルには、機能のためのprotypesが含まれます。それらの実装は、ボックスに存在する必要のあるファイル.soまたは.aファイルです。これらは、関数を含む動的および静的ライブラリです。
slm

さらにはapue.h何ですか?

回答:


13

UNIX®環境での高度なプログラミングでプログラムを作成およびコンパイルする方法の簡単なレビュー。手順を理解してくれたslmに感謝します。ここからソースコードをダウンロードできます。この情報が本の付録bの一部として含まれていて、ヘッダーファイルが説明されていることを望みます。

圧縮されていないファイルは、章の名称およびという名前の2つの他の人とのディレクトリが含まれていますincludelib。章の名前が付いているものには、その章のすべてのプログラムが含まれています。

includeディレクトリには、本の中のプログラムのほとんどで使用されているヘッダファイルが含まれていますapue.hlibディレクトリは、そのヘッダの実装のソースコードを有しています。

非圧縮ファイルが次の場所にあると仮定 SCADDRESS/しましょう。たとえば、次のようになります。 /home/yourid/Downloads/apue.3e/

ソースコードを解凍したら、ディレクトリに移動して実行しますmake

$ cd SCADDRESS
$ make

makeすべての章のすべてのプログラムをコンパイルします。しかし重要なことは、その前に、の関数の実装を含むライブラリを作成することapue.hです。

本から作成したサンプルプログラムをコンパイルするにmyls.cは、次のGCCコマンドを実行します(本の最初の名前が​​プログラム名であると仮定します)。

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

-I伝えgccファイルをインクルードを探すためにどのディレクトリ。 -Lライブラリディレクトリの場所を -lapue通知し、、はそのディレクトリで検索するライブラリファイルの名前を通知します。-LXXXは、ライブラリディレクトリ内でlibXXX.aまたはlibXXX.soという名前のファイルを探すことを意味します。


より頻繁に警告するようにコマンドに追加する-Wallと、啓発的な場合がありますgcc
MattBianco

3

私はこのstackoverflowのQ&Aと題しています:関数err_sys()はどこで定義されていますか?必要なものがあります。そのスレッドの2つの答えには、次のように書かれていました。

A1

err_sys()は、W。Richard Stevensによって書かれたいくつかの本で使用されている関数です。この関数は、発生したエラーのタイプを出力するために使用されます。

この関数は、カスタムヘッダーファイル "ourhdr.h"(または他の何か)を含むテキスト内のプログラムで使用されます。ヘッダーのリストまたは関数の定義については、付録を確認してください。

A2

この関数のソース(UNIX環境の高度なプログラミング、W。Richard Stevensによる)は、本のWebサイトhttp://www.apuebook.com/にあります

参照資料


感謝しますが、私の問題はそれをコンパイルする方法なので、これらのエラーは発生しません。これerr_sysは単なる例であり、そのヘッダーファイルには他の関数があります。したがって、この問題に対する一般的な答え(ヘッダーファイルをインクルードして正常にコンパイルする方法)を探していますが、この特定の関数を書き換えることはありません。
makhlaghi

1
@makhlaghi-エラーはb / cであり、基礎となる実装が欠落しています。通常、使用するライブラリを参照する引数gccを使用してこれらを含め-Lます。ライブラリは.soまたは.aファイルです。このチュートリアルはgccntu.edu.sg / home / ehchua / programming / cpp / gcc_make.htmlに慣れるのに役立ちます。特にこのセクション:「ヘッダーファイルとライブラリの検索(-I、-L、および-l)」
slm

私に対処することにあなたの忍耐に感謝します(経験が浅い!)。コンパイル方法を理解しました。次のコマンドを使用する必要がありますgcc -o myls myls.c -L LIBPOSITION -lapue。LIBPOSITIONはlib、非圧縮ディレクトリのディレクトリにあります。再度、感謝します。
マクラギ

@makhlaghi-言及しないでください。私は他の人が物事の仕組みを理解するのを助けるのが好きです。信じられないかもしれませんが、物事を説明する必要があるので、物事をよりよく理解するのにも役立ちます。Qとあなたのgcc旅の幸運に感謝します!
slm

2

次の手順は私のために働いています(Ubuntu 14.04 64bit):

  1. wget http://www.apuebook.com/src.3e.tar.gz公式の本サイトからgzip圧縮されたtarアーカイブをダウンロードします
  2. tar xzf src.3e.tar.gzこれにより、apue.3eデフォルトで現在のディレクトリの下に呼び出される解凍されたフォルダが作成されます
  3. cd apue.3e
  4. sudo apt-get install libbsd-dev。これは、/ threadsのリンク-lbsd用です
  5. make これにより、すべてのフォルダー内のすべてのソースコードが自動的にコンパイルされます。
  6. cd introその後./ls1 ..、期待どおりに動作します(親ディレクトリからファイルをリストします)

この本から他のコードスニペットを見つけるためにgrepする必要があるかもしれませんが、それは簡単なはずです。


1

makhlighiが彼の最後のコメントで説明したことは私にとってはうまくいきましたが、公式ウェブサイトwww.apuebook.comのものではなく、異なるソースコードを使用する必要がありました。

私が使用したものはhttps://github.com/roktas/apue2eにあります。誰かが説明したように、これは最新のLinuxシステムで動作するように実装されています。


おそらくこれを少し詳しく説明できますか?
slm

0

ここに示したコマンドライン命令を使用して、ライブラリを正常に構築しました。Xcodeでサンプルを作成するのに苦労しました。それを実現するために、ヘッダーファイルとライブラリの検索パスを定義しました([ビルド設定]ペイン)。「ライブラリとバイナリをリンク」ペインよりも「ビルドフェーズ」でライブラリ自体を定義したよりも。その後、それは簡単です。


0

apue.3eがインストールされている場合は、apueをosのデフォルトディレクトリに置くことができます。例:

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/

コードがコンパイルされたら、引数を追加してください: -lapue

code@lab:~/src/code$ gcc -o myls myls.c -lapue
code@lab:~/src/code$ ./myls
Usage: ls <dir>

0

「err_sys」と「err_quit」は、現在の作業ディレクトリにない「errno.c」というファイルに存在します。まず、ダウンロードして解凍したフォルダー「apue」を開き、そのフォルダー内のすべてのアイテム(たとえば、advio、daemonsなど)をすべて現在の作業ディレクトリにコピーします。現在の作業ディレクトリは、コマンド 'pwd'を使用すると、フォルダー 'include'にヘッダーファイルapueがあります。これも現在の作業ディレクトリにコピーします。つまり、プログラムで使用する.cファイルは、現在の作業ディレクトリにあるため、これらのファイルをすべて現在の作業ディレクトリにコピーします。

さて、問題を解決するために、errno.cファイルはapueフォルダーのlibフォルダーにあります。それを現在の作業ディレクトリにコピーします。これで問題が解決します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.