如何引入shell命令来创建makefile文件

时间:2015-07-31 18:54:08

标签: unix makefile

我的makefile出现问题:

需要从A.o和B.o创建程序X.但是,我没有在目录中创建A.o.的文件。然而。我首先需要在目录中的一个文件上运行命令以生成A.o所需的文件,并且它必须在makefile中。最好的方法是什么?

我尝试在A.o:

的规则下将其添加为$(命令)
    TARGET=programX
    OBJS=A.o B.o
    all: $(TARGET)
    $(TARGET): $(OBJS) 
    $(LINK) $(FLAGS) -o $(TARGET) $(OBJS) $(LFLAGS)

A.o: files
    $(command)
    $(LINK) $(FLAGS) file

B.o: files
    $(LINK) $(FLAGS) file

它不断吐出错误,没有给出规则来创建A.o所需的目标。如果我将其移动,则表示命令在第一个目标之前开始。

2 个答案:

答案 0 :(得分:0)

Here is an example makefile which assumes that your sources are under "src" directoy, the generated object files should be under "obj" directory and binary should reside in "bin" directory

#this is where teh source files should be
SRC_DIR=src

OBJ_DIR=obj
BIN_DIR=bin
EXECUTABLE=exe
EXE=$(BIN_DIR)/$(EXECUTABLE)

#compile and link using g++
CC=g++
LD=g++

CPP_FILES=$(wildcard $(SRC_DIR)/*.cpp)

OBJ_FILES=$(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(CPP_FILES))

#this is a virtual target which allows to create the directories 
#first and then create the executable
PHONY: default
default : create_directories $(EXE)

#main target
$(EXE) : $(OBJ_FILES)
    $(LD) -o $@ $^

#template rule for creating all prerequisite files (e.g. *.o files)
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp
    $(CC) -c -o $@ $^


PHONY: create_directories
create_directories:
    mkdir -p $(OBJ_DIR) $(BIN_DIR)

It is easy to write a makefile if you think top down. Like what is the command producing your final target and what are the prerequisites? Once you figure this out it is easy to add rules for generating prerequistes.

答案 1 :(得分:0)

You need to put your command into a rule for creating the files that it creates, so make knows when it's needed.

Also, your formatting was broken. Targets need to not be indented, IIRC.

TARGET=programX
OBJS=A.o B.o

all: $(TARGET)
$(TARGET): $(OBJS) 
    $(LINK) $(FLAGS) -o $(TARGET) $(OBJS) $(LFLAGS)

# run command from its own rule, so it happens when needed
files:
    $(command)

A.o: files
    $(LINK) $(FLAGS) file

B.o: files
    $(LINK) $(FLAGS) file

Or, if you want your command to always run right before linking A.o, remove the dependency of files from the rule for A.o. Then make can run that rule even when files don't / doesn't exist.

BTW, your example is weird. Linking is normally a process the combines multiple .o object files into a single executable or shared library. So the rule to create A.o shouldn't do any linking, just compiling.

Also, you can reduce duplication in your Makefile by using automatic variables like $< on the command line in your rule, instead of writing something as a dependency and on the command line. This even lets you make pattern rules for everything that's compiled the same way. This stuff gets more useful as your Makefile gets bigger.

IIRC, one of Make's built-in rules is something like:

%.o: %.c $(HEADERS)
    $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $<

(Actually, the built-in rule won't have a dependency on $(HEADERS), just the .c of the same name as the required .o. Putting this rule in your Makefile would tell make that all your object files need a rebuild if even one of the headers changed.)