如何在 makefile 中包含和编译库
Posted
技术标签:
【中文标题】如何在 makefile 中包含和编译库【英文标题】:how to include and compile a library in a makefile 【发布时间】:2016-06-21 18:47:07 【问题描述】:我正在尝试构建这个 hello world 项目,其中包含一个包含 .h
和 .cpp
文件的库(因此也需要编译该库)。目录结构是
helloworld/lib/StanfordCPPLib/console.h
/src/hello.h
/src/hello.cpp
可以看到项目代码here
当我使用以下 makefile 运行 make
时,我收到一个错误,即找不到 console.h
(包含在 hello.cpp
中)
CC=gcc
CFLAGS=-I.
DEPS = hello.h
OBJ = hello.o
#console.h is in lib/StanfordCPPLib and it is included by hello.cpp
INC=-I../lib/StanfordCPPLib
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
hellomake: $(OBJ)
g++ -o $@ $^ $(CFLAGS) $(INC)
如何在这个 makefile 中包含 StanfordLibrary,以便它被包含和编译。
(注意,我知道原始源代码包含一个 QT 创建器文件,但是,我正在尝试使用 make 构建它)
【问题讨论】:
在您看到错误消息之前,您将看到执行编译程序的命令,在它上面几行。如果您查看实际执行的命令,您应该能够自己找出问题所在。 @SamVarshavchik wadr,如果您因为您认为我“应该能够自己解决问题”而投反对票,我认为这不是投反对票的正当理由 @Leahcim 好吧,您至少应该向我们展示您遇到的错误。 @πάνταῥεῖ 它在 OP 中说我得到的错误:i get an error that console.h (which is included by hello.cpp) cannot be found
即未找到斯坦福图书馆中的 console.h 文件——还要注意斯坦福图书馆包含 .cpp文件,因此需要对其进行编译。
makefile 中存在矛盾:console.h 在 -I../lib/StanfordCPPLib 还是 -I../lib/StanfordCPP/Lib 中?另外,你的makefile在哪个目录?
【参考方案1】:
主要问题是您构建对象的规则:
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
不使用您在 $(INC) 中的包含路径
另一个问题是您匹配的文件扩展名错误。例如%.c
应该是 %.cpp
。
你还有一些多余的垃圾,所以我建议你像这样更新你的 makefile 以获得这个想法:
CC=gcc
DEPS = hello.h
OBJ = hello.o
INC=-I. -I../lib/StanfordCPPLib
%.o: %.cpp $(DEPS)
$(CC) $(INC) -c $<
hellomake: $(OBJ)
g++ -o $@ $^
这在我的小模拟设置中构建良好。
请记住,您实际上需要在hellomake:
下使用 g++ 才能正确链接所有内容。
【讨论】:
这个答案让我更进一步,但没有正确链接所有库代码。它给了我一个错误Undefined symbols for architecture x86_64: "startupMain(int, char**)", referenced from: _main in hello.o
。该函数startupMain
在斯坦福库的几个文件中声明,这些文件包含在斯坦福CPPLibrary 的console.h
中(请参阅OP 中的源代码链接)。那么您是否看到您的解决方案可能无法在这些库中正确链接?如果有,请有时间修改。
@Leahcim 我可以发誓我已经在这里发表了评论,但是是的,我看到这个 makefile 没有在库中链接。这只是解决您在 OP 中提到的特定问题的示例。这个 makefile 所做的就是正确编译带有包含设置的 hello.cpp。如果要构建和链接库,则需要为库创建一个目标,并在其下将cd
放入斯坦福库目录并编译库。一旦你有了一个库,你需要告诉编译器,在你的 hellomake 目标下,在哪里可以找到库(-L)并链接到它(-l)
@Leahcim 实际上,他们给你的项目文件看起来像是一个应用程序,希望你的代码具有主要功能。即不是图书馆。无论如何,该 pro 文件非常复杂,对于刚开始使用 makefile 的人来说,完全复制是很困难的。您需要编译 Stanford 目录中的所有文件,并将 ../libStanfordCPPLib/*.o
(加上所有其他目录)添加到您的 LIB 和 ../libStanfordCPPLib/*.h
(以及所有其他目录)到您的 INC,然后链接到库斯坦福代码用于您的平台。以上是关于如何在 makefile 中包含和编译库的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Python 的 setup.py 中包含和安装本地依赖项?
如何在您的 Ionic / AngularJs 应用程序中包含和使用节点模块?