I have created simple C++ Makefile Eclipse project in Ubuntu. Eclipse has created default Makefile:
PROJECT_ROOT = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
OBJS = cpp_makefile.o
ifeq ($(BUILD_MODE),debug)
CFLAGS += -g
else ifeq ($(BUILD_MODE),run)
CFLAGS += -O2
else ifeq ($(BUILD_MODE),linuxtools)
CFLAGS += -g -pg -fprofile-arcs -ftest-coverage
LDFLAGS += -pg -fprofile-arcs -ftest-coverage
else
$(error Build mode $(BUILD_MODE) not supported by this Makefile)
endif
all: cpp_makefile
cpp_makefile: $(OBJS)
$(CXX) $(LDFLAGS) -o $# $^
%.o: $(PROJECT_ROOT)%.cpp
$(CXX) -c $(CFLAGS) $(CXXFLAGS) $(CPPFLAGS) -o $# $<
%.o: $(PROJECT_ROOT)%.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $# $<
clean:
rm -fr cpp_makefile $(OBJS)
Everything goes fine in case I have only one source file. In case I create class TestMe with it's header and cpp file and add include header to main cpp file build fails. Looks like system can't find TestMe.cpp.
Error:
Building in: /home/a/cpp-workspace2/cpp_makefile/build/default
make -f ../../Makefile
g++ -c -O2 -o cpp_makefile.o /home/a/cpp-workspace2/cpp_makefile/cpp_makefile.cpp
g++ -o cpp_makefile cpp_makefile.o
/usr/bin/ld: cpp_makefile.o: in function `main':
cpp_makefile.cpp:(.text.startup+0x1c): undefined reference to `TestMe::TestMe()'
collect2: error: ld returned 1 exit status
make: *** [../../Makefile:19: cpp_makefile] Error 1
Build complete (3 errors, 0 warnings): /home/a/cpp-workspace2/cpp_makefile/build/default
In case I use same source in Eclipse C++ Managed build project everything goes fine. How to solve this problem in right way In Eclipse Makefile project?
cpp_makefile.cpp
#include "TestMe.h"
int main(int argc, char **argv)
{
TestMe testMe = TestMe();
return 0;
}
TestMe.h:
class TestMe {
public:
TestMe();
virtual ~TestMe(){};
};
TestMe.cpp:
#include "TestMe.h"
TestMe::TestMe() {
}
Eclipse will create a default Makefile for you, but it does not manage the Makefile(s) in a makefile-based project. It cannot really do so while also allowing you to make your own makefile changes or supporting makefiles it did not generate itself. If you want the build configuration to be completely managed by Eclipse then you should choose a different project type.
With a makefile-based project, then, you need to make appropriate changes to the Makefile yourself when you add sources to the project. In this particular case, it looks like you should change
OBJS = cpp_makefile.o
to
OBJS = cpp_makefile.o TestMe.o
Related
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)
I have been trying to link the SFML dlls to my windows C++ project, but I can't get it to work. I always end up with:
fatal error: SFML/System.hpp: No such file or directory
I've tried a bunch of things but nothing changes the issue.
Here is my makefile:
PROGRAM = zero_flip
OBJS = src/main.o src/Math.o src/card.o src/game_board.o src/indicator.o src/ui.o
CXX = g++
CXX_FLAGS = -O0 -g -Wall -Wextra -Wno-unused-parameter -Wno-unused-variable
LIB_DIRS = -L./Resources/libs/
LIBS = -lsfml-system -lsfml-graphics -lsfml-window -lsfml-audio
LNK_FLAGS = $(LIB_DIRS) $(LIBS)
DEPS=$(OBJS:.o=.d)
.PHONY: all clean
all: $(PROGRAM)
-include $(DEPS)
%.o: %.cpp
$(CXX) $(CXX_FLAGS) $(LNK_FLAGS) $< -o $#
$(PROGRAM): $(OBJS)
$(CXX) $(CXX_FLAGS) $(LNK_FLAGS) $^ -o $#
clean:
rm -f $(OBJS) $(DEPS) $(PROGRAM) && clear
The "./Resources/libs/" directory contains:
openal32.dll
sfml-audio-2.dll
sfml-audio-d-2.dll
sfml-graphics-2.dll
sfml-graphics-d-2.dll
sfml-system-2.dll
sfml-system-d-2.dll
sfml-window-2.dll
sfml-window-d-2.dll
Can anyone get me unstuck please this is driving me mad.
This is wrong:
%.o: %.cpp
$(CXX) $(CXX_FLAGS) $(LNK_FLAGS) $< -o $#
This rule says it will compile a source file into an object file, but the recipe actually builds a complete executable: it will compile the source file like xxx.cpp then link it into a program named xxx.o. You need to invoke just the compiler here, not the linker, so you should not have $(LNK_FLAGS) and you need to add the -c option to tell the compiler to stop after compiling and not link.
Then you need to add an -I option to the compile line telling the compiler where to find the header files needed during compilation... in this case SFML/System.hpp.
I have created Eclipse Makefile c++ project with intention to build project also without Eclipse. But I got error while run make in terminal:
Makefile:15: *** Build mode not supported by this Makefile. Stop.
How to fix that? Why I should need Eclipse Makefile if I can't build it with make?
Makefile content:
PROJECT_ROOT = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
OBJS = boiler.o
ifeq ($(BUILD_MODE),debug)
CFLAGS += -g
else ifeq ($(BUILD_MODE),profile)
CFLAGS += -O2
else ifeq ($(BUILD_MODE),run)
CFLAGS += -O2
else ifeq ($(BUILD_MODE),linuxtools)
CFLAGS += -g -pg -fprofile-arcs -ftest-coverage
LDFLAGS += -pg -fprofile-arcs -ftest-coverage
else
$(error Build mode $(BUILD_MODE) not supported by this Makefile)
endif
all: boiler
boiler: $(OBJS)
$(CXX) $(LDFLAGS) -o $# $^
%.o: $(PROJECT_ROOT)%.cpp
$(CXX) -c $(CFLAGS) $(CXXFLAGS) $(CPPFLAGS) -o $# $<
%.o: $(PROJECT_ROOT)%.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $# $<
clean:
rm -fr boiler $(OBJS)
I'm not sure exactly how you created your Makefile ...
... but the problem is clearly that your Makefile happens to rely on the variable "$(BUILD_MODE)" ...
... and, the way you're running "make", BUILD_MODE isn't being set to one of your options, or isn't being set at all.
SUGGESTION: Type this on the command line: make BUILD_MODE=debug
PS:
Equivalently, you could define BUILD_MODE as an environment variable, e.g. set BUILD_MODE=debug (DOS prompt) or export BUILD_MODE-debug (Linux term)
"BUILD_MODE" isn't "required". It's just a convention. That your "Makefile generator" happened to add when it created your particular makefile.
I am familiar with Gtkmm and C++, but new to Makefiles and am having issues getting mine to actually produce an executable. I know a full Makefile is overkill for the current simplicity of my project, but I am trying to put together a basic template for use in larger projects. I am on Ubuntu 17.10 and running the make command from my "build" folder. Any help would be greatly appreciated!
Terminal Output
pearscol#UBUNTU-1710:~/projects/testprogram/build$ make
g++ -o testprogram `pkg-config --libs gtkmm-3.0`
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In
function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:19: recipe for target 'testprogram' failed
make: *** [testprogram] Error 1
Source File Structure
- /build
- /build/Makefile
- /src
- /src/main.cpp
/build/Makefile
CXX = g++
CXXFLAGS = `pkg-config gtkmm-3.0 --cflags` -std=c++14 -g -Wall
INCLUDES = -I../include
SRCS = $(wildcard *.cpp)
OBJS = $(SRCS:.cpp=.o)
PROGRAM = testprogram
DEPDIR = ../src/
LIBS = `pkg-config --libs gtkmm-3.0`
all: $(PROGRAM)
-include $(OBJS:%.o=$(DEPDIR)/%.Po)
%.o: %.cpp
$(CXX) -MT $# -MD -MP -MF $*.Tpo -c -o $# $(CXXFLAGS) $<
$(PROGRAM): $(OBJS)
$(CXX) -o $(PROGRAM) $(OBJS) $(LIBS)
# DO NOT DELETE THIS LINE -- make depend needs it
/src/main.cpp
#include <gtkmm.h>
int main(int argc, char *argv[]) {
Glib::RefPtr<Gtk::Application> app =
Gtk::Application::create(argc, argv, "testprogram");
Gtk::Window window;
window.set_default_size(400, 200);
window.set_title("Tutorial");
return app->run(window);
}
If you want to specify the source files using a $(wildcard ...) function,
then replace:
SRCS = $(wildcard *.cpp)
with:
SRCS = $(wildcard src/*.cpp)
because src is where the *.cpp files are, with respect to the build directory.
To place the object files in the build directory, then replace:
OBJS = $(SRCS:.cpp=.o)
with:
$(notdir $(SRCS:.cpp=.o))
Finally do one of the following:
Either replace the pattern rule:
%.o: %.cpp
with:
%.o: src/%.cpp
Or, leave the pattern rule as it is and add:
VPATH := src
to the variable settings at the top of your makefile. See
VPATH.
Asides
You default target all is a phony target: you are never going to make
a file called all, and you assume no such file will ever exist. Better specify it as a .PHONY target.
For defining variables, use simple expansion - VAR := val - rather than
recursive expansion - VAR = val - unless recursive expansion is needed, which it isn't in your makefile.
Your makefile lacks a clean target for
deleting all make-prodicts and restoring the build directory to its pristine
state. It is standard to provide this phony target.
As far as I can tell,
$(CXX) -o $(PROGRAM) $(OBJS) $(LIBS)
results in
g++ -o testprogram `pkg-config --libs gtkmm-3.0`
because $(OBJS) is empty, because $(SRCS) is empty, because *.cpp matches no files, because your build directory contains no .cpp files.
As the title states I'm trying to create a makefile for compiling C++ programs using SDL2 on Windows. I have MinGW installed and working. I'm using Sublime 2 as my environment. Here's what I have so far:
CXX = g++
CXXFLAGS = -std=c++0x -g -O3 -w -Wl,-subsystem,windows
INCLFLAGS = -IC:\Libraries\i686-w64-mingw32\include\SDL2
LDFLAGS = -LC:\Libraries\i686-w64-mingw32\lib -lmingw32 -lSDL2main -lSDL2
OBJECTS = main.o
TARGET = 1_hellosdl
$(TARGET) : $(OBJECTS)
$(CXX) $(INCLFLAGS) $(LDFLAGS) $(CXXFLAGS) -o $(TARGET) $(OBJECTS)
main.o :
clean:
rm -rf $(OBJECTS) $(TARGET)
remake:
clean $(TARGET)
Right now when I compile I get the following error:
g++ -std=c++0x -g -O3 -w -Wl,-subsystems,windows -c -o main.o main.cpp
In file included from main.cpp:1:0:
main.hpp:4:17: fatal error: SDL.h: No such file or directory
#include <SDL.h>
So the issue is that g++ can't find the SDL include file when it tries to compile main.cpp. I get that this is because $(INCLFLAGS) isn't being added to the line under main.o :.
Optimally, I'd like to specify INCLFLAGS implicitly similar to CXXFLAGS and LDFLAGS, but based on this it doesn't look like it's possible.
Is there a way to do this using an implicit variable or, failing that, what's the best alternative? Is there anything else I am doing wrong?
I managed to solve this by moving $(INCLFLAGS) into $(CXXFLAGS):
INCLFLAGS = -IC:\Libraries\i686-w64-mingw32\include\SDL2
CXXFLAGS = $(INCLFLAGS) -std=c++0x -g -O3 -w -Wl,-subsystem,windows
Additionally, I had to move $(LDFLAGS) to the end in order for it to link correctly:
$(TARGET) : $(OBJECTS)
$(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJECTS) $(LDFLAGS)