从Apue编译代码


12

到目前为止,我已经开始阅读《UNIX®环境中的高级编程》这本书。我想尝试运行其第一个代码示例。我正在运行Scientific Linux 6.4。

我下载了源代码,并按自述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。但这是该目录中的唯一文件。我不知道实际的函数定义在哪里!我以为有人可能在这里熟悉本书的源代码文件结构。
makhlaghi

这些.h文件包括功能的原型。它们的实现位于.so.a需要显示在包装盒中的文件中。这些是包含功能的动态和静态库。
slm

什至是apue.h什么?
声音

Answers:


13

简短回顾一下UNIX®环境中如何在Advanced Programming中编写和编译程序,这要感谢slm帮助我理解了这些步骤。您可以从此处下载源代码。我希望此信息作为本书附录b的一部分包含在内,在其中解释了头文件。

未压缩的文件包含带有各章名称的目录以及另两个名为include和的目录lib。具有各章名称的程序中包含该章的所有程序。

include目录包含该书中大多数程序中使用的头文件apue.h。该lib目录具有该标头的实现源代码。

假设未压缩的文件位于: SCADDRESS/,例如,它可能是: /home/yourid/Downloads/apue.3e/

解压缩源代码后,进入目录并运行make

$ cd SCADDRESS
$ make

make将编译所有章节中的所有程序。但重要的是,在此之前,它将使该库包含中的功能的实现apue.h

要编译您从书中编写的示例程序,请运行以下GCC命令(假设程序名是myls.c书中的第一个):

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

-I告诉要在gcc哪个目录中查找包含文件。 -L告诉它库目录的位置,和 -lapue告诉要在该目录中查找的库文件的名称。这样,-LXXX意味着在库目录中查找名称为libXXX.a或libXXX.so的文件。


有时添加-Wallgcc命令以使其发出更多警告可能会很有启发性。
MattBianco 2014年

3

我认为标题为“ stackerflow Q&A”的函数在哪里定义err_sys()?有您需要的。该线程中的2个答案是这样说的:

A1

err_sys()是W.Richard Stevens写的几本书中使用的函数。此功能用于打印发生什么类型的错误。

该函数在带有自定义头文件“ ourhdr.h”(或其他名称)的文本程序中使用。检查附录中的标题列表或函数定义。

A2

该功能的来源(来自UNIX®环境中的Advanced Programming,由W. Richard Stevens撰写)可以在该书的网站上找到:http : //www.apuebook.com/

参考文献


谢谢,但是我的问题是如何编译它,所以这些错误不会出现。的err_sys仅仅是一个例子,也有在该头文件的其它功能。因此,我正在寻找解决此问题的通用方法(如何包括头文件并成功编译它),而不是重写此特定函数。
makhlaghi 2013年

1
@makhlaghi-错误是b / c,您缺少基本的实现。通常,gcc使用-L引用要使用的库的参数来包含这些w / using 参数。这些库是.so.a文件。本教程可能是结识W /乐于助人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 2013年

@makhlaghi-别说了。我喜欢帮助他人了解事物的运作方式。信不信由你,通过必须解释的事情,它也帮助我更好地理解事物。感谢您的问与答,祝您好运!
slm

2

以下步骤对我有效(Ubuntu 14.04 64位):

  1. wget http://www.apuebook.com/src.3e.tar.gz官方书籍网站下载压缩的tar存档
  2. tar xzf src.3e.tar.gzapue.3e默认情况下,这将创建在当前目录下调用的解压缩文件夹
  3. cd apue.3e
  4. sudo apt-get install libbsd-dev。这是针对/ threads中的-lbsd链接
  5. make 这将自动编译所有文件夹中的所有源代码
  6. cd intro然后./ls1 ..按预期工作(列出父目录中的文件)

您可能需要四处寻找才能从本书中找到其他代码片段,但这应该很简单。


1

makhlighi在他的最后评论中解释的内容对我有用,但我不得不使用不同的源代码,而不是来自官方网站www.apuebook.com的源代码。

我使用的一个可以在https://github.com/roktas/apue2e中找到。正如某人所解释的那样,已经实现了这一功能,以便与现代Linux系统一起使用。


也许您可以详细说明一下?
slm

0

我已经使用此处给出的命令行指令成功构建了库。我很难在Xcode中构建示例。为此,我已经定义了头文件和库的搜索路径(“构建设置”窗格)。除了在“构建阶段”中定义库本身之外,还没有在“将二进制文件与库链接”窗格中定义。在那之后,轻而易举。


0

如果已安装apue.3e,则可以尝试将apue放入操作系统的默认目录,例如:

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文件夹中,将其复制到当前工作目录中,这将解决您的问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.