图书馆链接

时间:2013-03-01 19:26:46

标签: makefile

我正在努力学习使用Zed Shaw的学习C的C编程。我一直在研究ex26,我们创建了一个用于安装软件的程序“devpkg”。此练习需要安装Apache Portable Runtime库。在为本练习编写代码之后,我无法使用以下makefile编译程序:

    PREFIX?=/user/local
    CFLAGS=-g -Wall -I${PREFIX}/apr/include/apr-1 -I{PREFIX}/apr/include/apr-util-1
    LDFLAGS=-L${PREFIX}/apr/lib -lapr-1 -pthread -laprutil-1

    all: devpkg

    install: all
             install -d${DESTDIR}/${PREFIX}/bin/
             install devpkg ${DESTDIR}/${PREFIX}/bin/

    clean:
            rm -f *.o
            rm -f devpkg
            rm -f *.dSYM

这个makefile似乎不起作用,因为我使用“$ make devpkg”时并未声明所有APR库函数。作为旁注,我在Ubuntu虚拟机上运行它。文中给出的解决方案是更改配置文件,然后“运行ldconfig”以帮助链接器找到合适的库。
我不太了解ldconfig的手册页,以便正确使用该函数。如何正确运行ldconfig?

经过一些挖掘后,我发现在makefile中使用“LDLIBS”代替“LDFLAGS”的引用修复了问题。我修改了makefile和编译的程序。

允许C编译器正确链接到APR库的“LDFLAGS”和“LDLIBS”之间有什么区别?是否有一个方便的命令列表可以帮助我更好地理解如何正确生成makefile?

感谢您的时间。

2 个答案:

答案 0 :(得分:3)

来自GNU Make Manual 10.2隐含规则目录

  

链接单个目标文件   
   n 是通过运行链接器(通常称为 n.o )从 ld 自动生成的C编译器。使用的精确配方是“ $(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS) ”。

如您所见,LDFLAGS位于您的目标文件之前,LDLIBS位于之前。有时候这个命令很重要 - 显然在你的情况下确实如此。

编者注:尽管使用make的隐式规则支持有时候很方便,但它几乎总是会让人感到更加混乱。我敦促你写一个完整的makefile - 它会帮助你更好地理解发生了什么,并希望将来避免这类问题。

答案 1 :(得分:3)

我只想添加此答案作为将“LDFLAGS”更改为“LDLIBS”的替代方法。上面的解决方案确实适用于我的情况,但在我看到其他人可能觉得有用或有趣之前,我找到了另一种解决方案(虽然不那么直接)。在编译时,我看到了许多“未定义的引用”错误,例如:

/MyCode/LCTHW/devpkg/devpkg.c:18: undefined reference to `apr_pool_initialize'

经过多次试验和错误,我改变了makefile(仍然使用LDFLAGS):

CC=gcc
PREFIX?=/usr/local
CFLAGS=-g   -Wall   -I$(PREFIX)/apr/include/apr-1   -I$(PREFIX)/apr/include/apr-util-1
LDFLAGS=-L$(PREFIX)/apr/lib -lapr-1 -laprutil-1 -pthread
OBJECTS=bstrlib.o   db.o    shell.o commands.o  devpkg.o

all:    devpkg

devpkg: $(OBJECTS)
    $(CC)   $(CFLAGS)   $(OBJECTS)  -o  devpkg  $(LDFLAGS)

install:    all
    install -d $(DESTDIR)/$(PREFIX)/bin/
    install devpkg $(DESTDIR)/$(PREFIX)/bin/

clean:
    rm -f *.o
    rm -f devpkg
    rm -rf *.dSYM

然后,我必须将.conf文件添加到/etc/ld.so.conf.d,其中包含apr库的路径,即

/usr/local/apr/lib

然后运行

sudo ldconfig

所以系统会选择新的.conf文件,因此知道在哪里找到库。从我所看到的,似乎最后一步是必要的,因为库没有存储在/ usr / local / lib中。如果我删除了.conf文件并重新运行ldconfig进行更新,程序将编译但无法在运行时找到库(无论是使用我的makefile还是使用OP编译)。

虽然我不完全理解我的解决方案,但它至少允许我编译并运行程序而没有错误。希望这个解决方案会让其他人感兴趣,也许更有知识的人能够更详细地解释它为什么会起作用。