0

I'm trying to compile a small CPP project (http://sourceforge.net/projects/ibmquestdatagen/) on a Mac using g++, however I'm getting the following error:

sudo make -f Makefile.txt

g++ -O ran1.o expdev.o gammln.o gasdev.o poidev.o dist.o gen.o main.o command.o -lm -o gen
i686-apple-darwin11-llvm-g++-4.2: ran1.o: No such file or directory
i686-apple-darwin11-llvm-g++-4.2: expdev.o: No such file or directory
i686-apple-darwin11-llvm-g++-4.2: gammln.o: No such file or directory
i686-apple-darwin11-llvm-g++-4.2: gasdev.o: No such file or directory
i686-apple-darwin11-llvm-g++-4.2: poidev.o: No such file or directory
i686-apple-darwin11-llvm-g++-4.2: dist.o: No such file or directory
i686-apple-darwin11-llvm-g++-4.2: gen.o: No such file or directory
i686-apple-darwin11-llvm-g++-4.2: main.o: No such file or directory
i686-apple-darwin11-llvm-g++-4.2: command.o: No such file or directory
make: *** [gen] Error 1

It seems that I don't have the required .o files. Is there a way of generating them?

Here's the makefile:

HFILES1 = glob.h dist.h
HFILES2 = gen.h

CFILES1 =  ran1.C expdev.C gammln.C gasdev.C poidev.C dist.C
CFILES2 =  gen.C main.C command.C

OBJECTS1 = ran1.o expdev.o gammln.o gasdev.o poidev.o dist.o
OBJECTS2 = gen.o main.o command.o

LIBES = -lm
CC = g++
CFLAGS = -O

.SUFFIXES: .C

.C.o: 
    $(CC) $(CFLAGS) -c $*.c

gen:    $(OBJECTS1) $(OBJECTS2)
    $(CC) $(CFLAGS) $(OBJECTS1) $(OBJECTS2) $(LIBES) -o gen

test:   $(OBJECTS1) test.o
    $(CC) $(CFLAGS) $(OBJECTS1) test.o $(LIBES) -o test

clean:
    /bin/rm $(OBJECTS1) $(OBJECTS2)

$(OBJECTS1): $(HFILES1)
$(OBJECTS2): $(HFILES1) $(HFILES2)

GNU Make 3.81

ksiomelo
  • 1,878
  • 1
  • 33
  • 38
  • 3
    You shouldn't run make as root (don't use sudo). Is the output you get there really all you see? And this is really your makefile, exactly? That doesn't seem possible. Make would not run your link line unless it found your `.o` files somewhere, since they're listed as prerequisites. Unless you've done something odd like set `VPATH` in your environment, make should be complaining that it doesn't know how to build `ran1.o`, etc. – MadScientist May 30 '13 at 21:54

3 Answers3

4

Try adding a couple lines to your Makefile like:

.SUFFIXES: .C

.C.o:
    $(CC) $(CFLAGS) -c $*.c

Most Makes have something like that built in (which is probably why it's not present in the makefile you got) but apparently yours doesn't. It may only recognize other extensions of C++, such as .cpp or .c++.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • @VladLazarenko: Some versions of `make` support different syntax; what I've given above has around for decades though, so I'd be a bit surprised to run into a make that didn't support it. – Jerry Coffin May 30 '13 at 21:53
  • 1
    The pattern syntax is a GNU make feature, which would work in this case since Mac uses GNU make although it's not portable to some other systems like Solaris, BSDs, etc. (unless you get GNU make for them). The suffix rule version is supported in all (POSIX-compliant) makes, including GNU make, but you forgot to add `.C` to the suffix list. – MadScientist May 30 '13 at 21:55
2

You can check to see if your "make" knows how to create .o files from .C files by removing or commenting out the last two lines of your makefile.

#$(OBJECTS1): $(HFILES1)
#$(OBJECTS2): $(HFILES1) $(HFILES2)

Those lines list the .h files as prerequisites for the .o files, so it seems that make finds the .h files and assumes the .o files are good to go. If "make" doesn't have an implicit rule for building the .o files, you can add it as indicated by Jerry in his answer.

update: If Jerry's rule does not work in your makefile, try this:

%.o : %.C
    $(CC) $(CFLAGS) -c $<
#make sure the line above is indented with a tab, not spaces

If that works, try adding the two lines back in.

update 2: For some reason, none of these pattern rules seem to be working for the OP. Here is the brute force way:

foo.o : foo.C foo.h
    $(CC) $(CFLAGS) -c foo.C

You can add one of these rules for each of the .C files, replacing "foo" with the appropriate filename. If you do it this way, you don't need the $(OBJECTS): $(HFILES) lines.

Markku K.
  • 3,840
  • 19
  • 20
  • 1
    In which case you lose the dependency. For instance, changing the header file won't trigger make to re-compile. –  May 30 '13 at 21:58
  • @Vlad, quite true, which makes you wonder why the .C files are not also listed. In any case, I suggested it as a troubleshooting step. It should probably be a comment rather than an answer. I will remove it shortly. – Markku K. May 30 '13 at 22:09
  • when those lines are commented: make: *** No rule to make target `ran1.o', needed by `gen'. Stop. – ksiomelo May 30 '13 at 22:13
  • @ksiomelo, it might also be useful if you said what version of make you are running. With GNU make, you should be able to run `make --version`. – Markku K. May 30 '13 at 22:25
  • @ksiomelo, GNU Make 3.81 should understand either kind of rule. I updated my answer with the "other" kind of pattern rule. If that doesn't work, I guess the brute force way is to create a rule for each .o file with its own compile command. – Markku K. May 30 '13 at 22:36
  • @MarkkuK, thanks, I tried every combination of the two snippets and I still get the same error. Here's the makefile: https://gist.github.com/anonymous/5681952 – ksiomelo May 30 '13 at 23:04
  • Your makefile on github is wrong: it will give you an error on line 17 like `missing separator` because you are not beginning the recipe with a TAB character. Make requires a hard TAB introducing each recipe line. The errors you are reporting do not seem to match at all with the makefile you're using, which is very frustrating for us trying to help you. I recommend you run `make -d` and see how make is trying to build the `.o` file, and why it ignores the `.C` file. I assume that you do have a `ran1.C` file, and it's in the same directory not some other directory? – MadScientist May 30 '13 at 23:52
  • @MadScientist thanks, it is not giving missing separator error. Here's the result: https://gist.github.com/anonymous/5682233 – ksiomelo May 31 '13 at 00:19
  • @MarkkuK. Here's what I get when I try the brute force option you suggested: make: *** No rule to make target `ran1.C', needed by `ran1.o'. Stop. – ksiomelo May 31 '13 at 00:22
  • I really appreciate your help guys! I have no idea why the heck none of your suggestions are working.. I better try another machine – ksiomelo May 31 '13 at 00:23
  • If you aren't seeing a `missing separator` error, then the makefile you have posted on GitHub is *NOT* the makefile you're using. Sorry, but it's not. If you want us to help please be sure to provide accurate information. As for the debug output, the reason for your problem is clear: make says `File 'ran1.C' does not exist.` make can't find your source file. If you type `ls 'ran1.C'` in the directory where you run make, what do you see? – MadScientist May 31 '13 at 04:06
1

"The way" for generating .o (object code) files is compiling the source files.

You may want to read this to get an idea about what's going on.

Community
  • 1
  • 1
  • OP seem to know that, the question is more why make did not figure this out as part of implicit dependency scanning. –  May 30 '13 at 21:46
  • @VladLazarenko I don't think so. He calls the linker error a "compiler error" and even more importantly, he considers the possibility of omitting object files when generating the final executable. I think that's a quite straightforward sign of him not knowing what happens here. –  May 30 '13 at 21:49