organize project and specify directory for object files in Makefile

14,722

Solution 1

  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.

Solution 2

  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) $<
Share:
14,722
Tim
Author by

Tim

Elitists are oppressive, anti-intellectual, ultra-conservative, and cancerous to the society, environment, and humanity. Please help make Stack Exchange a better place. Expose elite supremacy, elitist brutality, and moderation injustice to https://stackoverflow.com/contact (complicit community managers), in comments, to meta, outside Stack Exchange, and by legal actions. Push back and don't let them normalize their behaviors. Changes always happen from the bottom up. Thank you very much! Just a curious self learner. Almost always upvote replies. Thanks for enlightenment! Meanwhile, Corruption and abuses have been rampantly coming from elitists. Supportive comments have been removed and attacks are kept to control the direction of discourse. Outright vicious comments have been removed only to conceal atrocities. Systematic discrimination has been made into policies. Countless users have been harassed, persecuted, and suffocated. Q&amp;A sites are for everyone to learn and grow, not for elitists to indulge abusive oppression, and cover up for each other. https://softwareengineering.stackexchange.com/posts/419086/revisions https://math.meta.stackexchange.com/q/32539/ (https://i.stack.imgur.com/4knYh.png) and https://math.meta.stackexchange.com/q/32548/ (https://i.stack.imgur.com/9gaZ2.png) https://meta.stackexchange.com/posts/353417/timeline (The moderators defended continuous harassment comments showing no reading and understanding of my post) https://cs.stackexchange.com/posts/125651/timeline (a PLT academic had trouble with the books I am reading and disparaged my self learning posts, and a moderator with long abusive history added more insults.) https://stackoverflow.com/posts/61679659/revisions (homework libels) Much more that have happened.

Updated on June 04, 2022

Comments

  • Tim
    Tim almost 2 years

    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?

  • Tim
    Tim over 14 years
    Don't know who gave you the vote, not me. :) If you have many .cc files, to specify a rule for each object file is tedious, isn't it?
  • mrivard
    mrivard over 14 years
    The rule is generic, so it applies to any .cc-file. I have updated the example Makefile-code with a list of target objects. Just specify additional .o-files here, and they will be compiled with the same rule.
  • Admin
    Admin over 14 years
    Consider all the thousands of projects that have used CVS very succesfully.
  • mrivard
    mrivard over 14 years
    @Neil: Sorry. I was under the impression that everybody agreed CVS is a relic of the past. I might have been wrong. Anyway, this was intended as a helpful tip, but since it is not strictly an answer to anything in the question I have removed the possibly offending tip.
  • Steve Jessop
    Steve Jessop over 14 years
    Linus certainly agrees that CVS is fundamentally broken, and he's the one who decided that the linux kernel would use patch files in preference to existing version control systems, until that finally became unsustainable. Many people disagree with Linus about all sorts of things, although in my experience people who have switched away from CVS have not regretted it.
  • Admin
    Admin over 14 years
    CVS was certainly unsuitable for developing the Linux kernel, but most projects are not remotely similar to the Linux kernel. I would never advise anyone to use CVS on a project starting today, but in its time it a great a step forward from things like PVCS, and shouldn't be badmouthed. I now use SVN and am investigating Mercurial, but if forced to go back to CVS, I really wouldn't complain too much - I prefer its tagging model to SVN's, for example.
  • frankster
    frankster over 13 years
    If you adopted approach B), how would you approach the problems with the Makefile dependencies?
  • Beta
    Beta over 13 years
    @frankster, I'd probably modify the Makefile.depend command to prepend $(BIN_DIR) to the names of the object files. A little sed would do.
  • murrekatt
    murrekatt over 13 years
    Does not answer the question at all.
  • Tim
    Tim about 6 years
    Thanks, @Beta (1) I was wondering if the reason for "Make is good at using a source there to make something here" is the "problem with Makefile.depend" you described in B)? (2) In the way "a problem with Makefile.depend" which you suggested, where would you place makefile? in src/, or bin/, or the root directory of the project? See stackoverflow.com/q/49836438/156458