Makefile cannot find shared library - c++

I have this folder structure:
Project_folder
Project_folder/Ml.app (folder)
Project_folder/Ml.lib (folder)
In the folder Ml.lib I've created a shared library named ml.so
Now I want to link to the client application inside the Ml.app folder.
Here's my makefile:
LIBS = -L ../Ml.lib -l ml
INCLUDES = ../Ml.lib
CXXLAGS = -Wall -I$(INCLUDES)
OBJFILES = main.o
TARGET = mltest
all: $(TARGET)
$(TARGET): $(OBJFILES)
$(CXX) $(CXXLAGS) -o $(TARGET) $(OBJFILES) $(LIBS) $(LDFLAGS)
clean:
rm -f $(OBJFILES) $(TARGET) *~
but when I try to build it I get
g++ -Wall -I../Ml.lib -o mltest main.o -L ../Ml.lib -l ml
/usr/bin/ld: cannot find -lml collect2: error: ld returned 1 exit
status make: *** [Makefile:8: mltest] Error 1

The option -L specifies an additional search directory for libraries. -l looks for an additonal library. Use:
LIBS = -L .. -l Ml

Related

Handle Dependencies When Building With Multiple Cores

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 $#.o
ar rcs $(LIB)/lib$(LIBK).a $#.o
$(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)/*
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.

Undefined reference with glfw3 using g++ on windows

I'm trying to create an opengl project for this tutorial, and I can't get my program to compile.
The current problem here is that every glfw functions are undefined, but they exist in glfw3.h.
The glfw3 files are from the glfw download page (x64 version).
Here is a copy of the logs:
make
=== SRC ===
src/glad.c src/main.cpp
=== OBJ ===
bin/glad.o bin/main.o
===== Creating file bin/glad.o ===
C:/cygnus/cygwin-b20/H-i586-cygwin32/bin/mkdir -p bin/
C:/MinGW/bin/g++ -I./include -o bin/glad.o -c src/glad.c
===== Creating file bin/main.o ===
C:/cygnus/cygwin-b20/H-i586-cygwin32/bin/mkdir -p bin/
C:/MinGW/bin/g++ -I./include -o bin/main.o -c src/main.cpp
C:/MinGW/bin/g++ -L./libs -o build/program.exe bin/glad.o bin/main.o -lglfw3
bin/main.o:main.cpp:(.text+0xc): undefined reference to `glfwInit'
collect2.exe: error: ld returned 1 exit status
make: *** [program.exe] Erreur 1
I'm using the following main.cpp file:
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
int main(int argc, char** argv){
glfwInit();
return 0;
}
And the following makefile:
CXX = C:/MinGW/bin/g++
FAKEPATH = C:/cygnus/cygwin-b20/H-i586-cygwin32/bin/
CXXFLAGS = -W -Wall -ansi -Wno-deprecated
LDLIBS = -lglfw3
TARGET = program.exe
LIB_DIR = -L./libs
INC_DIR = -I./include
SRC = $(shell $(FAKEPATH)find src/ -type f \( -iname \*.cpp -o -iname \*.c \))
OBJ = $(patsubst src/%,bin/%,$(addsuffix .o, $(basename $(SRC))))
all: directories $(TARGET)
test:
echo $(FAKEPATHEXISTS)
directories:
#$(FAKEPATH)echo === SRC ===
#$(FAKEPATH)echo $(SRC)
#$(FAKEPATH)echo === OBJ ===
#$(FAKEPATH)echo $(OBJ)
#$(FAKEPATH)mkdir -p bin
#$(FAKEPATH)mkdir -p build
compileAndRun: all
build/$(TARGET)
$(TARGET): $(OBJ)
$(CXX) $(LDFLAGS) $(LIB_DIR) -o build/$# $^ $(LDLIBS)
bin/%.o: src/%.c
#$(FAKEPATH)echo ===== Creating file $# ===
$(FAKEPATH)mkdir -p $(dir $#)
$(CXX) $(INC_DIR) -o $# -c $<
bin/%.o: src/%.cpp
#$(FAKEPATH)echo ===== Creating file $# ===
$(FAKEPATH)mkdir -p $(dir $#)
$(CXX) $(INC_DIR) -o $# -c $<
clean:
#$(FAKEPATH)rm -rf bin/
cleaner: clean
#$(FAKEPATH)rm -rf build/
And finally, my files are sorted like this:
I'm using MinGW for g++ and cygwin for the linux commands.
Any help or try would be really appreciated ! (I really don't know where the problem came from)
Thanks !
Note: I already searched on google a lot without finding any working solution (including several stack overflow questions)
I found a solution to this.
The first things I had to do is add #define GLFW_DLL in my main.cpp.
After doing this I had the error Undefined reference to '_imp__glfwInit'. To solve this error I had to remove the *.a files in my /libs, and then I moved my .dll file to the root of the project (To avoid a missing dll error).

File linking with c++ makefile

Make file:
INCLUDE = -I/usr/X11R6/include/
LIBDIR = -L/usr/X11R6/lib
COMPILERFLAGS = -Wall
CC = g++
CFLAGS = $(COMPILERFLAGS) $(INCLUDE)
LIBRARIES = -lX11 -lXi -lXmu -lglut -lGL -lGLU -lm
All: project
project: main.o landscape.o point.o
$(CC) $(CFLAGS) -o $# $(LIBDIR) $< $(LIBRARIES)
clean:
rm *.o
I have a landscape.cpp, landscape.h, point.cpp, point.h, and main.cpp files
I'm including "point.h" in my main.cpp file and i'm getting:
g++ -Wall -I/usr/X11R6/include/ -o project -L/usr/X11R6/lib main.cpp -lX11 -lXi -lXmu -lglut -lGL -lGLU -lm
/tmp/ccdpJ8HH.o: In function main':
main.cpp:(.text+0x1c0): undefined reference toPoint::Point(int, int)'
collect2: error: ld returned 1 exit status
Makefile:15: recipe for target 'project' failed
make: *** [project] Error 1
project: main.o landscape.o point.o
$(CC) $(CFLAGS) -o $# $(LIBDIR) $< $(LIBRARIES)
Here you need to link all .o files. The rule you have here will only use the main.o file. Because $<is the first dependency only. $^ should be for all three. So try:
project: main.o landscape.o point.o
$(CC) $(CFLAGS) -o $# $(LIBDIR) $^ $(LIBRARIES)
I suggest you to use a more complete Makefile.
Also, use CXX=g++ and CXXFLAGS instead of CC and CFLAGS, because you are compiling C++ and make have special variables.
Here is an example of Makefile I could use.
# Project name
NAME= project
# Include directory
INC_DIR= /usr/X11R6/include/
# Library directory
LIB_DIR= /usr/X11R6/lib/
# Compiler
CXX= g++
# Source files
SRC_DIR= # in case your cpp files are in a folder like src/
SRC_FILES= main.c \
landscape.c \
point.c
# Obj files
OBJ= $($(addprefix $(SRC_DIR), $(SRC_FILES)):.c=.o)
# that rule is composed of two steps
# addprefix, which add the content of SRC_DIR in front of every
# word of SRC_FILES
# And a second rule which change every ".c" extension into ".o"
LIBS= X11 \
Xi \
Xmu \
glut \
GL \
GLU \
m
# Compilation flags
CXXFLAGS= -Wall
CXXFLAGS+= $(addprefix -I, $(INC_DIR))
LDFLAGS= $(addprefix -L, $(LIB_DIR)) \
$(addprefix -l, $(LIBS))
# Rules
# this rule is only linking, no CFLAGS required
$(NAME): $(OBJ) # this force the Makefile to create the .o files
$(CXX) -o $(NAME) $(OBJ) $(LDFLAGS)
All: $(NAME)
# Remove all obj files
clean:
rm -f $(OBJ)
# Remove all obj files and the binary
fclean: clean
rm -f $(NAME)
# Remove all and recompile
re: fclean all
# Rule to compile every .c file into .o
%.o: %.c
$(CXX) -o $# -c $< $(CFLAGS)
# Describe all the rules who do not directly create a file
.PHONY: All clean fclean re
I'm not sure it's perfect, but it's better.
Also don't forget to put you project rule before your All rule to avoid relinking when simply calling make.
That way, you can also add beautiful messages (in the %.o: %.c rule for example).
With that you just have to do make re to get your binary fully updated.

Compile using makefile in Windows with MinGW

I have a problem with the following makefile in Windows. Although it worked in Linux, I get an error now using MinGW in Windows.
I checked the article on this page: Compile using MakeFile in Window, but I still have no success.
CC = c++
CFLAGS = -Wall -g
ODIR = /OBJ
CFILES := $(wildcard SRC/*.cpp)
OFILES := $(addprefix OBJ/,$(notdir $(CFILES:.cpp=.o)))
meshl: $(OFILES)
$(CC) $(CFLAGS) -o $# $(OFILES)
OBJ/%.o: SRC/%.cpp
$(CC) $(CFLAGS) -c $< -o $#
clean:
rm -f OBJ/*.o
When I try to compile it in the command prompt, the following message appears:
OBJ/mpoint.o: file not recognized: File format not recognized
collect2.exe: error: ld returned 1 exit status
makefile:9: recipe for target 'meshl' failed
make: ***[meshl] Error 1
Thanks for your time and help!

Calling matlab from c++ using cygwin

I'm working in windows and want to send data from C++ to Matlab. I've gotten the impression this is done most easy creating a makefile. Therefore I've installed cygwin to use the make command.
My makefile is as follows:
CXX = g++
CFLAGS = -O3 -I /cygdrive/c/Program\ Files/MATLAB/R2011a/extern/include
LIBS = -L /cygdrive/c/Program\ Files/MATLAB/R2011a/extern/lib/win64/microsoft/
LIBS2 = -L /cygdrive/c/Program\ Files/MATLAB/R2011a/extern/lib/win64/microsoft/libmx.lib
LDFLAGS = -leng -lmx
RKspace2d: RKspace2d.o
$(CXX) -o $# $^ $(LDFLAGS) $(LIBS)
RKspace2d.o: RKspace2d.cpp
$(CXX) -c $(CFLAGS) $(LIBS) $<
# $# name of the target
# $^ name of all prerequisites with duplicates removed
# $< name of the first prerequisite
When I type in "make" in the cygwin terminal, being in the right directory I get the following error:
$ make
g++ -o RKspace2d RKspace2d.o -leng -lmx -L /cygdrive/c/Program\ Files/MATLAB/R2011a/extern/lib/win64/microsoft/
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: cannot find -leng
/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/ld: cannot find -lmx
collect2: ld returnerede afslutningskoden 1
makefile:8: recipe for target `RKspace2d' failed
make: *** [RKspace2d] Error 1
I believe the path is correct since both libeng.lib and libmx.lib are contained in the microsoft folder.
Hope you guys can help
Thomas