0
votes

I have two directories which contains cpp source files (C:\projects\project1\cpputest\src\cpp_sources) (C:\projects\project1\cpputest\src\cpp_second_sources)

I created two simple makefile within each of the directory where the cpp source files are located. The makefile creates only a static library (windows platform and gnu compiler) "lib.a". For example:

#Set this to @ to keep the makefile quiet
ifndef SILENCE
    SILENCE = @
endif

CPPUTEST_HOME = C:/projects/project1/cpputest
CPP    = g++
CXXFLAGS = -Wall
SOURCE = $(wildcard *.cpp)
OBJECTS= $(SOURCE:.cpp=.o)
TARGET = lib.a

.SUFFIXES: .cpp

all: $(TARGET)

.cpp.o:
    $(CPP) $(CXXFLAGS) -c $< -o $@

$(TARGET): $(OBJECTS)
    ar -rc $(TARGET) $(OBJECTS)

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

This works so far. Now I would like to run one makefile from "C:\projects\project1" directory to create one library for the two source directories.I modified the makefile as follow:

CPPUTEST_HOME = C:/projects/project1/cpputest
CPP    = g++
CXXFLAGS = -Wall

SOURCE_DIR = $(CPPUTEST_HOME)/src/cpp_sources 
SOURCE_DIR += $(CPPUTEST_HOME)/src/cpp_second_sources

SOURCES = $(wildcard $(SOURCE_DIR)/*.cpp)
OBJECTS= $(SOURCES:.cpp=.o)
TARGET = libgcc.a

.SUFFIXES: .cpp

default: $(TARGET)

.cpp.o:
    $(CPP) $(CXXFLAGS) -c $< -o $@

 $(TARGET): $(OBJECTS)
    ar -rc $(TARGET) $(OBJECTS)

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

The output is:

g++ -Wall -c C:/projects/project1/cpputest/cpp_sources/file1.cpp -o     C:/projects/project1/cpputest/cpp_sources/file1.o
g++ -Wall -c C:/projects/project1/cpputest/cpp_sources/file2.cpp -o     C:/projects/project1/cpputest/cpp_sources/file2.o
g++ -Wall -c C:/projects/project1/cpputest/cpp_sources/file3.cpp -o     C:/projects/project1/cpputest/cpp_sources/file3.o
g++ -Wall -c C:/projects/project1/cpputest/cpp_sources/file4.cpp -o     C:/projects/project1/cpputest/cpp_sources/file4.o
g++ -Wall -c C:/projects/project1/cpputest/cpp_sources/file5.cpp -o     C:/projects/project1/cpputest/cpp_sources/file5.o
g++ -Wall -c C:/projects/project1/cpputest/cpp_sources/file6.cpp -o     C:/projects/project1/cpputest/cpp_sources/file6.o
g++ -Wall -c C:/projects/project1/cpputest/cpp_sources/file7.cpp -o     C:/projects/project1/cpputest/cpp_sources/file7.o
g++ -Wall -c C:/projects/project1/cpputest/cpp_sources/file8.cpp -o     C:/projects/project1/cpputest/cpp_sources/file8.o
g++ -Wall -c C:/projects/project1/cpputest/cpp_sources/file9.cpp -o     C:/projects/project1/cpputest/cpp_sources/file9.o
g++ -Wall -c C:/projects/project1/cpputest/cpp_sources/file10.cpp -o     C:/projects/project1/cpputest/cpp_sources/file10.o
g++ -Wall -c C:/projects/project1/cpputest/cpp_sources/file11.cpp -o     C:/projects/project1/cpputest/cpp_sources/file11.o
g++ -Wall -c C:/projects/project1/cpputest/cpp_sources/file11.cpp -o     C:/projects/project1/cpputest/cpp_sources/file10.o
g++ -Wall -c C:/projects/project1/cpputest/cpp_sources/file12.cpp -o     C:/projects/project1/cpputest/cpp_sources/file12.o
ar -rc libgcc.a C:/projects/project1/cpputest/cpp_second_sources     C:/projects/project1/cpputest/cpp_sources/file1.o     C:/projects/project1/cpputest/cpp_sources/file2.o     C:/projects/project1/cpputest/cpp_sources/file3.o     C:/projects/project1/cpputest/cpp_sources/file4.o     C:/projects/project1/cpputest/cpp_sources/file5.o     C:/projects/project1/cpputest/cpp_sources/file6.o     C:/projects/project1/cpputest/cpp_sources/file7.o     C:/projects/project1/cpputest/cpp_sources/file8.o     C:/projects/project1/cpputest/cpp_sources/file9.o     C:/projects/project1/cpputest/cpp_sources/file10.o     C:/projects/project1/cpputest/cpp_sources/file11.o     C:/projects/project1/cpputest/cpp_sources/file12.o     C:/projects/project1/cpputest/cpp_sources/file13.o
c:\MinGW\bin\ar.exe: C:/projects/project1/cpputest/cpp_second_sources: Permission denied
make: *** [libgcc.a] Error 1

As you can see, all the sources from the directory /cpp_sources are compiled and objects files created, after this, the same has to be done for the directory /cpp_second_sources. Instead of this, the makefile is invoking the ar-rc command on the /cpp_second_sources directory... that's what is strange.

1
Always, always use forward slashes and only forward slashes (/) as directory separators in GNU make makefiles. See if that fixes your problem.MadScientist
oh, damn, thx! So, now it works partially after changing to forward slashes. The object files are created and after finishing the step "ar -rc $(TARGET) $(OBJECTS)" I get the same message as mentioned aboveJohnDoe
Please edit your comment and copy/paste the ar.exe command line make printed as well as the exact error message. Without the command line it's hard to know what's wrong.MadScientist
@MadScientist: So, make prints this output:'c:\MinGW\bin\ar.exe: C:/projects/project1/cpputest/src/cpp_sources: Permission denied make: *** [lib.a] Error 1'JohnDoe
First, please edit your question because it's very hard to read unformatted content in comments. Second, you are showing me the error message. What I want to see is the ar.exe command line, that should be printed before the error message. There's nothing in your makefile that hides the command line (no @ prefix to the recipe line) so make should print it out, if your makefile looks like the one above. If you do have a @ prefix in your real makefile, remove it.MadScientist

1 Answers

0
votes

Aha. This is much more clear. So your problem is here:

SOURCE_DIR = $(CPPUTEST_HOME)/src/cpp_sources 
SOURCE_DIR += $(CPPUTEST_HOME)/src/cpp_second_sources

SOURCES = $(wildcard $(SOURCE_DIR)/*.cpp)

What happens? Well, you set SOURCE_DIR to two different directories, so the value of SOURCE_DIR is this:

$(CPPUTEST_HOME)/src/cpp_sources $(CPPUTEST_HOME)/src/cpp_second_sources

Then you run $(wildcard $(SOURCE_DIR)/*.cpp) which expands to a wildcard command like this:

$(wildcard $(CPPUTEST_HOME)/src/cpp_sources $(CPPUTEST_HOME)/src/cpp_second_sources/*.cpp)

Probably you can now see your problem. You can't just write $(FOO)/bar and expect the suffix /bar to be appended to each word in the expansion of $(FOO); that's not how it works. It's just added to the end, as written.

If you want the SOURCE_DIR variable to be able to hold multiple directories, not just one, then first you should probably rename it to SOURCE_DIRS or something more descriptive, and second you have to use things like addsuffix etc. to operate on all words in the list:

SOURCES = $(wildcard $(addsuffix /*.cpp,$(SOURCE_DIR))