Use Linux setcap command to set capabilities during Yocto build - linux

I'm using Yocto 1.8 to build a linux system.
I need to use the command "setcap" to set files capabilities during build, which is introduced via libcap package recipe: http://cgit.openembedded.org/openembedded-core/tree/meta/recipes-support/libcap/libcap_2.25.bb?h=master
The problem is that the recipe provides libcap package, which is only the library, and another subpackage called libcap-bin which contains the binaries I need to use. But I couldn't build or use the libcap-bin-native package inside my recipe as a dependancy (using DEPENDS variable). so everytime I call "setcap" binary, Yocto uses the host binaries (Ubuntu 14.04 64-bit) not the build system ones (as it's not there).
I need to know how to include the native binaries built from libcap-bin package in my native sysroot buildsystem to be used during recipe execution.
Example recipe to use setcap command:
DESCRIPTION = "Apply CAPs on files"
SECTION = "bin"
LICENSE = "CLOSED"
do_install() {
install -d ${D}${bindir}
touch ${D}${bindir}/testacl
}
DEPENDS = "libcap libcap-native"
#New task will be added to each recipe to apply attributes inside ipks
fakeroot do_setcaps() {
setcap 'cap_sys_admin,cap_sys_rawio+ep' ${WORKDIR}/packages-split/${PN}${bindir}/testacl
}
#Adding the new task just before do_package_write_ipk task
addtask setcaps before do_package_write_ipk after do_packagedata
This recipe is working fine, except that it uses the setcap command from my host system (Ubuntu 14.04 64-bit) which is located "/sbin/setcap"
The dependency package libcap-native only includes the library files inside my native sysroot, but not the binaries.
If I used this inside my recipe:
DEPENDS = "libcap-bin"
I got this error:
ERROR: Nothing PROVIDES 'libcap-bin'
I also saw this thread talking about the same topic:
Linux capabilities with yocto
But he uses Yocto > 2.3 and I'm using Yocto 1.8 , and I can't update it right now.
Any help?
PS: I already updated my yocto build system to preserve ACLs and extended attributes during IPK creation, and it's working and being preserved inside the IPK, inside the rootfs, and on the target after flashing.

I found the solution.
I had to add this to the libcap recipe
PACKAGECONFIG_class-native = "attr"
As the generated binaries (setcap & getcap) are depending on libattr, and this has to be configured manually.
I found that it's already configured for the target package
PACKAGECONFIG ??= "attr ${#bb.utils.contains('DISTRO_FEATURES', 'pam', 'pam', '', d)}"
Sorry for disturbing.

I can't comment yet so comment here.
The command setcap should be provided by libcap-native. And please double check whether it exists in tmp/work/x86_64-linux/libcap-native/2.25-r0/image/:
$ find tmp/work/x86_64-linux/libcap-native/2.25-r0/sysroot-destdir/ -name setcap
tmp/work/x86_64-linux/libcap-native/2.25-r0/sysroot-destdir/buildarea3/kkang/cgp9/builds/qemumips64-Apr24/tmp/sysroots/x86_64-linux/usr/sbin/setcap
You can find setcap here after remove the prefix:
$ ls /buildarea3/kkang/cgp9/builds/qemumips64-Apr24/tmp/sysroots/x86_64-linux/usr/sbin/setcap
/buildarea3/kkang/cgp9/builds/qemumips64-Apr24/tmp/sysroots/x86_64-linux/usr/sbin/setcap

Related

How to automatically add a shared libraries to cache in yocto

I am climbing the learning curve of Yocto (Honister) trying to add an third party executable ELF file to my Linux image.
My current issue is that the ELF requires a couple of shared libraries e.g. libpam.so. I have created a recipe that builds these libraries from source code and puts then in the correct place in the file system, but they are not being added to the shared library cache (e.g. not listed when you run /sbin/ldconfig -p | grep pam on the resulting system).
I can correct this manually on a running system via /sbin/ldconfig /path/to/library but I assume I am missing a something in my do_install() step or something.
My reading of the various docs suggest that the bitbake build process should automatically sort this out
On a side note the library version of Linux-PAM is is 1.5.2 but the automake Makefile.am file specifies a version number of 0.85.1
libpam_la_LDFLAGS = -no-undefined -version-info 85:1:85
Is there a way I can access this 0.85.1 version number from an environment variable similar to ${PV} (which returns 1.5.2)
Thanks

How do I Distribute my Haxe application with Hashlink?

I've got a Haxe Application that I want to make available to people with a Windows system. I use Hashlink to run the Application locally and it works very nicely.
I am wondering if I'm supposed to distribute my Application with Hashlink. Can it build me an .exe?
It looks like generating distributable binary files isn't supported out of the box today (March 10, 2017):
> haxe -main Main -hl main.c
Code generated in main.c automatic native compilation not yet implemented
Hopefully it will be supported soon!
Note: I'm talking about building a final executable using hashlink. An entirely separate approach I do not cover here is the possibility of delivering the hashlink virtual machine with your output hl bitcode.
Sane people stop reading here.
But in the meantime... it is possible to generate binaries with hashlink today if you build hashlink from source.
Warnings:
This isn't a generic, cross-platform answer to your question -- it's just my experience on Linux.
There will probably soon be a better way than this.
But I wanted to jot these notes down even for myself to recall later.
Here's what I had to do on Ubuntu 14.04, 64-bit:
Install prerequisite libraries for building hl (there may be others I already have installed, like build-essential, etc)
sudo apt-get install libvorbis-dev libturbojpeg libsdl2-dev libopenal-dev libssl-dev
Clone and build the mbedtls library: (rev note: b5ba28)
cd ~/dev/
git clone https://github.com/ARMmbed/mbedtls.git
cd mbedtls
make CFLAGS='-fPIC'
Clone the hashlink repo: (rev note: eaa92b)
cd ~/dev/
git clone https://github.com/HaxeFoundation/hashlink.git
cd hashlink
In the # Linux section of the Makefile, ~line 67, add these flags:
CFLAGS += -I ../mbedtls/include
LIBFLAGS += -L../mbedtls/library
Now build with make
If everything works, you'll see two important output files, hl and libhl.so
Ok, at this point, it's easiest if you just build your project in the hashlink directory. For example:
# Still in the hashlink directory
haxe -cp /path/to/my/project -debug -main Main.hx -hl src/_main.c
Now run make hlc, and if everything works, hlc is the output executable (which depends on libhl.so):
cp libhl.so hlc /tmp/
cd /tmp/
./hlc
Prints:
Main.hx:7: Hello world!

How to compile c++ programs in the new c++ driver provided by Datastax in Linux

I am new to Cassandra. I installed c++ driver from Datastax. Can some one please provide me the steps like in which path I have to create the ā€˜.cā€™ file and how I can compile it. I can see some example programs in example folder. Can anyone plz tell me how to compile the example programs.
The cpp-driver uses cmake and depends on libuv. So the first steps would be to ensure you have cmake installed as well as libuv. Depending on your linux distribution it may be as simple as using package manager like apt or yum (i.e. sudo apt-get install cmake libuv-dev)
Building is just a matter of running the following steps in the cpp-driver directory:
cmake .
make
sudo make install
This will install libcassandra.so to somewhere in your lib path. You can then link by providing '-lcassandra' in your parameters to clang or gcc (i.e. clang myfile.c -o myfile -lcassandra)
There is very comprehensive documentation on building from source here.

The Jungo WinDriver need a linux symbolic link , what does it mean?

Its manual says:
To run GUI WinDriver applications (e.g., DriverWizard [5]; Debug Monitor [7.2]) you must also
have version 5.0 of the libstdc++ library ā€” libstdc++.so.5. If you do not have this file, install it from the relevant RPM in your Linux distribution (e.g., compat-libstdc++).
Before proceeding with the installation, you must also make sure that you have a linux symbolic link. If you do not, create one by typing : /usr/src$ ln -s 'target kernel'/linux
For example, for the Linux 2.4 kernel type :
/usr/src$ ln -s linux-2.4/ linux
what does this symbolic link mean ? what do the <target kernel> and linux preset ?
If I install WinDriver in Ubuntu 13.10 , how should specify these two parameters ?
When installing WinDriver on a Linux machine, you must make sure that you are compiling WinDriver with the same header files that were used to build your kernel. #uname -a will tell you your kernel version number.
You should verify that the directory /usr/src/linux (normally a symbolic ink) is pointing to the correct kernel header sources and that the header files are using exactly the same version numbers as your running kernel.
A refers to the location of the kernel headers and refers to the Linux kernel name-number.
To fix this:
Become super user: $su ;
Change directory to: /usr/src/: # cd /usr/src/ ;
Delete the previous link you created (if any): # rm linux ;
And create a new symbolic: # ln -s linux-2.4/ linux.
I recommend following the Linux installation procedure from the Windriver manual at:
http://www.jungo.com/st/support/documentation/windriver/11.5.0/wdpci_manual.mhtml/wd_install_process.html#wd_install_linux
Regards,
Nadav, Jungo support manager

How do I configure Qt for cross-compilation from Linux to Windows target?

I want to cross compile the Qt libraries (and eventually my application) for a Windows x86_64 target using a Linux x86_64 host machine. I feel like I am close, but I may have a fundamental misunderstanding of some parts of this process.
I began by installing all the mingw packages on my Fedora machine and then modifying the win32-g++ qmake.conf file to fit my environment. However, I seem to be getting stuck with some seemingly obvious configure options for Qt: -platform and -xplatform. Qt documentation says that -platform should be the host machine architecture (where you are compiling) and -xplatform should be the target platform for which you wish to deploy. In my case, I set -platform linux-g++-64 and -xplatform linux-win32-g++ where linux-win32-g++ is my modified win32-g++ configuration.
My problem is that, after executing configure with these options, I see that it invokes my system's compiler instead of the cross compiler (x86_64-w64-mingw32-gcc). If I omit the -xplatform option and set -platform to my target spec (linux-win32-g++), it invokes the cross compiler but then errors when it finds some Unix related functions aren't defined.
Here is some output from my latest attempt: http://pastebin.com/QCpKSNev.
Questions:
When cross-compiling something like Qt for Windows from a Linux host, should the native compiler ever be invoked? That is, during a cross compilation process, shouldn't we use only the cross compiler? I don't see why Qt's configure script tries to invoke my system's native compiler when I specify the -xplatform option.
If I'm using a mingw cross-compiler, when will I have to deal with a specs file? Spec files for GCC are still sort of a mystery to me, so I am wondering if some background here will help me.
In general, beyond specifying a cross compiler in my qmake.conf, what else might I need to consider?
Just use M cross environment (MXE). It takes the pain out of the whole process:
Get it:
$ git clone https://github.com/mxe/mxe.git
Install build dependencies
Build Qt for Windows, its dependencies, and the cross-build tools;
this will take about an hour on a fast machine with decent internet access;
the download is about 500MB:
$ cd mxe && make qt
Go to the directory of your app and add the cross-build tools to the PATH environment variable:
$ export PATH=<mxe root>/usr/bin:$PATH
Run the Qt Makefile generator tool then build:
$ <mxe root>/usr/i686-pc-mingw32/qt/bin/qmake && make
You should find the binary in the ./release directory:
$ wine release/foo.exe
Some notes:
Use the master branch of the MXE repository; it appears to get a lot more love from the development team.
The output is a 32-bit static binary, which will work well on 64-bit Windows.
(This is an update of #Tshepang's answer, as MXE has evolved since his answer)
Building Qt
Rather than using make qt to build Qt, you can use MXE_TARGETS to control your target machine and toolchain (32- or 64-bit). MXE started using .static and .shared as a part of the target name to show which type of lib you want to build.
# The following is the same as `make qt`, see explanation on default settings after the code block.
make qt MXE_TARGETS=i686-w64-mingw32.static # MinGW-w64, 32-bit, static libs
# Other targets you can use:
make qt MXE_TARGETS=x86_64-w64-mingw32.static # MinGW-w64, 64-bit, static libs
make qt MXE_TARGETS=i686-w64-mingw32.shared # MinGW-w64, 32-bit, shared libs
# You can even specify two targets, and they are built in one run:
# (And that's why it is MXE_TARGET**S**, not MXE_TARGET ;)
# MinGW-w64, both 32- and 64-bit, static libs
make qt MXE_TARGETS='i686-w64-mingw32.static x86_64-w64-mingw32.static'
In #Tshepang's original answer, he did not specify an MXE_TARGETS, and the default is used. At the time he wrote his answer, the default was i686-pc-mingw32, now it's i686-w64-mingw32.static. If you explicitly set MXE_TARGETS to i686-w64-mingw32, omitting .static, a warning is printed because this syntax is now deprecated. If you try to set the target to i686-pc-mingw32, it will show an error as MXE has removed support for MinGW.org (i.e. i686-pc-mingw32).
Running qmake
As we changed the MXE_TARGETS, the <mxe root>/usr/i686-pc-mingw32/qt/bin/qmake command will no longer work. Now, what you need to do is:
<mxe root>/usr/<TARGET>/qt/bin/qmake
If you didn't specify MXE_TARGETS, do this:
<mxe root>/usr/i686-w64-mingw32.static/qt/bin/qmake
Update: The new default is now i686-w64-mingw32.static
Another way to cross-compile software for Windows on Linux is the MinGW-w64 toolchain on Archlinux. It is easy to use and maintain, and it provides recent versions of the compiler and many libraries. I personally find it easier than MXE and it seems to adopt newer versions of libraries faster.
First, you will need an arch-based machine (virtual machine or docker container will suffice). It does not have to be Arch Linux, derivatives will do as well. I used Manjaro Linux.
Most of the MinGW-w64 packages are not available at the official Arch repositories, but there is plenty in AUR. The default package manager for Arch (Pacman) does not support installation directly from AUR, so you will need to install and use an AUR wrapper like yay or yaourt. Then installing MinGW-w64 version of Qt5 and Boost libraries is as easy as:
yay -Sy mingw-w64-qt5-base mingw-w64-boost
#yaourt -Sy mingw-w64-qt5-base mingw-w64-qt5-boost #if you use yaourt
This will also install the MinGW-w64 toolchain (mingw-w64-gcc) and other dependencies.
Cross-compiling a Qt project for windows (x64) is then as simple as:
x86_64-w64-mingw32-qmake-qt5
make
To deploy your program you will need to copy corresponding dlls from /usr/x86_64-w64-mingw32/bin/. For example, you will typically need to copy /usr/x86_64-w64-mingw32/lib/qt/plugins/platforms/qwindows.dll to program.exe_dir/platforms/qwindows.dll.
To get a 32bit version you simply need to use i686-w64-mingw32-qmake-qt5 instead. Cmake-based projects work just as easily with x86_64-w64-mingw32-cmake.
This approach worked extremely well for me, was the easiest to set-up, maintain, and extend.
It also goes well with continuous integration services. There are docker images available too.
For example, let's say I want to build QNapi subtitle downloader GUI. I could do it in two steps:
Start the docker container:
sudo docker run -it burningdaylight/mingw-arch:qt /bin/bash
Clone and compile QNapi
git clone --recursive 'https://github.com/QNapi/qnapi.git'
cd qnapi/
x86_64-w64-mingw32-qmake-qt5
make
That's it! In many cases, it will be that easy. Adding your own libraries to the package repository (AUR) is also straightforward. You would need to write a PKBUILD file, which is as intuitive as it can get, see mingw-w64-rapidjson, for example.
Ok I think I've got it figured out.
Based in part on https://github.com/mxe/mxe/blob/master/src/qt.mk and https://www.videolan.org/developers/vlc/contrib/src/qt4/rules.mak
It appears that "initially" when you run configure (with -xtarget, etc.), it configures then runs your "hosts" gcc to build the local binary file ./bin/qmake
./configure -xplatform win32-g++ -device-option CROSS_COMPILE=$cross_prefix_here -nomake examples ...
then you run normal "make" and it builds it for mingw
make
make install
so
yes
only if you need to use something other than msvcrt.dll (its default). Though I have never used anything else so I don't know for certain.
https://stackoverflow.com/a/18792925/32453 lists some configure params.
In order to compile Qt, one must run it's configure script, specifying the host platform with -platform (e.g. -platform linux-g++-64 if you're building on a 64-bit linux with the g++ compiler) and the target platform with -xplatform (e.g. -xplatform win32-g++ if you're cross compiling to windows).
I've also added this flag:
-device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32-
which specifies the prefix of the toolchain I'm using, which will get prepended to 'gcc' or 'g++' in all the makefiles that are building binaries for windows.
Finally, you might get problems while building icd, which apparently is something that is used to add ActiveX support to Qt. You can avoid that by passing the flag -skip qtactiveqt to the configure script. I've got this one out of this bug report: https://bugreports.qt.io/browse/QTBUG-38223
Here's the whole configure command I've used:
cd qt_source_directory
mkdir my_build
cd my_build
../configure \
-release \
-opensource \
-no-compile-examples \
-platform linux-g++-64 \
-xplatform win32-g++ \
-device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- \
-skip qtactiveqt \
-v
As for yout questions:
1 - Yes. The native compiler will be called in order to build some tools that are needed in the build process. Maybe things like qconfig or qmake, but I'm not entirely sure which tools, exactly.
2 - Sorry. I have no idea what specs files are in the context of compilers =/ . But as far as I know, you wouldn't have to deal with that.
3 - You can specify the cross compiler prefix in the configure command line instead of doing it in the qmake.conf file, as mentioned above. And there's also that problem with idc, whose workaround I've mentioned as well.

Resources