路径包括和src目录makefile [英] path include and src directory makefile

查看:149
本文介绍了路径包括和src目录makefile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

遵循本教程:

http://www.cs.colby.edu/maxwell/courses /tutorials/maketutor/

它有3个文件,其中2个是.c文件和1个.h文件.本教程是关于设置makefile的,前几个步骤正在工作.最后一步涉及为.h.c文件设置目录路径.我已经将.c文件放在src文件中,而.h文件放在了包含文件中.

It has 3 files 2 of which are .c files and 1 .h file. The tutorial is about setting up makefiles, and the first few steps are working. The last step involves setting up directory paths for the .h and .c files. I have put the .c files in a src file and the .h files in an include file.

看起来像这样的/home/bob/testcode/src<-包含.c文件.

It looks like this /home/bob/testcode/src <- containing the .c files.

/home/bob/testcode/include<-包含.h文件.

And /home/bob/testcode/include <- containing the .h files.

代码:

IDIR =../include
CC=gcc
CFLAGS=-I$(IDIR)

ODIR=obj
LDIR =../lib

_DEPS = hellomake.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))

_OBJ = hellomake.o hellofunc.o 
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))


$(ODIR)/%.o: %.c $(DEPS)
    $(CC) -c -o $@ $< $(CFLAGS)

hellomake: $(OBJ)
    gcc -o $@ $^ $(CFLAGS)

.PHONY: clean

clean:
    rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 

我想了解它的工作原理,然后在正在使用的库中使用它.有人可以指出我如何设置此代码吗?我尝试了很多选项,例如"/home/bob/testcode/include/" w/和w/o "/,但仍然无法正常工作.

I want to understand how it works and then use it on a library which I'm working with. Could someone please point me how to set up this code? I have tried a lot of options as "/home/bob/testcode/include/" w/ and w/o " and / and I still don't get it working.

目标是要使用一个包含60多个头文件和30个源文件的库,从这些文件中,我将必须运行1个main,所以我真的需要使此基本makefile起作用,以便可以对其进行扩展

The goal is to get working with a library which contains over 60 header files and 30 source files, from these files I will have to run 1 main, so I really need to get this basic makefile thing working so I could expand it.

普遍的问题是这些线一直保持打开状态:

The general problem are these lines wich are left open:

IDIR =../include

DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))

OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))

为此,我尝试了多种不同的路径替代方法,但生成的错误提示:

For which I have tried a multitude of different path substitutes but the error I generate says:

gcc -o hellomake  -I../include
gcc: fatal error: no input files
compilation terminated.
make: *** [hellomake] Error 4

请帮助,谢谢.

推荐答案

您的教程提倡不良做法,应避免恕我直言.

Your tutorial promotes bad practices, you should avoid it IMHO.

您在这里的规则:

$(ODIR)/%.o: %.c $(DEPS)

您要告诉make在源文件位于src目录中时在当前目录中查找,因此永远不会使用此模式,并且您没有合适的模式.

You're telling make to look in the current directory while your source files are in the src directory, thus this pattern is never used and you have no suitable one.

确保像这样组织项目目录:

Make sure you organize your project directory like this :

+ include/
|-- all .h files here
+ lib/
|-- all thirdparty library files (.a files) here
+ obj/
|-- all .o files will be placed here
+ src/
|-- all .c files here
+ Makefile

然后,按照良好做法逐步进行操作.

Then let's take the process step by step, using good practices.

首先,如果不需要,请不要定义任何内容. Make具有许多预定义的变量和函数,您在尝试手动进行操作之前应使用它们.实际上,他的工作量如此之大,以至于您甚至可以在目录中根本没有Makefile的情况下编译一个简单的项目!

Firstly, don't define anything if you don't need to. Make has a lot of predefined variables and functions that you should use before trying to do it manually. In fact, he has so many that you can compile a simple project without even having a Makefile in the directory at all !

  1. 命名您的最终目标,即您的可执行文件:

  1. Name your final target, that is, your executable:

EXE := hellomake

  • 列出您的源代码并构建输出目录:

  • List your source and build output directories:

    SRC_DIR := src
    OBJ_DIR := obj
    

  • 列出您的源文件:

  • List your source files:

    SRC := $(wildcard $(SRC_DIR)/*.c)
    

  • 从源文件中,列出目标文件:

  • From the source files, list the object files:

    OBJ := $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) # patsubst is far less readable imo
    # You can also do it like that
    OBJ := $(addprefix $(OBJ_DIR)/, $(notdir $(SRC)))
    

  • 有一些预处理器标志要传递吗?继续.

  • Got some preprocessor flags to pass? Go on.

    CPPFLAGS := -Iinclude # -I is a preprocessor flag, not a compiler flag
    

  • 要添加一些编译器标志吗?给你.

  • Got some compiler flags to add? Here you go.

    CFLAGS := -Wall # some warnings about bad code
    

  • 有一些链接器标志吗?

  • Got some linker flags?

    LDFLAGS := -Llib # -L is a linker flag
    

  • 有一些第三方库可以链接吗?

  • Got some thirdparty libraries to link against?

    LDLIBS := -lm # Left empty if no libs are needed
    

  • 好吧,现在我们的变量已正确填写,现在该轮一些食谱了.

    Ok, time to roll some recipes now that our variables are correctly filled.

    广泛传播,默认目标应称为all,并且它应该是Makefile中的第一个目标.当在命令行上仅编写make时,其先决条件将是您要构建的目标:

    It is widely spread that the default target should be called all and that it should be the first target in your Makefile. Its prerequisites shall be the target you want to build when writing only make on the command line:

    all: $(EXE)
    

    现在列出构建可执行文件的先决条件,并填写其配方以告诉您如何处理这些可执行文件:

    Now list the prerequisites for building your executable, and fill its recipe to tell make what to do with these:

    $(EXE): $(OBJ)
        $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
    

    一些简要说明:

    • $(CC)是一个内置变量,已经包含在C中进行编译和链接时所需的内容,
    • 为避免链接器错误,应 $(LDFLAGS) 放置在目标文件之前,将$(LDLIBS) 放置在之后.
    • $(CPPFLAGS)$(CFLAGS)在这里没用,编译阶段已经结束,在这里是链接阶段.
    • $(CC) is a built-in variable already containing what you need when compiling and linking in C,
    • To avoid linker errors, you should put $(LDFLAGS) before your object files and $(LDLIBS) after.
    • $(CPPFLAGS) and $(CFLAGS) are useless here, the compilation phase is already over, it is the linking phase here.

    下一步,由于您的源文件和目标文件不共享相同的前缀,因此您需要确切说明要执行的操作,因为其内置规则不能满足您的特定情况:

    Next step, since your source and object files don't share the same prefix, you need to tell make exactly what to do since its built-in rules don't cover your specific case:

    $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
        $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
    

    尽管有一个问题,您的$(OBJ_DIR)可能还不存在,所以对编译器的调用可能会失败.让我们告诉make,您要它首先对其进行检查:

    One problem though, your $(OBJ_DIR) might not exist yet so the call to the compiler might fail. Let's tell make that you want it to check for that first:

    $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
        $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
    
    $(OBJ_DIR):
        mkdir $@
    

    好吧,现在可执行文件应该可以很好地构建了,如果需要,我们可以清理构建目录:

    Ok, now the executable should build nicely, we can clean the build directory if we want:

    clean:
        $(RM) -r $(OBJ_DIR)
    

    最后一件事.您应该使用.PHONY特殊规则指出何时某条规则未产生任何目标输出:

    Last thing. You should indicate whenever a rule does not produce any target output with the .PHONY special rule:

    .PHONY: all clean
    


    最终结果:


    Final result:

    EXE := hellomake
    
    SRC_DIR := src
    OBJ_DIR := obj
    
    SRC := $(wildcard $(SRC_DIR)/*.c)
    OBJ := $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
    
    CPPFLAGS := -Iinclude
    CFLAGS   := -Wall
    LDFLAGS  := -Llib
    LDLIBS   := -lm
    
    .PHONY: all clean
    
    all: $(EXE)
    
    $(EXE): $(OBJ)
        $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@
    
    $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
        $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
    
    $(OBJ_DIR):
        mkdir $@
    
    clean:
        $(RM) $(OBJ)
    

    这篇关于路径包括和src目录makefile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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