【问题标题】:Makefile with linking different folders带有链接不同文件夹的 Makefile
【发布时间】:2014-06-12 16:54:47
【问题描述】:

我必须为具有以下文件夹结构的项目构建一个 makefile:

1) 所有的标题都在 /include 中

2) 在 /provided_objects 中提供了一些 .o 编译的实现(没有 .c)

3) 我创建的源代码必须在/src中

4) 我的 C 代码生成的 .o 文件必须在 /built_objects 中

5) 可执行文件在根目录中

我最初的目的是用我的实现替换 /provided_objects 中的一些实现,记住我的实现可以使用我没有实现的头文件定义的函数。已经有一个默认的 makefile 包含(以及更小的细节):

LD        = gcc
LDFLAGS   = -lm
OBJDIR    = provided_objects
OBJECTS = $(OBJDIR)/obj1.o    \    /$(OBJDIR)/obj2.o ...
MY_OBJECTS = 
quiet-command = $(if $(VERB),$1,$(if $(2),@echo $2 && $1, @$1))

all     : $(OBJDIR) $(PROG)

$(PROG) : $(OBJECTS) $(MY_OBJECTS)
    $(call quiet-command, $(LD) $^ -o $@, "  LD       $@" $(LDFLAGS))

$(OBJDIR):
    $(call quiet-command, mkdir -p $(OBJDIR),)

我应该删除我实现的在 OBJECTS 中命名的条目并在 MY_OBJECTS 中引用它们。我的问题是,我该怎么做?我在 makefile 方面不是很有经验,而且我发现研究的链接并没有解决我的限制。

提前致谢!

【问题讨论】:

  • 为什么是quit-command?而且,最好将其删除,因为它只会使您的 makefile 变得复杂,而不会给您的问题添加任何内容。
  • 正如我所说,它是一个默认的 makefile。它是给我的,我应该改变它。我不知道那是做什么的。

标签: c linker makefile


【解决方案1】:

假设我正确理解了您想要的内容,那么下面 makefile 中的 OBJECTS := ... 行应该可以满足您的需求。

OBJDIR    = provided_objects
OBJECTS = $(OBJDIR)/obj1.o \
          $(OBJDIR)/obj2.o \
          $(OBJDIR)/obj3.o \
          $(OBJDIR)/obj4.o \
          $(OBJDIR)/obj5.o
MY_OBJDIR = built_objects
MY_OBJECTS = $(MY_OBJDIR)/obj2.o $(MY_OBJDIR)/obj4.o

$(info Before)
$(info OBJECTS: $(OBJECTS))
$(info MY_OBJECTS: $(MY_OBJECTS))

OBJECTS := $(filter-out $(addprefix $(OBJDIR)/,$(notdir $(MY_OBJECTS))),$(OBJECTS))

$(info After)
$(info OBJECTS: $(OBJECTS))
$(info MY_OBJECTS: $(MY_OBJECTS))

【讨论】:

    【解决方案2】:

    让我们一步一步来:

    1. 所有标题都在/include

       CPPFLAGS := -I /include # preprocessor flags
      
    2. /provided_objects 中提供了一些.o 编译实现(没有.c

      PROVIDED_OBJ_DIR := /provided_objects
      PROVIDED_OBJ     := $(wildard $(PROVIDED_OBJ_DIR)/*.o)
      
    3. 我创建的源代码必须在/src

      SRC_DIR := /src
      SRC     := $(wildcard $(SRC_DIR)/*.c)
      
    4. 我的C代码生成的.o文件必须在/built_objects

      MY_OBJ_DIR := /built_objects
      MY_OBJ     := $(SRC:$(SRC_DIR)/%.c=$(MY_OBJ_DIR)/%.o)
      
    5. 可执行文件在根目录中

      EXE := /executable
      
    6. 我应该删除我实现的在OBJECTS 中命名的条目,并在MY_OBJECTS 中引用它们。

      PROVIDED_OBJ := $(addprefix $(PROVIDED_OBJ_DIR)/,$(filter-out $(notdir $(MY_OBJ)), $(notdir $(PROVIDED_OBJ))))
      

      这一行有点长而且复杂,所以我们也来复习一下:

      主要目标是从提供的文件中过滤掉您重新实现的目标文件。
      因此使用的函数是$(filter-out files_to_remove, files_to_remove_from)

      $(filter-out $(MY_OBJ), $(PROVIDED_OBJ))
      

      问题是MY_OBJ 中的文件以/built_objects/ 为前缀,而PROVIDED_OBJ 中的文件以/provided_objects/ 为前缀,因此按原样提供,不会过滤掉任何内容。我们需要从名称中删除任何路径组件,所以这里有函数$(notdir files)

      $(filter-out $(notdir $(MY_OBJ)), $(notdir $(PROVIDED_OBJ)))
      

      最后一步:我们需要重新添加正确的路径,否则 make 将找不到文件。功能 $(addprefix prefix, files) 救援!

      $(addprefix $(PROVIDED_OBJ_DIR)/,$(filter-out $(notdir $(MY_OBJ)), $(notdir $(PROVIDED_OBJ))))
      
    7. 最后,不要忘记编译所有这些的正确规则!完成 Makefile

      EXE                 :=  /executable
      
      SRC_DIR             :=  /src
      SRC                 :=  $(wildcard $(SRC_DIR)/*.c)
      
      MY_OBJ_DIR          :=  /built_objects
      MY_OBJ              :=  $(SRC:$(SRC_DIR)/%.c=$(MY_OBJ_DIR)/%.o)
      
      PROVIDED_OBJ_DIR    :=  /provided_objects
      PROVIDED_OBJ        :=  $(wildcard $(PROVIDED_OBJ_DIR)/*.o)
      PROVIDED_OBJ        :=  $(addprefix $(PROVIDED_OBJ_DIR)/,$(filter-out $(notdir $(MY_OBJ)), $(notdir $(PROVIDED_OBJ))))
      
      LDFLAGS             :=  # -L flags
      LDLIBS              :=  -lm # -l flags
      
      CFLAGS              :=  -W -Wall
      CPPFLAGS            :=  -I /include
      
      .PHONY: all
      
      all:    $(EXE)
      
      $(EXE): $(MY_OBJ)
          $(CC) $(LDFLAGS) $^ $(PROVIDED_OBJ) $(LDLIBS) -o $@
      
      $(MY_OBJ_DIR)/%.o:  $(SRC_DIR)/%.c
          @mkdir -p $(@D)
          $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-16
      • 1970-01-01
      相关资源
      最近更新 更多