organize project and specify directory for object files in Makefile

Here are my two questions:

  • I am now learning to manage my code with CVS, and I just want to make a repository for my C++ files, Makefile and bash and python scripts only, not the object files and executables. So I made several subdirectories under my project directory: src, bin, scripts, results and data. I put C++ files and Makefile under ~/myproject/src, bash and python scripts under ~/myproject/scripts and object and executables under ~/myproject/bin. I am hoping only the files under src and scripts will be updated via CVS. I wonder how you guys organize your projects? Just hope to follow some good habits

  • Since I put my C++ files and Makefile into ~/myproject/src and object and executable files into ~/myproject/bin, I have to specify the directories in Makefile. Here is what I am doing

  • Makefile:

    ...
    BIN_DIR=/home/myproject/bin/
    
    all: $(BIN_DIR)myexecutable TAGS
    
    TAGS: *.cc *.h
        etags --members --declarations -l c++ *.cc *.h
    
    $(BIN_DIR)myexecutable: $(BIN_DIR)myobject.o
        $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
    
    Makefile.depend: *.h *.cc Makefile
        $(CXX) -M $(CXXFLAGS) *.cc > Makefile.depend
    
    clean:
        rm -f $(BIN_DIR)myexecutable $(BIN_DIR)*.o Makefile.depend TAGS`
    

    However this will give error

    make: *** No rule to make target /home/myproject/bin/myobject.o', needed by /home/myproject/bin/myexecutable'.

    How to specify a different directory for object and executable files from C++ files in Makefile?

    Thanks and regards!


  • You can keep your files in different directories if you like, but that isn't necessary. Add a file or directory to the CVS repository once, and CVS will retain it indefinitely. From then on you can update it, check it in, whatever. If you don't add an object file to the repository, CVS won't touch it. If you want to add a whole directory tree, and you're in the habit of keeping objects there, just make clean before you do it.

  • Make is a wonderful tool, but it has some glaring faults. What you're describing is one of the classic problems: Make is good at using a source there to make something here, but not the other way around. Here are a couple of ways to do what you're trying to do.

  • A) Run make in your binary directory:

        ...
        all: myexecutable TAGS
    
        myexecutable: myobject.o
            $(CXX) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
    
        VPATH = /home/myproject/src
        ...
    

    cd ~/myproject/bin
    make -f ../src/makefile

    B) Put the objects on the bin directory by brute force:

        $(BIN_DIR)%.o: %.cc
            $(CXX) $(CXXFLAGS) -c -o $@ $^
    

    This will give you a problem with Makefile.depend, which you can approach several ways.

    C) Learn some more advanced Make techniques. You probably shouldn't try this yet.


    If you want to learn make, the GNU make manual is very good, both as a reference and a tutorial. You might want to consider using the patsubst command. The following is a chopped down version of one of my own makefiles that uses it:

    OUT = bin/csvfix.exe
    CC = g++
    IDIR = inc
    ODIR = obj
    SDIR = src
    INC = -Iinc -I../alib/inc
    LIBS = ../alib/lib/alib.a -lodbc32 
    
    _OBJS = csved_atable.o 
            csved_case.o 
            csved_cli.o 
            csved_command.o 
            csved_date.o 
    
    OBJS = $(patsubst %,$(ODIR)/%,$(_OBJS))
    
    $(ODIR)/%.o: $(SDIR)/%.cpp 
        $(CC) -c $(INC) -o $@ $< $(CFLAGS) 
    
    $(OUT): $(OBJS)
        $(CC) -o $@ $^ $(CFLAGS) $(LIBS)
        strip $(OUT)
    
    clean:
        rm -f $(ODIR)/*.o $(OUT)
    

  • Your directory structure seems sensible.

  • I would make an explicit rule for executing the compiler, like

  • TARGET_DIR=bin
    SRC_DIR=src
    CXX=g++
    CXXFLAGS=
    ETC=
    
    OBJS=$(TARGET_DIR)/test.o
    
    all: $(OBJS)
    
    $(TARGET_DIR)/%.o: $(SRC_DIR)/%.cc
            $(CXX) -c -o $@ $(CXXFLAGS) $(ETC) $<
    
    链接地址: http://www.djcxy.com/p/97106.html

    上一篇: Makefile multiline dash命令在分离的进程中运行可执行文件

    下一篇: 组织项目并在Makefile中指定目标文件的目录