I'm trying to compile a simple program, with
#include <gtkmm.h>
The path to gtkmm.h is /usr/include/gtkmm-2.4/gtkmm.h. g++ doesn't see this file unless I specifically tell it -I /usr/include/gtkmm-2.4.
My question is, how can I have g++ automatically look recursively through all the directories in /usr/include for all the header files contained therein, and why is this not the default action?
In this case, the correct thing to do is to use pkg-config in your Makefile or buildscripts:
# Makefile
ifeq ($(shell pkg-config --modversion gtkmm-2.4),)
$(error Package gtkmm-2.4 needed to compile)
endif
CXXFLAGS += `pkg-config --cflags gtkmm-2.4`
LDLIBS += `pkg-config --libs gtkmm-2.4`
BINS = program
program_OBJS = a.o b.o c.o
all: $(BINS)
program: $(program_OBJS)
$(CXX) $(LDFLAGS) $^ $(LOADLIBES) $(LDLIBS) -o $#
# this part is actually optional, since it's covered by gmake's implicit rules
%.o: %.cc
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $#
If you're missing gtkmm-2.4, this will produce
$ make
Package gtkmm-2.4 was not found in the pkg-config search path.
Perhaps you should add the directory containing `gtkmm-2.4.pc'
to the PKG_CONFIG_PATH environment variable
No package 'gtkmm-2.4' found
Makefile:3: *** Package gtkmm-2.4 needed to compile. Stop.
Otherwise, you'll get all the appropriate paths and libraries sucked in for you, without specifying them all by hand. (Check the output of pkg-config --cflags --libs gtkmm-2.4: that's far more than you want to type by hand, ever.)
I guess you are not using a makefile? The only thing that could be annoying is having to type the long -I option each time you compile your program. A makefile makes it a lot easier.
For example, you could modify the hello world makefile from wikipedia to something like the following:
INC=-I/usr/include/gtkmm-2.4/
helloworld: helloworld.o
g++ -o $# $<
helloworld.o: helloworld.c
g++ $(INC) -c -o $# $<
.PHONY: clean
clean:
rm -f helloworld helloworld.o
You can't. The whole point of include paths is so you can pick and choose what you want and what versions.
What you could do is..
#include <gtkmm-2.4/gtkmm.h>
Which would achieve the same effect.
Related
I have been trying to set up my coding environment for GUI development in c++ recently, with little success. I use Manjaro Linux with Visual Studio Code, but for some reason, I always seem to get include errors when including files that I know are there.
Most recently, I tried to set up gtkmm-4.0 by installing the package and the documentation. I double checked in /usr/include/ to ensure the packages were all present, but I still am getting include errors:
cannot open source file "gtkmm.h" and
gtkmm.h:No such file or directory
At this point, all the code I have is:
#include <gtkmm.h>
#include <iostream>
int main(int argc, char* argv[]){
return 0;
}
Makefile:
exec = game.out
sources = $(wildcard src/*.cpp)
objects = $(sources:.cpp=.o)
flags = -g $(shell pkg-config gtkmm-4.0 --cflags)
libs = $(shell pkg-config gtkmm-4.0 --libs)
$(exec): $(objects)
g++ $(objects) $(flags) -o $(exec) $(libs)
%.o: %.cpp include/%.h
g++ -c $(flags) $< -o $#
install:
make
cp ./game.out /usr/local/bin/game
clean:
-rm *.out
-rm *.o
-rm src/*.o
I have scoured the internet for answers, but everything I found was either for a different os/environment or just didn't
#Galik and #John helped me solve this!
What I had to do was use g++ src/main.cpp -o main $(pkg-config gtkmm-4.0 --cflags --libs) to compile my code, then run the executable.
Thank you both for your help and guidance!!
You need to install pkg-configand add this to the compiler flags in your Makefile:
flags = -g $(shell pkg-config gtkmm-2.4 --cflags)
libs = $(shell pkg-config gtkmm-2.4 --libs)
# ...
$(exec): $(objects)
g++ $(objects) $(flags) -o $(exec) $(libs)
The tool pkg-config has a database of the correct paths for supporting libraries.
Depending on your version if gtkmm, you may need to substitute gtkmm-3.0, if you have version 3.0.
How can I set properly the makefile to import some OpenCV lib into the libmat.o?
this is the make file:
# Define a variable for classpath
CLASS_PATH = ../bin
# Debug: -g3=compile with extra debugg infos. -ggdbg3=include things like macro defenitions. -O0=turn off optimizations.
DEBUGFLAGS = -g3 -ggdb3 -O0
CFLAGS = $(DEBUGFLAGS)
# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)
all : libMat.so
# $# matches the target, $< matches the first dependancy
libMat.so : libMat.o
g++ $(CFLAGS) -W -shared -o $# $<
# $# matches the target, $< matches the first dependancy
libMat.o : Mat2Image.cpp Mat2Image.h
g++ $(CFLAGS) -fPIC -I/usr/lib/jvm/jdk1.8.0_111/include -I/usr/lib/jvm/jdk1.8.0_111/include/linux -c $< -o $# -L/usr/local/lib
# $* matches the target filename without the extension
# manually this would be: javah -classpath ../bin HelloJNI
HelloJNI.h : Mat2Image.class
javah -classpath $(CLASS_PATH) $*
clean :
rm -f Mat2Image.h libMat.o libMat.so
i need some OpenCV lib located in /usr/local/lib
for example libopencv_imgproc.so
I think what you want to do is get (e.g.) libopencv_imgproc.so,
located in /usr/local/lib, to be linked with your shared library libMat.so.
The way you are trying to do this in your makefile is by "linking"
libopencv_imgproc.so with the object file libMat.o by the recipe:
libMat.o : Mat2Image.cpp Mat2Image.h
g++ $(CFLAGS) -fPIC -I/usr/lib/jvm/jdk1.8.0_111/include \
-I/usr/lib/jvm/jdk1.8.0_111/include/linux -c $< -o $# \
-L/usr/local/lib
You think that -L/usr/local/lib at the end will in some way let the linker
know you want to link libopencv_imgproc.so and do so.
That won't work for more than one reason:
-L/usr/local/lib will just tell the linker that /usr/local/lib is
a directory where you want it search for libraries that you ask it to
link. It doesn't ask it to link any libraries from there, and if you
don't tell it to, it won't. To tell the linker
to search for libraries in /usr/local/lib and ask it to link
libopencv_imgproc.so you would use:
`-L/usr/local/lib -lopencv_imgproc
But you don't need to tell it to search for libraries in /usr/local/lib,
because that is one of the directories the linker searches for libraries
by default. So -lopencv_imgproc is all you would need.
But more important than that,
g++ $(CFLAGS) -fPIC -I/usr/lib/jvm/jdk1.8.0_111/include \
-I/usr/lib/jvm/jdk1.8.0_111/include/linux -c $< -o $# \
-L/usr/local/lib
is the command that simply compiles libMat.o from Mat2Image.cpp. It
doesn't do any linkage. It is not possible and does not make sense to "link"
anything with an object file. So adding any linkage options to your
compile command is pointless. The compiler will ignore them. This command is
effectively no different from:
g++ $(CFLAGS) -fPIC -I/usr/lib/jvm/jdk1.8.0_111/include \
-I/usr/lib/jvm/jdk1.8.0_111/include/linux -c $< -o $#
and that's what it should be.
The recipe that does your linkage is:
libMat.so : libMat.o
g++ $(CFLAGS) -W -shared -o $# $<
So this is where you have to tell the linker that you want libopencv_imgproc.so
to be linked:
libMat.so : libMat.o
g++ $(CFLAGS) -W -shared -o $# $< -lopencv_imgproc
With this, libMat.so will be linked containing libMat.o and a runtime
dependency on the shared library libopencv_imgproc.so - that is, an
instruction to the runtime loader that it must load libopencv_imgproc.so
into the same process when it loads libMat.so.
Your makefile has various other faults but what I've said is enough to
explain and fix the particular problem I think you're asking about. You
can learn how to write a better makefile, if you want, by searching for tutorials
and ariticles about GNU Make and studying the documentation
I'll just point out one other fault that is serious. Your recipe:
clean:
rm -f Mat2Image.h libMat.o libMat.so
is going to delete the header file Mat2Image.h when you run
make clean. That header file is one of your original source files. It
isn't generated by this makefile - like libMat.o and libMat.so - unless
you've ommitted some bits of the real makefile. So
if you delete it you'll have to recover it from you source-control system; and
if its not under a source-control system, you'll have to rewrite it. So
I think you just want:
clean:
rm -f libMat.o libMat.so
I am having issue with Makefile that I produced. It consists of one .cpp file with main() inside and I want to create executable from it. While putting in terminal make command I get following:
g++ STutorial.o -o MyExecutable
g++: error: STutorial.o: No such file or directory
g++: fatal error: no input files
While putting first make STutorial.o (.o created) and then make get this:
g++ STutorial.o -o MyExecutable
STutorial.o: In function `main':
STutorial.cpp:(.text+0x47a): undefined reference to `alcOpenDevice'
Firstly, why make does not go from the beginning?
Secondly, why this reference is undefined as if I did not include library, I did that in Makefile aswell as in STutorial.cpp file.
Can you please help me out? I was reading up what could I do wrong and see no clue. (I am beginner and maybe mistake is a rookie one, I apologise in advance but cannot understand it alone)
Makefile:
FLAGS += -std=c++11
CCX=g++
FLAGS +=-c -Wall #for compilation, for warning
FLAGS += -lopenal -lSDL
all: MyExecutable
MyExecutable:
$(CXX) STutorial.o -o MyExecutable
STutorial.o: STutorial.cpp
$(CXX) $(FLAGS) STutorial.cpp
Your makefile should be like this:
CCX=g++
FLAGS +=-c -Wall #for compilation, for warning
LINK_FLAGS += -lopenal -lSDL
all: MyExecutable
MyExecutable: Stutorial.o
$(CXX) STutorial.o -o MyExecutable $(LINK_FLAGS)
STutorial.o: STutorial.cpp
$(CXX) $(FLAGS) STutorial.cpp
Explanation:
Your MyExecutable depends on Stutorial.o which inturn depends on Stutorial.cpp
Now -c flag should be used only with .cpp file to create an object file and not with already created .o file.
Therefore you should have two flags: FLAGS for compiling and LINK_FLAGS for linking libraries during making executable file.
Your executable rule is the issue:
MyExecutable:
$(CXX) STutorial.o -o MyExecutable
It has a target (MyExecutable) and it has a recipe ($(CXX) ...), that all looks good. But what are its prerequisites? MyExecutable does have prerequisites - it needs STutorial.o in order to generate the binary! You need to explicitly tell make about this:
MyExecutable: STutorial.o
$(CXX) STutorial.o -o MyExecutable
Otherwise, you are telling make that you want to build all. all depends on MyExecutable. MyExecutable doesn't depend on anything, so the rule for STutorial.o never gets run.
As for the linker error, you're not linking in the library you need, so you should define something like:
LFLAGS += -lopenal -lSDL
MyExecutable: STutorial.o
$(CXX) STutorial.o $(LFLAGS) -o MyExecutable
You have a few problem in your Makefile starting with:
FLAGS +=-c -Wall #for compilation, for warning
FLAGS += -lopenal -lSDL
You are redefining the FLAGS variable here.
So what you should have is a different variable for your compiler and linker flags:
CFLAGS +=-c -Wall #for compilation, for warning
LDFLAGS += -lopenal -lSDL
Now, for the sake of giving a complete answer, and not solving your immediate problem only I'll try to show how to make the Makefile more flexible:
Start with the sources - you should have a variable for them as well; it's useful when adding/removing source files to/from the project:
SOURCES = STutorial.cpp
define a variable for your object files (this will come in handy at link-time):
OBJ = $(SOURCES:.cpp=.o)
Compile all source files into object files:
.cpp.o:
$(C++) $(CFLAGS) -o $# $<
Link your binary file using the compiled object files:
$(MyExecutable): $(OBJ)
$(C++) $(LDFLAGS) $(OBJ) -o $#
Add a clean command for completeness (removes the binary and object files):
clean:
$(RM) $(EXECUTABLE) $(OBJ)
Now, putting it all together:
CCX=g++
CFLAGS +=-c -Wall -std=c++11#for compilation, for warning
LDFLAGS += -lopenal -lSDL
SOURCES = STutorial.cpp
OBJ = $(SOURCES:.cpp=.o)
all: $(MyExecutable)
$(MyExecutable): $(OBJ)
$(CCX) $(LDFLAGS) $(OBJ) -o $#
.cpp.o:
$(CCx) $(CFLAGS) -o $# $<
clean:
$(RM) $(EXECUTABLE) $(OBJ)
This should allow you to flexibly build, rebuild, clean you project.
This is how you should do:
g++ -std=c++11 -Wall -lopenal -lSDL STutorial.cpp -o MyExecutable
I've got a Makefile that works good so far. Although, as it started growing, recompiling all the sources every time began to take too long. Here's a snippet from the working version:
CC=$(CROSS_COMPILE)g++
CFLAGS=-Wall -I./include -pg -O2
VPATH=./src:./include
all: dotgazer.cpp dotgazer/Dot.cpp
$(CC) $(CFLAGS) $^ -o dotgazer.out `pkg-config --libs opencv`
There are a lot more dependencies, but these two are enough to show what the problem is. I'm trying to move the compilation stage of each cpp file to a separate target. When it comes to the top-level file (dotgazer.cpp) it's not a problem and a general rule %.o: %.cpp works fine. But I can't get the second dependency to work. Here's how it looks now:
CC=$(CROSS_COMPILE)g++
CFLAGS=-Wall -I./include -pg -O2
VPATH=./src:./include
all: dotgazer.o dotgazer/Dot.o
$(CC) $(CFLAGS) $^ -o dotgazer.out `pkg-config --libs opencv`
%.o: %.cpp
$(CC) -c $(CFLAGS) $^ -o $#
dotgazer/Dot.o: dotgazer/Dot.cpp
$(CC) -c $(CFLAGS) $^ -o $#
I've tried different variations of the Dot.o rule but none of them seems to work. The error I get with the one above is:
Fatal error: can't create dotgazer/Dot.o: No such file or directory
How should I do that? I'd most prefer to have the .o files in the same folders as their sources. Also, I'd be thankful for general rules (like %.o: %.cpp) as there are lots of source files and I don't want the Makefile to get too bloated. Thank you!
I think your Makefile is a bit to specific and thus error-prone. I suggest to look at my following example that is way more generic than yours.
My example takes advantage of make's catalouge of implicit rules. For cpp-files exists a generic implicit rule already. So why should one not use it!?
The reference manual describes it as follows:
Compiling C++ programs
n.o is made automatically from n.cc, n.cpp, or n.C with a recipe of the form $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c.
So if you have %.o files as prerequisites like in the rule dotgazer.out: $(OBJS) make applies above implicit rule to all those files automatically. Assumed you have set valid values for CXX, CPPFLAGS and/or CXXFLAGS.
Furthermore you usually don't need to add your sources by hand to a variable. Most of the time all the sources in your project's directory tree are needed to build the executable. If it's not the case you should consider to build a appropriate tree that reflects this.
Since find is responsible to assign the sources to CPPFILES we don't need to set VPATH either. Due to our usage of find and patsubst we have only one explicit file name in our Makefile. That make working on a real project with plenty of different sources much more smooth.
Of course you don't need the all and the clean rule. I just added these for convenience.
CXX=$(CROSS_COMPILE)g++
CPPFLAGS=-I./include
CXXFLAGS=-Wall -pg -O2
LDLIBS=`pkg-config --libs opencv`
CPPFILES=$(shell find . -name "*.cpp")
OBJS=$(patsubst %.cpp, %.o, $(CPPFILES))
all: dotgazer.out
#echo $(CPPFILES)
#echo $(OBJS)
dotgazer.out: $(OBJS)
$(CXX) $(CXXFLAGS) -o $# $^ $(LDLIBS)
clean:
rm -f $(OBJS)
How can I link jsoncpp with a C++ program using g++? I tried:
g++ -o program program.cpp -L/path/to/library/files -ljsoncpp, -ljson, -llibjsoncpp
but g++ keeps saying:
/usr/bin/ld: cannot find -lsomething
You could also try using the new Amalgamated version of jsoncpp, which is new as of version 0.6.0.
The Amalgamated version allows you to use jsoncpp by adding just one directory with a couple of header files and one .cpp file to your project. You then can directly compile jsoncpp into your program with no worries about having to link to any jsoncpp libraries.
Look in /path/to/library/files to see what your *.a file is really named. On my system, I link with:
-ljson_linux-gcc-4.4.3_libmt
Some libraries will create a link from lib<name>.a to lib<name>-<version>.a for you, but I don't think that jsoncpp does this automatically. Therefore, you need to specify the complete name when linking.
You basically need to tell the path and the library.
jsoncpp library has pkg-config and you can use the command
`pkg-config --cflags path/to/jsoncpp/build/pkg-config/jsoncpp.pc`
for the include path and
`pkg-config --libs ../jsoncpp/build/pkg-config/jsoncpp.pc`
for linking (when running the command with g++ use the ). To see the single commands which is -L/libraryPath -ljsoncpp) run the commands above in the terminal without the ``.
It is easier to use this commands in a Makefile. As example my Makefile is:
CXX = g++
CXXFLAGS = -std=c++11
INC_PATH = `pkg-config --cflags ../jsoncpp/build/pkg-config/jsoncpp.pc`
LIBS = `pkg-config --libs ../jsoncpp/build/pkg-config/jsoncpp.pc`
SOURCES := $(wildcard *.cpp)
OBJDIR=obj
OBJECTS := $(patsubst %.cpp,$(OBJDIR)/%.o,$(SOURCES))
DEPENDS := $(patsubst %.cpp,$(OBJDIR)/%.d,$(SOURCES))
# ADD MORE WARNINGS!
WARNING := -Wall -Wextra
# .PHONY means these rules get executed even if
# files of those names exist.
.PHONY: all clean
# The first rule is the default, ie. "make",
# "make all" and "make parking" mean the same
all: yourProjectExecutableName
clean:
$(RM) $(OBJECTS) $(DEPENDS) parking
# Linking the executable from the object files
yourProjectExecutableName: $(OBJECTS)
$(CXX) $(WARNING) $(CXXFLAGS) $(INC_PATH) $^ -o $# $(LIBS)
-include $(DEPENDS)
$(OBJDIR):
mkdir -p $(OBJDIR)
$(OBJDIR)/%.o: %.cpp Makefile $(OBJDIR)
$(CXX) $(WARNING) $(CXXFLAGS) $(INC_PATH) -MMD -MP -c $< -o $#
and then in the directory of the file I run make. The final command(s) will be printed out in the Terminal