6
votes

Here are my two questions:

  1. 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 organize your projects? Just hope to follow some good habits.

  2. 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?

5
Please indent your excerpt from the Makefile by four spaces. This will give it proper formatting and syntax highlighting.Magnus Hoff
It seems there is a bug somewhere which prevent putting code after a list. I've added "Makefile:" as a work around.AProgrammer

5 Answers

8
votes

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)
2
votes
  1. Your directory structure seems sensible.

  2. 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) $<
2
votes
  1. 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.

  2. 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.

0
votes

Use automake and autoconf for building your project.

As for the structure of files just look at any big open-source C++ application. Any KDE application will do fine for that matter. If you find an application that uses C++ and Python even better.

-5
votes

Why not go for eclipse, which is quite popular and handy for managing large projects. You can make a new project in eclipse, import-export code into the project from other projects, does version control for you as well etc. No need to write your make files, eclipse does it for you with your mentioned preferences in GUI. If you are involved in a C++ project, just install the CDT plugin over eclipse and your are done.