I'm trying to compile the following short C++ program (not written by me) in Debian:
$ cat checksig.cpp
#include <QByteArray>
#include <QDebug>
#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/ecdsa.h>
#include <openssl/sha.h>
static EC_KEY* EC_KEY_pub_key ( const QByteArray& pub )
{
static EC_KEY* eckey = EC_KEY_new_by_curve_name ( NID_secp256k1 );
const quint8* ppub = (const quint8*)pub.constData ( );
o2i_ECPublicKey ( &eckey, &ppub, pub.size ( ) );
return eckey;
}
//--------------------------------------------------------------
int main(int argc, char *argv[])
{
const QByteArray data ( QByteArray::fromHex ( argv [1] ) );
const QByteArray sign ( QByteArray::fromHex ( argv [2] ) );
const QByteArray pubk ( QByteArray::fromHex ( argv [3] ) );
quint8 tmp [32];
::SHA256 ( (const quint8*)data.constData ( ), data.size ( ), tmp );
quint8 digest [32];
::SHA256 ( tmp, 32, digest );
qDebug ( ) << "data=" << QString ( data.toHex ( ) );
qDebug ( ) << "sign=" << QString ( sign.toHex ( ) );
qDebug ( ) << "pubk=" << QString ( pubk.toHex ( ) );
qDebug ( ) << "digest=" << QString ( QByteArray ( (const char*)digest, 32 ).toHex ( ) );
const bool v ( ::ECDSA_verify ( 0, digest, 32, (const quint8*)sign.constData ( ), sign.size ( ), EC_KEY_pub_key ( pubk ) ) );
qDebug ( ) << "result=" << v;
return 0;
}
But I don't think I'm using the right includes, or maybe I need to install more Qt libraries?
$ g++ -Wall checksig.cpp -o checksig -L /usr/include/i386-linux-gnu/qt5/QtCore/ -lQtCore -I /usr/include/i386-linux-gnu/qt5/QtCore/
In file included from /usr/include/i386-linux-gnu/qt5/QtCore/QByteArray:1:0,
from checksig.cpp:4:/usr/include/i386-linux-gnu/qt5/QtCore/qbytearray.h:45:30: fatal error: QtCore/qrefcount.h: No such file or directory
#include <QtCore/qrefcount.h>
^
and alternatively, using includes and libraries from one directory back:
g++ -Wall checksig.cpp -o checksig -L /usr/include/i386-linux-gnu/qt5/ -lQtCore -I /usr/include/i386-linux-gnu/qt5/
checksig.cpp:4:22: fatal error: QByteArray: No such file or directory
#include <QByteArray>
^
compilation terminated.
I'm new to C++. How can I compile this small program in a 1-liner?
As requested in the comments:
$ sudo apt-file search "QtCore/qrefcount.h"
qtbase5-dev: /usr/include/i386-linux-gnu/qt5/QtCore/qrefcount.h
thanks to Michael Popovich's answer i tried the following and got further. but now i have new errors:
$ g++ -Wall checksig.cpp -o checksig -L /usr/include/i386-linux-gnu/qt5/QtCore/ -lQtCore -I /usr/include/i386-linux-gnu/qt5/ -I /usr/include/i386-linux-gnu/qt5/QtCore/
In file included from /usr/include/i386-linux-gnu/qt5/QtCore/qatomic.h:42:0,
from /usr/include/i386-linux-gnu/qt5/QtCore/qrefcount.h:45,
from /usr/include/i386-linux-gnu/qt5/QtCore/qbytearray.h:45,
from /usr/include/i386-linux-gnu/qt5/QtCore/QByteArray:1,
from checksig.cpp:4:
/usr/include/i386-linux-gnu/qt5/QtCore/qglobal.h:1034:4: error: #error "You must build your code with position independent code if Qt was built with -reduce-relocations. " "Compile your code with -fPIC or -fPIE."
# error "You must build your code with position independent code if Qt was built with -reduce-relocations. "\
^
i have no idea if qt was built with -reduce-relocations i don't think i even installed it myself - it was probably pulled in as a dependency for another install.
anyway, trying with -fPIC and -fPIE:
$ g++ -Wall checksig.cpp -o checksig -L /usr/include/i386-linux-gnu/qt5/QtCore/ -lQtCore -I /usr/include/i386-linux-gnu/qt5/ -I /usr/include/i386-linux-gnu/qt5/QtCore/ -fPIC
/usr/bin/ld: cannot find -lQtCore
collect2: error: ld returned 1 exit status
$ g++ -Wall checksig.cpp -o checksig -L /usr/include/i386-linux-gnu/qt5/QtCore/ -lQtCore -I /usr/include/i386-linux-gnu/qt5/ -I /usr/include/i386-linux-gnu/qt5/QtCore/ -fPIE
/usr/bin/ld: cannot find -lQtCore
collect2: error: ld returned 1 exit status
I'd recommend to build Qt with either CMake or QMake, here is the solution with QMake:
checksig.pro:
QT += core
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = checksig
TEMPLATE = app
SOURCES += checksig.cpp
LIBS += -lssl -lcrypto
And compile like this:
qmake checksig.pro
make
Will compile a correct binary.
And if you really need some 1-liner:
g++ checksig.cpp -o checksig -fPIC -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -lssl -lcrypto -lQt5Core -lpthread
Check #find /usr/include/i386-linux-gnu/qt5/ -name qrefcount.h
Add result path to QtCore/ in your project or your system PATH
Related
I am trying to compile a program for the raspberry pi.
But when I run the build in Geany I got this error:
g++ $(pkg-config opencv4 --cflags --libs) -o g++ $(pkg-config raspicam --cflags --libs) -o camera_2 camera_2.cpp (in directory: /home/pi/Desktop)
/usr/bin/ld: /tmp/ccTDUfOT.o: undefined reference to symbol '_ZN2cv6imshowERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11_InputArrayE'
/usr/bin/ld: //usr/local/lib/libopencv_highgui.so.405: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Compilation failed.
The camera.cpp file looks like this:
#include <opencv2/opencv.hpp>
#include <raspicam_cv.h>
#include <iostream>
using namespace std;
using namespace cv;
using namespace raspicam;
Mat frame;
void Setup ( int argc,char **argv, RaspiCam_Cv &Camera )
{
Camera.set ( CAP_PROP_FRAME_WIDTH, ( "-w",argc,argv,400 ) );
Camera.set ( CAP_PROP_FRAME_HEIGHT, ( "-h",argc,argv,240 ) );
Camera.set ( CAP_PROP_BRIGHTNESS, ( "-br",argc,argv,50 ) );
Camera.set ( CAP_PROP_CONTRAST ,( "-co",argc,argv,50 ) );
Camera.set ( CAP_PROP_SATURATION, ( "-sa",argc,argv,50 ) );
Camera.set ( CAP_PROP_GAIN, ( "-g",argc,argv ,50 ) );
Camera.set ( CAP_PROP_FPS, ( "-fps",argc,argv,100));
}
int main(int argc,char **argv)
{
RaspiCam_Cv Camera;
Setup(argc, argv, Camera);
cout<<"Connecting to camera"<<endl;
if (!Camera.open())
{
cout<<"Failed to Connect"<<endl;
return -1;
}
cout<<"Camera Id = "<<Camera.getId()<<endl;
Camera.grab();
Camera.retrieve(frame);
imshow("frame", frame);
waitKey();
return 0;
}
So far I have figured that when I remove
Mat frame;
the error does not appear.
The pkg-config file looks like this:
prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/opencv4/opencv2
includedir_new=${prefix}/include/opencv4
Name: OpenCV
Description: Open Source Computer Vision Library
Version: 4.5.5
L: -Libs${exec_prefix}/lib -lopencv_calib3d -lopencv_core -lopencv_dnn -lopencv_features2d -lopencv_flann -lopencv_gapi -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_video -lopencv_videoio
Libs.private: -ldl -lm -lpthread -lrt
Cflags: -I${includedir_old} -I${includedir_new}
The command in Geany looks like this:
g++ $(pkg-config opencv4 --cflags --libs) -o g++ $(pkg-config raspicam --cflags --libs) -o %e %f
Do you have any idea what is wrong and what I do have to change?
Thank you
The argument -o g++ is very weird because it will make an output file named g++, which is confusing because that's also the name of your compiler. You probably want to remove that since you already have a -o argument.
Secondly, the order of the different objects/libraries that are getting linked together often matters when you are linking a program. Try putting the calls to pkg-config at the end of the command.
I have solved the error.
I have added two libraries to the command:
g++ $(pkg-config opencv4 --cflags --libs) $(pkg-config raspicam --cflags --libs) -o %e %f -lopencv_highgui -lopencv_core
I wonder why the libraries do not work in the config file.
I need to use libcurl with https in my project, so I've built zlib, openssl and libcurl (with mingw32-make mingw32-ssl-zlib) successfully. But after I copied include libcurl.a libcurldll.a libcurl.dll to my project folder, sent a GET request to https://www.google.com it failed with error Unsupported protocol
My OPENSSL_PATH and ZLIB_PATH in my lib/Makefile.m32 src/Makefile.m32 are:
ZLIB_PATH = ../../zlib-1.2.8
OPENSSL_PATH = /c/OpenSSL
and the build log:
Compeador#DESKTOP-QCSNUGN MSYS /e/programming/c/lib/curl-7.74.0
$ mingw32-make mingw32-ssl-zlib
C:/msys64/mingw32/bin/mingw32-make.exe -C lib -f Makefile.m32 CFG=mingw32-ssl-zlib
mingw32-make[1]: Entering directory 'E:/programming/c/lib/curl-7.74.0/lib'
gcc -I. -I../include -I"C:/OpenSSL/include" -I"../../zlib-1.2.8" -g -O2 -Wall -W -fno-strict-aliasing -m32 -DBUILDING_LIBCURL -DUSE_OPENSSL -DHAVE_OPENSSL_PKCS12_H -DOPENSSL_NO_KRB5 -DHAVE_LIBZ -DHAVE_ZLIB_H -c altsvc.c -o altsvc.o
gcc ......
ar cru libcurl.a altsvc.o amigaos.o asyn-ares.o asyn-thread.o base64.o conncache.o connect.o content_encoding.o cookie.o curl_addrinfo.o curl_ctype.o curl_des.o curl_endian.o curl_fnmatch.o curl_get_line.o curl_gethostname.o curl_gssapi.o curl_memrchr.o curl_multibyte.o curl_ntlm_core.o curl_ntlm_wb.o curl_path.o curl_range.o curl_rtmp.o curl_sasl.o curl_sspi.o curl_threads.o dict.o dotdot.o easy.o escape.o file.o fileinfo.o formdata.o ftp.o url.o ftplistparser.o getenv.o getinfo.o gopher.o hash.o hmac.o hostasyn.o hostcheck.o hostip.o hostip4.o hostip6.o hostsyn.o http.o http2.o http_chunks.o http_digest.o http_negotiate.o http_ntlm.o http_proxy.o idn_win32.o if2ip.o imap.o inet_ntop.o inet_pton.o krb5.o ldap.o llist.o md4.o md5.o memdebug.o mime.o mprintf.o mqtt.o multi.o netrc.o non-ascii.o nonblock.o openldap.o parsedate.o pingpong.o pop3.o progress.o psl.o doh.o rand.o rename.o rtsp.o select.o sendf.o setopt.o sha256.o share.o slist.o smb.o smtp.o socketpair.o socks.o socks_gssapi.o socks_sspi.o speedcheck.o splay.o strcase.o strdup.o strerror.o strtok.o strtoofft.o system_win32.o telnet.o tftp.o timeval.o transfer.o urlapi.o version.o warnless.o wildcard.o x509asn1.o dynbuf.o version_win32.o easyoptions.o easygetopt.o hsts.o vauth/cleartext.o vauth/cram.o vauth/digest.o vauth/digest_sspi.o vauth/krb5_gssapi.o vauth/krb5_sspi.o vauth/ntlm.o vauth/ntlm_sspi.o vauth/oauth2.o vauth/spnego_gssapi.o vauth/spnego_sspi.o vauth/vauth.o vtls/bearssl.o vtls/gskit.o vtls/gtls.o vtls/keylog.o vtls/mbedtls.o vtls/mbedtls_threadlock.o vtls/mesalink.o vtls/nss.o vtls/openssl.o vtls/schannel.o vtls/schannel_verify.o vtls/sectransp.o vtls/vtls.o vtls/wolfssl.o vquic/ngtcp2.o vquic/quiche.o vquic/vquic.o vssh/libssh.o vssh/libssh2.o vssh/wolfssh.o
ranlib libcurl.a
strip -g libcurl.a
windres --include-dir=../include -DDEBUGBUILD=0 -O coff -F pe-i386 -i libcurl.rc -o libcurl.res
gcc -s -m32 -shared -o libcurl.dll \
-Wl,--output-def,libcurl.def,--out-implib,libcurldll.a \
altsvc.o amigaos.o asyn-ares.o asyn-thread.o base64.o conncache.o connect.o content_encoding.o cookie.o curl_addrinfo.o curl_ctype.o curl_des.o curl_endian.o curl_fnmatch.o curl_get_line.o curl_gethostname.o curl_gssapi.o curl_memrchr.o curl_multibyte.o curl_ntlm_core.o curl_ntlm_wb.o curl_path.o curl_range.o curl_rtmp.o curl_sasl.o curl_sspi.o curl_threads.o dict.o dotdot.o easy.o escape.o file.o fileinfo.o formdata.o ftp.o url.o ftplistparser.o getenv.o getinfo.o gopher.o hash.o hmac.o hostasyn.o hostcheck.o hostip.o hostip4.o hostip6.o hostsyn.o http.o http2.o http_chunks.o http_digest.o http_negotiate.o http_ntlm.o http_proxy.o idn_win32.o if2ip.o imap.o inet_ntop.o inet_pton.o krb5.o ldap.o llist.o md4.o md5.o memdebug.o mime.o mprintf.o mqtt.o multi.o netrc.o non-ascii.o nonblock.o openldap.o parsedate.o pingpong.o pop3.o progress.o psl.o doh.o rand.o rename.o rtsp.o select.o sendf.o setopt.o sha256.o share.o slist.o smb.o smtp.o socketpair.o socks.o socks_gssapi.o socks_sspi.o speedcheck.o splay.o strcase.o strdup.o strerror.o strtok.o strtoofft.o system_win32.o telnet.o tftp.o timeval.o transfer.o urlapi.o version.o warnless.o wildcard.o x509asn1.o dynbuf.o version_win32.o easyoptions.o easygetopt.o hsts.o vauth/cleartext.o vauth/cram.o vauth/digest.o vauth/digest_sspi.o vauth/krb5_gssapi.o vauth/krb5_sspi.o vauth/ntlm.o vauth/ntlm_sspi.o vauth/oauth2.o vauth/spnego_gssapi.o vauth/spnego_sspi.o vauth/vauth.o vtls/bearssl.o vtls/gskit.o vtls/gtls.o vtls/keylog.o vtls/mbedtls.o vtls/mbedtls_threadlock.o vtls/mesalink.o vtls/nss.o vtls/openssl.o vtls/schannel.o vtls/schannel_verify.o vtls/sectransp.o vtls/vtls.o vtls/wolfssl.o vquic/ngtcp2.o vquic/quiche.o vquic/vquic.o vssh/libssh.o vssh/libssh2.o vssh/wolfssh.o libcurl.res -L"C:/OpenSSL/lib" -lssl -lcrypto -lgdi32 -lcrypt32 -L"../../zlib-1.2.8" -lz -lwldap32 -lws2_32
mingw32-make[1]: Leaving directory 'E:/programming/c/lib/curl-7.74.0/lib'
C:/msys64/mingw32/bin/mingw32-make.exe -C src -f Makefile.m32 CFG=mingw32-ssl-zlib
mingw32-make[1]: Entering directory 'E:/programming/c/lib/curl-7.74.0/src'
windres --include-dir=../include -O coff -DCURL_EMBED_MANIFEST -F pe-i386 -i curl.rc -o curl.res
gcc -I. -I../include -I../lib -I"C:/OpenSSL/include" -I"../../zlib-1.2.8" -g -O2 -Wall -W -fno-strict-aliasing -m32 -DCURL_STATICLIB -DUSE_OPENSSL -DHAVE_LIBZ -DHAVE_ZLIB_H -c slist_wc.c
gcc ......
rm -f curl.exe
gcc -s -m32 -static -o curl.exe curl.res slist_wc.o tool_binmode.o tool_bname.o tool_cb_dbg.o tool_cb_hdr.o tool_cb_prg.o tool_cb_rea.o tool_cb_see.o tool_cb_wrt.o tool_cfgable.o tool_convert.o tool_dirhie.o tool_doswin.o tool_easysrc.o tool_filetime.o tool_formparse.o tool_getparam.o tool_getpass.o tool_help.o tool_helpers.o tool_homedir.o tool_hugehelp.o tool_libinfo.o tool_main.o tool_metalink.o tool_msgs.o tool_operate.o tool_operhlp.o tool_panykey.o tool_paramhlp.o tool_parsecfg.o tool_progress.o tool_strdup.o tool_setopt.o tool_sleep.o tool_urlglob.o tool_util.o tool_vms.o tool_writeout.o tool_writeout_json.o tool_xattr.o strtoofft.o nonblock.o warnless.o curl_ctype.o curl_multibyte.o version_win32.o dynbuf.o -L../lib -lcurl -L"C:/OpenSSL/lib" -lssl -lcrypto -lgdi32 -lcrypt32 -L"../../zlib-1.2.8" -lz -lwldap32 -lws2_32
mingw32-make[1]: Leaving directory 'E:/programming/c/lib/curl-7.74.0/src'
and my code:
#include <iostream>
#include <windows.h>
#include <openssl/ssl.h>
#include <curl/curl.h>
using namespace std;
size_t CurlStrWCallback(char* content, size_t size, size_t nmemb, void *userdata){
auto total = size*nmemb;
((std::string*)userdata)->append((char*)content, total);
return total;
}
int main(){
auto curl = curl_easy_init();
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK){
std::cout << "Fail to init curl\n";
return 0;
}
if(curl){
std::string buffer;
curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlStrWCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
auto res = curl_easy_perform(curl);
if(res != CURLE_OK){
std::cout << "failed to perform request: " << curl_easy_strerror(res) << '\n';
}
else{
std::cout << "Response:\n" << buffer << std::endl;
}
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
output: failed to perform request: Unsupported protocol
meanwhlie I also tried to run libcurl/src/curl.exe https://www.google.com -k and it sucessed
Turns out I have to compile all source in the same fashion I use in Linux: ./configure && make && make install
here are the commands I use:
zlib:
./configure
make && make install
openssl:
./configure --prefix=$PWD/dist no-idea no-mdc2 no-rc5 shared mingw (or mingw64 for 64 bits)
make && make install
libcurl:
./configure --prefix=$PWD/dist --with-zlib=PATH_TO_COMPILED_ZLIB --with-ssl=PATH_TO_COMPILED_OPENSSL --host=i686-w64-mingw32 (or x86_64-w64-mingw32 for 64 bits)
make && make install
I am trying to compile lex.yy.c and y.tab.c with C++ code, here is the Make status -
(base) rajatkmitra#spider:~/modeler> make
flex ./src/lex.l
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o main.o ./src/main.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o convertFloatToFixed.o ./src/convertFloatToFixed.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o convertProductFloatToFixed.o ./src/convertProductFloatToFixed.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o printer.o ./src/printer.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o vectorToString.o ./src/vectorToString.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o printFixedPointProduct.o ./src/printFixedPointProduct.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o fixedPointFormatter.o ./src/fixedPointFormatter.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o tokenize.o ./src/tokenize.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o y.tab.o y.tab.c
bison -y -d ./src/bison.y
./src/bison.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr]
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o lex.yy.o lex.yy.c
###############################################################################
# Building main.o convertFloatToFixed.o convertProductFloatToFixed.o printer.o vectorToString.o
printFixedPointProduct.o fixedPointFormatter.o tokenize.o y.tab.c lex.yy.c
###############################################################################
g++ -Wno-write-strings -I ./ main.o convertFloatToFixed.o convertProductFloatToFixed.o printer.o vectorToString.o printFixedPointProduct.o fixedPointFormatter.o tokenize.o y.tab.c lex.yy.c -o lynx -lm
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: /tmp/cc8jVMLM.o: in function `yylex()':
lex.yy.c:(.text+0x343): undefined reference to `yyerror(char*)'
collect2: error: ld returned 1 exit status
make: *** [Makefile:71: lynx] Error 1
----Makefile----
####################################################################
# Library Paths
####################################################################
####################################################################
#Sources, use vpath and $CC/$LEX/$YACC should have arguments $<
#debug %make --just-print should show simulate make procedure
####################################################################
INCLUDE=-I ./
LEXSRC=lex.l
YACCSRC=bison.y
SRC=main.cc convertFloatToFixed.cc convertProductFloatToFixed.cc \
printer.cc vectorToString.cc printFixedPointProduct.cc fixedPointFormatter.cc \
tokenize.cc y.tab.c lex.yy.c
vpath %cc ./src
vpath %l ./src
vpath %y ./src
#####################################################################
#Compiler Settings
#####################################################################
OBJCC=$(SRC:.cc=.o)
OBJC=$(SRC:.c=.o)
EXE=lynx
DEFINE=#-D _XOPEN_SOURCE
CFLAGS=$(INCLUDE) $(DEFINE) $(LIBPATH) -c -Wall -Wreorder -Wno-write-strings \
-Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm
CXXFLAGS=$(CFLAGS)
CC=g++
LEX=flex
YACC=bison -y -d
######################################################################
#Build Rules
######################################################################
new: all
all:$(SRC) $(EXE)
# These dependency rules indicate that (1) lex.yy.o depends on
# lex.yy.c and y.tab.h and (2) lex.yy.o and y.tab.o depend on calc.h.
# Make uses the dependencies to figure out what rules must be run when
# a file has changed.
lex.yy.o: lex.yy.c y.tab.h
lex.yy.o y.tab.o:
## This rule will use yacc to generate the files y.tab.c and y.tab.h
## from our file $(YACCSRC).y
y.tab.c y.tab.h: $(YACCSRC)
$(YACC) $<
## this is the make rule to use lex to generate the file lex.yy.c from
## our file $(LEXSRC).lex
lex.yy.c: $(LEXSRC)
$(LEX) $<
## for lex.yy.c and y.tab.c
%.c.o:
$(CC) $(CFLAGS) $< -o $#
## all other C++ files
%.cc.o:
$(CC) $(CFLAGS) $< -o $#
$(EXE):$(OBJCC) $(OBJC)
#echo \###############################################################################
#echo \# Building $(OBJCC)
#echo \###############################################################################
$(CC) -Wno-write-strings $(INCLUDE) $(OBJCC) $(LIBPATH) $(LIB) -o $# -lm
clean:
rm -rf $(EXE) *~ *.o lex.yy.c y.tab.h
Okay so here is the grammar file bison.y
%{
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
int yylex();
void yyerror(const char *s);
/*|--------------------------
for global parsing
-----------------------------|*/
unsigned int attributeFlag;
%}
/*Possible types from lexer*/
%union {
int ival;
double fval;
const char *sval;
}
/*Possible tokens*/
%token KWREAL
%token <ival> INTEGER
%token <fval> FLOAT;
%token <sval> VARIABLE
/*associativity*/
%left GE LE EQ NE '>' '<'
%left '+' '-'
%left '*' '/'
%nonassoc UMINUS
/*parse rules*/
%%
description:
description decl_attributes {}
| description stmt_list {}
| description real_variable_decl {}
| decl_attributes {}
| stmt_list {}
| real_variable_decl {}
;
decl_attributes:
attribute {}
| decl_attributes attribute {}
;
attribute:
open_attribute several_attribute_assignments close_attribute
real_variable_decl
{
attributeFlag = 0;
}
;
open_attribute:
'(' '*' {attributeFlag = 1;}
;
close_attribute:
'*' ')' {}
;
several_attribute_assignments:
integer_assignment {}
| continued_attribute_assignments integer_assignment {}
;
continued_attribute_assignments:
integer_assignment ',' {}
| continued_attribute_assignments integer_assignment ',' {}
;
real_variable_decl:
KWREAL VARIABLE ';'
{
}
;
stmt_list:
stmt { }
| stmt_list stmt { }
;
stmt:
VARIABLE '=' expr ';' {printf("%s\n\n",$1); }
| integer_assignment ';' { }
;
integer_assignment:
VARIABLE '=' INTEGER
{
if(attributeFlag==1){
if(strcmp($1, "S")==0){
//attrContainer.isSigned = $3;
}else if(strcmp($1, "IB")==0){
//attrContainer.intBits = $3;
}else if(strcmp($1, "FB")==0){
//attrContainer.fracBits = $3;
}
}
}
;
expr:
VARIABLE { printf("%s\n",$1); }
| FLOAT { printf("%f\n",$1); }
| '-' expr %prec UMINUS { }
| expr '+' expr { }
| expr '-' expr { }
| expr '*' expr { }
| expr '/' expr { }
| expr '<' expr { }
| expr '>' expr { }
| expr GE expr { }
| expr LE expr { }
| expr NE expr { }
| expr EQ expr { }
| '(' expr ')' { }
;
%%
/*|-----------------------------------------------------
Parsing Functions
-----------------------------------------------------|*/
/*Definition of yyerror*/
void yyerror(const char *s)
{
extern int yylineno; // defined and maintained in lex.c
extern char *yytext; // defined and maintained in lex.c
printf("ERROR: %s on line %d\n", yytext, yylineno);
}
and the lexer -
%{
#include <stdlib.h>
#include <stdio.h>
#include "y.tab.h"
void yyerror(char *);
%}
%%
"real" return KWREAL;
[a-zA-Z][a-zA-Z]* {
//yylval.sval= *yytext - 'a';
yylval.sval = strdup(yytext);
return VARIABLE;
}
0 {
yylval.ival = atoi(yytext);
return INTEGER;
}
[1-9][0-9]* {
yylval.ival = atoi(yytext);
return INTEGER;
}
(([0-9]*\.[0-9]*)([eE][-+]?[0-9]+)?) {
yylval.fval = atof(yytext);
return FLOAT;
}
[-()<>=+*/;,{}.] {
return *yytext;
}
">=" return GE;
"<=" return LE;
"==" return EQ;
"!=" return NE;
#[^\n]* { /* Discard preprocessor comments. */ }
"//"[^\n]* { /* Discard c99 comments. */ }
[ \t\n]+ ; /* ignore whitespace */
. yyerror("Unknown character");
%%
int yywrap(void) {
return 1;
}
This is the main routine main.cc
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
/*------------------------------------------------
Front end parser
------------------------------------------------*/
extern void yyparse(void);
extern FILE *yyin;
int main(int argc, char **argv)
{
/*------------------------
parse the file
------------------------*/
/*open file handle to a file of interest*/
if(argc < 2){
printf("Usage: main <filename> \n");
exit(-1);
}
yyin = fopen(argv[1],"r");
if(yyin==NULL){
printf("Could not open file !\n");
exit(-1);
}
/*Parse the design*/
do{
yyparse();
}while(!feof(yyin));
}
So there you go! I have added the Minimal Reproducable Example. When I compile everything with g++ I end up getting a linker error that does not find the yyerror() routine in yylex()
g++ -Wno-write-strings -I ./ y.tab.o lex.yy.o main.o -o lynx -lm -lfl -
std=c++11
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld:
lex.yy.o: in function yylex()': /home/rajatkmitra/modeler/minimal/lex.l:46: undefined reference to yyerror(char*)'
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld:
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../lib64/libfl.so: undefined
reference to `yylex'
collect2: error: ld returned 1 exit status
make: *** [Makefile:68: lynx] Error 1
Changes Made to get this environment to work -
(1) Compile ALL sources including the output from lex and yacc with g++
(2) yyerror arguments are (char *s) and NOT (const char *s)
(2) do not link with -lfl as this is not not required with g++
Here's a minimal example which shows the problem:
file: yyerror.c
#include <iostream>
void yyerror(const char* msg) {
std::cout << msg;
}
file: main.c
void yyerror(char* msg);
int main(void) {
char* msg[] = "Hello, world";
yyerror(msg);
}
Try to build
$ g++ -Wall -o main main.c yyerror.c
/tmp/cc4xbjus.o: In function `main':
main.c:(.text+0x5f): undefined reference to `yyerror(char*)'
collect2: error: ld returned 1 exit status
Note that the declaration of yyerror in main.c is different from the definition of yyerror in yyerror.c. Since you're compiling these files as C++, this matters: in C++, function names can be overloaded with different argument types, and const char* is a different argument type than char*. So the two files cannot be successfully linked: the overload of yyerror declared in main.c is not defined anywhere.
Although you don't show the declaration of yyerror you placed in your lexer file, I'm assuming that it is the same as my example, based on the error message generated by the compiler. The error message indicates the complete name (including argument types) of the function which cannot be linked.
I have installed PocketSphinx on Ubuntu 14 and now trying to create simple sample. I took code from official website Sphinx.
#include <pocketsphinx.h>
int
main(int argc, char *argv[])
{
ps_decoder_t *ps;
cmd_ln_t *config;
FILE *fh;
char const *hyp, *uttid;
int16 buf[512];
int rv;
int32 score;
config = cmd_ln_init(NULL, ps_args(), TRUE,
"-hmm", MODELDIR "/en-us/en-us",
"-lm", MODELDIR "/en-us/en-us.lm.dmp",
"-dict", MODELDIR "/en-us/cmudict-en-us.dict",
NULL);
if (config == NULL)
return 1;
ps = ps_init(config);
if (ps == NULL)
return 1;
fh = fopen("goforward.raw", "rb");
if (fh == NULL)
return -1;
rv = ps_start_utt(ps);
if (rv < 0)
return 1;
while (!feof(fh)) {
size_t nsamp;
nsamp = fread(buf, 2, 512, fh);
rv = ps_process_raw(ps, buf, nsamp, FALSE, FALSE);
}
rv = ps_end_utt(ps);
if (rv < 0)
return 1;
hyp = ps_get_hyp(ps, &score);
if (hyp == NULL)
return 1;
printf("Recognized: %s\n", hyp);
fclose(fh);
ps_free(ps);
cmd_ln_free_r(config);
return 0;
}
And Qmake is
QT += core
QT -= gui
TARGET = OpenCVQt
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
DEPENDPATH += /usr/local/lib
INCLUDEPATH += /usr/local/include
INCLUDEPATH += /usr/local/include/pocketsphinx
INCLUDEPATH += /usr/local/include/sphinxbase
LIBS += -lopencv_core
LIBS += -lopencv_imgproc
LIBS += -lopencv_highgui
LIBS +=-lpocketsphinx
LIBS += -lsphinxbase
LIBS += -lsphinxad
SOURCES += main.cpp
Can't understand what is wrong. I saw sphinx_config.h in /usr/local/include/sphinxbase. Thanks.
18:54:06: Starting: "/usr/bin/make"
/home/warezovvv/Qt/5.4/gcc_64/bin/qmake -spec linux-g++ CONFIG+=debug -o Makefile ../OpenCVQt/OpenCVQt.pro
g++ -c -pipe -g -Wall -W -D_REENTRANT -fPIE -DQT_CORE_LIB -I../OpenCVQt -I. -I/usr/local/include -I/usr/local/include/pocketsphinx -I/usr/local/include/sphinxbase -I../../../Qt/5.4/gcc_64/include -I../../../Qt/5.4/gcc_64/include/QtCore -I. -I../../../Qt/5.4/gcc_64/mkspecs/linux-g++ -o main.o ../OpenCVQt/main.cpp
In file included from /usr/include/sphinxbase/cmd_ln.h:66:0,
from /usr/local/include/pocketsphinx/pocketsphinx.h:52,
from ../OpenCVQt/main.cpp:1:
/usr/include/sphinxbase/prim_type.h:88:27: fatal error: sphinx_config.h: No such file or directory
#include <sphinx_config.h>
^
compilation terminated.
make: *** [main.o] Error 1
18:54:06: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project OpenCVQt (kit: Desktop Qt 5.4.1 GCC 64bit)
When executing step "Make"
18:54:06: Elapsed time: 00:01.
No error with header. Now new error ->
22:42:41: Running steps for project OpenCVQt...
22:42:41: Configuration unchanged, skipping qmake step.
22:42:41: Starting: "/usr/bin/make"
/home/warezovvv/Qt/5.4/gcc_64/bin/qmake -spec linux-g++ CONFIG+=debug -o Makefile ../OpenCVQt/OpenCVQt.pro
g++ -c -pipe -g -Wall -W -D_REENTRANT -fPIE -DQT_CORE_LIB -I../OpenCVQt -I. -I/usr/local/include -I/usr/local/include/pocketsphinx -I/usr/local/include/sphinxbase -I/usr/include/sphinxbase -I../../../Qt/5.4/gcc_64/include -I../../../Qt/5.4/gcc_64/include/QtCore -I. -I../../../Qt/5.4/gcc_64/mkspecs/linux-g++ -o main.o ../OpenCVQt/main.cpp
../OpenCVQt/main.cpp: In function 'int main(int, char**)':
../OpenCVQt/main.cpp:14:22: error: 'MODELDIR' was not declared in this scope
"-hmm", MODELDIR "/en-us/en-us",
^
../OpenCVQt/main.cpp:15:30: error: expected ')' before string constant
"-lm", MODELDIR "/en-us/en-us.lm.dmp",
^
../OpenCVQt/main.cpp:16:32: error: expected ')' before string constant
"-dict", MODELDIR "/en-us/cmudict-en-us.dict",
^
../OpenCVQt/main.cpp:9:23: warning: unused variable 'uttid' [-Wunused-variable]
char const *hyp, *uttid;
^
../OpenCVQt/main.cpp: At global scope:
../OpenCVQt/main.cpp:4:1: warning: unused parameter 'argc' [-Wunused-parameter]
main(int argc, char *argv[])
^
../OpenCVQt/main.cpp:4:1: warning: unused parameter 'argv' [-Wunused-parameter]
make: *** [main.o] Error 1
22:42:42: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project OpenCVQt (kit: Desktop Qt 5.4.1 GCC 64bit)
When executing step "Make"
22:42:42: Elapsed time: 00:01.
I solved it with this CMake config:
cmake_minimum_required(VERSION 2.8)
add_definitions(-std=c++11)
find_package(PkgConfig REQUIRED)
pkg_check_modules(POCKETSPHINX REQUIRED pocketsphinx)
pkg_check_modules(SPHINXBASE REQUIRED sphinxbase)
message(STATUS "SPHINXBASE_LIBRARIES => " "${SPHINXBASE_LIBRARIES}")
message(STATUS "POCKETSPHINX_LIBRARIES => " "${POCKETSPHINX_LIBRARIES}")
message(STATUS "POCKETSPHINX_INCLUDE_DIRS => " "${POCKETSPHINX_INCLUDE_DIRS}")
message(STATUS "SPHINXBASE_INCLUDE_DIRS => " "${SPHINXBASE_INCLUDE_DIRS}")
set(
your_pocketsphinx_app_src
your_pocketsphinx_app.cpp
...
)
add_executable(your_pocketsphinx_app your_pocketsphinx_app.cpp)
set_property(TARGET your_pocketsphinx_app PROPERTY CXX_STANDARD 11)
target_include_directories(your_pocketsphinx_app PUBLIC ${POCKETSPHINX_INCLUDE_DIRS})
target_include_directories(your_pocketsphinx_app PUBLIC ${SPHINXBASE_INCLUDE_DIRS})
target_compile_options(your_pocketsphinx_app PUBLIC ${POCKETSPHINX_CFLAGS_OTHER})
target_compile_options(your_pocketsphinx_app PUBLIC ${SPHINXBASE_CFLAGS_OTHER})
target_link_libraries(your_pocketsphinx_app ${SPHINXBASE_LIBRARIES})
target_link_libraries(your_pocketsphinx_app ${POCKETSPHINX_LIBRARIES})
# Binary to be installed.
install(TARGETS your_pocketsphinx_app DESTINATION bin)
You seem to have installation of sphinxbase headers in /usr/include, not in /usr/local/include. If you intentionally compiled sphinxbase this way, you need to add -I/usr/include/sphinxbase in Makefile, not -I/usr/local/include/sphinxbase.
Overall pocketsphinx-5prealpha requires sphinxbase-5prealpha and default installation prefix for them is /usr/local. I suggest you to remove sphinxbase from /usr.
Let's take this snippet:
#include "SDL/SDL.h"
int main( int argc, char* args[] )
{
SDL_Init( SDL_INIT_EVERYTHING );
SDL_Quit();
return 0;
}
Compile command would be:
g++ -o myprogram mysource.cpp -lSDL
How can I 'include' SDL in my executable so that another enduser can execute it at once (without installing SDL or even recompiling my source) ?
Try:
g++ -o myprogram mysource.cpp -Wl,-Bstatic \
$(sdl-config --static-libs) -Wl,-Bdynamic