【问题标题】:Make implicit rules with GCC: Redirecting *.o使用 GCC 制定隐含规则:重定向 *.o
【发布时间】:2016-02-02 10:45:31
【问题描述】:

我正在尝试使用隐式规则让 make 执行以下操作:

obj/lsabase.o : inc/lsabase.h lsabase.c
    cc -c lsabase.c && mv lsabase.o obj

我搜索了使用编译器选项重定向“cc -c ..”输出的方法,但没有找到任何here

此外,为从源编译到对象定义的隐式规则只允许您使用 $(CPPFLAGS) 和 $(CFLAGS)。

有谁知道如何欺骗 make 在隐式规则中使用这个 (mv lsabase.o obj),所以我可以将所有 *.o 文件放在单独的目录中?

【问题讨论】:

    标签: c gcc makefile


    【解决方案1】:
    obj/lsabase.o : inc/lsabase.h lsabase.c
        cc -I"inc" -c lsabase.c -o obj/lsabase.o
    

    【讨论】:

      【解决方案2】:

      我愿意

      • 避免手动执行mv,而是告诉gcc 放入obj 目录
      • 让 gcc 处理依赖项(通过创建 .d 文件)

      当我的所有 .c 文件都在子目录中并且我想在并行目录obj 中编译所有文件时,我通常会这样做(我可以轻松删除):

      default: my_code
      
      #add subdirs
      DIRS := $(shell find src -type d)
      #add include directives for subdirs
      CFLAGS += $(DIRS:%=-I%)
      
      #collect all c files
      SRCS := $(shell find src/* -name \*.c)
      OBJS := $(addprefix obj/, $(SRCS:.c=.o))
      DEPS := $(addprefix obj/, $(SRCS:.c=.d))
      
      # this generates a dependency file for every .c
      obj/%.d: %.c
          @ mkdir -p "$(@D)" 
          @ echo "Checking dependencies for $<"
      # create and modify dependecy file .d to take into account the location obj (sed magical)
          @ gcc $(CFLAGS) -MM $< 2>/dev/null | sed -e "s@\(^.*\)\.o:@obj/$(shell  dirname $<)/\1.d obj/$(shell  dirname $<)/\1.o:@" > $@  
      
      #this compiles
      obj/%.o : %.c
          gcc $(CFLAGS) -c $< -o $@
      
      #this creates the executable
      my_code: $(OBJS)
          gcc $(OBJS) -o $@ $(LDFLAGS) 
      
      # this does the magic
      -include $(DEPS)
      
      clean:
          rm -rf obj 
      

      如果您是 Make 新手,这可能看起来很困难,但是一旦您完成了它就会非常强大。

      【讨论】:

      • 感谢您的回复,但这有点让我头疼。难道没有一种简单的方法来做@dasan 在上面的评论中所做的事情,而是使用隐含的规则和每个 *.o 文件?我无法让您运行 makefile,我只是收到一堆错误,抱歉。
      【解决方案3】:

      你可以这样写makefile规则:

      obj/lsabase.o : lsabase.c inc/lsabase.h 
      <tab>cc $(CFLAGS) -c $< -o $@ -Iinc/. 
      

      在实际的 makefile 中,&lt;tab&gt; 将被替换为实际的制表符

      注意 *.c 文件在依赖列表的第一位,所以可以使用$&lt; 快捷方式

      您提到要对所有目标文件执行此操作..

      obj/$.o : %.c inc/%.h 
      <tab>cc $(CFLAGS) -c $< -o $@ -Iinc/. 
      

      但是,这可能不是最灵活的。为了获得最大的灵活性,建议添加一个规则来生成和包含名为 *.d 的依赖文件。然后使用:

      obj/$.o : %.c %.d 
      <tab>cc $(CFLAGS) -c $< -o $@ -Iinc/.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-05-12
        • 1970-01-01
        • 2015-12-22
        • 2018-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多