Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GNU Make producing a totally different result

Tags:

c++

makefile

g++

This is confusing. I have my Makefile:

OBJECTS =
INCLUDE_BUILD_PATH = /Users/wen/Projects/include

# Change compilation settings here
COMPILE = g++
override COMPILE_FLAGS += -O2

# Change linker/compiler specific settings here
LD_FLAGS :=
CC_FLAGS := -c -I$(INCLUDE_BUILD_PATH)/bigint

# Add source extensions here
SRC_EXT = cpp cc

# Add header dependencies here
HEADERS = $(wildcard *.hpp) $(wildcard $(INCLUDE_BUILD_PATH)/*/*.hh)

# Add source files here
CC_FILES = $(wildcard *.cpp) $(wildcard $(INCLUDE_BUILD_PATH)/*/*.cc)
CC_O_BUFFER = $(CC_FILES)
CC_O_BUFFER := $(CC_O_BUFFER:.cpp=.o)
CC_O_BUFFER := $(CC_O_BUFFER:.cc=.o)
OBJECTS = $(CC_O_BUFFER)

# Change .exe name here
EXE_NAME = maketest

# Link object files

$(EXE_NAME): $(OBJECTS)
    $(COMPILE) $(COMPILE_FLAGS) $(LD_FLAGS) -o $@ $^

# Build source files

define compile_rule
%.o : %.$1
        $$(COMPILE) $$(COMPILE_FLAGS) $$(CC_FLAGS) -o $$@ $$<
endef
    $(foreach EXT,$(SRC_EXT),$(eval $(call compile_rule,$(EXT))))

# Clean

clean:
    rm -f $(OBJECTS) $(EXE_NAME)

# Debug Build

debug:
    @echo "Rerun with COMPILE_FLAGS=-D_DEBUG"

# Print variables

print:
    @echo $(CC_FILES)
    @echo $(OBJECTS)
    @echo $(HEADERS)

it compiled successfully at first, but then it stopped for no reason and this was the output:

Yoshi-Air:maketest wen$ make
c++    -c -o maketest.o maketest.cpp
maketest.cpp:4:10: fatal error: 'BigIntegerLibrary.hh' file not found
#include "BigIntegerLibrary.hh"
         ^
1 error generated.

the problem was, I didn't even tell it to use "c++" in the Makefile but "g++" instead. Also, when I cleared CC_FLAGS the -c was still there. It's like Make's having a mind of it's own.

If I use make print to print out my variables it seems to be all right:

maketest.cpp /Users/wen/Projects/include/bigint/BigInteger.cc /Users/wen/Projects/include/bigint/BigIntegerAlgorithms.cc /Users/wen/Projects/include/bigint/BigIntegerUtils.cc /Users/wen/Projects/include/bigint/BigUnsigned.cc /Users/wen/Projects/include/bigint/BigUnsignedInABase.cc
maketest.o /Users/wen/Projects/include/bigint/BigInteger.o /Users/wen/Projects/include/bigint/BigIntegerAlgorithms.o /Users/wen/Projects/include/bigint/BigIntegerUtils.o /Users/wen/Projects/include/bigint/BigUnsigned.o /Users/wen/Projects/include/bigint/BigUnsignedInABase.o
maketest.hpp /Users/wen/Projects/include/bigint/BigInteger.hh /Users/wen/Projects/include/bigint/BigIntegerAlgorithms.hh /Users/wen/Projects/include/bigint/BigIntegerLibrary.hh /Users/wen/Projects/include/bigint/BigIntegerUtils.hh /Users/wen/Projects/include/bigint/BigUnsigned.hh /Users/wen/Projects/include/bigint/BigUnsignedInABase.hh /Users/wen/Projects/include/bigint/NumberlikeArray.hh

Any help or advice will be appreciated. Thanks!

Update

I updated my print to print the expected execution of compile:

print:
    @echo $(CC_FILES)
    @echo $(OBJECTS)
    @echo $(HEADERS)
    @echo "Compiles with:"
    @echo $(COMPILE) $(COMPILE_FLAGS) $(LD_FLAGS) $(CC_FLAGS)

Result:

maketest.cpp /Users/wen/Projects/include/bigint/BigInteger.cc /Users/wen/Projects/include/bigint/BigIntegerAlgorithms.cc /Users/wen/Projects/include/bigint/BigIntegerUtils.cc /Users/wen/Projects/include/bigint/BigUnsigned.cc /Users/wen/Projects/include/bigint/BigUnsignedInABase.cc
maketest.o /Users/wen/Projects/include/bigint/BigInteger.o /Users/wen/Projects/include/bigint/BigIntegerAlgorithms.o /Users/wen/Projects/include/bigint/BigIntegerUtils.o /Users/wen/Projects/include/bigint/BigUnsigned.o /Users/wen/Projects/include/bigint/BigUnsignedInABase.o
maketest.hpp /Users/wen/Projects/include/bigint/BigInteger.hh /Users/wen/Projects/include/bigint/BigIntegerAlgorithms.hh /Users/wen/Projects/include/bigint/BigIntegerLibrary.hh /Users/wen/Projects/include/bigint/BigIntegerUtils.hh /Users/wen/Projects/include/bigint/BigUnsigned.hh /Users/wen/Projects/include/bigint/BigUnsignedInABase.hh /Users/wen/Projects/include/bigint/NumberlikeArray.hh
Yoshi-Air:maketest wen$ make print
maketest.cpp /Users/wen/Projects/include/bigint/BigInteger.cc /Users/wen/Projects/include/bigint/BigIntegerAlgorithms.cc /Users/wen/Projects/include/bigint/BigIntegerUtils.cc /Users/wen/Projects/include/bigint/BigUnsigned.cc /Users/wen/Projects/include/bigint/BigUnsignedInABase.cc
maketest.o /Users/wen/Projects/include/bigint/BigInteger.o /Users/wen/Projects/include/bigint/BigIntegerAlgorithms.o /Users/wen/Projects/include/bigint/BigIntegerUtils.o /Users/wen/Projects/include/bigint/BigUnsigned.o /Users/wen/Projects/include/bigint/BigUnsignedInABase.o
maketest.hpp /Users/wen/Projects/include/bigint/BigInteger.hh /Users/wen/Projects/include/bigint/BigIntegerAlgorithms.hh /Users/wen/Projects/include/bigint/BigIntegerLibrary.hh /Users/wen/Projects/include/bigint/BigIntegerUtils.hh /Users/wen/Projects/include/bigint/BigUnsigned.hh /Users/wen/Projects/include/bigint/BigUnsignedInABase.hh /Users/wen/Projects/include/bigint/NumberlikeArray.hh
Compiles with:
g++ -O2 -c -I/Users/wen/Projects/include/bigint

That proves that make knows what I wanted, but when it builds it's completely different: c++ instead of g++?!

Update 2:

c++ invokes clang, installed on my system.

Solution by Alex B:

But from the compilation command line it looks like Make is trying to use the implicit suffix rule, and ignores your pattern rule.

I tried .SUFFIXES: and yes, it reported a no-rule found. Thanks, I will go and consult the manual.

like image 359
ihsoy ih Avatar asked Dec 20 '12 03:12

ihsoy ih


People also ask

What does GNU Make do?

GNU Make is a tool which controls the generation of executables and other non-source files of a program from the program's source files. Make gets its knowledge of how to build your program from a file called the makefile, which lists each of the non-source files and how to compute it from other files.

Can G ++ compile C code?

gcc is used to compile C program. g++ can compile any . c or . cpp files but they will be treated as C++ files only.

How do you compile a file?

c -I. If you put this rule into a file called Makefile or makefile and then type make on the command line it will execute the compile command as you have written it in the makefile. Note that make with no arguments executes the first rule in the file.


1 Answers

As I stated in the comment, it works in my environment (Mac OSX, GNU Make 3.81), so the issue may be that the makefile you've posted is incomplete or you are using a different version of Make.

But from the compilation command line it looks like Make is trying to use the implicit suffix rule, and ignores your pattern rule.

You can tell Make to ignore default rules by specifying an empty list of suffixes, so you can debug your issue further.

.SUFFIXES:
like image 128
Alex B Avatar answered Oct 09 '22 10:10

Alex B