How to compile a source into an ARM binary - cmake

I want to compile VTK-DICOM to run on an ARM Raspberry Pi (Raspbian). Is it posible? Where should I start?

Building for Raspbian Debian Buster images and ARMv6
This tutorial also supports older Rasperry Pi (A, B, B+, Zero) based on the ARMv6 CPU.
See also:
GCC 8 Cross Compiler outputs ARMv7 executable instead of ARMv6
Set up the toolchain
There is no official git repository containing an updated toolchain (See https://github.com/raspberrypi/tools/issues/102).
Here is a github repository which includes building and precompiled toolchains for ARMv6 based on GCC8 and newer:
https://github.com/Pro/raspi-toolchain
As mentioned in the project's readme, these are the steps to get the toolchain. You can also build it yourself (see the README for further details).
Download the toolchain:
wget https://github.com/Pro/raspi-toolchain/releases/latest/download/raspi-toolchain.tar.gz
Extract it. Note: The toolchain has to be in /opt/cross-pi-gcc since it's not location independent.
sudo tar xfz raspi-toolchain.tar.gz --strip-components=1 -C /opt
You are done! The toolchain is now in /opt/cross-pi-gcc
Optional, add the toolchain to your path, by adding:
export PATH=$PATH:/opt/cross-pi-gcc/bin
to the end of the file named ~/.bashrc
Now you can either log out and log back in (i.e. restart your terminal session), or run . ~/.bashrc in your terminal to pick up the PATH addition in your current terminal session.
Get the libraries from the Raspberry PI
To cross-compile for your own Raspberry Pi, which may have some custom libraries installed, you need to get these libraries onto your host.
Create a folder $HOME/raspberrypi.
In your raspberrypi folder, make a folder called rootfs.
Now you need to copy the entire /liband /usr directory to this newly created folder. I usually bring the rpi image up and copy it via rsync:
rsync -vR --progress -rl --delete-after --safe-links pi#192.168.1.PI:/{lib,usr,opt/vc/lib} $HOME/raspberrypi/rootfs
where 192.168.1.PI is replaced by the IP of your Raspberry Pi.
Use CMake to compile your project
To tell CMake to take your own toolchain, you need to have a toolchain file which initializes the compiler settings.
Get this toolchain file from here:
https://github.com/Pro/raspi-toolchain/blob/master/Toolchain-rpi.cmake
Now you should be able to compile your cmake programs simply by adding this extra flag: -D CMAKE_TOOLCHAIN_FILE=$HOME/raspberrypi/pi.cmake and setting the correct environment variables:
export RASPBIAN_ROOTFS=$HOME/raspberry/rootfs
export PATH=/opt/cross-pi-gcc/bin:$PATH
export RASPBERRY_VERSION=1
cmake -DCMAKE_TOOLCHAIN_FILE=$HOME/raspberry/Toolchain-rpi.cmake ..
An example hello world is shown here:
https://github.com/Pro/raspi-toolchain/blob/master/build_hello_world.sh
Source:
https://stackoverflow.com/a/58559140/13859552

Related

CMake build fails with Xcode 12 and CMAKE_IOS_INSTALL_COMBINED=YES

EDIT This is a known CMake issue.
With Xcode 11 (specifically Xcode 11.2.1) I used to be able to cross-compile my project for iOS with this command:
cd /path/to/project
mkdir build
cd build
cmake .. -G Xcode -DCMAKE_SYSTEM_NAME=iOS \
"-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64" \
-DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO \
-DCMAKE_IOS_INSTALL_COMBINED=YES \
-DCMAKE_INSTALL_PREFIX=install
cmake --build . --config Release --target install
This created a build with two slices, one slice for the arm64 architecture (for running on a real device) and one slice for the x86_64 architecture (for running in a simulator on an Intel-based dev environment).
After upgrading to Xcode 12 (specifically Xcode 12.3) this no longer works. The build consistently fails with this error message (line break added by me):
error: unable to attach DB: error: accessing build database "/path/to/project/build/ios/build/XCBuildData/build.db":
database is locked Possibly there are two concurrent builds running in the same filesystem location.
The issue seems to be a post-build rule that CMake creates for the install target. In that post-build rule a second build is initiated while the first one is still in progress.
if test "$CONFIGURATION" = "Release"; then :
cd /path/to/project/build/ios
/usr/local/Cellar/cmake/3.19.2/bin/cmake -DBUILD_TYPE=$CONFIGURATION -DEFFECTIVE_PLATFORM_NAME=$EFFECTIVE_PLATFORM_NAME -P cmake_install.cmake
fi
The build succeeds when I no longer set CMAKE_IOS_INSTALL_COMBINED to YES, but then the resulting build only contains one slice (arm64 in my case, presumably because this is the first architecture that is listed in CMAKE_OSX_ARCHITECTURES).
I'm considering making a separate build for each architecture, and then stitching the slices together manually. Before I go down that road, has anyone been able to find a more elegant solution?
Environment: macOS 11.1, Xcode 12.3, CMake 3.19.2
The CMake 3.19 release notes contain this hint:
The Xcode generator now uses the Xcode “new build system” when generating for Xcode 12.0 or higher. See the CMAKE_XCODE_BUILD_SYSTEM variable. One may use -T buildsystem=1 to switch to the legacy build system.
The workaround, for the moment, is therefore to add the -T option to the build system generation command line:
cmake .. -G Xcode -T buildsystem=1
-DCMAKE_SYSTEM_NAME=iOS \
"-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64" \
-DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO \
-DCMAKE_IOS_INSTALL_COMBINED=YES \
-DCMAKE_INSTALL_PREFIX=install
This should work as long as Xcode still supports the legacy build system. The Xcode 12 Release Notes have this to say on the matter:
The legacy build system is deprecated, and will be removed in a future release. (62742902)
So the -T buildsystem=1 option can only be considered a temporary workaround.

Linker only sees a portion of libraries in a directory

In my makefile I have:
g++ -o Out Out.o -I Headers_Directory -L Libraries_Directory -lFile1 -lFile2
In my Libraries_Directory I have two files libFile1.a and libFile2.so
ld finds libFile1.a but cannot find libFile2.so. How that is possible and how can I resolve the issue?
I am compiling in Cygwin and using GNU gcc-g++ compiler.
A minimalist that regenerates the error:
Download the Linux Version of Gurobi here. Then, install the software using this instruction. You need to activate the software by obtaining a license from here. Free academic license for research purpose is available. Finally navigate to the following folder
installation_directory/gurobi701/linux64/examples/build
and issue the command make. You have to compile on Cygwin with GNU gcc-g++ compiler.

How to set up Kurento Media Server helpers?

I want to build Kurento Media Server against latest Fedora.
However, CMake fails to configure sources:
Could not find a package configuration file provided by "KurentoHelpers"
with any of the following names:
KurentoHelpersConfig.cmake
kurentohelpers-config.cmake
I installed kms-cmake-utils, as suggested, to /usr/local/. However, I still have this error, even if I set CMAKE_PREFIX_PATH to the folder where kms-cmake-utils's install target put .cmake modules.
In fact, there is no KurentoHelpersConfig.cmake file in kms-cmake-utils.
How can I configure Kurento for Fedora?
Try installing to /usr instead of /usr/local because cmake is looking for modules in /usr/share
Executing cmake like this should fix the problem:
cmake .. -DCMAKE_PREFIX_PATH=/usr
You should append path of KurentoHelpersConfig.cmake to CMAKE_MODULE_PATH, do that by adding this line to CMakeLists.txt :
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "/usr/local/share/cmake-3.5/Modules")
It seems something wrong in cmake, it cannot read external CMAKE_MODULE_PATH, so I force set into its arguments line ( Ubuntu server x86_64 used), pay attention -DCMAKE_MODULE_PATH=$CMAKE_MODULE_PATH.
HOME=`pwd`
BUILD=$HOME/build
export CMAKE_MODULE_PATH=$BUILD/usr/local/share/cmake-3.5/Modules
mkdir -p build
cd build
cmake -DCMAKE_PREFIX_PATH=$HOMEDIR/build -DCMAKE_MODULE_PATH=$CMAKE_MODULE_PATH ..
make DESTDIR=$HOMEDIR/build install

Using libdl.so in MinGW

I want to generate a dll file in MinGW, I have several object dependencies in order to do that, one of my object dependencies is libdl.so, I add this object in unix simply as :
g++ xx.o yy.o /usr/lib/libdl.so -o module.so
but in MinGW, I don't have any idea how to add this object. any ideas?
There is a MinGW port of libdl that you can use just like under Unix. Quote from the website:
This library implements a wrapper for dlfcn, as specified in POSIX and SUS, around the dynamic link library functions found in the Windows API.
It requires MinGW to build.
You may get pre-built binaries (with MinGW gcc 3.4.5) and a bundled source code from the Downloads section.
The following commands build and install it in a standard MinGW installation (to be run from your MinGW shell):
./configure --prefix=/ --libdir=/lib --incdir=/include && make && make install
To compile your library as a DLL, use the following command:
g++ -shared xx.o yy.o -ldl -o module.dll
I encountered the same problem (msys2, 32bit version of compiler etc.).
For me I found out that the libdl.a was available in /usr/lib but not in /mingw32/lib. I was able to solve the problem by linking it to the /mingw32/lib folder:
ln -s /usr/lib/libdl.a /mingw32/lib

Install apache module X-Sendfile on MAMP

How can I install X-Sendfile apache module so that MAMP can use it?
I have followed these instructions to install X-Sendfile, but it didn't work (it seems like it just installed it for the default apache installation). I also tried to manually copy /usr/libexec/apache2/mod_xsendfile.so to /Applications/MAMP/Library/modules/, but that produced the following error when restarting Apache:
Cannot load /Applications/MAMP/Library/modules/mod_xsendfile.so into server: cannot create object file image or add library
naabster's answer is correct if your MAMP binary is built for the same architecture as your kernel. The problem you're having might be that MAMP is not built using the same architecture -- I have Lion running here (10.7.3) with XAMPP 1.7.3 and I just ran across the same issue you were having.
Here's how I figured out what was wrong on my system, and how I fixed it. If your issue is the same as mine, then you should be able to follow along and verify as you go.
First, here's the output of 'uname -a' to show you that what I'm running:
Darwin Tads-Mac-Pro.local 11.3.0 Darwin Kernel Version 11.3.0:
Thu Jan 12 18:47:41 PST 2012; root:xnu-1699.24.23~1/RELEASE_X86_64 x86_64
Here are the steps I took to track down the problem and fix it:
Figure out what attributes the other (working) modules had that my freshly-built xsendfile module was missing. I picked mod_headers.so as an example. The command to find that info is 'file [filename]'. I'm running this from a terminal cd'd to the /Applications/XAMPP/xamppfiles/modules directory:
file mod_headers.so
mod_headers.so: Mach-O universal binary with 2 architectures
mod_headers.so (for architecture i386): Mach-O bundle i386
mod_headers.so (for architecture ppc): Mach-O bundle ppc
As you can see, XAMPP kindly provides a universal binary that supports i386 and ppc architectures. However, because the Lion kernel is running x86_64, everything I build using apxs unless I tell it to otherwise will be x86_64.
Check the mach-o bundle type and architecture(s) supported by the module that was built with the recommended apxs build command ('sudo apxs -cia mod_xsendfile.c'). Because we're passing '-i' the apxs will install the .so into the default apache modules dir ... /usr/libexec/apache2...
file /usr/libexec/apache2/mod_xsendfile.so
/usr/libexec/apache2/mod_xsendfile.so: Mach-O 64-bit bundle x86_64
Just to double-check that this is the problem you can also look at the httpd (apache) binary:
file /Applications/XAMPP/xamppfiles/bin/httpd
/Applications/XAMPP/xamppfiles/bin/httpd: Mach-O universal binary with 2 architectures
/Applications/XAMPP/xamppfiles/bin/httpd (for architecture i386): Mach-O executable i386
/Applications/XAMPP/xamppfiles/bin/httpd (for architecture ppc): Mach-O executable ppc
Well now, that certainly will not work with an apache instance built without an x86_64 image. Trust, but verify, eh!
Now that I'm certain I understand the issue, let's re-build the .so with the proper architecture forced on the apxs command line. To do that I'm just adding two new params, Wl (linker flags) and Wc (compiler flags). The -i means 'install' (move .so into the modules directory) and the -a means 'activate' (add or re-enable LoadModule line in the httpd.conf)
sudo apxs -cia -Wl,"-arch i386" -Wc,"-arch i386" mod_xsendfile.c
re-check that our new .so supports an architecture that matches the Apache installed (i386, not x86_64)
file /Applications/XAMPP/xamppfiles/modules/mod_xsendfile.so
/Applications/XAMPP/xamppfiles/modules/mod_xsendfile.so: Mach-O bundle i386
Awesome. Now then, copy this turkey into the XAMPP install dir:
sudo cp /usr/libexec/apache2/mod_xsendfile.so /Applications/XAMPP/xamppfiles/modules/
And add the LoadModule line to the /Applications/XAMPP/xamppfiles/etc/httpd.conf.
LoadModule xsendfile_module modules/mod_xsendfile.so
You should be able to fire up the server using either the UI or the apachectl script found in the xamppfiles/bin directory.
Hope that helps you.
Also, I did a pretty decent due-diligence search and found just about squat looking for 'XAMPP X-SendFile cannot create object' in the Goog. What I did find was your question here, once I eliminated the 'XAMPP' since I was searching for 'XAMPP', not 'MAMP'
I started out with the 'x'AMP stack something like 10 years back using LAMPP, then WAMPP but the ApacheFriends guys call theirs XAMPP now for all of the platforms they support. I prefer using theirs since I know if I have to set up on a Windows server I can just download the same package that I use now but for Windows and I can expect to find all of the same servers installed without (too many) surprises.
So, just to be (very) thorough, the other way to discover these types of problems more easily is via Console.app. Open that up, filter on org.apache.httpd and you should see something similar to this:
httpd: Syntax error on line 117 of /private/etc/apache2/httpd.conf: Cannot load
/usr/libexec/apache2/mod_xsendfile.so into server:
dlopen(/usr/libexec/apache2/mod_xsendfile.so, 10): no suitable image found.
Did find:\n\t/usr/libexec/apache2/mod_xsendfile.so: mach-o, but wrong architecture
You can also get that from a command line when you start the apache server manually:
sudo apachectl -E /tmp/foo.txt -k start; tail -f /tmp/foo.txt
This worked for me:
Install mod_xsendfile according to this for the default OsX Apache server.
copy /usr/libexec/apache2/mod_xsendfile.so to /Applications/MAMP/Library/modules/
Edit the Mamp httpd.conf file and add this line: LoadModule xsendfile_module modules/mod_xsendfile.so
Restart Mamp