poco library linking issue in Solaris platform - c++

I have build the poco library in solaris. My system configuration is SunOS solaris2 5.10 Generic_144488-07 sun4v sparc SUNW,SPARC-Enterprise-T1000. When I tried to run the sample which was provided along with the sample I am able to build and run the sample application. But when I wrote a seperate program and tried to link with poco library, I am getting the following error
ld: fatal: file /74bkp/ramesh/poco-1.4.7p1/lib/SunOS/sun4v/libPocoXML.so: wrong ELF class: ELFCLASS32
ld: fatal: file /74bkp/ramesh/poco-1.4.7p1/lib/SunOS/sun4v/libPocoFoundation.so: wrong ELF class: ELFCLASS32
I use the following command to compile the source
g++ -I/74bkp/ramesh/poco-1.4.7p1/XML/include -I/74bkp/ramesh/poco-1.4.7p1/Foundation/include -L/74bkp/ramesh/poco-1.4.7p1/lib/SunOS/sun4v DOMParser.cpp -lPocoXML -lPocoFoundation -m64
Can some one please give a clue. I could not move further.
regards,
Sam Mouli

You have built 32-bit binaries of Poco, therefore you cannot link them to 64-bit binaries.
Remove the -m64 option from the compiler call and optionally add -m32, then it should work. Alternatively, build 64-bit binaries of Poco and link to them.

Related

Wine cannot load DLLs even though the directory is added to PATH

I am trying to cross-compile Windows software on Linux using mingw32-w64 and running it with wine. However wine cannot load the libstdc++-6.dll library file. I searched online and found out that you have to put the directory that contains the DLL file into the path registry. In my case, that directory is Z:\bin\i686-w64-mingw32\bin.
Then I tried to run the compiled file by using wine executable.exe and the output is:
0100:err:module:import_dll Loading library libstdc++-6.dll (which is needed by L"Z:\\home\\sunnymonster\\dev\\c++\\opengl-tests\\cmake-build-debug\\opengl_tests.exe") failed (error c000007b).
0100:err:module:LdrInitializeThunk Importing dlls for L"Z:\\home\\sunnymonster\\dev\\c++\\opengl-tests\\cmake-build-debug\\opengl_tests.exe" failed, status c0000135
I have verified that I am using the correct wine prefix.
Additional information:
Linux distro: Manjaro Linux 21.2.5
Linux kernel: 5.16.14-1
There're multiple approaches. First, let's formalize the problem:
$ cat test.cpp
#include <iostream>
int main() { std::cout << "hello" << std::endl; }
$ i686-w64-mingw32-g++ test.cpp -o a && WINEDEBUG=-all,err+module wine ./a.exe
0024:err:module:import_dll Library libgcc_s_dw2-1.dll (which is needed by L"Z:\\tmp\\a.exe") not found
0024:err:module:import_dll Library libstdc++-6.dll (which is needed by L"Z:\\tmp\\a.exe") not found
0024:err:module:LdrInitializeThunk Importing dlls for L"Z:\\tmp\\a.exe" failed, status c0000135
Solutions:
Link the core libraries statically:
$ i686-w64-mingw32-g++ test.cpp -o a -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic
$ WINEDEBUG=-all,err+module wine ./a.exe
hello
Use WINEPATH env. variable to tell wine the additional paths to load dlls from. In the example I pass it the location with mingw dlls that wine complains about. It may be different on your system, you might find it by asking package manager to list files in mingw-g++/gcc packages (whatever it's called on your system). Multiple paths should be separated by semicolon.
$ i686-w64-mingw32-g++ test.cpp -o a
$ WINEDEBUG=-all,err+module WINEPATH=/usr/i686-w64-mingw32/sys-root/mingw/bin/ wine ./a.exe
hello
Install a Windows version of MinGW, and then use it to compile the app. However, from what I remember, if you want to distribute the executable produced, you still need to either statically link against MinGW libs, or provide them together with the binary. So the only difference to point 1 is that the binary should work under your WINEPREFIX with no modifications.
Using wineg++. I mention it solely for completeness, I think it's the least useful solution. It produces a Linux file, which in itself might be okay, one could use that for debugging. However, in my tests, I didn't manage to makewineg++ link against a dll, even though mingw links to the same dll without a problem. It seems to link against .so files instead, even though the application you build with it can load .dll files dynamically. Odd utility.
$ wineg++ test.cpp -o a
$ WINEDEBUG=-all,err+module wine ./a.exe
hello

Xcode static library seems to change architecture on build

Here's a bit of background before I dive into the question. My ultimate goal is to compile the source of a c++ static library for the architectures arm64, armv7, armv7s, i386, and x86_64, and then package the libraries into a fat library so that I can use them during iOS development. This will enable me to use the simulator and a device with the same library.
Here's my issue. I'm trying to test the i386 version of the library, on it's own, using the iPhone 5 simulator. I compiled the static library for i386 as follows:
./configure --enable-utf8-only --disable-shared --host=i386-apple-darwin LDFLAGS="-L." CC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" CXX="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++"
then
make CXXFLAGS="-arch i386 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.3.sdk" CCFLAGS="-arch i386 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.3.sdk"
This resulted in my static library, libtest.a. I then ran the follow to verify the libraries architecture
jamespc:Desktop $ lipo -info libtest.a
input file libtest.a is not a fat file
Non-fat file: libtest.a is architecture: i386
Everything seemed to look good so far. Next I added the library to my Xcode project and tried to build the project. When building the project I get the following warning and error.
ld: warning: ignoring file
/Users/cleandev/Library/Developer/Xcode/DerivedData/MyProject-hjtfdovfmdsubkejojqknkmqkzps/Build/Products/Debug-iphonesimulator/libtest.a,
file was built for archive which is not the architecture being linked (i386):
/Users/cleandev/Library/Developer/Xcode/DerivedData/MyProject-hjtfdovfmdsubkejojqknkmqkzps/Build/Products/Debug-iphonesimulator/libtest.a
Undefined symbols for architecture i386:
...
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Perplexed by error I ran lipo on my static lib again, this time using the path listed in the warning, in the derived data folder.
jamespc:Debug-iphonesimulator $ lipo -info libtest.a
input file libtest.a is not a fat file
Non-fat file: libtest.a is architecture: x86_64
I'm confused as to why the library appears to have a different architecture associated with it when I take a look at it in the derived data.
Is the way I'm compiling the static library wrong?
Is there something I might be doing wrong in my Xcode build settings?
Thank you for taking the time to read my question
I guess the framework was not compiled for the iOS Simulator's architecture, which is i386. Xcode only compiles a framework for the target architecture.
Please follow this tutorial: http://www.raywenderlich.com/65964/create-a-framework-for-ios
It may help.

Statically linking matio library using g++

How do you statically link matio, a library for reading mat-files, mainly used by matlab and octave into an executable?
If the file main.cpp holds matio functionality the compiler call
g++ -o main main.cpp -Imatio/include matio/lib/libmatio.a
fails with a bunch of error messages like: undefined reference to `inflateEnd'. This can be resolved by also adding zlib to the compiler call:
g++ -o main main.cpp -Imatio/include matio/lib/libmatio.a -lz
Now the error messages differ with something like undefined reference to `__intel_sse2_strlen'. So it appears that the zlib library is necessary for the comilation.
I now have the following questions:
What do you need to do to statically link the matio library in an executable?
Why do I need to add the zlib library even though I configured and compiled matio with ./configure --without-libz?
To build matio without zlib you apparently need to invoke configure with
./configure --with-zlib=no
(Checked this from configure.ac and config/matio_zlib.m4.)
In case you want to build matio with icc, Intel's developer pages tell that __intel_sse2_strlen is defined in libirc.a on Linux and libirc.lib on Windows.
To compile matio with the gcc do
./configure --with-zlib=no CC=gcc
afterwards, the matio library is statically linkable with the call posted in the question

How to recompile with -fPIC

I was trying to reinstall my ffmpeg, following this guide, on my ARM Ubuntu machine. Unfortunately, when I compile a program which uses this lib I get the following failure:
/usr/bin/ld: /usr/local/lib/libavcodec.a(amrnbdec.o): relocation R_ARM_MOVW_ABS_NC against `a local symbol' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/libavcodec.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
Now I would like to recompile it with -fPIC like the compiler is suggesting but I have no idea how. Any help is appreciated.
Briefly, the error means that you can't use a static library to be linked w/ a dynamic one.
The correct way is to have a libavcodec compiled into a .so instead of .a, so the other .so library you are trying to build will link well.
The shortest way to do so is to add --enable-shared at ./configure options. Or even you may try to disable shared (or static) libraries at all... you choose what is suitable for you!
Have a look at this page.
you can try globally adding the flag using: export CXXFLAGS="$CXXFLAGS -fPIC"
I had this problem when building FFMPEG static libraries (e.g. libavcodec.a) for Android x86_64 target platform (using Android NDK clang). When statically linking with my library the problem occured although all FFMPEG C -> object files (*.o) were compiled with -fPIC compile option:
x86_64/libavcodec.a(h264_qpel_10bit.o):
requires dynamic R_X86_64_PC32 reloc against 'ff_pw_1023'
which may overflow at runtime; recompile with -fPIC
The problem occured only for libavcodec.a and libswscale.a.
Source of this problem is that FFMPEG has assembler optimizations for x86* platforms e.g. the reported problem cause is in libavcodec/h264_qpel_10bit.asm -> h264_qpel_10bit.o.
When producing X86-64 bit static library (e.g. libavcodec.a) it looks like assembler files (e.g. libavcodec/h264_qpel_10bit.asm) uses some x86 (32bit) assembler commands which are incompatible when statically linking with x86-64 bit target library since they don't support required relocation type.
Possible solutions:
compile all ffmpeg files with no assembler optimizations (for ffmpeg this is configure option: --disable-asm)
produce dynamic libraries (e.g. libavcodec.so) and link them in your final library dynamically
I chose 1) and it solved the problem.
Reference: https://tecnocode.co.uk/2014/10/01/dynamic-relocs-runtime-overflows-and-fpic/
After the configure step you probably have a makefile. Inside this makefile look for CFLAGS (or similar). puf -fPIC at the end and run make again. In other words -fPIC is a compiler option that has to be passed to the compiler somewhere.
If you're building a shared library but need to link with static libavcodec add linker flags:
-Wl,-Bsymbolic
In case of cmake:
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic")
I hit this same issue trying to install Dashcast on Centos 7. The fix was adding -fPIC at the end of each of the CFLAGS in the x264 Makefile. Then I had to run make distclean for both x264 and ffmpeg and rebuild.
In addirion to the good answers here, specifically Robert Lujo's.
I want to say in my case I've been deliberately trying to statically compile a version of ffmpeg. All the required dependencies and what else heretofore required, I've done static compilation.
When I ran ./configure for the ffmpeg process I didnt notice --enable-shared was on the commandline. Removing it and running ./configure is only then I was able to compile correctly (All 56 mbs of an ffmpeg binary). Check that out as well if your intention is static compilation
I'm building ffmpeg 5.1.2 on CentOS7 with gcc4.8.5.
As mentioned in ${ffmpegRoot}/doc/platform.texi:
1)configure with option
"--enable-pic"
2)add the following option to your project LDFLAGS
"-Wl,-Bsymbolic"
Before compiling make sure that "rules.mk" file is included properly in Makefile or include it explicitly by:
"source rules.mk"

What architecture to use in OSX?

I finished installing boost mpi, with openmpi as the underlying implementation, and trying to compile a simple program to test.
I compile my boost mpi library as follow:
./bjam toolset=darwin architecture=x86 address-model=32 install
I compiled my mpi program with following:
mpic++ -I/opt/boost_1_46_1/include mpi_play.cpp -L/opt/boost_1_46_1/lib -lboost_mpi -lboost_serialization
But it says
ld: warning: in /opt/boost_1_46_1/lib/libboost_mpi.dylib, file was built for i386 which is not the architecture being linked (x86_64)
I knew that the bjam command that I used was for building the library in i386. This is what I need to do for using boost thread library in XCode. So, now I am not sure what is the best approach to make all these boost libraries and mpi libraries work in mac.
If you want i386 builds, pass -arch i386 to mpic++, which should pass it on to the underlying compiler.
Pass address-model=64 to the bjam command line to create an x86_64 MPI library you can link against your code. Or compile your code as x86 (-arch i386) to use the already-x86 MPI library you previously compiled.