I'm trying to take a Qt C++ project originally written for Windows and cross compile it for embedded Linux. Now this program compiles find and works on Windows, so this problem must be something OS specific (which I didn't think happend with Qt code) or configuration related, but I'm having a hard time tracking it down because I don't fully understand C++ syntax.
my make command:
arm-linux-gnueabihf-g++ -c -march=armv7-a -marm -mthumb-interwork
-mfloat-abi=hard -mfpu=neon -mtune=cortex-a8 -O2 -O3 -Wall -W -D_REENTRANT -DCHL80Net -DPHASE_TO_NEUTRAL -DCHL80NET -DCANLCD_BUILD -DQT_NO_DEBUG -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I../mkspecs/qws/linux-am335x-g++ -I. -I../include/QtCore -I../include/QtGui -I../include/QtXml -I../include -I. -IApp -IApp/Model/ModelSim -IApp/Model -I. -IPages -IApp/GUI/Widgets -IApp/GUI/Pages -IApp/GUI -IApp/GUI/Widgets -IApp/GUI/Pages/Util -IApp/GUI/Pages -IApp/Log4Qt -I.obj -o .obj/CanInterface.o App/Can/CanInterface.cpp
The error:
App/Can/CanInterface.cpp: In member function ‘void
CanInterface::closeConnection()’: App/Can/CanInterface.cpp:68:5:
error: ‘::close’ has not been declared make: * [.obj/CanInterface.o]
Error 1
Here's the line of code in question:
void CanInterface::closeConnection()
{
::close(m_socket);
m_socket = -1;
I thought this didn't look like valid code at all at first, but I don't really know C++ so I had to do a little research, it seems like this ::function() syntax is to ensure resolution occurs from the global namespace instead of the local one.
So what I'm trying to find out is what namespace should have declaired this close() function. If my understanding of this code is correct I don't need to look in the CanInterface class for the undeclaired function, but it's parent class?
In the header file for the CanInterface class I found this:
class CanInterface : public QObject
{
Q_OBJECT
which I think means that it inharents from a QObject class. So:
Am I on the right track?
How do I know if I need to look at the QObject class for the missing close() function or if I need to keep going up? Does ::close somehow tell me how many levels of nested classes I need to search through?
Any other ideas or tips for further investigating this?
You are correct, in that ::some_function() calls a function from the global scope.
This includes all C library or system functions. You can lookup global functions on a *nix system with man, e.g.
man close
which gives on my Ubuntu
NAME
close - close a file descriptor
SYNOPSIS
#include <unistd.h>
int close(int fd);
So, to fix your compile error, you must include unistd.h somewhere in your C++ source or in a surrounding header file.
You can get the same information, when you google for man close, e.g. http://linux.die.net/man/2/close
C++ encapsulates names in namespaces to avoid naming collisions. It's somewhat analagous to the C practice of prepending a prefix specific to a library to the names of functions in that library, e.g., my_library_foo() in C might be called my_library::foo() in C++. When :: appears at the beginning of a name, it means that name is fully qualified: it is looked up beginning from the global namespace instead of the current/enclosing namespace, much like with absolute (/etc/passwd/) vs. relative (foo/bar) file names.
So the name ::close is intended to resolve to the close function declared in the global namespace, the one which would be put there by including <unistd.h> on a POSIX system.
Related
I'm working in a big project with Qt/MinGW/Windows. Recently I changed the places of some of my source files and recompile them, and after some corrections, I began to receive messages such as
(.idata$5+0x0):-1: error: multiple definition of `_imp___ZN9QwtThermo16staticMetaObjectE'
This happens regarding two classes: QwtThermo and QwtPlotPicker in a code where previously there was no such error (remember: I just changed the places of the files in the base folder to some subfolders; no code changed (as far as I remember) and notice that many other Qwt classes are also included and normally used without any compile error; this are the only two ones that are giving me problems).
Now "multiple definition of" is a common error in C++ and I already know how one would normally solve it (many threads, including in StackOverflow, talk about it): one should only declare things in header files while defining them in the .cpp files.
Unfortunately this doesn't seem to be a viable solution this time. Here is what is going on:
I did a research regarding where this header was being included, and I found no problems. As I sad, it used to compile nicely before.
The problem would only occur with QwtPlotPicker if I create a subclass of it (doesn't matter if I use it). If I only declare the name of the subclass in the header and define it in the .cpp, then I'm able to compile, but as soon as I start using it (with a member pointer declared in the header), then the compile error "undefined reference for 'vtable for Picker'" appears. So declaring the class in the header and define it in the .cpp doesn't actually help;
With QwtThermo, if I include the file in the header and ONLY declare a pointer to it (no subclass), then the error start appearing already. This is solved if I only declare the QwtThermo class in my project's header and include QwtThermo's own header in the .cpp file; this way I'm able to declare a member pointer to it and also instantiate the pointer with "new" in the .cpp file inside it's parent class, but as soon as I start using it by calling its methods, the "multiple definition of" starts appearing again.
So as you may see, it would seem that this time it's not just a matter of "declare in the header and define it in the .cpp"; something more is going on. :T
So what could be wrong? Sorry not posting any code, but believe me that everything of interesting of it that could be seen was written already; the only change of posting the code would be by copying more then 5000 lines ^^
I'm glad for any help you can give me :)
Thanks,
EDIT: Here is the code from Qt Creator's "Compile Output":
g++ -c -pipe -fno-keep-inline-dllexport -g -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -DMGENERALDEFINES_GUI -DMGENERALDEFINES_DEBUG -DMGENERALDEFINES_GENERAL -DQWT_INCLUDED -DDEBUG -DRELEASE -DQT_NO_DEBUG -DQT_NO_DEBUG_OUTPUT -DQT_PRINTSUPPORT_LIB -DQT_MULTIMEDIA_LIB -DQT_WIDGETS_LIB -DQT_SQL_LIB -DQT_NETWORK_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I. -I"MSHARE_REPO" -I"MSHARE_COMMON" -I"C:\Qt\Qwt-6.1.0\include" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include\QtPrintSupport" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include\QtMultimedia" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include\QtWidgets" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include\QtSql" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include\QtNetwork" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include\QtGui" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\include\QtCore" -I"build\moc" -I"build\ui" -I"C:\Qt\Qt5.2.1\5.2.1\mingw48_32\mkspecs\win32-g++" -o build\obj\moc_mainwindow.o build\moc\moc_mainwindow.cpp
g++ -Wl,-subsystem,windows -mthreads -o debug\mShare.exe object_script.mShare.Debug -lglu32 -lopengl32 -lgdi32 -luser32 -lmingw32 -lqtmaind "D:/Minhas obras/Softwares/mShare Project/mShare/SMTPEmail.dll" -lpsapi C:/Qt/Qwt-6.1.0/lib/qwtd.dll "D:/Minhas obras/Softwares/mShare Project/mShare/../../Classes/mLogger/build/debug/mLogger.dll" "D:/Minhas obras/Softwares/mShare Project/mShare/../mShareLib/build/debug/mShareLib.dll" C:/Qt/Qwt-6.1.0/lib/qwt.dll "D:/Minhas obras/Softwares/mShare Project/mShare/../../Classes/mLogger/build/release/mLogger.dll" "D:/Minhas obras/Softwares/mShare Project/mShare/../mShareLib/build/release/mShareLib.dll" -LC:\Qt\Qt5.2.1\5.2.1\mingw48_32\lib -lQt5PrintSupportd -lQt5Multimediad -lQt5Widgetsd -lQt5Sqld -lQt5Networkd -lQt5Guid -lQt5Cored .\build\obj\icone_res.o
d000171.o:(.idata$5+0x0): multiple definition of `_imp___ZN13QwtPlotPicker16staticMetaObjectE'
d000022.o:(.idata$5+0x0): first defined here
d000171.o:(.idata$6+0x0): multiple definition of `_nm___ZN13QwtPlotPicker16staticMetaObjectE'
d000022.o:(.idata$6+0x0): first defined here
d000172.o:(.idata$5+0x0): multiple definition of `_imp___ZN9QwtThermo16staticMetaObjectE'
d000102.o:(.idata$5+0x0): first defined here
d000172.o:(.idata$6+0x0): multiple definition of `_nm___ZN9QwtThermo16staticMetaObjectE'
Makefile.Debug:246: recipe for target 'debug\mShare.exe' failed
d000102.o:(.idata$6+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
mingw32-make[1]: [debug\mShare.exe] Error 1 (ignored)
I could be wrong as I don't know what your code looks like, but it sounds like it is compiling these classes multiple times? If you don't already add #pragma once to the top of your header files to ensure only one compiled copy of that class. Hope you find a solution soon!
A few things could be of interest here. I notice that your error talks about static keyword. Your code possibly declares static variable and initializes it at many places.
Another reason could be that you are not using ifndef or pragma once to ensure that only one instance is being initialized for all classes + headers.
You need to put something like this in your headers:
#ifndef MY_HEADER_H
#define MY_HEADER_H
... // all of your code
#endif
Well, after some try-and-retry I managed to find WHERE the problem lies - but not how exactly to SOLVE it. The problem exists because in my Qt .pro file I tried to configure some specific configurations for debug compilation and others for release compilation, but for some reason the system is not making distinction between those two configurations. To be more specific, the following code should work:
win32 {
LIBS += -lpsapi
debug {
LIBS += C:/Qt/Qwt-6.1.0/lib/qwtd.dll \
$${MLOGGER}/build/debug/mLogger.dll \
$${MSHARE_LIB}/build/debug/mShareLib.dll
DEFINES += DEBUG
}
release {
LIBS += C:/Qt/Qwt-6.1.0/lib/qwt.dll \
$${MLOGGER}/build/release/mLogger.dll \
$${MSHARE_LIB}/build/release/mShareLib.dll
DEFINES += RELEASE \
QT_NO_DEBUG \
QT_NO_DEBUG_OUTPUT
}
} # win32
since in the Qt Assistant files regarding qmake, such is the way to write such configurations with a secondary scope:
win32 {
debug {
CONFIG += console
}
}
I noticed that, after commenting the "release" part, the problem vanished and I was capable of compiling without errors; if the comment was erased, the problem returns. At the same time, while uncommented, I was able to notice that the release defines were defined despite the fact that I was in a debug compilation 'state'. And finally this was a code that didn't exist prior to my changes.
The only question that arrives is: why isn't qmake being capable of interpreting the .pro file correctly? But I'll put that in another question.
Thanks for the help,
I am writing a Rcpp code that include two library RcppArmadillo and trng4. However, when I include two header files (RcppArmadillo.h and trng/gamma_dist.hpp) it gives compilation error.
trng/special_functions.hpp:47:39: error: declaration of ‘float lgammaf(float) throw ()’ has a different exception specifier
extern "C" float lgammaf(float) throw();
include-fixed/math.h:476:14: error: from previous declaration ‘float lgammaf(float)’
extern float lgammaf(float);
Full compilation options are
-fopenmp -lgomp -DUSE_R -DNDEBUG -DDISABLE_SINGLE -DNTHROW -DDISABLE_FIO -I/usr/local/include -I"/Users/avi/Library/R/3.0/library/Rcpp/include" -I"/Users/avi/Library/R/3.0/library/RcppArmadillo/include" -fPIC -pipe -std=c++0x -Wall -pedantic -c
Seems like the lgammaf is declared in both header files. I tried using -E with g++ option but that give ld warning " .o, file was built for unsupported file format" and give error function in not available in .Call when I try it to after loading in R. What am I doing wrong?
Perhaps out of context I am using trng4 package to develop a thread gibbs sampler (in openmp) that sample from gamma distribution. I am currently running this MacOS. But eventual it will run in linux server.
It sounds like you do have a problem between Armadillo and trng4. Maybe you should try to, if possible, separate your interface so that you do not need to include from both in the same file.
Someone can correct me if I'm wrong, but I believe you prevent this issue by using #ifndef in each header file so that it's not defined a second time even if it's included a second time. But I guess these aren't your files are they...?
#ifndef __your_unique_header_name__
blah blah
#endif
Follow up to my answer to this question: SIGSEGV on declaration
In this question the questioner had a problem with a segmentation fault on some simple code. As it turned out it didn't even compile for me and others. GCC (4.8.1) gave an error due to redeclaration of a variable with name bsearch, which happens to be identical to a function name in std. This resulted in a clash as the code also used using namespace std;. Since the questioner accepted my answer I guess this was somehow related with the runtime error (though strange).
The questioner however said the code would compile fine on codeblocks and others confirmed this. bsearch should be defined in cstdlib, but the code did not include it.
It turned out that gcc includes cstdlib if iostream is included anyway as one can see from the trace:
g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c++0x -Wall -Wextra -pedantic -MMD -MP -MF"src/Test.d" -MT"src/Test.d" -o "src/Test.o" "../src/Test.cpp"
../src/Test.cpp:14:27: error: ‘long long int bsearch’ redeclared as different kind of symbol
long long int bsiter,bsearch;
^
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/cstdlib:72:0,
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/ext/string_conversions.h:41,
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/bits/basic_string.h:2815,
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/string:52,
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/bits/locale_classes.h:40,
src/subdir.mk:18: recipe for target 'src/Test.o' failed
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/bits/ios_base.h:41,
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/ios:42,
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/ostream:38,
from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/iostream:39,
from ../src/Test.cpp:1:
/usr/include/stdlib.h:754:14: error: previous declaration of ‘void* bsearch(const void*, const void*, size_t, size_t, __compar_fn_t)’
extern void *bsearch (const void *__key, const void *__base,
^
make: *** [src/Test.o] Error 1
It does so only in c++0x and c++11 mode.
Is this structure of includes required, allowed or defined at all in the c++ standards? On cplusplus.com I can find that iostream will include ostream and ios, but there is no information about includes further down.
The C++ standard mandates in certain places that another header has to be included (e.g., <iostream> has to include <istream> and <ostream>). Otherwise, the standard allows headers to be included and to make declaration available which are not required to become available from a specific header.
I'd think it would be useful to have a system of headers which make exactly those declarations available that are required to be made available but I'm not aware of that being available. These headers could be without actual definitions and would only be used to verify that all necessary headers are included. It might be better to have the headers be part of an actual implementation but that would make the declarations quite a bit more complex.
I build a C++ project of mine using clang++, using the following command line command (split into lines):
clang++
-std=c++11
-W -Wall -Wextra -pedantic -Wno-newline-eof -Werror
-O4
-I<dirs>
-L<dirs>
-l<libs>
-framework <frameworks>
-D <defs>
-o <filename>
<files>
However, when I run strings <filename>, several class names show up, despite the -O4 in the command line. I've tried -Wl,-s which should tell llvm to strip all symbols, but that doesn't remove these.
The class names that show up seem to all have one thing in common: they have a vtable. One of these classes is :
class MyClass {
public:
virtual void myFunc() = 0;
};
It shows up as the symbol :
N9namespace7MyClassE
I don't like it that my namespace and class names show up in the final file. How do I strip these? My binary is a command line utility, so only the main function should be exported.
Even after supplying -fno-rtti (as suggested by #n.m.), some names still remain, such as :
__ZN15MyClassInstance6myFuncEv
(MyClassInstance being a subclass of the MyClass above)
Additionally, even the names of global variables are in the binary.
I solved this by supplying the clang argument -fno-rtti, which disables RTTI, a C++ feature I don't use anyway.
[edit]
It looks like -O4 does not imply strip, and the last few references to my class names can be removed by executing strip.
I just picked up an old project and I'm not sure what the following error could mean.
g++ -o BufferedReader.o -c -g -Wall -std=c++0x -I/usr/include/xmms2 -Ijsoncpp/include/json/ -fopenmp -I/usr/include/ImageMagick -I/usr/include/xmms2 -I/usr/include/libvisual-0.4 -D_GNU_SOURCE=1 -D_REENTRANT -I/usr/include/SDL -DQT_CORE_LIB -DQT_GUI_LIB -DQT_SCRIPT_LIB -DQT_SHARED -I/usr/include/QtCore -I/usr/include/QtGui -I/usr/include/QtScript BufferedReader.cpp
In file included from BufferedReader.cpp:23:
/usr/include/string.h:36:42: error: missing binary operator before token "("
In file included from /usr/lib/gcc/i686-redhat-linux/4.4.3/../../../../include/c++/4.4.3/cwchar:47,
from /usr/lib/gcc/i686-redhat-linux/4.4.3/../../../../include/c++/4.4.3/bits/postypes.h:42,
from /usr/lib/gcc/i686-redhat-linux/4.4.3/../../../../include/c++/4.4.3/iosfwd:42,
from /usr/lib/gcc/i686-redhat-linux/4.4.3/../../../../include/c++/4.4.3/ios:39,
from /usr/lib/gcc/i686-redhat-linux/4.4.3/../../../../include/c++/4.4.3/istream:40,
from /usr/lib/gcc/i686-redhat-linux/4.4.3/../../../../include/c++/4.4.3/sstream:39,
from BufferedReader.cpp:24:
At line 24 of BufferedReader.cpp is #include <string.h>. I've tried it with just <string> but get the same thing. Any clue?
Here's the snippet of code from string.h
/* Tell the caller that we provide correct C++ prototypes. */
#if defined __cplusplus && __GNUC_PREREQ (4, 4) //line 36
# define __CORRECT_ISO_CPP_STRING_H_PROTO
#endif
Does that mean __GNUC_PREREQ isn't defined?
Edit:
Changing -Ijsoncpp/include/json/ to Ijsoncpp/include stopped the errors. I noticed I was including <json/json.h>.
I'm about to switch to JsonGlib though, which is the reason I pulled the project up again. So it's all good. :)
Try #include <cstring>.
Strange errors like this usually happen in the include file before the one you included. This is often when a class in a header file does not end with a semicolon (;). Check which file in included on line 22 of BufferedReader.cpp and check that file for syntax errors towards the end.
The reason for this peculiar behavior is probably a file name collision: string.h includes <features.h> which should usually resolve to /usr/include/features.h or similar. But the json/ dir also contains a features.h, so if it comes first in the include path, that will be included instead, although it probably serves a different purpose than string.h needs.