Yocto recipe to install binaries generated from cmake - cmake

I am new to Yocto and cmake. After looking and searching on internet I was able to make my own recipe and was able to successfully compile the code using cmake from Yocto recipe.
But the binary compiled and generated is in the build folder where the code source files reside. How do I copy over the binaries from the build folder to the custom file system path when the image is generated using Yocto.
My .bb file currently looks like this:
#
# This file is the pscode recipe.
#
SUMMARY = "Simple test application"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://src/* \
file://include/* \
file://CMakeLists.txt\
"
S = "${WORKDIR}"
do_configure() {
cmake ../
}
inherit pkgconfig cmake
do_install() {
install -d ${D}/home/first
cp -r ${WORKDIR} ${D}/home/first
#install -m 0755 ${S} ${D}/home/first
}
FILES_${PN} += "/home/first"
This runs into error
cp: cannot copy a directory <path-to-the-test-folder-in-temp> into itself, <path-to-the-test-folder-in-temp/image/home/first>
Can I someone please guide me. Thank you in advance.

Like the comments suggested:
SUMMARY = "Simple test application"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://src/* \
file://include/* \
file://CMakeLists.txt \
"
S = "${WORKDIR}"
inherit pkgconfig cmake
If the CMakeLists.txt uses the install command then bitbake will do the install for you and you won't need to define you own do_install. see cmake-documentation-install for details. Here the example for binaries:
install(TARGETS <your cmake target> DESTINATION bin)
From cmake install documentation:
If a full path (with a leading slash or drive letter) is given it is
used directly. If a relative path is given it is interpreted relative
to the value of the CMAKE_INSTALL_PREFIX variable.

Related

Yocto include cmake compilation with custom steps

I'm trying to add elibinie package into my custom recipe layer in yocto !
The step to install this package are :
* git clone https://github.com/pcercuei/libini.git
* cd libini
* mkdir build && cd build && cmake ../ && make && sudo make install
Normally yocto take care to install ccmake with do install but with my recipe "libinit.bb", i get compilation error.
libinit.bb :
DESCRIPTION = ""
SECTION = "libini"
DEPENDS = ""
LICENSE = "CLOSED"
SRC_URI = "git://github.com/pcercuei/libini.git;protocol=https"
SRCREV = "e22154361dfc63778a1ca4f153f085c5236ed8f7"
S = "${WORKDIR}/git"
inherit cmake
do_install() {
install -d ${D}/home/root/
install -m 0755 libini ${D}/home/root/
}
error compilation :
linux/libini/1.0-r0/temp/run.do_install.42454' failed with exit code 1:
install: cannot stat 'libini': No such file or directory
I think there is more problem than just cmake, maybe the problem come from folder that i try to install.
Also how should creat build folder in git source and let cmake working !

Clang: Using Cmake to build a compile_commands.json for my project

I'm trying to create the compile_commands.json file by following these instructions: http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
I don't see any option on the docs that allows be to build the compile_commands.json file against my own code. The command that I use when I follow the doc builds the json file, but the contents of the file contains files/directories in the llvm source directory. I'm assuming that if this file contains contents of my own project, then when I run run-clang-tidy.py (from here), then it will run clang-tidy against my own project.
So the question: How do I get Cmake to build the compile_commands.json to contain my own project?
It is unclear exactly what you want to achieve. In the link you provided, the author is building LLVM from source code, which is why the compilation database (compile_commands.json) refers to those sources.
In general to build the compilation database while building the source tree with CMake, you provide it with the -DCMAKE_EXPORT_COMPILE_COMMANDS=ON flag.
So, where the blog post you linked calls
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON path/to/llvm/sources
...you would exchange the path to the sources for your own source tree:
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON this/is/my/source/tree/path
...which should generate the json-file in the current (build) directory.
As in the article, you will probably want to symlink that file to the root of your source tree and then run your tools from there.
Here's a (very) simple build script that I wrote and sometimes use. Maybe it can be helpful to you (adjust to your own needs obviously). It should be run from the root of your source tree.
#!/usr/bin/env sh
type=Debug
if ! [[ -z "$1" ]]; then
type="$1"
mkdir -p build/$type
shift
fi
# Configure build
cmake -S . -B build/$type -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=$type .
# Build
cmake --build build/$type --parallel 4 --config $type "$#"
ln -fs build/$type/compile_commands.json .

How to pass sysroot from Yocto to cmake

I am using a Yocto recipe to build a cmake project. In the Yocto enviroment, I confirmed that --sysroot=my-app/recipe-sysroot and all dependent libraries have been installed into that location. In my CMakeList.txt, I set link_directories(/usr/lib), but error messages occur while building to indicate the dependent libraries cannot be found.
Does anyone know how to pass the Yocto sysroot environment to cmake?
My recipe,
inherit cmake
DEPENDS = "\
azure-iot-sdk-c \
openssl \
zlib \
curl \
boost \
parson \
gtest \
"
S = "${WORKDIR}/git"
B = "${WORKDIR}/build"
EXTRA_OECMAKE = "\
-DCMAKE_BUILD_TYPE=Debug \
-DBUILD_SAMPLES=ON \
-DBUILD_TESTS=ON \
-DBUILD_TOOLS=ON \
"
FILES_${PN}-staticdev = "${libdir}/*.a"
FILES_${PN} += "${libdir}/*.so"
FILES_SOLIBSDEV = ""
INSANE_SKIP_${PN} += "dev-so rpaths"
And if I set the real path in my CMakeList, it works,
set(LIBRARY_DIR "${CMAKE_CURRENT_LIST_DIR}/../recipe-sysroot/usr/lib")
set(STATIC_LIBRARY ${LIBRARY_DIR}/libiothub_client.a)
But if I set the related path according to sysroot, it does not work,
set(LIBRARY_DIR "/usr/lib")
Don't do:
set(LIBRARY_DIR "${CMAKE_CURRENT_LIST_DIR}/../recipe-sysroot/usr/lib")
It is usually not necessary to have any yocto specific information in your cmake. Instead add
include(GNUInstallDirs)
In your recipe add:
inherit cmake
If your cmake installs the static library and headers correctly e.g.:
install (TARGETS <yourtarget> DESTINATION ${CMAKE_INSTALL_LIBDIR})
file(GLOB HEADERS include/*.h)
install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
My above advice should work, if you not install the static library using cmake you have to define an do_install task in your package recipe. For example
do_install() {
install -m 0755 -d ${D}${libdir}
install -m 0755 ${B}/test-staticlibrary.a ${D}/${libdir}
}
If you post your cmake files I can assist you further

How to insert OV5640 camera driver as module in yocto

I am trying to use the OV5640 camera driver as a module in yocto. So I took the .c code and made a makefile (based on the example hello-mod)
obj-m += OV5640.o
SRC := $(shell pwd)
all:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules
modules_install:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install
clean:
$(MAKE) -C $(KERNEL_SRC) M=$(SRC) clean
I also made a recipe in yocto
DESCRIPTION = "..."
LICENSE = "GPL-2.0"
LIC_FILES_CHKSUM = "\
file:// ${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6 \
"
inherit module
SRCREV = "${AUTOREV}"
BPV = "0.0.0"
PV = "${BPV}+git${SRCREV}"
SRC_URI = "git://git/my-repo;protocol=ssh;user=git;branch=master \
"
S = "${WORKDIR}/git"
In the git repo I have the .c code of the camera and the Makefile.
But when I try to build, it fails on do_compile and says:
fatal error: v4l2-int-device.h: No such file or directory
When I search on the file in the 'tmp' folder of yocto I find one in:
tmp/work-shared/myboard/kernel-source/drivers/media/platform/mxc/capture/v4l2-int-device.h
The question is, How can I modify the recipe to be able to build the module without changing the source code or the makefile?
Note:
I also tried to add snippet below to the recipe but this gave no succes.
CFLAGS_prepend = " -I${STAGING_KERNEL_DIR}/drivers/media/platform/mxc/capture "
You need to modify your Makefile and add:
ccflags-y += -I$(KERNEL_SRC)/drivers/media/platform/mxc/capture/
You can also try to compile it out of the tree, you need to set the variable KERNEL_SRC, source your environment, and compile it.

Use Fortify sourceanalyzer with CMake

I have a Makefile generated by CMake. The following path to CMake executable is set in the Makefile:
CMAKE_COMMAND = /home/xyz/opt/cmake/cmake-3.1.1/bin/cmake
How can I integrate Fortify sourceanalyzer with it and run scans?
I had the same challenge but solved it by running it like this:
sourceanalyzer -b project_ID -clean
Go to your build directory and perform make clean or remove all contents including the Makefile
Run cmake by changing CC and CXX variables:
CC="sourceanalyzer -b project_ID gcc" CXX="sourceanalyzer -b project_ID g++" cmake ..
Run make and fortify should be translating files while compilers do their job.
Run sourceanalyzer -b project_ID -scan -f results.fpr
Hope it helps.
I was tasked with integrating our CMake build system with HP Fortify SCA and came across this Thread that gave some insights but lacked specifics as related to HP Fortify so I thought I would share my implementation.
I created a fortify_tools directory at the same level as the source directory. Inside the fortify_tools are a toolchain file and fortify_cc, fortify_cxx, and fortify_ar scripts that will be set as the cmake_compilers via the toolchain file.
fortify_cc
#!/bin/bash
sourceanalyzer -b <PROJECT_ID> gcc $#
fortify_cxx
#!/bin/bash
sourceanalyzer -b <PROJECT_ID> g++ $#
fortify_ar
#!/bin/bash
sourceanalyzer -b <PROJECT_ID> ar $#
NOTE: insert your project name in place of PROJECT_ID
Setting cmake to use the scripts is accomplished in a toolchain file.
fortify_linux_toolchain.cmake
INCLUDE (CMakeForceCompiler)
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
#specify the compilers
SET(CMAKE_C_COMPILER ${CMAKE_SOURCE_DIR}/fortify_tools/fortify_cc)
SET(CMAKE_CXX_COMPILER ${CMAKE_SOURCE_DIR}/fortify_tools/fortify_cxx)
SET(CMAKE_AR_COMPILER ${CMAKE_SOURCE_DIR}/fortify_tools/fortify_ar)
To generate makefiles using the toolchain file
ccmake -DCMAKE_TOOLCHAIN_FILE=../fortify_tools/foritfy_linux_toolchain.cmake ../
configure and generate your makefiles and build your project.
Once the project is built from within the build directory generate a fortify report by
sourceanalyzer -Xmx2400M -debug -verbose -b <PROJECT_ID> -scan -f <PROJECT_ID>.fpr
I understand the last step is outside of CMake but I am pretty confident a cmake_custom_command can be created to perform the scan step as a post build action.
Finally, this is just the linux implementation but the concept scales well to Windows by creating the necessary batch files and windows specific toolchain file
Fortify doesn't support CMake, I received confirmation from Fortify support team.
This answer is late, but might help someone. This is actually easy to fix - you simply need to run cmake inside sourceanalyzer as well. Make a simple build script that calls cmake and then make, and use sourceanalyzer on that instead. I am using fortify 4.21.
Our old Fortify script for building hand-created Makefiles used a build command that looked like this:
$SOURCEANALYZER $MEMORY $LAUNCHERSWITCHES -b $BUILDID make -f Makefile -j12
I was able to get it working for a project that had been converted to CMake by replacing the above line with this, inspired by a couple of the other answers here:
CC="$SOURCEANALYZER $MEMORY $LAUNCHERSWITCHES -b $BUILDID gcc" \
CXX="$SOURCEANALYZER $MEMORY $LAUNCHERSWITCHES -b $BUILDID g++" \
AR="$SOURCEANALYZER $MEMORY $LAUNCHERSWITCHES -b $BUILDID ar" \
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug ..
make -f Makefile -j12 VERBOSE=1
This is with cmake 2.8.12.2 on Linux.
Below is the script i use for my example project to generate HP Fortify report for Android JNI C/C++ Code.
#!/bin/sh
# Configure NDK version and CMake version
NDK_VERSION=21.0.6113669
CMAKE_VERSION=3.10.2
CMAKE_VERSION_PATH=$CMAKE_VERSION.4988404
PROJECTID="JNI_EXAMPLE"
REPORT_NAME=$PROJECTID"_$(date +'%Y%m%d_%H:%M:%S')"
WORKING_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
BUILD_HOME=${WORKING_DIR}/../hpfortify_build
FPR="$BUILD_HOME/$REPORT_NAME.fpr"
# Following exports need to be configured according to host machine.
export ANDROID_SDK_HOME=/Library/Android/sdk
export ANDROID_CMAKE_HOME=$ANDROID_SDK_HOME/cmake/$CMAKE_VERSION_PATH/bin
export ANDROID_NDK_HOME=$ANDROID_SDK_HOME/ndk/$NDK_VERSION
# E.g. JniExample/app/hpfortify/build/CMakeFiles/3.10.2
export CMAKE_FILES_PATH=${BUILD_HOME}/CMakeFiles/$CMAKE_VERSION
export HPFORTIFY_HOME="/Applications/Fortify/Fortify_SCA_and_Apps_20.1.0/bin"
export PATH=$PATH:$ANDROID_SDK_HOME:$ANDROID_NDK_HOME:$ANDROID_CMAKE_HOME:$HPFORTIFY_HOME
echo "[========Start Android JNI C/C++ HP Fortify scanning========]"
echo "[========Build Dir: $BUILD_HOME========]"
echo "[========HP Fortify report path: $FPR========]"
function create_build_folder {
rm -rf $BUILD_HOME
mkdir $BUILD_HOME
}
# The standalone cmake build command can be found from below file.
# JniExample/app/.cxx/cmake/release/x86/build_command.txt
# This file is generated after running command
# `➜ JniExample git:(master) ✗ ./gradlew :app:externalNativeBuildRelease`
function configure_cmake_files {
cd $BUILD_HOME
$ANDROID_CMAKE_HOME/cmake -H$BUILD_HOME/. \
-DCMAKE_CXX_FLAGS=-std=c++11 -frtti -fexceptions \
-DCMAKE_FIND_ROOT_PATH=$BUILD_HOME/.cxx/cmake/release/prefab/x86/prefab \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE=$ANDROID_SDK_HOME/ndk/$NDK_VERSION/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=x86 \
-DANDROID_NDK=$ANDROID_SDK_HOME/ndk/$NDK_VERSION \
-DANDROID_PLATFORM=android-16 \
-DCMAKE_ANDROID_ARCH_ABI=x86 \
-DCMAKE_ANDROID_NDK=$ANDROID_SDK_HOME/ndk/$NDK_VERSION \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=$BUILD_HOME/intermediates/cmake/release/obj/x86 \
-DCMAKE_MAKE_PROGRAM=$ANDROID_SDK_HOME/cmake/$CMAKE_VERSION_PATH/bin/ninja \
-DCMAKE_SYSTEM_NAME=Android \
-DCMAKE_SYSTEM_VERSION=16 \
-B$BUILD_HOME/.cxx/cmake/release/x86 \
-GNinja ..
}
function build {
cmake --build .
}
function cleanup {
rm -rf $BUILD_HOME/CMakeFiles/native-lib.dir
rm -rf $FPR
$HPFORTIFY_HOME/sourceanalyzer -clean
}
function replace_compiler_paths {
FORTIFY_TOOLS_PATH="$WORKING_DIR"
CLANG_PATH="$ANDROID_SDK_HOME/ndk/$NDK_VERSION/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang"
CLANGXX_PATH="$ANDROID_SDK_HOME/ndk/$NDK_VERSION/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++"
HPFORTIFY_CCPATH="$FORTIFY_TOOLS_PATH/fortify_cc"
HPFORTIFY_CXXPATH="$FORTIFY_TOOLS_PATH/fortify_cxx"\"
sed -i '' 's+'$CLANG_PATH'+'$HPFORTIFY_CCPATH'+g' $CMAKE_FILES_PATH/CMakeCCompiler.cmake
sed -i '' 's+'$CLANG_PATH.*[^")"]'+'$HPFORTIFY_CXXPATH'+g' $CMAKE_FILES_PATH/CMakeCXXCompiler.cmake
}
function scan {
$HPFORTIFY_HOME/sourceanalyzer -b $PROJECTID -scan -f $FPR
# copy the file to $WORKING_DIR
cp $FPR $WORKING_DIR
}
create_build_folder
configure_cmake_files
echo "[========Compile C/C++ using normal compiler ========"]
build
echo "[========Replace the compiler with HP Fortify analyser wrapper compilers ========"]
replace_compiler_paths
echo "[========Clean up the build intermediates and the older build ID and fpr file ========"]
cleanup
echo "[========Recompile C/C++ using HP Fortify analyser wrapper compilers ========"]
build
echo "[========Scan the compiled files and generate final report ========"]
scan
echo "[========Change directory to original working dir ========"]
cd $WORKING_DIR
Need to configure below vars before using it. For my case, I use NDK 21 and CMake 3.10.2 and my project ID is "JNI_EXAMPLE"
# Configure NDK version and CMake version
NDK_VERSION=21.0.6113669
CMAKE_VERSION=3.10.2
CMAKE_VERSION_PATH=$CMAKE_VERSION.4988404
PROJECTID="JNI_EXAMPLE"
# Following exports need to be configured according to host machine.
export ANDROID_SDK_HOME=/Library/Android/sdk
export ANDROID_NDK_HOME=$ANDROID_SDK_HOME/ndk/$NDK_VERSION
export HPFORTIFY_HOME="/Applications/Fortify/Fortify_SCA_and_Apps_20.1.0/bin"
Here is a more detailed explanation: Using HP Fortify to Scan Android JNI C/C++ Code
On recent version of CMake one can use:
CMAKE_<LANG>_COMPILER_LAUNCHER='sourceanalyzer;-b;<PROJECT_ID>'
You can add other arguments (like -Xmx2G for instance), semicolon separated, as mentioned on cmake documentation
You need to check if you don't use the compiler launcher for another tool like ccache. We can probably use both with
CCACHE_PREFIX='.../sourceanalyzer -b ID'
Here is what I've used in CMake project:
project(myFortifiedProject LANGUAGES CXX)
set(CMAKE_CXX_COMPILER_LAUNCHER ${FORTIFY_TOOL} -b ${PROJECT_NAME})
So when running cmake (assuming sourceanalyzer is on the path):
cmake <other args> -DFORTIFY_TOOL=sourceanalyzer
So the normal build command works:
make myFortifiedProject
And you can finally collect results with:
sourceanalyzer -b myFortifiedProject -scan