到目前为止,我一直在使用以下为我的学校项目生成的makefile:
但是现在我有不同的情况:我应该为一个项目编译4个程序,而部分代码应该编译为.so,以供这4个程序使用。如此处所述:
1-所有应该一起编译为一个。so文件的部分,例如:
gcc -shared -fPIC src/file1.c src/file2.c src/file3.c -o libutils.so
3,4,5应该被编译并与此。so文件链接在一起,例如:
gcc src/file4.c -L'pwd' lutils -o file4.out
对所有3个项目采用相同的方式,对项目2进行了另一种简单的编译。
我在网上,谷歌,您的网站等处徘徊。试图为这种情况找到解决方案,没有任何运气。
已经看到的解决方案是这样的:solution example您在其中提供包含整个项目结构详细信息的makefile。
我考虑过将所有文件分成4个文件夹,位于主文件夹下,并在makefile中创建一个循环,该循环将在每个循环中编译每个程序,并根据索引使用“ if”语句进行不同的编译。但我没有运气,这似乎很复杂(也许有人可以向我展示这样的解决方案...)。
我想知道是否有一种使整个编译过程像当前文件一样通用和自动的方法(可能少一些),
[如果有办法,我想学习并发现它。
谢谢你!!!阿里
Makefile
。您可能想以此开始:
.PHONY: all
all: reloader.exe block_finder.exe formatter.exe printdb.exe
MODULES = reloader block_finder formatter printdb linked_list bitcoin file_handler
SRCS = $(MODULES:%=%.c)
reloader.exe block_finder.exe formatter.exe printdb.exe: libbitcoin_manager.so
reloader.exe: reloader.o
block_finder.exe: block_finder.o
formatter.exe: formatter.o
printdb.exe: printdb.o
libbitcoin_manager.so: linked_list.o bitcoin.o file_handler.o
gcc -shared -fPIC $^ -o $@
%.exe: %.o
gcc $< -L. -lbitcoin_manager -o $@
%.o: %.c
gcc -c $< -o $@
%.d: %.c
gcc -MM -MT $@ -MT $*.o -MF $@ $<
include $(SRCS:%.c=%.d)
因为在图中没有循环,所以在Makefile
中不需要循环。相反,您将所有相关文件放在冒号的左边,并将它们所依赖的文件放在右边。您可能希望在变量中收集更多的“对象”,例如要构建的程序,库中的模块,等等。
我还使用了通用模式从头文件生成依赖关系。所示的方式只是实现它的一种方式。它使用带有“
.d
”扩展名的文件来获得“依赖性”。 GCC具有构建这些文件的选项,它可以扫描源文件并收集所有包含的标头(即使已“堆叠”)。例如,“
bitcoin.d
”看起来像这样:
bitcoin.d bitcoin.o: bitcoin.c bitcoin.h linked_list.h definitions.h \ file_handler.h
根据源中的更改重新生成依赖性文件,它也是目标,而不仅仅是目标文件。编辑:
首先,使用目录会使Makefile更加困难。我不喜欢这样的结构,不仅因为这个原因,而且因为它们将显然彼此属于的头文件和实现文件分开。无论如何,这是增强的
Makefile
:
.PHONY: all SRCDIR = src INCDIR = include BLDDIR = build APPS = reloader block_finder formatter printdb MODULES = reloader block_finder formatter printdb linked_list bitcoin file_handler LIBNAME = bitcoin_manager LIBMODULES = linked_list bitcoin file_handler VPATH = $(SRCDIR) SRCS = $(MODULES:%=%.c) LIB = $(LIBNAME:%=lib%.so) #win LIB = $(LIBNAME:%=%.lib) EXES = $(APPS:%=%.exe) all: $(BLDDIR) $(EXES) $(BLDDIR): mkdir $@ $(LIB): $(LIBMODULES:%=$(BLDDIR)/%.o) gcc -shared -fPIC $^ -o $@ $(EXES): $(LIB) $(EXES): %.exe: $(BLDDIR)/%.o gcc $< -L. -l$(LIBNAME) -o $@ $(BLDDIR)/%.o: %.c gcc -I$(INCDIR) -c $< -o $@ $(SRCDIR)/%.d: %.c gcc -I$(INCDIR) -MM -MT $@ -MT $(BLDDIR)/$*.o -MF $@ $< include $(SRCS:%.c=$(SRCDIR)/%.d)
它使用更多变量来简化重命名和管理不断增长的库和应用程序。一个重要的问题是
VPATH
的使用。这使make
在分配给它的路径列表中搜索源。确保您完全理解它,搜索文章和文档。错误使用起来很容易。模式
$(EXES): %.exe: $(BLDDIR)/%.o
很不错。它由三部分组成,第一部分是目标列表,第二部分是具有单个目标及其来源的通用模式。这意味着对于所有可执行文件,每个可执行文件都是从其目标文件构建的。现在有您的问题:
- 新提案已回答。我没有添加目录,但是使用了
VPATH
。- Make停止运行不是因为exe-from-o模式错误,而是因为它没有找到构建所需目标文件的方法。新提案也解决了这一问题。要了解如果删除旧提案中的这4个食谱会发生什么:您可以尝试,做吧!
- 点就像user3629249试图说的那样,是当前的工作目录。您在Makefile中将其替换为
'pwd'
,我将其替换了。这对于make
并不特殊,在包括Windows在内的所有主要操作系统中都很常见。您可能知道..
,它指定了父目录。make
启动时,它将读取Makefile
或任何给定的文件。如果此文件包含include
指令,则检查列出的文件是否需要重建。即使您用make
调用它,-n
也会执行此操作!在(重新)构建要包括的所有文件之后,它们最终将被包括在内。现在make
具有所有配方,并继续其“常规”工作。