Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何为具有SRC、OBJ和BIN子目录的C项目创建Makefile?_C_Makefile - Fatal编程技术网

如何为具有SRC、OBJ和BIN子目录的C项目创建Makefile?

如何为具有SRC、OBJ和BIN子目录的C项目创建Makefile?,c,makefile,C,Makefile,几个月前,我为学校作业提出了以下通用Makefile: # ------------------------------------------------ # Generic Makefile # # Author: yanick.rochon@gmail.com # Date : 2010-11-05 # # Changelog : # 0.01 - first version # ------------------------------------------------ #

几个月前,我为学校作业提出了以下通用
Makefile

# ------------------------------------------------
# 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!"
这将基本上编译每个
.c
.h
文件,以生成
.o
文件和可执行文件
projectname
都在同一文件夹中

现在,我想把这个推一推如何编写Makefile来编译具有以下目录结构的C项目?

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

您可以将
-I
标志添加到编译器标志(CFLAGS)中,以指示编译器应在何处查找源文件,-o标志指示二进制文件应保留在何处:

CFLAGS   = -Wall -I./src
TARGETPATH = ./bin

$(TARGET): obj
    @$(LINKER) $(TARGETPATH)/$(TARGET) $(LFLAGS) $(OBJECTS)
    @echo "Linking complete!"
要将目标文件放入
obj
目录,请在编译时使用
-o
选项。另外,请查看
$@
$

通过查看makefile,我意识到您正在使用
-o
标志。好。继续使用它,但添加一个目标目录变量以指示输出文件应写入的位置。

首先,您的
$(对象)
规则有问题,因为:

  • 这有点不分青红皂白,把所有来源都当作每个物体的先决条件
  • 它经常使用错误的源代码(正如您在
    file1.o
    file2.o
    中发现的那样)
  • 它尝试构建可执行文件,而不是停止在对象上,并且
  • 目标(
    foo.o
    )的名称不是规则实际生成的名称(
    obj/foo.o
  • 我建议如下:

    OBJECTS  := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
    
    $(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
        $(CC) $(CFLAGS) -c $< -o $@
        @echo "Compiled "$<" successfully!"
    
    <>这一切都是有序的,你可能会考虑更复杂的依赖处理;如果修改其中一个头文件,此生成文件将不知道必须重建哪些对象/可执行文件。但这可以再等一天

    编辑:

    对不起,我省略了上面的
    $(OBJECTS)
    规则的一部分;我已经改正了。(我希望我可以在代码示例中使用“strike”)

    这些天我已经停止编写makefiles,如果您的目的是学习继续,否则您就有eclipse CDT附带的好的makefile生成器。如果您希望在构建树中提供一些可维护性/多项目支持,请查看以下内容-


    我觉得这个很好

    这里的具体问题是什么?我不确定我是否理解你想要做什么。更新了
    Makefile
    。我接近了,但我在自动变量方面有问题,所以不管怎样,我似乎刚刚找到了一个解决方案。如果有人想找到更好的,Makefile仍然可以改进。@YanickRochon我不是想批评你的英语技能。但是对于那些虚假的目标来说,你绝对不能写香蕉;)你能说得更具体些吗?您的意思是将
    -l…
    添加到
    CFLAGS
    和。。。链接器(
    linker
    )已经有了
    -o
    参数是的,CFLAGS,是的,继续使用-o,只需添加TARGETPATH变量。谢谢,我已经做了修改,但似乎仍然缺少一些东西(请参阅问题的更新)只是
    make
    ,从Makefile所在的位置可以读取正在执行的命令吗?例如gcc-cyadayada。非常确定有一个变量不包含您所建议的更改所需的内容,我得到:
    obj/file1.o:在函数“main”中:\n main.c:(.text+0x0):“main”的多个定义\n obj/main.o:main.c:(.text+0x0):首先在这里定义
    @Yanick Rochon:您有多个
    main
    函数吗?可能一个在
    file1.c
    中,一个在
    main.c
    中?如果是这样,您将无法链接这些对象;可执行文件中只能有一个
    main
    。不,我没有。我在问题中发布的最后一个版本一切正常。当我将Makefile更改为您建议的内容时(我确实理解您所说内容的好处),这就是我得到的。我刚刚粘贴了
    file1.c
    ,但它为项目的每个文件提供了相同的消息。而
    main.c
    是唯一一个具有main函数的。。。和
    main.c
    导入
    file1.h
    file2.h
    (在
    file1.c
    file2.c
    之间没有关系),但我怀疑问题来自哪里。@Yanick Rochon:我粘贴
    $(对象)
    规则的第一行时出错;我已经编辑过了。我有一个错误,但不是你的错误…基于观点。没有回答OP的问题。假定为Eclipse环境。
    CFLAGS= -g -Wall -O3                                                            
    OBJDIR= ./obj
    
    SRCS=$(wildcard *.c)
    OBJS=$(SRCS:.c=.o )
    all:$(OBJS)
    
    %.o: %.c 
       $(CC) $(CFLAGS) -c $< -o $(OBJDIR)/$@
    
    OBJECTS  := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
    
    $(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
        $(CC) $(CFLAGS) -c $< -o $@
        @echo "Compiled "$<" successfully!"
    
    $(BINDIR)/$(TARGET): $(OBJECTS)
        $(LINKER) $@ $(LFLAGS) $(OBJECTS)
        @echo "Linking complete!"