Mixing Qt and boost causes compilation error with "check" keyword - qt

I am using Qt in a project and am now trying to include another project that uses boost.
I have added no_keywords to my config in the qt project file to avoid collision between the signal and slots functionality that is present in boost and Qt. But now I get a compilation error which seems to stem from double definition of a function called "check". Is there some way to avoid this?
An example is has_postfix_operator.hpp (line 141):
static ::boost::type_traits::yes_type check(has_operator); // this version is preferred when operator exists
Apparently there is a "check" defined in Qt.
I'm using Qt4.7 and boost 1.48. Running MacOSX 10.6.8

You should also look at /usr/include/AssertMacros.h, which defines a macro named "check" - that could be the cause of your problem.
To check this, add -d __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES=0 to your compiler flags.
If that works, that was your problem.
Here's a comment from that file:
Prior to Mac OS X 10.6 the macro names used in this file conflicted
with some user code, including libraries in boost and the proposed C++
standards efforts, and there was no way for a client of this header to
resolve this conflict. Because of this, most of the macros have been
changed so that they are prefixed with
__ and contain at least one capital letter, which should alleviate the current and future conflicts. However, to allow current sources to
continue to compile, compatibility macros are defined at the end with
the old names. A tops script at the end of this file will convert
all of the old macro names used in a directory to the new names.
Clients are recommended to migrate over to these new macros as they
update their sources because a future release of Mac OS X will remove
the old macro definitions ( without the double-underscore prefix ).
Clients who want to compile without the old macro definitions can
define the macro
__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES to 0 before this file is included.

Related

How do i analyse a complex project like open62541?

I am a student and currently trying to analyse the reference implementation for the OPC Ua protocol in C with cppcheck and frama-c. My goal is not to do very dedicated testing but more some general/basic tests to see if there are some obvious issues with the code.
The project can be found here
I am running a VM with Ubuntu 19.10 and Frama-C version 20.0 (Calcium).
The steps i performed are as follows:
git clone https://github.com/open62541/open62541.git
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 /path/to/source
frama-c -json-compilation-database /path/to/compile_commands.json
Until now everything works as expected and there are no Errors.
However now i am having trouble understanding how to continue.
Do i need to do my analysis on all files seperately or is it possible to throw in the whole project like with cppcheck?
How would i approach this in general? Do i need to to analyse all files step by step?
For example i tried:
frama-c -json-compilation-database /path/to/compilation_commands.json -val /path/to/open62541/src/
which returns:
[kernel] Parsing src (with preprocessing)
gcc: warning: /path/to/open62541/src/: linker input file unused because linking not done
[kernel] User Error: cannot find entry point `main'.
Please use option `-main' for specifying a valid entry point.
[kernel] Frama-C aborted: invalid user input.
So apperantly frama-c requires an entry point, however i do not know which entry point i need to specify.
Any help regarding this is much appreciated.
I apologize for my lack of understanding. This is my first project of this kind and i am a little bit overwhelmed by frama-c and the complexity of the open62541 project.
Do i need to do my analysis on all files separately or is it possible to throw in the whole project like with cppcheck?
Frama-C can actually analyze the entire project in one go provided multiple files do not define the same symbols. See http://blog.frama-c.com/index.php?post/2018/01/25/Analysis-scripts%3A-helping-automate-case-studies, paragraph "Setting sources and testing parsing":
The list of source files to be given to Frama-C can be obtained from the compile_commands.json file. However, it is often the case that the software under analysis contains several binaries, each requiring a different set of sources. The JSON compilation database does not map the sources used to produce each binary, so it is not always possible to entirely automate the process.
The key point in your case is that the compilation_commands.json instructs Frama-C on how to parse each file, but you must still supply the files you want to see parsed yourself. With your current command-line, Frama-C tries to interpret /path/to/open62541/src/ as a file (and fails), and has no other file to parse. This is why you get the error User Error: cannot find entry point 'main'.
Thus, you must specify the files you want to parse on the command-line. This can be done in two ways:
manually, by extracting the files referenced in compilation_commands.json
automatically, using the frama-c-script helpers, described at http://blog.frama-c.com/index.php?post/2019/01/16/Setting-up-an-analysis-with-the-help-of-frama-c-script
I used the first approach, but I suggest you use the second, as frama-c-script is very helpful to start a first analysis.
Once you have done this listing step, you will encounter at least three more problems:
Frama-C will choke on # include <sys/param.h>, because this file is not present in the standard C library bundled with Frama-C. Either remove this include in the source files, or add an empty sys/param.h somewhere
some .c files refer to generated headers that are not present in the git repo of open62541. So you will need to compile the repo to get those headers before launching Frama-C.
Frama-C will also choke on the definition of the macro UA_STATIC_ASSERT in architecture_definitions.h. I did not investigate whether one of the definitions was accepted, and I simply defined it to the empty macro.
After all this, you should be good to go.

ld skips shared library

I am trying to deploy a Qt application by providing the Qt libraries as shared libraries in a directory and pointing ld to them using LD_LIBRARY_PATH. This works for all Qt libraries such as libQt5Network or libQt5Gui, but not for libQt5Core which is somehow not found and the system version is used instead.
Using LD_DEBUG=all I can see that ld tries the file which exists, but skips it
3705: file=libQt5Core.so.5 [0]; needed by ./app.bin [0]
3705: find library=libQt5Core.so.5 [0]; searching
3705: search path=/home/user/app/lib:/usr/lib64/tls/x86_64/x86_64:/usr/lib64/tls/x86_64:/usr/lib64/tls/x86_64:/usr/lib64/tls:/usr/lib64/x86_64/x86_64:/usr/lib64/x86_64:/usr/lib64/x86_64:/usr/lib64 (LD_LIBRARY_PATH)
3705: trying file=/home/user/app/lib/libQt5Core.so.5 <- this file exists
3705: trying file=/usr/lib64/tls/x86_64/x86_64/libQt5Core.so.5
3705: trying file=/usr/lib64/tls/x86_64/libQt5Core.so.5
3705: trying file=/usr/lib64/tls/x86_64/libQt5Core.so.5
3705: trying file=/usr/lib64/tls/libQt5Core.so.5
3705: trying file=/usr/lib64/x86_64/x86_64/libQt5Core.so.5
3705: trying file=/usr/lib64/x86_64/libQt5Core.so.5
3705: trying file=/usr/lib64/x86_64/libQt5Core.so.5
3705: trying file=/usr/lib64/libQt5Core.so.5
Both libQt5Core.so.5 and app.bin are 64 bit elf.
Is there any way to find out why ld rejects the file?
Solution is here: https://github.com/Microsoft/WSL/issues/3023
The library contains an ABI note which can be removed using strip to make ld accept the library.
The other answer is correct. Just in case the link there gets broken, here's what happened in my case and how I fixed it.
I was running an older kernel, version 3.10, on a system where Qt5 was installed. One of the libraries – namely, libQt5Core.so.5.11.0, has an ELF section .note.ABI-tag, which specifies that the library was compiled for kernel 3.17.0. Presence of this section can be seen via e.g.
objdump -sj .note.ABI-tag /path/to/library.so
And the fact that it's compiled for a newer kernel is revealed by file, with the hard to notice note, "for GNU/Linux 3.17.0", near the end of its output. In my case it was:
/opt/qt511/lib/libQt5Core.so.5.11.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.17.0, BuildID[sha1]=df5f7e933899d1ff629145ab7ca35b2f9bc41843, stripped
So the fix in my case was to run
strip --remove-section=.note.ABI-tag /path/to/library.so
which removed this section and allowed the library to load.
Beware though, that if you do this, you explicitly break the assumptions the library build system may have used, so things may break. In my case they didn't, though.

Compiling haskell module Network on win32/cygwin

I am trying to compile Network.HTTP (http://hackage.haskell.org/package/network) on win32/cygwin. However, it does fail with following message:
Setup.hs: Missing dependency on a foreign library:
* Missing (or bad) header file: HsNet.h
This problem can usually be solved by installing the system package that
provides this library (you may need the "-dev" version). If the library is
already installed but in a non-standard location then you can use the flags
--extra-include-dirs= and --extra-lib-dirs= to specify where it is.
If the header file does exist, it may contain errors that are caught by the C
compiler at the preprocessing stage. In this case you can re-run configure
with the verbosity flag -v3 to see the error messages.
Unfortuntely it does not give more clues. The HsNet.h includes sys/uio.h which, actually should not be included, and should be configurered correctly.
Don't use cygwin, instead follow Johan Tibells way
Installing MSYS
Install the latest Haskell Platform. Use the default settings.
Download version 1.0.11 of MSYS. You'll need the following files:
MSYS-1.0.11.exe
msysDTK-1.0.1.exe
msysCORE-1.0.11-bin.tar.gz
The files are all hosted on haskell.org as they're quite hard to find in the official MinGW/MSYS repo.
Run MSYS-1.0.11.exe followed by msysDTK-1.0.1.exe. The former asks you if you want to run a normalization step. You can skip that.
Unpack msysCORE-1.0.11-bin.tar.gz into C:\msys\1.0. Note that you can't do that using an MSYS shell, because you can't overwrite the files in use, so make a copy of C:\msys\1.0, unpack it there, and then rename the copy back to C:\msys\1.0.
Add C:\Program Files\Haskell Platform\VERSION\mingw\bin to your PATH. This is neccesary if you ever want to build packages that use a configure script, like network, as configure scripts need access to a C compiler.
These steps are what Tibell uses to compile the Network package for win and I have used this myself successfully several times on most of the haskell platform releases.
It is possible to build network on win32/cygwin. And the above steps, though useful (by Jonke) may not be necessary.
While doing the configuration step, specify
runghc Setup.hs configure --configure-option="--build=mingw32"
So that the library is configured for mingw32, else you will get link or "undefined references" if you try to link or use network library.
This combined with #Yogesh Sajanikar's answer made it work for me (on win64/cygwin):
Make sure the gcc on your path is NOT the Mingw/Cygwin one, but the
C:\ghc\ghc-6.12.1\mingw\bin\gcc.exe
(Run
export PATH="/cygdrive/.../ghc-7.8.2/mingw/bin:$PATH"
before running cabal install network in the Cygwin shell)

Cant use shared libraries in Qt project

I created a C++ library project in Qt creator. After building the project I have the libMylib.so, .so.1, .so.1.0, .so.1.0.0, Makefile and mylib.o files. I added the library headers to my other project and added the path to my .pro file like this:
LIBS += "/home/peter/Workspace/build-Libtester-Desktop-Release/libMyLib.so"
When building the application I don't get no such file error, but when running it I get this:
/home/peter/Workspace/build-Libtester-Desktop-Debug/Libtester: error while loading shared libraries: libMyLib.so.1: cannot open shared object file: No such file or directory
which I can't understand, because it's right there next to the .so which it seem to find, because when the path is wrong I get a no such file or directory error when trying to build the project.
Could someone explain what I'm missing here?
Thanks for your time.
Fortunately, your problem has nothing to do with both Qt and Qt Creator. The error simply boils down to how shared libraries are searched by LD for dynamic linking on Unix OS family.
Today, I've answered similar question, have a look, please. This question was asked in regard to Mac OS X. However, Linux and Mac OS X are the same in the context of your problem. I've provided additional explanation for Linux at the bottom, so pay attention to it. "it's right there next to the .so" - you seem to have Windows background if you make this assumption, but it is wrong for Unix OS family altogether (as stated in the answer too). If you have further questions, just ask.
You are adding the library incorrectly. You are doing:
LIBS += "/home/peter/Workspace/build-Libtester-Desktop-Release/libMyLib.so"
instead of:
LIBS += -L"/home/peter/Workspace/build-Libtester-Desktop-Release" -lMyLib
The first version works on windows, but not linux.
Basically, you create a library, which will be named "libMyLib.so", and then you specify the path to its folder, prepended by "-L" and then do "-lMyLib" at the end, note that it's not "-llibMyLib", but just "-lMyLib", despite the fact that the .so name is "libMyLib".
Look here: https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application for more info.

using a foreign library in sbcl - uffi or cffi?

I am an struggling with using a C++ library I have just sucessfully
compiled on ubuntu in sbcl.
I have tried to use the .h file parser 'ah2cl' but from the
documentation it is not clear if I require UFFI or CFFI (is there a
difference?). My attempts to use the dummy test library and the
dummy header file provided with 'ah2cl' have failed. I get a message
about a missing CALLBACK package from sbcl. But does sbcl not support
callback natively ?
Is there another .h file parser that I should use for this
kind of task ?
You might want to try CFFI's groveller, which parses header files to produce the corresponding CFFI bindings. BTW, UFFI is basically deprecated in favour of CFFI for a while now.

Resources