seems I keep missing the idea of "target" and "rules" - c++

tried to make a own makefile using alias
keep getting " make: *** No rule to make target g++', needed byrelease'. Stop."
PROGRAMS = stl
CPP = g++
CPPFLAGS = -Wall -ansi -pedantic -std=c++98
DEBUG_FLAGS = -g -DDEBUG -UNDEBUG
RELEASE_FLAGS = -O3 -UDEBUG -DNDEBUG
TEST_NAME = test$(PROGRAMS).out
DBG_TEST_NAME = test$(PROGRAMS).dbg.out
all: release debug
release: $(CPP) $(CPPFLAGS) $(RELEASE_FLAGS) $(PROGRAMS).cpp -o $(TEST_NAME)
debug: $(CPP) $(CPPFLAGS) $(DEBUG_FLAGS) $(PROGRAMS).cpp -o $(DBG_TEST_NAME)
clean:
rm -rvf *.o *.a *.out *dbg.out $(PROGRAMS)

The code for a target should be on a separate line, indented by a tab.
A rule in a makefile is:
target: dependencies
commands-for-rule
So in your case, something like e.g.
debug: $(PROGRAMS).cpp
$(CPP) $(CPPFLAGS) $(DEBUG_FLAGS) $(PROGRAMS).cpp -o $(DBG_TEST_NAME)
This makes the debug target depend on $(PROGRAMS).cpp, so the rule will always be executed if $(PROGRAMS).cpp is modified.

Related

Error while loading shared libraries when running executable

When I make the Makefile everything works fine, I get a library in the directory dir. And when I run "Make test" I get a testfile that I want to run. But when I want to run this file I get this weird error: ./programma: error while loading shared libraries: libprogramma.so: cannot open shared object file: No such file or directory. I have tried running the program on both WSL and Linux, but nothing makes this error go away. Can anyone help me?
Here I have my Makefile which makes the library and the executable:
INC_DIR = include
SRC_DIR = src
SOURCES = $(sort $(shell find $(SRC_DIR) -name '*.cc'))
OBJECTS = $(SOURCES:.cc=.o)
DEPS = $(OBJECTS:.o=.d)
TARGET = programma
CXX = g++
CFLAGS = -Wall -Wextra -Wpedantic -std=c++11
CPPFLAGS = $(addprefix -I, $(INC_DIR))
.PHONY: all clean debug release
release: CFLAGS += -O3 -DNDEBUG
release: all
debug: CFLAGS += -O0 -DDEBUG -ggdb3
debug: all
all: $(TARGET)
clean:
rm -f $(OBJECTS) $(DEPS) lib/*.so programma *.d
$(TARGET): $(OBJECTS)
$(CXX) $(CFLAGS) $(CPPFLAGS) -fPIC -shared -o lib/lib$#.so $^
-include $(DEPS)
%.o: %.cc
$(CXX) $(CFLAGS) $(CPPFLAGS) -fPIC -MMD -o $# -c $<
test:
$(CXX) $(CFLAGS) -L./lib $(CPPFLAGS) -MMD -o programma tests/main.cc -l$(TARGET)
Executables on Linux don't look for shared libraries in the directory they're located in, at least by default.
You can either fix that at link-time, by passing -Wl,-rpath='$ORIGIN', or at runtime, by setting LD_LIBRARY_PATH env variable to the directory with the library. (LD_LIBRARY_PATH=path/to/lib ./programma)

SDL Max OSX via Homebrew, Makefile not quite working

I have installed SDL through homebrew, and it works perfectly with my test program if I enter the following command directly in the terminal:
g++ -O3 -g -Wall -Wextra -std=c++1y hello.cpp hello_main.cpp `sdl2-config --cflags --libs` -o hello
but unfortunately my attempts to write a makefile (I will definitely need one) have yielded unsuccessful/unexplained results.
I am following this, but my configuration is different/I am not specifying Cocoa (I don't need to) so I expect that the issues I am encountering are probably due in part to my different requirements:
Compiling SDL on OS X with makefile
Example:
CC=g++
CFLAGS=-c -Wall
SDLFLAGS=`sdl-config --cflags --libs` -framework Cocoa
SOURCES=main.cpp Game.cpp IO.cpp Board.cpp Pieces.cpp Piece.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=tetris
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) $(SDLFLAGS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
clean:
rm -rf *.o $(EXECUTABLE)
My makefile so far:
CXX = g++
CXXFLAGS = -c -O3 -g -Wall -Wextra -std=c++1y
SDLFLAGS = `sdl2-config --cflags --libs`
SOURCES = hello_main.cpp hello.cpp
OBJECTS = $(SOURCES:.cpp=.o)
EXECNAME = hello
all: $(SOURCES) $(EXECNAME)
$(EXECUTABLE): $(OBJECTS)
$(CXX) $ (OBJECTS) $(SDLFLAGS) -o $#
.cpp.o:
$(CXX) $(CXXFLAGS) $< -o $#
clean :
-rm -f *.o *.core $(EXECNAME)
In my .hpp header file if I #include <SDL.h> and run the one-liner command, everything is successful. If I try my makefile above, cannot be found, but if I then change the directive into #include <SDL2/SDL.h> the library is discovered. Yet the console output is the following:
g++ -c -O3 -g -Wall -Wextra -std=c++1y hello.cpp -o hello
which is odd.
Running ./hello yields a "permission denied" error, which confirms that the linking and compilation were not successful.
Everyone's system is a little bit different and the questions I've found so far don't help in this case.
I am very close to having this working (but then again, how would I start using this in an IDE? I suppose that as long as I can import the fixed makefile or build from the terminal/edit only from the IDE, I am fine.)
What changes in the makefile do I need to make?
Thank you.
EDIT:
Variation 1:
CXX = g++
CXXFLAGS = -O3 -g -Wall -Wextra -std=c++1y -c
SDLCFLAGS = `sdl2-config --cflags`
SDLLIBFLAGS = `sdl2-config --libs`
SOURCES = hello_main.cpp hello.cpp
OBJECTS = $(SOURCES:.cpp=.o)
EXECNAME = hello
all: $(SOURCES) $(EXECNAME)
$(EXECUTABLE): $(OBJECTS)
$(CXX) $ (OBJECTS) $(SDLLIBFLAGS) -o $#
.cpp.o:
$(CXX) $(CXXFLAGS) $(SDLCFLAGS) $< -o $#
clean :
-rm -f *.o *.core $(EXECNAME)
I chatted with a friend and figured what was wrong: a bunch of typos and rule oddities. The following works, for anyone out there who needs a basic makefile:
CXX = g++
CXXFLAGS = -O3 -g -Wall -Wextra -std=c++1y
#LDFLAGS = -lSDL2_image
SDLCFLAGS = $(shell sdl2-config --cflags)
SDLLIBFLAGS = $(shell sdl2-config --libs)
SOURCES = hello_main.cpp hello.cpp
OBJECTS = $(SOURCES:.cpp=.o)
EXECNAME = hello
all: $(EXECNAME)
$(EXECNAME): $(OBJECTS)
$(CXX) $(OBJECTS) $(SDLLIBFLAGS) $(LDFLAGS) -o $#
%.o: %.cpp
$(CXX) -c $(CXXFLAGS) $(SDLCFLAGS) $< -o $#
clean :
-rm -f *.o *.core $(EXECNAME)
You should split your sdl2-config into two - as there are two steps. sdl2-config --cflags should go in the compiler step - thats is the .cpp:.o line in your example. The linking step should be sdl2-config --libs then. The second one seems fine for your case, the additional --cflags there does no harm but is not required.

C++ File Requires Library Support

I'm trying to compile a simple program from the terminal that utilizes the condition_variable class. Upon building, I get the following error:
This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
In researching this error here, I added the necessary flag to my make file, but I'm still getting the same error.
Here is my makefile:
CXX= g++ $(CCFLAGS)
MAIN= main.o
DATACLASS= dataclass.o
OBJS = $(MAIN) $(DATACLASS)
LIBS= -pthread
CCFLAGS= -g -std=c++11
all: main
main: $(MAIN) $(DATACLASS)
$(CXX) -o main $(MAIN) $(DATACLASS) $(LIBS)
dataclass: $(DATACLASS)
$(CXX) -o dataclass $(DATACLASS) $(LIBS)
clean:
rm -f $(OBJS) $(OBJS:.o=.d)
realclean:
rm -f $(OBJS) $(OBJS:.o=.d) main
%.d: %.cc
$(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< \
| sed '\''s/\($*\)\.o[ :]*/\1.o $# : /g'\'' > $#; \
[ -s $# ] || rm -f $#'
include $(OBJS:.o=.d)
I'm sure I'm missing something small and stupid as I'm new to makefiles, but any help would be greatly appreciated.
Rewrite CXX to CXX = g++
Change CCFLAGS to CXXFLAGS = -g -std=c++11, and
Rewrite your rules to $(CXX) $(CXXFLAGS) ....
$(CXX) $(CXXFLAGS) will then be replaced with g++ -g -std=c++11. This is more of a standard method for defining a makefile. Here is a snippet of the resulting makefile.
CXX = g++
MAIN = main.o
DATACLASS = dataclass.o
OBJS = $(MAIN) $(DATACLASS)
LIBS = -pthread
CXXFLAGS = -g -std=c++11
all: main
main: $(OBJS)
$(CXX) $(CXXFLAGS) $? -o $# $(LIBS)
As a side note, are you sure this rule should be defined as such?
dataclass: $(DATACLASS)
$(CXX) $(CXXFLAGS) $? -o $# $(LIBS)
Should the target not be dataclass.o or $(DATACLASS) and the prerequisite some other file?
Note: I've also included some make automatic variables to tidy up the makefile rules.
$? - is replaced by all prerequisites
$# - is replaced by the target name

Multiple compile modes in makefile

I want to use a single make file to generate a project in multiple modes, and then each mode in a "normal" and "debug" mode, ie:
I have the following files (ofc more in reality, but this will serve to show my point):
kernel/core/main.cpp
kernel/processor/Processor.cpp
kernel/processor/x86/Processor.cpp
kernel/processor/x86_common/Processor.cpp
kernel/processor/x64/Processor.cpp
And i want to be able to use my makefile in the following ways:
make x86
(compiles all files except "kernel/processor/x64/Processor.cpp")
(enables the pre-processor directives X86 & X86_COMMON)
And,
make x86debug
(compiles all files except "kernel/processor/x64/Processor.cpp")
(enables the pre-processor directives X86 & X86_COMMON & DEBUG)
(puts "-g -ggdb" infront of all gcc/g++/as arguments)
And so on.
Currently i have the following makefile, which while it works, only lets me compile in x86-debug mode and now that i am porting my software to other platforms I wish to be able to specify what mode to build in.
CC = i586-elf-g++
CFLAGS = -g -ggdb -ffreestanding -Wall -Wextra -fno-exceptions -fno-rtti -std=gnu++11 -Isrc/system/include -DX86 -DX86_COMMON
LD = i586-elf-gcc
LDFLAGS = -g -ggdb -ffreestanding -O2 -nostdlib -lgcc
AS = i586-elf-as
ASFLAGS = -g -ggdb
OBJECTS = src/system/kernel/core/main.o
ALL_OBJECTS = $(OBJECTS) $(X86_OBJECTS)
X86COMMON_OBJECTS = src/system/kernel/core/processor/x86_common/Processor.o
X86_OBJECTS = $(X86COMMON_OBJECTS) src/system/kernel/core/processor/x86/boot.o
X86_LINKER = src/system/kernel/core/processor/x86/link.ld
X86_OUTPUT = bin/kernel_x86.bin
.PHONY: clean
clean: $(ALL_OBJECTS)
rm $(ALL_OBJECTS)
.PHONY: all
all: $(X86_OUTPUT)
$(X86_OUTPUT): $(X86_LINKER) $(OBJECTS) $(X86_OBJECTS)
$(LD) $(LDFLAGS) -T $(X86_LINKER) $^ -o $#
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $#
%.o: %.asm
$(AS) $(ASFLAGS) $< -o $#
As you can probably tell, im not an expert with make so any help/ideas would be appreciated.
Remove -g from CFLAGS and LDFLAGS, and add the following PHONY:
.PHONY: x86_debug
x86_debug: CFLAGS += -g
x86_debug: LDFLAGS += -g
x86_debug: $(X86_OUTPUT)
To compile in normal mode: make.
To compile in debug mode: make x86_debug
It may not do exactly what you're expecting, but it's easy to modify

Writing a makefile to use -D_GLIBCXX_DEBUG in debug build

I have a makefile that can be reduced to this:
OBJS = obj1.o obj2.o
FLAGS = -Wall -Wextra -Werror -pedantic-errors -fno-rtti -std=c++0x
DEBUG_FLAGS = -ggdb -O0 -fstack-protector-all -D_GLIBCXX_DEBUG
RELEASE_FLAGS = -O3
release: $(OBJS)
g++ $(FLAGS) $(RELEASE_FLAGS) $(OBJS)
debug: $(OBJS)
g++ $(FLAGS) $(DEBUG_FLAGS) $(OBJS)
obj1.o: obj1.cpp
g++ -c $(FLAGS) obj1.cpp
obj2.o: obj2.cpp
g++ -c $(FLAGS) obj2.cpp
The problem is that all or none of the files must be built with the -D_GLIBCXX_DEBUG flag. I don't know how to do this without writing two entries for every compilation unit, like
obj1_release.o: obj1.cpp
g++ -c $(FLAGS) $(RELEASE_FLAGS) obj1.cpp
obj1_debug.o: obj1.cpp
g++ -c $(FLAGS) $(DEBUG_FLAGS) obj1.cpp
How can I make the -D_GLIBCXX_DEBUG flag (and the other debug flags) take effect for all compilation units only when the user types make debug without writing two entries for every CU? (And vice versa; the release flags need to take effect on all CUs when the user types make release.)
I apologise if this is the basics of writing Makefiles, I don't know much about them.
You are looking for pattern rules: something like this should do what you want. Note that this cannot be made to work correctly unless the debug and release versions of the program are given different names.
OBJS := obj1 obj2 obj3
R_OBJS := $(OBJS:=_r.o)
D_OBJS := $(OBJS:=_d.o)
all: prog_r prog_d
release: prog_r
debug: prog_d
prog_r: $(R_OBJS)
$(CXX) $(CXXFLAGS) $(RELEASE_FLAGS) $(LDFLAGS) $^ $(LIBS) -o $#
prog_d: $(D_OBJS)
$(CXX) $(CXXFLAGS) $(DEBUG_FLAGS) $(LDFLAGS) $^ $(LIBS) -o $#
%_r.o: %.cc
$(CXX) $(CXXFLAGS) $(RELEASE_FLAGS) -c $< -o $#
%_d.o: %.cc
$(CXX) $(CXXFLAGS) $(DEBUG_FLAGS) -c $< -o $#
# header files
obj1_d.o obj1_r.o: foo.h bar.h
obj2_d.o obj2_r.o: quux.h
# ... etc ...
There is a pretty straightforward way to select compilation flags based on the type of the build in Makefiles.
In addition to that you may like to ensure that debug build only links debug object files and same for release (i.e. no mixing debug and release object files). To achieve that compile object into different directories depending on the build type.
This might help : http://sunsite.ualberta.ca/Documentation/Gnu/make-3.79/html_chapter/make_7.html
You could check the first argument (debug/release) and set the CFLAGS accordingly.
HTH.