Reputation: 13
I am building a small utility library in c++, and I am adding some examples to it. The project structure looks like this:
MyLib
|__bin
|
|__include
| |__mylib.hpp
|
|__lib
|
|__examples
| |__example.cpp
|
|__src
| |__mylib.cpp
|
|__Makefile
Here is what my Makefile looks like:
LIBK = mylib
LIBS = $(LIBK).a
CXXFLAGS := -Wall -Wextra -std=c++17 -ggdb
BIN := bin
SRC := src
INCLUDE := include
LIB := lib
EXAMPLES := examples
all: lib examples
lib: $(LIB)/$(LIBK)
examples: lib $(BIN)/$(EXAMPLES)
run: clean all
clear
./$(LIB)/$(LIBK)
$(LIB)/$(LIBK): $(SRC)/*.cpp
-mkdir -p lib
$(CXX) -c $(CXXFLAGS) -I$(INCLUDE) -L$(LIB) $^ -o [email protected]
ar rcs $(LIB)/lib$(LIBK).a [email protected]
$(BIN)/$(EXAMPLES): $(EXAMPLES)/*.cpp
-mkdir -p bin
$(CXX) $(CXXFLAGS) -I$(INCLUDE) -L$(LIB) -l$(LIBK) $^ -o $@
clean:
-rm -rf $(BIN)/*
-rm -rf $(LIB)/*
My problem is that everything seems to look fine when I run make
, but it fails when I run make -j8
with the following error.
cannot find -lmylib
collect2: error: ld returned 1 exit status
make: *** [Makefile:36: bin/examples] Error 1
make: *** Waiting for unfinished jobs....
ar rcs lib/libmylib.a lib/mylib.o
It seems like the multiple core instruction triggers both compilations at the same time, without waiting for the library to build before launching the job to build the example. I believe I had defined the dependencies correctly, but there is something obviously wrong that I don't seem to be able to find by myself.
EDIT: Seeing that I the original Makefile is fundamentally incorrect, but no answer really provided an alternative one, I created a new one to the best of my knowledge that seems to work. Any constructive and respectful criticism is welcome.
LIBNAME := libIntegration.a
CXX := g++
BIN := bin
SRC := src
INCLUDE := include
LIB := lib
LIBRARIES := -lIntegration
EXECUTABLE := main
LIBRARY_SOURCES := $(SRC)/mxIntegration.o
EXECUTABLE_SOURCES := examples/main.o
CXXFLAGS := -Wall -Wextra -std=c++17 -ggdb -I$(INCLUDE)
all: $(BIN)/$(EXECUTABLE)
run: clean all
clear
./$(BIN)/$(EXECUTABLE)
$(LIB)/$(LIBNAME): $(LIBRARY_SOURCES)
ar rcs $@ $^
$(BIN)/$(EXECUTABLE): $(LIB)/$(LIBNAME)
$(CXX) $(CXXFLAGS) -I$(INCLUDE) -L$(LIB) $(EXECUTABLE_SOURCES) -o $@ $(LIBRARIES)
clean:
-rm -rf $(BIN)/*
-rm -rf $(LIB)/*
Upvotes: 0
Views: 68
Reputation: 100926
This is a super-bizarre makefile. I'm not sure why you even bother to use make at all, because you are always recompiling every source file whenever any source file changes.
But, just to deal with your specific question your error message says:
cannot find -lmylib
so clearly the example is being built before the library is done. So, let's look at the rule for building examples
:
$(BIN)/$(EXAMPLES): $(EXAMPLES)/*.cpp
Here you list the source files as prerequisites of the target. But nowhere have you listed the library as a prerequisite. So, make has no idea that you need to wait for the library to be built, and you definitely haven't defined that dependency.
Upvotes: 3