I want to finally get to know how to write an application which uses database. I chose C++, PostgreSQL and SOCI (SQL wrapper to C++). I use Xubuntu 11.4 and installed everyting which was necessary to run a simple program.
To use SOCI I installed:
1) libboost-dev
2) libpq-dev
3) libtool
4) SOCI, using this: http://soci.sourceforge.net/doc/backends/postgresql.html#required and I compiled SOCI with this command: cmake cmake -G "Unix Makefiles" -DWITH_BOOST=ON -DWITH_POSTGRESQL=ON ../
My simple program is veeery simple:
#include "soci-postgresql.h"
int main(int argc, char **argv){
soci::session sql(postgresql, "testDB");
return 0;
}
I compile it like this:
g++ test.cpp -lsoci_core -lsoci_postgresql -ldl -lpq
but it gives me error:
test.cpp:1:29: fatal error: soci-postgresql.h: No such file or
directory compilation terminated.
How to fix this, whats wrong? Did I miss to install something?
Some more infos:
/usr/local/include/soci$ ls
backend-loader.h postgresql soci-platform.h
blob-exchange.h prepare-temp-type.h soci-simple.h
blob.h procedure.h statement.h
boost-fusion.h ref-counted-prepare-info.h transaction.h
boost-gregorian-date.h ref-counted-statement.h type-conversion.h
boost-optional.h row-exchange.h type-conversion-traits.h
boost-tuple.h row.h type-holder.h
connection-pool.h rowid-exchange.h type-ptr.h
empty rowid.h unsigned-types.h
error.h rowset.h use.h
exchange-traits.h session.h use-type.h
into.h soci-backend.h values-exchange.h
into-type.h soci-config.h values.h
once-temp-type.h soci.h version.h
/usr/local/include/soci/postgresql$ ls
common.h soci-postgresql.h
/usr/local/lib$ ls
libCOS4.a libomniORB4.so.1
libCOS4.so libomniORB4.so.1.6
libCOS4.so.1 libomnithread.a
libCOS4.so.1.6 libomnithread.so
libCOSDynamic4.a libomnithread.so.3
libCOSDynamic4.so libomnithread.so.3.4
libCOSDynamic4.so.1 libsoci_core.a
libCOSDynamic4.so.1.6 libsoci_core.so
libomniCodeSets4.a libsoci_core.so.3.1
libomniCodeSets4.so libsoci_core.so.3.1.0
libomniCodeSets4.so.1 libsoci_empty.a
libomniCodeSets4.so.1.6 libsoci_empty.so
libomniConnectionMgmt4.a libsoci_empty.so.3.1
libomniConnectionMgmt4.so libsoci_empty.so.3.1.0
libomniConnectionMgmt4.so.1 libsoci_postgresql.a
libomniConnectionMgmt4.so.1.6 libsoci_postgresql.so
libomniDynamic4.a libsoci_postgresql.so.3.1
libomniDynamic4.so libsoci_postgresql.so.3.1.0
libomniDynamic4.so.1 pkgconfig
libomniDynamic4.so.1.6 python2.7
libomniORB4.a python3.2
libomniORB4.so
I also tried this one: g++ test.cpp -lsoci_core -lsoci_postgresql -ldl -lpq -I /usr/local/include/soci/postgresql and got the error:
g++ test.cpp -lsoci_core -lsoci_postgresql -ldl -lpq -I
/usr/local/include/soci/postgresql In file included from test.cpp:1:0:
/usr/local/include/soci/postgresql/soci-postgresql.h:27:26: fatal
error: soci-backend.h: No such file or directory compilation
terminated.
g++ test.cpp -Iyour_soci_dir -lsoci_core -lsoci_postgresql -ldl -lpq
your_soci_dir is directory with installed soci include files.
You need to set the search path with -I option.
g++ test.cpp -lsoci_core -lsoci_postgresql -ldl -lpq -I<path to headers>
^^^^^^^^^^^^^^^^^ Put the path
You need to provide all paths. I guess in your case, it should be like this :
g++ test.cpp -lsoci_core -lsoci_postgresql -ldl -lpq -I/usr/local/include/soci/postgresql -I/usr/local/include/soci
There is also another option (which is more used in makefiles) : to use pkg-config. Here you can find such example :
PROGRAM = test
PROGRAM_FILES = test.c
CFLAGS += -g $(shell pkg-config --cflags xmlsec1-nss)
LDFLAGS += -g
LIBS += $(shell pkg-config --libs xmlsec1-nss)
all: $(PROGRAM)
%: %.c
$(cc) $(PROGRAM_FILES) $(CFLAGS) $(LDFLAGS) -o $(PROGRAM) $(LIBS)
clean:
#rm -rf $(PROGRAM)
In your case, it would be something like this (not tested) :
PROGRAM = test
PROGRAM_FILES = test.cpp
CC=g++
CXXFLAGS += -g $(shell pkg-config --cflags soci_core) $(shell pkg-config --cflags soci_postgresql)
LDFLAGS += -g
LIBS += $(shell pkg-config --libs soci_core) $(shell pkg-config --libs soci_postgresql)
all: $(PROGRAM)
%: %.cpp
$(CC) $(PROGRAM_FILES) $(CFLAGS) $(LDFLAGS) -o $(PROGRAM) $(LIBS)
clean:
#rm -rf $(PROGRAM)
Ok guys, I found a solution on a polish programming website.
My new code (socitest.cpp):
#include <iostream>
#include <soci.h>
#include <postgresql/soci-postgresql.h>
int main(int argc, char **argv)
{
try
{
soci::session sql(soci::postgresql, "dbname=testDB");
}
catch (soci::postgresql_soci_error const & e)
{
std::cerr << "PostgreSQL error: " << e.sqlstate() << " " << e.what() << std::endl;
}
catch (std::exception const & e)
{
std::cerr << "Some other error: " << e.what() << std::endl;
}
return 0;
}
And I have to compile it :
g++ socitest.cpp -lsoci_core -lsoci_postgresql -ldl -lpq -I
/usr/local/include/soci -I /usr/include/postgresql -o socitest
It should compile but it might not run. If it's not running, I have to do sth more:
1) create soci.conf file:
touch /etc/ld.so.conf.d/soci.conf
2) edit my soci.conf with gedit:
gedit /etc/ld.so.conf.d/soci.conf
3) paste in soci.conf:
/usr/local/lib64
(for Xubuntu x64) or
/usr/local/lib
(for Xubuntu x32) and save file
4) run command:
ldconfig
5) run my compiled socitest like this: ./socitest and it's wooooorking !!! :D
Thanks all of you for helping me:)
Above example code can be compiled with just one command, without soci.conf and ldconfig:
g++ socitest.cpp -o socitest -I/usr/include/postgresql -I/usr/local/include/soci -L/usr/local/lib64/ \
-lsoci_core -lsoci_postgresql -Wl,-rpath=/usr/local/lib64/
For 32 bit unix use /usr/local/lib instead of /usr/local/lib64
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.
I'm trying to build a python wrapper using the following Makefile:
CC=/usr/local/opt/llvm/bin/clang
OS_NAME=$(shell uname -s)
ifeq ($(OS_NAME),Linux)
LAPACKLDFLAGS=/usr/lib64/atlas/libsatlas.so # single-threaded blas
#LAPACKLDFLAGS=/usr/lib64/atlas/libtatlas.so # multi-threaded blas
#BLAS_THREADING=-D MULTITHREADED_BLAS # remove this if wrong
endif
ifeq ($(OS_NAME),Darwin) # Mac OS X
LAPACKLDFLAGS=-framework Accelerate # for OS X
endif
LAPACKCFLAGS=-Dinteger=int $(BLAS_THREADING)
STATICLAPACKLDFLAGS=-fPIC -Wall -g -fopenmp -static -static-libstdc++ /home/lear/douze/tmp/jpeg-6b/libjpeg.a /usr/lib64/libpng.a /usr/lib64/libz.a /usr/lib64/libblas.a /usr/lib/gcc/x86_64-redhat-linux/4.9.2/libgfortran.a /usr/lib/gcc/x86_64-redhat-linux/4.9.2/libquadmath.a # statically linked version
CFLAGS= -fPIC -Wall -g -std=c++11 $(LAPACKCFLAGS) -fopenmp -DUSE_OPENMP -O3
LDFLAGS=-fPIC -Wall -g -ljpeg -lpng -fopenmp
CPYTHONFLAGS=-I/usr/include/python2.7
SOURCES := $(shell find . -name '*.cpp' ! -name 'deepmatching_matlab.cpp')
OBJ := $(SOURCES:%.cpp=%.o)
HEADERS := $(shell find . -name '*.h')
all: deepmatching
.cpp.o: %.cpp %.h
$(CC) -o $# $(CFLAGS) -c $+
deepmatching: $(HEADERS) $(OBJ)
$(CC) -o $# $^ $(LDFLAGS) $(LAPACKLDFLAGS)
deepmatching-static: $(HEADERS) $(OBJ)
$(CC) -o $# $^ $(STATICLAPACKLDFLAGS)
python: $(HEADERS) $(OBJ)
# swig -python $(CPYTHONFLAGS) deepmatching.i # not necessary, only do if you have swig compiler
/usr/local/opt/llvm/bin/clang $(CFLAGS) -c deepmatching_wrap.c $(CPYTHONFLAGS)
/usr/local/opt/llvm/bin/clang -shared $(LDFLAGS) $(LAPACKLDFLAGS) deepmatching_wrap.o $(OBJ) -o _deepmatching.so $(LIBFLAGS)
clean:
rm -f $(OBJ) deepmatching *~ *.pyc .gdb_history deepmatching_wrap.o _deepmatching.so deepmatching.mex???
Previously, CC was set to g++, however, when I tried to build it like this, I'd get "ERROR: clang: error: unsupported option '-fopenmp".
Now I installed "brew install llvm" as this comes with the -fopenmp option. The unsupported error is resolved for now, but now the compiler doesn't seem to find a header file:
(base) MacBook-Pro-van-Brent:deepmatching BrentDeHauwere$ make python
/usr/local/opt/llvm/bin/clang -o hog.o -fPIC -Wall -g -std=c++11 -Dinteger=int -fopenmp -DUSE_OPENMP -O3 -I/usr/local/opt/llvm/include -c hog.cpp
In file included from hog.cpp:18:
In file included from ./std.h:20:
/usr/local/opt/llvm/bin/../include/c++/v1/math.h:300:15: fatal error: 'math.h' file not found
#include_next <math.h>
^~~~~~~~
1 error generated.
make: *** [hog.o] Error 1
I've tried setting options (I might have set them incorrectly) like -L/usr/local/opt/llvm/lib and -I/usr/local/opt/llvm/include, but no result so far. Any idea how I could point the compiler to the right direction for the header files?
Try running xcode-select —install in your terminal. This installs the xcode command line tools which should also install system headers files (as part of the macos sdk) and set your system include paths.
I'm trying to setup SDL2 to use with g++, a text editor and terminal.
I have my SDL2.framework in /Library/Frameworks.
I have a folder on my desktop named testsdl which contains two files:
1) main.cpp
2) makefile
when I type make I get the following error:main.cpp:2:10: fatal error: 'SDL2/SDL.h' file not found.
here is a copy of my makefile
CXX = g++
SDL = -framework SDL2
CXXFLAGS = -Wall -c -std=c++11 -I ~/Library/Frameworks/SDL2.framework/Headers
LDFLAGS = $(SDL) -F /Library/Frameworks -F ~/Library/Frameworks/
EXE = SDL_Lesson0
all: $(EXE)
$(EXE): main.o
$(CXX) $(LDFLAGS) $< -o $#
main.o: main.cpp
$(CXX) $(CXXFLAGS) $< -o $#
clean:
rm *.o && rm $(EXE)
and here is a copy of main.cpp:
#include <iostream>
#include <SDL2/SDL.h>
int main(int, char**)
{
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Quit();
return 0;
}
I tried changing the #include to "SDL2/SDL.h" or just or any other possible combination. I had no problem setting it up through Xcode but can't figure out how to do it without using an IDE.
a second part of the question is:
if I wanted to include the frameworks in the project folder itself so I can later distribute the binaries to people who do not have SDL on their machines how would I do that?
thanks.
You were on the right track, but -F /Library/Frameworks needs to also be in the CXXFLAGS. The resulting commands should look something like:
g++ -Wall -F /Library/Frameworks -c -o main.o main.cpp
g++ main.o -o main -framework SDL2 -I /Library/Frameworks/SDL2.framework/Headers
Here's a simplified makefile that works for me on OSX 10.12.6:
CXX = g++
CXXFLAGS = -Wall -F /Library/Frameworks
LDFLAGS = -framework SDL2 -F /Library/Frameworks -I /Library/Frameworks/SDL2.framework/Headers
all: main
main: main.o
$(CXX) main.o -o main $(LDFLAGS)
obj/main.o : main.cpp
$(CXX) $(CXXFLAGS) -c main.cpp -o main.o
clean:
rm main.o main
if you go into
/Users/path/where/i/unzipped/SDL2-2.0.5
and run
sdl2-config --cflags --libs
it prints out the header include path and library path SDL
The full generic build probably looks something like:
g++ -std=c++11 main.cpp -o main.exe `sdl2-config --cflags` `sdl2-config --libs`
which you can translate into your make file if you like
I have a logger that I wrote in C, and have included it in a C++ project I am working on. It works fine, but I get a deprecated warning from Clang++: "Treating C input as C++ when in C++ mode, this behaviour is deprecated."
In hopes of doing away with this warning, I moved the compilation of the logger into its own step in the make file and compiled the object file with Clang. Then I added a reference to that object file to my Clang++ rule to link against. Now it fails to link properly: "Linker command failed with exit code 1"
My makefile is below. How would I properly go about compiling and linking this C logger so as to do away with that warning in Clang++?
CC= clang++
PROG= ./bin/tetris
OBJS= ./src/main.o ./src/Tetris.o ./src/states/BaseState.o ./src/states/MenuState.o \
./src/states/GameState.o ./src/entities/Block.o ./src/entities/Tetromino.o \
./src/entities/Grid.o
LIBS= allegro-5.0 allegro_dialog-5.0 allegro_font-5.0 allegro_ttf-5.0 allegro_color-5.0 \
allegro_primitives-5.0 allegro_main-5.0 allegro_image-5.0 allegro_audio-5.0 allegro_memfile-5.0
CXXFLAGS= -g -Wall -std=c++11 $(shell pkg-config --cflags ${LIBS})
LDFLAGS= $(shell pkg-config --static --libs ${LIBS})
all: logger $(PROG)
$(PROG): $(OBJS)
mkdir -p ./bin
$(CC) -v -o $(PROG) $(LDFLAGS) $(OBJS) ./src/util/SimpleLogger/simplog.o
rm -f $(OBJS)
logger:
clang -c -Wall ./src/util/SimpleLogger/simplog.c -o ./src/util/SimpleLogger/simplog.o
clean:
rm -f $(PROG) $(OBJS)
This may not be what you are looking for, but you could include it in your C++ file by:
#ifdef __cplusplus
extern "C" {
#endif
// C code
#ifdef __cplusplus
}
#endif
I've been trying to get the MySQL connector working I've installed both the connector and the mysql client library but I am still getting this error:
obj/Database.obj: In function `Database::connect()':
/home/xeross/alpine/src/server/Database.cpp:13: undefined reference to `get_driver_instance'
collect2: ld returned 1 exit status
make[2]: *** [alpine-server] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
Using Ubuntu 10.04
And my makefile is as follows:
INCLUDES = -I./src -I./src/shared
OUTDIR = bin
INTDIR = obj
OPTIONS = -ggdb -g3 -Wall -O0
alpine-server : Shared.a AsyncServerSocket.obj PlayerHandler.obj PacketHandler.obj Session.obj User.obj Database.obj init
g++ $(INCLUDES) $(OPTIONS) -static \
-pthread \
-lmysqlcppconn-static \
-o $(OUTDIR)/alpine-server src/server/main.cpp \
$(INTDIR)/AsyncServerSocket.obj \
$(INTDIR)/PacketHandler.obj \
$(INTDIR)/Database.obj \
$(INTDIR)/PlayerHandler.obj \
$(INTDIR)/Session.obj \
$(INTDIR)/User.obj \
$(INTDIR)/Shared.a \
-lboost_system \
-lmysqlclient
AsyncServerSocket.obj : src/server/AsyncServerSocket.cpp init
g++ -c $(INCLUDES) $(OPTIONS) -o $(INTDIR)/AsyncServerSocket.obj src/server/AsyncServerSocket.cpp
PlayerHandler.obj : src/server/PlayerHandler.cpp init
g++ -c $(INCLUDES) $(OPTIONS) -o $(INTDIR)/PlayerHandler.obj src/server/PlayerHandler.cpp
PacketHandler.obj : src/server/PacketHandler.cpp init
g++ -c $(INCLUDES) $(OPTIONS) -o $(INTDIR)/PacketHandler.obj src/server/PacketHandler.cpp
Session.obj : src/server/Session.cpp init
g++ -c $(INCLUDES) $(OPTIONS) -o $(INTDIR)/Session.obj src/server/Session.cpp
User.obj : src/server/User.cpp init
g++ -c $(INCLUDES) $(OPTIONS) -o $(INTDIR)/User.obj src/server/User.cpp
Database.obj : src/server/Database.cpp init
g++ -c $(INCLUDES) $(OPTIONS) -o $(INTDIR)/Database.obj src/server/Database.cpp
# Shared.a
Shared.a : Packet.obj Flags.obj AsyncSocket.obj Log.obj init
ar -cvq $(INTDIR)/Shared.a \
$(INTDIR)/Packet.obj \
$(INTDIR)/Flags.obj \
$(INTDIR)/AsyncSocket.obj \
$(INTDIR)/Log.obj
ranlib $(INTDIR)/Shared.a
Packet.obj : src/shared/packet.cpp init
g++ -c $(INCLUDES) $(OPTIONS) -o $(INTDIR)/Packet.obj src/shared/packet.cpp
Flags.obj : src/shared/Flags.cpp init
g++ -c $(INCLUDES) $(OPTIONS) -o $(INTDIR)/Flags.obj src/shared/Flags.cpp
AsyncSocket.obj : src/shared/AsyncSocket.cpp init
g++ -c $(INCLUDES) $(OPTIONS) -o $(INTDIR)/AsyncSocket.obj src/shared/AsyncSocket.cpp
Log.obj : src/shared/Log.cpp init
g++ -c $(INCLUDES) $(OPTIONS) -o $(INTDIR)/Log.obj src/shared/Log.cpp
init:
mkdir -p bin obj
clean:
rm -f $(INTDIR)/*.obj $(INTDIR)/*.a
The Code
// Excerpt from .hpp file
#include <cppconn/driver.h>
#include <cppconn/connection.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
// End excerpt
void Database::connect()
{
std::stringstream connString;
connString << "tcp://";
connString << m_host;
connString << ":";
connString << m_port;
m_driver = get_driver_instance(); // This guy is being a *****
m_conn = m_driver->connect(connString.str(), m_user, m_password);
m_conn->setSchema(m_database);
}
What can I do to fix this ?
Finally I could successfully compile a program with C++ connector in Ubuntu 10.10.
Initially I faced the same problem with "undefined reference to `get_driver_instance' " to solve this I declare my driver instance variable of MySQL_Driver type. For ready reference this type is defined in mysql_driver.h file. Here is the code snippet I used in my program.
sql::mysql::MySQL_Driver *driver;
try {
driver = sql::mysql::get_driver_instance();
}
and I compiled the program with -l mysqlcppconn linker option
Thank you so much, I got it fixed too. I had the exact experience.
I am using Eclipse CDT on 64 Bit CentOS and for anyone reading this here are the following steps .
first, be sure that the following are in the code.
include "mysql_driver.h"
include "mysql_connection.h"
using namespace sql::mysql;
Be sure that in Eclipse you have specified in your Eclipse project settings.
the mysql/include and mysql/include/cppconn directories in your include and then also the mysql/lib in the library directory, then and more importantly you specify -lmysqlcppconn.
Be sure you got the -m64 set in the Eclipse compiler options too.
When you run your program, it may complain of missing libmysqlcppconn.so.1 . Do this, copy libmysqlcppconn.so.1.0.5 in your /usr/lib64 directory. Make a link of libmysqlcppconn.so.1 towards libmysqlcppconn.so.1.0.5 within that directory.
Your program should now run.
You need to link with
-lmysqlcppconn -lmysqlcppconn-static
The first library contains the code for the headers in /usr/include/cppconn/, and the second library contains the code found in the headers mysql_driver.h and mysql_connection.h.
You'll need to add -lmysqlcppconn-static after the object files that uses stuff inside that library.
The code would be more helpful than the make file but try adding using namespace sql; to the top of Database.cpp.
// Excerpt from .hpp file
#include <cppconn/driver.h>
#include <cppconn/connection.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
using namespace sql; // <---- add here
To me was needed -lmysqlclient
g++ -o mariaS2json test.cpp -L/usr/lib/ -lmysqlcppconn -lmysqlclient
And now all works