I'm trying to build the static libraries of Eclipse Paho MQTT C on a Raspberry Pi 3 B+. As a prerequisite it is necessary to have the static version of the OpenSSL library on the system.
First, I attempted to get it using the following commands:
git clone git://git.openssl.org/openssl.git
cd openssl
git checkout OpenSSL_1_1_1a
./config -static
sudo make install
This does produce a libssl.a File in /usr/local/lib. However, when I then try to build the static libraries of Paho using the following commands, it fails with the error below:
git clone https://github.com/eclipse/paho.mqtt.c.git
mkdir /tmp/build.paho
cd /tmp/build.paho
cmake -GNinja -DPAHO_WITH_SSL=TRUE -DPAHO_BUILD_STATIC=TRUE ~/paho.mqtt.c
ninja
/usr/bin/ld: /usr/local/lib/libssl.a(methods.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/libssl.a: error adding symbols: Bad value
The suggested solution to this problem in several Stackoverflow questions seems to be to build the static OpenSSL library with the shared flag: ./config shared -static
But even then, building of the static Paho libraries fails with the exact same error.
I should add that I did not have any troubles with this procedure on other hardware architectures. Could this problem be related to the Raspberry Pi in any way? How do I solve it?
CFLAGS=-fPIC ./config shared -static seems to have worked for OpenSSL. However, after building the static Paho MQTT C libraries, which finishes without any errors, there are no static libraries to be found anywhere.
If I then look in /usr/local/lib, I only find the dynamic .o libraries there, no static .a ones. Why is this not working on the Pi but worked perfectly fine on a different system?
Related
I'd like to build the TensorFlow Lite as C API static library (Linux Debian x64). The instructions state the following CMake workflow:
// get the sources
git clone https://github.com/tensorflow/tensorflow.git tensorflow_src
// create a build directory
mkdir tflite_build
cd tflite_build
// build the lib using CMake
cmake ../tensorflow_src/tensorflow/lite/c
cmake --build . -j
However, this builds the shared library libtensorflowlite_c.so.
What would be the recommended way to build static version of the C API lib? Does modifying the CMake config files require expert CMake knowledge or it could be achieved rather easy?
According to the TensorFlow Lite CMakeLists.txt file this should be rather easy. Add -DTFLITE_C_BUILD_SHARED_LIBS:BOOL=OFF to your CMake configuration step. That means, clear your build directory before doing any changes and rerun the CMake commands
cmake -S ../tensorflow_src/tensorflow/lite/c -DTFLITE_C_BUILD_SHARED_LIBS:BOOL=OFF
cmake --build . -j
Be sure to also add to your project a dependency to TF-lite and its dependencies (as mentioned here in its CMakeLists.txt) if they are not header only, as TF-lite does not provide a CMake config package (AFAIK) that otherwise would include these transitive dependencies.
I have two versions of libusb installed:
$ pkg-config --libs libusb
-lusb
$ pkg-config --libs libusb-1.0
-lusb-1.0
For a project I want to use the libusb-1.0 version, hence I have the following in my CMakeLists.txt:
pkg_check_modules(LIBUSB REQUIRED libusb-1.0)
However, the resulting variable that I use for linking ${LIBUSB_LIBRARIES} contains only usb, not usb-1.0. So basically I'm linking against the wrong library. Why is that so? What am I doing wrong?
Following the instructions to compile dlib using cmake (here) generates a static dlib library:
cd examples
mkdir build
cd build
cmake ..
cmake --build . --config Release
How can I instruct cmake to generate a shared (.so) library instead?
If you want to make a .so file then do this:
cd dclib/dlib
mkdir build
cd build
cmake -DBUILD_SHARED_LIBS=1 ..
make
sudo make install
On a unix system, that will install dlib system wide. This means installing the .so file and also the header files so you can compile programs with a command like g++ main.cpp -ldlib. Finally, on linux systems you will also need to run sudo ldconfig after installing any new shared libraries.
However, for most users, I would recommend using CMake as shown in the examples. That way would allow you to enable or disable debugging modes whenever you want and also makes distributing the project easier, both in source form and compiled form. For example, if you wanted to compile on windows then shared libraries are definitely not the way to go. Moreover, using CMake as shown in the examples will always work in a straightforward manner without any setup.
According to dlib/CMakeLists.txt, standalone (not from examples) building of dlib also creates shared library named dlib-shared:
mkdir shared_build # Build directory can be any
cd shared_build
cmake ..
cmake --build . --config Release
make install # Install library for make it acessible for others
For use this library in examples, you need to add definition of dlib library into your examples/CMakeLists.txt before include(../dlib/cmake).
examples/CMakeLists.txt:
...
PROJECT(examples)
add_library(dlib SHARED IMPORTED) # Imported(!) dlib target
set_target_properties(dlib PROPERTIES IMPORTED_LOCATION "<full path to the installed dlib-shared library file>")
# Now it is safe to include other dlib infrustucture - it won't build dlib again.
include(../dlib/cmake)
...
I want to program in C with libnet in Mac OS.
When I type in gcc *.o -o network -lnet, there's an error:
library not found for -lnet.
And when I use homebrew install linnet, is says:
Warning: libnet-1.1.6 already installed.
It is the problem of library PATH.Flow the steps to solve this problem.
First, find where you install the library. For my case, the libnet is located in /usr/local/Cellar/libnet/1.1.6.
Second, run /usr/local/Cellar/libnet/1.1.6/bin/libnet-config.
Third, use -L to add the path when you link.
gcc *.o -L/usr/local/Cellar/libnet/1.1.6/lib -lnet.
I downloaded and built GNUstep libobjc2 1.6.1,
svn co http://svn.gna.org/svn/gnustep/libs/libobjc2/1.6.1/ rep
cd rep
make
and got this error when I tried to compile a Objective-C code.
hoon#ubuntu:~/work/objc2$ clang -fobjc-nonfragile-abi -fobjc-arc -fblocks *.m *.a -l pthread; ./a.out
Objective-C ABI Error: Loading modules from incompatible ABIs while loading
a.out: loader.c:38: __objc_exec_class: Assertion `objc_check_abi_version(module)' failed.
Aborted (core dumped)
It seems I need to build libobjc.a with some different configurations. What is the problem and what should I do to fix this error?
Env: Ubuntu 12.04 LTS
This is a good question because LLVM and CLang and GNUstep don't claim to be hard or complicated to use. They do ask their users to read (and reread) their documentation though. I've just discovered this combination for Ubuntu myself and it is very intriguing. And there are a lot of moving parts at the moment.
If the OP got an answer on one of the gnustep mailing lists, then it would be nice to hear here how it was resolved.
Without suggesting the normal route of starting over and only installing the latest from LLVM and GNUstep directly, here's my take.
The OP is trying to use ARC and blocks with the runtime provided by the gunstep/libobjc2 project.
libobjc2 should probably be built with clang version 3.2 - or maybe the top of tree.
clang -v will tell you what version you have on your machine. I've found even Ubuntu 12.10 doesn't provide clang-3.2. So I download it from the LLVM website. They have prebuilt binaries for Ubuntu 12.04 LTS. To get make to use clang for this build step, I've seen instructions to set and export CC=clang and CXX=clang++.
Once libobjc2 is built, care must be taken where it gets installed. If the system already has an older libobjc.so.x.y library (this provides the runtime environment for Obj-C), clang or the linker may be picking up the wrong one when you start compiling your own source. I found libobjc.so.4.6.0 built from the libobjc2 source was installed to /usr/local/lib both on Ubuntu 12.04 and 12.10 when I ran the make install step. This path was not setup by the libobjc2 install step.
To get this library picked up, I had to add /usr/local/lib to the env variable LD_LIBRARY_PATH. It wouldn't hurt to try 'locate libojbc.so' to see if there are other versions on the system.
Finally, the libobjc2 readme, https://github.com/gnustep/gnustep-libobjc2#readme, says this new version of the gnustep library supports two ABIs, and each ABI supports ARC and blocks. The advice I've seen about compiling with libobjc2 is to also provide the runtime version expected to be compiling and linking with: -fobjc-runtime=gnustep. Clang on Ubuntu still defaults to the older ABI. -fobjc-nonfragile-abi may accomplish the same thing but I've seen it mentioned that flag was or will be deprecated.
The OP error may actually come from the step where a.out is being run, rather than where clang was compiled. Perhaps the dynamic loader is picking up the legacy libobj.so. Again, I would use locate to see if the system even has more than one.
This is just a guess, but I'm gonna go out on a limb and guess that GNUstep is going to build with GCC by default. A good first step might be to reconfigure the GNUstep build to use Clang. I can't say what variety of issues that will expose, but...
Alternately, you could try building your application with GCC instead of Clang.
This is a fairly late answer, but I have found a way to get everything working (on Elementary OS specifically so I imagine it should be fine on Ubuntu and similar distros).
As mentioned, it is better/easier to build everything from source because you get to pick the prefix, build options, etc. The general method:
Install cmake (if it's not already installed) --> sudo apt-get install cmake
Download, build and install llvm and clang as per the instructions here (or see attached build script). For speed, use the --enable-optimized flag. Tests are "optional" ;-)
The default build scripts for compiler-rt do not include the Blocks runtime. You could modify the build scripts, or rejoice that someone else has already done it (particularly if, like me, your cmake isn't great). Download, build and install libBlocksRuntime from this git repo (it is essentially a clone of the latest compiler-rt Blocks runtime code with custom build scripts). FOLLOW THEIR COMPILATION AND TESTING METHOD.
Download, build and install libobjc2 from GNUStep. The instructions for correct building are actually inside the now-deprecated makefile.
Run ldconfig (if required - though there's no harm in running it even if it isn't).
As #WeakPointer you may still need to edit the LD_LIBRARY_PATH environment variable to pick up your new libraries. Another option is to make some quick and dirty symlinks so clang can find your new libraries.
Final note: I haven't done any comparisons between GNUStep's libobjc2 and GCC's libobjc, the latter of which DOES contain some Objective-C 2.0 features... Be careful with your library selection if you keep both on your system at the same time!
The following script should do it all (untested!):
#!/bin/bash
# Temporary base directories
basedir="./clangllvm_temp"
basedir2="./libBlocksRuntime_temp"
basedir3="./libObjc2_temp"
# Clang, llvm, compiler-rt
mkdir $basedir
cd $basedir
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
cd llvm/tools
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
cd ../..
cd llvm/tools/clang/tools
svn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk extra
cd ../../../..
cd llvm/projects
svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt
cd ../..
mkdir build
cd build
../llvm/configure --prefix=$PREFIX --enable-optimized
make
sudo make install
cd ../..
# libBlocksRuntime
git clone https://github.com/mackyle/blocksruntime.git $basedir2
cd $basedir2
sudo ./buildlib
sudo ./checktests
sudo ./installlib
# Test!
clang -o sample -fblocks sample.c -lBlocksRuntime && ./sample
cd ..
# libobjc2
https://github.com/gnustep/gnustep-libobjc2.git $basedir3
cd $basedir3
mkdir Build
cd Build
cmake .. -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
sudo make && sudo -E make install
cd ../..
# Cleanup
rm -rf $basedir
rm -rf $basedir2
rm -rf $basedir3
# ldconfig
sudo ldconfig
# Additional symlink/LD_LIBRARY_PATH stuff here if required.
# EOF
Key difference was using Clang for build. Take care not to use GCC which is system default compiler. I removed gobjc and g++ packages from system to avoid this issue.
export CC=clang
export CXX=clang++
svn co http://svn.gna.org/svn/gnustep/libs/libobjc2/1.6.1/
cd 1.6.1
make
This answer was hinted from this mailing list thread:
http://lists.gnu.org/archive/html/discuss-gnustep/2012-12/msg00036.html
Described script is posted here:
http://wiki.gnustep.org/index.php/GNUstep_under_Ubuntu_Linux
Now it compiles simple ARC code.
It seems GCC and Clang generated codes are incompatible.
Update
I wrote scripts to setup libobjc2 on FreeBSD and CentOS.
The scripts are mostly copied from a blog.