我怎么能对C项目SRC,OBJ,和BIN子目录创建一个Makefile? [英] How can I create a Makefile for C projects with SRC, OBJ, and BIN subdirectories?

查看:174
本文介绍了我怎么能对C项目SRC,OBJ,和BIN子目录创建一个Makefile?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几个月前,我想出了下面的泛型的Makefile 学校分配:

 #------------------------------- -----------
#通用的Makefile

#作者:yanick.rochon@gmail.com
#日期:2010-11-05

#更新日志:
#0.01 - 第一个版本
#------------------------------------------------#项目名称(生成可执行这个名字)
TARGET =项目名称CC = GCC -std = C99 -c
#编译这里的标志
CFLAGS = -Wall -I。链接器GCC = -o
#链接旗帜在这里
LFLAGS = -Wall来源:= $(通配符的* .c)
包含:= $(通配符是* .h)
对象:= $(来源:.C = * O)
RM = RM -f$(TARGET):OBJ
    @ $(LINKER)$(TARGET)$(LFLAGS)$(对象)
    @echo链接完成!OBJ:$(SOURCES)$(含)
    @ $(CC)$(CFLAGS)$(来源)
    @echo编制完成!清洁:
    @ $(RM)$(TARGET)$(对象)
    @echo清理完成!

这将基本编译每个 .C .H 文件来生成的.o 文件和可执行项目名称都在同一个文件夹中。

现在,我想推动这个一点点。 如何写一个Makefile来编译以下目录结构一个C项目?

  ./
 ./Makefile
 ./src/*.c;*.h
 ./obj/*.o
 ./bin/<executable>

在换句话说,我想有一个编译C源文件从 ./ SRC / ./ OBJ / ,然后链接一切创造可执行./斌/

我试图读取不同的Makefile,但我根本无法让他们为上述项目结构工作;相反,项目失败了各种各样的错误进行编译。当然,我可以用完全成熟的IDE(MonoDevelop的,Anjuta的,等等),但老实说,我preFER坚持用gedit和良好的醇'端。

有没有大师谁可以给我一个工作的解决方案,或有关如何可以做到这一点的明确信息?谢谢!

** UPDATE(V4) **

最终的解决方案:

 #------------------------------- -----------
#通用的Makefile

#作者:yanick.rochon@gmail.com
#日期:2011-08-10

#更新日志:
#2010-11-05 - 第一版
#2011-08-10 - 增加结构:来源,对象,二进制文件
#感谢http://stackoverflow.com/users/128940/beta
#------------------------------------------------#项目名称(生成可执行这个名字)
TARGET =项目名称CC = GCC
#编译这里的标志
CFLAGS = -std = C99 -Wall -I。链接器GCC = -o
#链接旗帜在这里
LFLAGS = -Wall -I。 -lm#更改这些设置正确的目录中,每个文件shoould是
SRCDIR = SRC
OBJDIR = OBJ
BINDIR =斌来源:= $($通配符(SRCDIR)/ * C)。
包含:= $($通配符(SRCDIR)/ * H)。
对象:= $(来源:$(SRCDIR)/%C = $(OBJDIR)/‰)
RM = RM -f
$(BINDIR)/ $(TARGET):$(对象)
    @ $(LINKER)$ @ $(LFLAGS)$(对象)
    @echo链接完成!$(对象):$(OBJDIR)/%○:。$(SRCDIR)/%C
    @ $(CC)$(CFLAGS)-c $&LT; -o $ @
    @echo编译$&LT;!成功.PHONEY:干净
清洁:
    @ $(RM)$(对象)
    @echo清理完成!.PHONEY:删除
删除:干净
    @ $(RM)$(BINDIR)/ $(TARGET)
    @echo可执行删除!


解决方案

首先,你的 $(对象)规则是有问题的,因为:1)它是一种不加选择,使的每个对象的所有的来源prerequisites,2)经常使用的错误源的(如你与 file1.o file2.o )3)它试图建立,而不是在对象停止可执行文件,以及4)目标的名称(富的.o )是不是有什么规则实际上将产生( OBJ / foo.o的)。我建议如下:

 对象:= $(来源:$(SRCDIR)/%C = $(OBJDIR)/‰。)$(对象):$(OBJDIR)/%○:。$(SRCDIR)/%C
    $(CC)$(CFLAGS)-c $&LT; -o $ @
    @echo编译$&LT;!成功

$(TARGET)规则都有目标名称不实际描述的规则建立什么样的同样的问题。因此,如果你输入制作几次,使每次将重建目标,即使是没有理由。一个小小的改变解决了:

  $(BINDIR)/ $(TARGET):$(对象)
    $(LINKER)$ @ $(LFLAGS)$(对象)
    @echo链接完成!

在这一切秩序,你可能会考虑更复杂的依赖关系处理;如果修改的头文件之一,这个makefile不会知道哪些对象/可执行文件必须重建。但是,可以等待另一天。

编辑:的结果
对不起,我省略上面的 $(对象)规则的一部分;我已经纠正了。 (我希望我可以用罢工一个code样品里面。)

A few months ago, I came up with the following generic Makefile for school assignments:

# ------------------------------------------------
# Generic Makefile
#
# Author: yanick.rochon@gmail.com
# Date  : 2010-11-05
#
# Changelog :
#   0.01 - first version
# ------------------------------------------------

# project name (generate executable with this name)
TARGET   = projectname

CC       = gcc -std=c99 -c
# compiling flags here
CFLAGS   = -Wall -I.

LINKER   = gcc -o
# linking flags here
LFLAGS   = -Wall

SOURCES  := $(wildcard *.c)
INCLUDES := $(wildcard *.h)
OBJECTS  := $(SOURCES:.c=*.o)
rm       = rm -f

$(TARGET): obj
    @$(LINKER) $(TARGET) $(LFLAGS) $(OBJECTS)
    @echo "Linking complete!"

obj: $(SOURCES) $(INCLUDES)
    @$(CC) $(CFLAGS) $(SOURCES)
    @echo "Compilation complete!"

clean:
    @$(rm) $(TARGET) $(OBJECTS)
    @echo "Cleanup complete!"

This will basically compile every .c and .h file to generate .o files and the executable projectname all in the same folder.

Now, I'd like to push this a little. How can I write a Makefile to compile a C project with the following directory structure?

 ./
 ./Makefile
 ./src/*.c;*.h
 ./obj/*.o
 ./bin/<executable>

In other words, I'd like to have a Makefile that compiles C sources from ./src/ into ./obj/ and then link everything to create the executable in ./bin/.

I've tried to read different Makefiles, but I simply can't make them work for the project structure above; instead, the project fails to compile with all sorts of errors. Sure, I could use full blown IDE (Monodevelop, Anjuta, etc.), but I honestly prefer to stick with gEdit and the good ol' terminal.

Is there a guru who can give me a working solution, or clear information about how this can be done? Thank you!

** UPDATE (v4) **

The final solution :

# ------------------------------------------------
# Generic Makefile
#
# Author: yanick.rochon@gmail.com
# Date  : 2011-08-10
#
# Changelog :
#   2010-11-05 - first version
#   2011-08-10 - added structure : sources, objects, binaries
#                thanks to http://stackoverflow.com/users/128940/beta
# ------------------------------------------------

# project name (generate executable with this name)
TARGET   = projectname

CC       = gcc
# compiling flags here
CFLAGS   = -std=c99 -Wall -I.

LINKER   = gcc -o
# linking flags here
LFLAGS   = -Wall -I. -lm

# change these to set the proper directories where each files shoould be
SRCDIR   = src
OBJDIR   = obj
BINDIR   = bin

SOURCES  := $(wildcard $(SRCDIR)/*.c)
INCLUDES := $(wildcard $(SRCDIR)/*.h)
OBJECTS  := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
rm       = rm -f


$(BINDIR)/$(TARGET): $(OBJECTS)
    @$(LINKER) $@ $(LFLAGS) $(OBJECTS)
    @echo "Linking complete!"

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
    @$(CC) $(CFLAGS) -c $< -o $@
    @echo "Compiled "$<" successfully!"

.PHONEY: clean
clean:
    @$(rm) $(OBJECTS)
    @echo "Cleanup complete!"

.PHONEY: remove
remove: clean
    @$(rm) $(BINDIR)/$(TARGET)
    @echo "Executable removed!"

解决方案

First, your $(OBJECTS) rule is problematic, because 1) it's kind of indiscriminate, making all sources prerequisites of every object, 2) it often uses the wrong source (as you discovered with file1.o and file2.o) 3) it tries to build executables instead of stopping at objects, and 4) the name of the target (foo.o) is not what the rule will actually produce (obj/foo.o). I suggest the following:

OBJECTS  := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)

$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
    $(CC) $(CFLAGS) -c $< -o $@
    @echo "Compiled "$<" successfully!"

The $(TARGET) rule has the same problem that the target name does not actually describe what the rule builds. For that reason, if you type make several times, Make will rebuild the target each time, even though there is no reason to. A small change fixes that:

$(BINDIR)/$(TARGET): $(OBJECTS)
    $(LINKER) $@ $(LFLAGS) $(OBJECTS)
    @echo "Linking complete!"

Once that's all in order, you might consider more sophisticated dependency handling; if you modify one of the header files, this makefile will not know which objects/executables must be rebuilt. But that can wait for another day.

EDIT:
Sorry, I omitted part of the $(OBJECTS) rule above; I've corrected it. (I wish I could use "strike" inside a code sample.)

这篇关于我怎么能对C项目SRC,OBJ,和BIN子目录创建一个Makefile?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆