I'm starting with creating Makefile. I write simple Makefile, which create two library, static and dynamica and use to compile executable file. The files for the operation of the program are in individual folders: *.c in src, *.h in include,
*.a and *.so in lib and executable file in bin. The rest are in the makefile folder. My Makefile create all files but cant find files. I use VPATH, and -L in gcc. But that's not work. I'm working on Ubuntu 20.04 LTS. Thanks for all help.
vpath %.c src
vpath %.h include
vpath %.a lib
vpath %.so lib
%.o: %.c
gcc -c $<
%: %.o
gcc -o ./bin/$# $^ -L./lib -I./bin
libj%.a: %j.o
ar rs ./lib/$# $^
lib%r.so: p%.o
gcc -shared -o ./lib/$# $^ -L./lib
prog: prog.o libjp.a libgr.so
prog.o: prog.c libgr.h libjp.h
libjp.a: pj.o pp.o
pj.o: pj.c
pp.o: pp.c
libgr.so: pg.o pr.o
pg.o: pg.c
pr.o: pr.c
I don't understand what you mean by "in which folder", you have to do it your shell before you run your program.
So, if you run this:
$ make
$ ./bin/prog
and you get an error, you should use this:
$ make
$ export LD_LIBRARY_PATH=$(pwd)/lib
$ ./bin/prog
Do NOT put the setting of LD_LIBRARY_PATH inside the makefile as I mentioned above in my comments.
Related
I have a problem trying to create a Makefile that compile multiple sorces, generate only a shared library and make an exe with another file wiht the main function.
The sorces also have dependencies.
My Makefile is
CC=gcc
CFLAGS=-Wall -g
BINS=libsensorMotor.so maintarget
all: $(BINS)
libsensorMotor.o: libsensorMotor.cpp sensorMotor.h Adafruit_ADS1015.cpp Adafruit_ADS1015.h wiringPiI2C.c wiringPiI2C.h enumADCGain.h
$(CC) $(CFLAGS) -c libsensorMotor.cpp Adafruit_ADS1015.cpp wiringPiI2C.c
libsensorMotor.so: libsensorMotor.cpp sensorMotor.h
$(CC) $(CFLAGS) -fPIC -shared -o $# libsensorMotor.cpp -lc
maintarget: maintarget.c
$(CC) $(CFLAGS) -o $# $^ -L. -lsensorMotor -pthread
clean:
rm *.o $(BINS)
The script show the errors:
libsensorMotor.so Undefined reference to 'functionXXXX'
maintarget contains the main and use libsensorMotor as a shared library. libsensorMotor depends and include all the rest of the files
The error mention all the functions that libsensorMotor uses from the include sources.
I only need to generate a correct libsensorMotor.so that can use as shared library from any other main file. Internet has many tutorials but are unclear, weird and complicated, and not show how do this simple.
Is not Makefile problem, simply the line
gcc -pthread -lm -o maintarget maintarget.c libsensorMotor.cpp Adafruit_ADS1015.cpp wiringPiI2C.c
sends same error, the compiler not recongnice the function inside the pthread_create while compile C and C++ with gcc
I have some C++ code on an openSuse platform that I need to compile to be executed on a different linux-based target. Part of the code is a dynamic library libfoo.so. I compile everything with make and then copy the compiled executable prog together with the libfoo.so to the target. When I then run the executable, I get some errors indicating the libfoo could not be initialized. I've tried everything I could find to tell the executable where it can find the libfoo.so but I still get the error.
Could anybody tell me what I am doing wrong here? I feel like it could be an error in the Makefile.
I am very new to C++ and using Makefiles in general, and on top of it all, the target runs kind of a proprietary linux version, so I cannot provide much information about it. I do have the appropriate compiler for it though.
My directory structure on the openSuse platform:
|src
|--Foolib
|----foolib.h
|----libfoo.so
|--Otherlib
|----otherlib.h
|----otherlib.hpp
|---+OtherlibSrcDirectory
|--bar.cpp
|--bar.h
|--Makefile
Directory structure on the target:
|program
|--libfoo.so
|--prog
My Makefile:
LIBS = -LFoolib -lfoo
INC = -I OtherLib -I Foolib
CXXFLAGS += -lpthread -std=c++11 -D_GLIBCXX_USE_NANOSLEEP $(INC)
LDFLAGS = '-Wl,-rpath,$$ORIGIN'
SRC_FILES = bar.cpp
OBJ = $(SRC_FILES:%.cpp=%.o)
prog: $(OBJ)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(LIBS) -o $# $^
%.o: %.cpp
$(CXX) $(CXXFLAGS) $(LIBS) -c $<
Basically, bar.h includes Foolib/foolib.h as well as Otherlib/OtherlibSrcDirectory and bar.cpp includes bar.h. Then some functions from foolib.h are called in bar.cpp and they return error values. If necessary I can provide some more insights into the code but I'll leave it out for now to keep it a bit shorter.
Any help would be highly appreciated!
Found my mistake.
libfoo.so was already on the target machine and it was located in the correct folder (/lib). My program had been able to find it without problems.
My mistake: I executed my program on the target machine without root permissions.
Without root permissions, I am not allowed to initialize Foolib.
sudo ./prog fixed everything.
I am trying to write what I thought would be quite a simple Makefile and I'm just baffled! I'm not a makefile writer, but I thought I understood them enough to be able to get a simple one working.
Okay, I have a small project in a directory and also in this directory is a libs directory containing many .c files. What I'm trying to do is write a makefile that will build the contents of the /libs directory into a static lib file in the /libs directory and then compile a few source files in the / directory and link it against the built .a file.
I'm sure someone's going to suggest "why not use cmake", but that's not answer I'm looking for (waves hand like a Jedi.. ehehehehe)
CC = gcc
CFLAGS = -Wall
SOURCES = lzx.c csum.c dirs.c listner.c tree.c
OBJECTS = $(SOURCES:.c=.o)
TARGETLIB = libs/mylib.a
TARGET = TestApp
libs/%.o : libs/%.c
$(CC) $CFLAGS -c $<
$(TARGETLIB) : $(OBJECTS)
ar rcs $# $^
$(TARGET) :
$(CC) $CFLAGS Source1.cpp Source2.cpp -llibs/mylib.a -o $#
My understanding was that the first recipe, would compile all the .c files into objects, but it seems to compile the first .c file and then stop.
Any help anyone could give me would be appreciated.
Since Your final app is TARGET, You should make it first Makefile rule. And since it also depends on TARGETLIB it should be given as dependency, like so:
$(TARGET): $(TARGETLIB)
$(CC) $(CFLAGS) Source1.cpp Source2.cpp -Lmylib -o $#
next I assume that *.c files You mentioned are lib files. Thus You will need a prefix to them, since You want to specify them by hand, not via wildcard or rule.
OBJECTS = $(addprefix(libs, $(SOURCES)):.c=.o)
and last thing that comes to my mind is library name, which supposed to be libSOMENAME.a (well, linker searches for this name in path and -Lotherpaths). So we have:
TARGETLIB = libs/libmylib.a
summing it all up:
CC = gcc
CFLAGS = -Wall
SOURCES = lzx.c csum.c dirs.c listner.c tree.c
OBJECTS = $(addprefix(libs, $(SOURCES)):.c=.o)
TARGETLIB = libs/libmylib.a
TARGET = TestApp
$(TARGET) : $(TARGETLIB)
$(CC) $(CFLAGS) Source1.cpp Source2.cpp -static -L./libs -lmylib -o $#
$(TARGETLIB) : $(OBJECTS)
ar rcs $# $^
And yes, this could be written much better, but I assume if You wanted to learn more about Makefiles or linker, and not just shown where You made mistakes, You'd know how to find manual pages.
I have a makefile which is supposed to compile a large number of source files into individual object files, then link them into a shared library.
The list of source files are stored in a variable, SOURCES. During the $(OBJECTS) target, where the object files are compiled, make runs the command $(CC) $(CFLAGS) -c $< -o $#, where $< is $(addprefix $(SRCPATH),$(SOURCES)).
This makes the command use the same source file for every object file, giving me a bunch of object files made from Time.cpp and causing the linker to give me a bunch of errors of functions that are already defined in every other object file. How can I get this makefile to work?
# Variable setup
# BUILD - Either Debug or Release, specify when running make
# ARCH - Either 32 or 64, specify when running make
# CC - The compiler
# INC - The include directories
# CFLAGS - Compiler flags to use
# LDFLAGS - Linker flags to use
# OBJDIR - Directory for .o files
# BINARY - Output file path
# SOURCES - Path to each individual source file
# OBJECTS - Object files
ifeq ($(and $(ARCH),$(BUILD)),)
$(error You have either not defined an architecture or build or both, please run "make BUILD=(DEBUG/RELEASE) ARCH=(32/64)")
endif
CC = g++
INC = -I../../include -I../../extlibs/headers -I../../extlibs/headers/libfreetype/linux
LDFLAGS = -lX11 -lGL -lGLEW -lfreetype -ljpeg -lopenal -lsndfile
CFLAGS = $(INC) -std=c++0x -fPIC -pthread -m$(ARCH)
OBJDIR = ./obj/$(BUILD)/$(ARCH)-bit
BINPATH = ./bin/$(BUILD)/$(ARCH)-bit
BINARY = $(BINPATH)/libTyrant$(ARCH).so
SRCPATH = ../../src/
SOURCES = System/Time.cpp System/Mutex.cpp System/Log.cpp System/Clock.cpp System/Sleep.cpp System/Unix/ClockImpl.cpp System/Unix/MutexImpl.cpp System/Unix/SleepImpl.cpp System/Unix/ThreadImpl.cpp System/Unix/ThreadLocalImpl.cpp System/Lock.cpp System/String.cpp System/ThreadLocal.cpp System/Thread.cpp Audio/SoundRecorder.cpp Audio/SoundBuffer.cpp Audio/SoundSource.cpp Audio/AudioDevice.cpp Audio/ALCheck.cpp Audio/Sound.cpp Audio/Music.cpp Audio/SoundFile.cpp Audio/SoundStream.cpp Audio/SoundBufferRecorder.cpp Audio/Listener.cpp Graphics/RectangleShape.cpp Graphics/VertexArray.cpp Graphics/Shader.cpp Graphics/ConvexShape.cpp Graphics/ImageLoader.cpp Graphics/Sprite.cpp Graphics/RenderTexture.cpp Graphics/BlendMode.cpp Graphics/Shape.cpp Graphics/CircleShape.cpp Graphics/TextureSaver.cpp Graphics/Vertex.cpp Graphics/RenderTextureImpl.cpp Graphics/Texture.cpp Graphics/Text.cpp Graphics/GLExtensions.cpp Graphics/Image.cpp Graphics/RenderTextureImplFBO.cpp Graphics/GLCheck.cpp Graphics/RenderTextureImplDefault.cpp Graphics/Color.cpp Graphics/Transformable.cpp Graphics/RenderTarget.cpp Graphics/Transform.cpp Graphics/View.cpp Graphics/RenderStates.cpp Graphics/RenderWindow.cpp Graphics/Font.cpp Window/JoystickManager.cpp Window/Joystick.cpp Window/Window.cpp Window/Keyboard.cpp Window/GlResource.cpp Window/Unix/JoystickImpl.cpp Window/Unix/WindowImplX11.cpp Window/Unix/GlxContext.cpp Window/Unix/Display.cpp Window/Unix/VideoModeImpl.cpp Window/Unix/InputImpl.cpp Window/VideoMode.cpp Window/Mouse.cpp Window/GlContext.cpp Window/Context.cpp Window/WindowImpl.cpp Network/Ftp.cpp Network/TcpListener.cpp Network/Packet.cpp Network/IpAddress.cpp Network/TcpSocket.cpp Network/Socket.cpp Network/Unix/SocketImpl.cpp Network/UdpSocket.cpp Network/SocketSelector.cpp Network/Http.cpp
OBJECTS = $(addprefix $(OBJDIR)/,$(SOURCES:.cpp=.o))
ifeq ($(BUILD),DEBUG)
CFLAGS := $(CFLAGS) -g -pg -Og
endif
ifeq ($(BUILD),RELEASE)
CFLAGS := $(CFLAGS) -s -O3
endif
all: clean $(addprefix $(SRCPATH),$(SOURCES)) $(BINARY)
$(BINARY): $(OBJECTS) $(BINPATH)
$(CC) $(LDFLAGS) $(OBJECTS) -shared -o $#
$(OBJECTS): $(addprefix $(SRCPATH),$(SOURCES)) $(OBJDIR)
$(CC) $(CFLAGS) -c $< -o $#
$(OBJDIR):
mkdir ./obj
mkdir ./obj/$(BUILD)
mkdir $#
mkdir $#/Audio
mkdir $#/Graphics
mkdir $#/Network
mkdir $#/Network/Unix
mkdir $#/System
mkdir $#/System/Unix
mkdir $#/Window
mkdir $#/Window/Unix
$(BINPATH):
mkdir ./bin
mkdir ./bin/$(BUILD)
mkdir $#
clean:
rm -rf bin
rm -rf obj
You have several problems here.
Suppose all of the source files were in the working directory, and that's where the object files belonged too. Instead of trying to build all of the objects with one command, you could build each object separately, with a pattern rule to cover them all:
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $#
Then you could make the OBJECTS prerequisites of the library, and Make would handle it all:
$(BINARY): $(OBJECTS)
$(CC) $(LDFLAGS) $^ -shared -o $#
(Once you had that working, you might remember that Make already had built-in rules for things like building foo.o from foo.cpp, but never mind that for now.)
But in your build scheme you combine this with other problems: 1) you have source files in several different directories, and 2) you want to build the objects elsewhere, namely 3) in a directory tree that mirrors the source tree, 4) which you build on the fly.
Addressing all of those points would make for quite an involved answer. Which of them are you already comfortable with?
I've made it work, though it may not be optimal. My solution:
$(BINARY): $(SOURCES) $(BINPATH)
$(CC) $(LDFLAGS) $(OBJECTS) -shared -o $#
$(SOURCES): $(OBJDIR)
$(CC) $(CFLAGS) -c $(SRCPATH)$# -o $(patsubst %.cpp,%.o,$(OBJDIR)/$#)
Basically, I just switched the targets from the Object files to the source files, appended the source path to the target name for the input file, and appended the object directory to the target name while also using patsubst to change the file extension from .cpp to .o. The entire makefile is pretty hacked together, I'm aware of that, but it works and that's good enough for me for my first makefile.
i am new to makefiles and have just rescently created a makefile that works for a c++ project. it has two cpp files and one h file. i am trying to convert my file to work in linux but cant seem to figure out how. any ideas?
EXE = NumberGuessingGame.exe
CC = cl
LD = cl
OBJ = game.obj userInterface.obj
STD_HEADERS = header.h
CFLAGS = /c
LDFLAGS = /Fe
$(EXE): $(OBJ)
$(LD) $(OBJ) $(LDFLAGS)$(EXE)
game.obj: game.cpp $(STD_HEADERS)
$(CC) game.cpp $(CFLAGS)
userInterface.obj: userInterface.cpp $(STD_HEADERS)
$(CC) userInterface.cpp $(CFLAGS)
#prepare for complete rebuild
clean:
del /q *.obj
del /q *.exe
For in depth treatment of make on Linux, see GNU make.
There are a few differences. Binaries have no extension
EXE = NumberGuessingGame
The compiler is gcc, but need not be named, because CC is built in, same goes for LD. But since your files are named .cpp, the appropriate compiler is g++, which is CXX in make.
Object files have extension .o
OBJ = game.o userInterface.o
STD_HEADERS = header.h
Compiler flags
CXXFLAGS = -c
The equivalent for /Fe is just -o, which is not specified as LDFLAGS, but spelled out on the linker command line.
Usually, you use the compiler for linking
$(EXE): $(OBJ)
$(CXX) $(LDFLAGS) $(OBJ) -o $(EXE)
You don't need to specify the rules for object creation, they are built in. Just specify the dependencies
game.o: $(STD_HEADERS)
userInterface.o: $(STD_HEADERS)
del is called rm
clean:
rm -f $(OBJ)
rm -f $(EXE)
One important point is, indentation is one tab character, no spaces. If you have spaces instead, make will complain about
*** missing separator. Stop.
or some other strange error.
You can also use CMake to accomplish your task:
Put following into CMakeLists.txt file in the root directory of your project (<project-dir>):
cmake_minimum_required (VERSION 2.6)
project (NumberGuessingGame)
add_executable(NumberGuessingGame game.cpp serInterface.cpp)
Then on the console do
"in-source" build
$ cd <project-dir>
$ cmake .
$ make
or "out-source" build
$ mkdir <build-dir>
$ cd <build-dir>
$ cmake <project-dir>
$ make
You can adjust build setting using nice GUI tool. Just go to the build directory and run cmake-gui.
You don't need to include headers in the dependency list. The compiler will fail on its own, stopping make from continuing. However, if you're including them in the dependency list to force make to rebuild files in case the header changes, nobody will stop you.
CFLAGS never needs to contain -c, nor does LDFLAGS need -o. Below is a revamped makefile. Note that you can always override a macro explicitly defined in a makefile or implicitly defined using something like make CFLAGS=-Wall for example. I used the de facto standard CXX macro name in the event that you have C source files, which must be compiled using a C compiler (the value of the CC macro) instead of a C++ compiler.
.POSIX:
#CC is already implicitly defined.
CXX = g++
OBJ = game.o userInterface.o
STD_HEADERS = header.h
.SUFFIXES:
.SUFFIXES: .o .cpp .c
NumberGuessingGame: $(OBJ) $(STD_HEADERS)
$(CXX) $(CFLAGS) -o $# $(OBJ) $(LDFLAGS)
.cpp.o: $(STD_HEADERS)
$(CXX) $(CFLAGS) -c $<
#There is already an implicit .c.o rule, thus there is no need for it here.
#prepare for complete rebuild
clean:
-rm -f NumberGuessingGame *.o
As yegorich answered, you can use a build system like Cmake. It is much more flexible, cross-platform, and can generate Unix Makefiles as well as Nmake Makefiles and Visual Studio solutions on Windows.