-1

I'm using make to build a C++ project. During the course of the project, I wanted to make some changes to the Makefile. Unfortunately, ever since I executed make once, it keeps using that particular version of the Makefile and just doesn't do anything with the changes at all.

I have run make clean, I have renamed the makefile, I've searched for other Makefiles which might be used instead, all to no avail. There is no mention of any caching mechanism in the man pages for make, nor anywhere on Google.

Does anyone have any idea why make isn't using the new version and what I can do about it? I'm compiling on a Ubuntu 12.04.2 LTS (x86_64) box, with (GNU) make version 3.81.

Update: Some additional information. It seems make is using the current version of the makefile after all. If I change something in the main target, it's working just fine. But if I change something in the obj/%.o target, it just keeps running the same command, no matter what changes I make to that target.

Full Makefile an be found here: http://pastebin.com/WK43NRcL

BramN
  • 11
  • 4
  • 1
    How are you executing `make`, i.e. what is your command line? – devnull Aug 20 '13 at 09:47
  • I have tried "make", I've tries "make -f Makefile", I've tried "make -f Makefile all" and "make -f Makefile api" (api is the name of the main target, which invokes other targets). This made me think: I tried removing the target which isn't updating from the main target and this does work. So it seems there's something going wrong with the subtarget. I'll post the entire makefile below. – BramN Aug 20 '13 at 09:52
  • 1
    It could be that all of your targets are built, and none of them depends on the ``Makefile``. – juanchopanza Aug 20 '13 at 09:53
  • Pastebin might be a better way, so here's the link: http://pastebin.com/zWskMr43 The offending target is obj/%.o – BramN Aug 20 '13 at 09:53
  • what do you mean by "The offending target"? what is or is not happening with that target? expected and actual result? – codeling Aug 20 '13 at 09:57
  • Oops, I messed up; the right Pastebin file is here: http://pastebin.com/WK43NRcL . Another weird thing I just noted: It isn't using the CFLAGS variable at all in that target. For example, it's running the following command: g++ -c -o src/main.o src/main.cc. This should have -Werror -Wall in it. That has been there since the very first version of the Makefile. – BramN Aug 20 '13 at 09:59
  • I meant the target that isn't working properly. I expect it to run a different command if I change it in the Makefile, but it just keeps running g++ -c -o OBJ_FILENAME_HERE SRC_FILENAME_HERE, no matter what I put in the target. – BramN Aug 20 '13 at 10:00
  • `CFLAGS` is for C. `CXXFLAGS` is for C++. – juanchopanza Aug 20 '13 at 10:02
  • for which command do you expect it to run a different command? if you run e.g. `make obj`, what's the output? – codeling Aug 20 '13 at 10:04
  • juanchopanza, thanks; I'm new to C++, I've only used plain C before. Changing it into CXXFLAGS magically makes the obj/%.o target use the variable contents; I was under the impression those variables were just a name, but it seems the names actually mean something to make. Is that right? Anyway, that's the only progress; other changes are still not reflected when running make. – BramN Aug 20 '13 at 10:09
  • nyarlathotep, the api target depends on $(OBJ_FILES). So running make api should run the obj/%.o target for every source file. And it is, it's just not using the commands I've entered for the obj/%.o target. – BramN Aug 20 '13 at 10:11
  • I might have found the error: the patsubst which should turn src/main.c into obj/main.o isn't replacing the src part. Therefore, the target api is depending on is src/main.o instead of obj/main.o, which is why the obj/%.o target is never invoked in the first place. This means make has default targets for .o files; is this right? – BramN Aug 20 '13 at 10:15

2 Answers2

3
CC_FILES        = $(shell find -name "*.cc" -exec echo "{}" +;)

That find command is incorrect, shouldn't it be looking in the src directory? And why use echo to print the name when that's what find does anyway?

That means your list of CC_FILES and so also list of OBJ_FILES is empty.

I think you want:

CC_FILES        := $(shell find src -name "*.cc")

Note that this uses := not = because otherwise the shell function gets run every time you reference the CC_FILES variable. Using := means it is run and evaluated only once.

However, since it seems all your .cc files are in the same directory you don't need a recursive find, just do:

CC_FILES := $(wildcard src/*.cc)

As you've realised, your patsubst is broken, you can just do:

OBJ_FILES := $(patsubst src/%.cc,obj/%.o,$(CC_FILES))

(Again, use := here)

Also:

obj/%.o: obj src/%.cc
    $(CXX) $(CFLAGS) -c -o $@ $<

I think you need to read what the $< variable expands to, because the rule above isn't going to do what you expect.

This makefile is full of errors, you need to use echo in pattern rules to print out the values of variables, so you can verify they have the values you expect. (As another option for debugging, set SHELL=bash -x so every shell command is echoed)

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • You're my hero! I'm not very good at makefiles (as you can see), so I copies the CC_FILES line and the $< from another makefile. After changing those lines, everything works perfectly! I can't thank you enough! – BramN Aug 20 '13 at 10:29
2

make does not somehow magically keep track of your old makefile; it will use whatever file is first in the list of files it looks for, in the current directory.

To find out which Makefile is actually used, see this question: Getting the name of the makefile from the makefile

Since you're using GNU make, check its excellent manual on what filenames it looks for, and in which order.

Community
  • 1
  • 1
codeling
  • 11,056
  • 4
  • 42
  • 71
  • It seems it's using the right file after all (also see the comments on my question), so that's not the problem. Thanks anyway! – BramN Aug 20 '13 at 09:55