【问题标题】:How to properly make my makefile to compile and run?如何正确使我的 makefile 编译和运行?
【发布时间】:2023-03-08 01:40:01
【问题描述】:

这个问题可能不是描述我的问题的最佳问题,但我想不出更好的问题。我的makefile是这样的:

PROGRAM_NAME = prog

OBJECT_FILES = $(PROGRAM_NAME).o
CFLAGS = -O2 -Wall -g

$(PROGRAM_NAME) : $(OBJECT_FILES)
    gcc $(CFLAGS) -o $@ $(OBJECT_FILES)

$(PROGRAM_NAME).o : $(PROGRAM_NAME).c data.h
    gcc $(CFLAGS) -c $<

clean :
    $(RM) $(PROGRAM_NAME)
    $(RM) $(OBJECT_FILES)
    $(RM) *~ *.bak

run :
    @$(MAKE) && ./$(PROGRAM_NAME) $(ARGS)

当我想编译和运行时,我只需要“make run”。这个问题是我的程序处理由 Ctrl+Z 产生的信号,如果我用“make run”启动我的程序,信号将被发送到“make run”而不是我的程序本身。

基本上,调用“make run”与直接调用“make && ./prog”不同,因为在第一种情况下,“make run”不会终止,除非“prog”先终止。

有没有办法解决这个问题?

【问题讨论】:

    标签: c makefile signals


    【解决方案1】:

    你可以简化你的“运行”目标,让它取决于你的程序是否是最新的,然后简单地运行程序:

    run:    ${PROGRAM_NAME}
            ./${PROGRAM} ${ARGS}
    

    当您已经在运行 make 时,运行 make 没有多大意义 - 至少在这种情况下不是这样。也许用于递归操作(在不同的目录中),但请参阅'Recursive Make Considered Harmful'。

    此外,您的 makefile 通常应该提供一个目标“all”,它通常应该是第一个目标,因此也是默认目标。

    【讨论】:

      【解决方案2】:

      从 makefile 运行有点不寻常。您是否正在尝试复制某些 IDE 提供的“编译并运行”菜单项? Make 不具备这样做的能力。

      目标命令中发生的所有事情都发生在不直接连接到终端的子进程中,这就是 make 接收您的击键的原因。

      另一件需要注意的事情:通常目标文件到可执行阶段(链接)使用一组不同的标志(LDFLAGSLIBS)然后是编译阶段。在这个简单的示例中,您可以不使用它,但如果您复制此 makefile 以用于更复杂的情况,您会遇到麻烦。

      【讨论】:

      • 我最好不要这样使用它...... :)
      【解决方案3】:

      如果您要反复构建和运行,您可以使用history 命令来帮助解决此问题:

      # Run this once
      make && ./foo
      
      # Repeat last command
      !!
      

      【讨论】:

      • 更好的是,在 Bash 中,您可以使用 !make 重复以“make”开头的最后一个命令,即使您在其间运行其他命令也是如此。该工作流程对我来说非常有效。
      • @GuiPrá 的提示也适用于 zsh,以防你想知道
      【解决方案4】:

      正如 dmckee 的回答所说,make(1) 正在制作一些东西,而不是用于编译和运行。

      当然,没有什么能阻止你创建一个 shell 别名 make-run 来执行预期的 'make && ./prog args' .

      【讨论】:

        【解决方案5】:

        你可以这样试试:

        APP      = olupxtest
        
        SRCS     = $(wildcard *.cpp)
        OBJS     = $(SRCS:.cpp=.o)
        
        CXXFLAGS = -g -fPIC -c
        LDFLAGS  =
        LIBS     =
        
        .PHONY: all clean
        
        all: clean $(APP) run
        
        $(APP): $(OBJS)
                $(CXX) $(LDFLAGS) $^ $(LIBS) -o $@
        
        clean:
                $(RM) $(OBJS) $(APP)
        
        run:    ${APP}
                ./${APP} ${ARGS}
        

        这里你调用了多个目标规则:all: clean $(APP) run

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-07-22
          • 2018-05-29
          • 2018-12-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多