How to compile a basic c file in yocto - c

I am working on yocto, I want to compile some C files in yocto and install the resulting binary to external filesystem.
Before doing that I tried creating a separate reciepe and compile c code from it.
I am unable to compile it.

I am not sure to understand the question since it is not precise enough.
Including C files in recipe tree
If you want to have the C files in your recipe, having a file tree like this:
recipe-example/example/example_0.1.bb
recipe-example/example/example-0.1/helloworld.c
You can generate this example when you create a new layer using
yocto-layer <your-layer-name>
Your bb file will look like this:
#
# This file was derived from the 'Hello World!' example recipe in the
# Yocto Project Development Manual.
#
SUMMARY = "Simple helloworld application"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://helloworld.c"
S = "${WORKDIR}"
do_compile() {
${CC} helloworld.c -o helloworld
}
do_install() {
install -d ${D}${bindir}
install -m 0755 helloworld ${D}${bindir}
}
It will compile the hello world file and install it into /usr/bin on your image.
From a Git repo
You also can compile from a git repository, I advise you to read the manual and examples in your yocto folder. Here is an example here of wiringPi:
DESCRIPTION = "A library to control Raspberry Pi GPIO channels"
HOMEPAGE = "https://projects.drogon.net/raspberry-pi/wiringpi/"
SECTION = "devel/libs"
LICENSE = "LGPLv3+"
LIC_FILES_CHKSUM = "file://COPYING.LESSER;md5=e6a600fd5e1d9cbde2d983680233ad02"
# tag 2.29
SRCREV = "d79506694d7ba1c3da865d095238289d6175057d"
S = "${WORKDIR}/git"
SRC_URI = "git://git.drogon.net/wiringPi \
file://0001-Add-initial-cross-compile-support.patch \
file://0001-include-asm-ioctl.h-directly-for-_IOC_SIZEBITS.patch \
"
COMPATIBLE_MACHINE = "raspberrypi"
CFLAGS_prepend = "-I${S}/wiringPi -I${S}/devLib"
EXTRA_OEMAKE += "'INCLUDE_DIR=${D}${includedir}' 'LIB_DIR=${D}${libdir}'"
EXTRA_OEMAKE += "'DESTDIR=${D}/usr' 'PREFIX=""'"
do_compile() {
oe_runmake -C devLib
oe_runmake -C wiringPi
oe_runmake -C gpio 'LDFLAGS=${LDFLAGS} -L${S}/wiringPi -L${S}/devLib'
}
do_install() {
oe_runmake -C devLib install
oe_runmake -C wiringPi install
oe_runmake -C gpio install
}
It is fetching from a git repository, applying patches generated by git, using oe_runmake to compile with the makefiles.
With devtool
It has been asked in a comment on how to add a recipe with devtool.
We will still use wiringPi as an example again. Download it doing
https://github.com/WiringPi/WiringPi
The Makefile is is the folder wiringPi.
You can then do
devtool add <name_of_recipe> <path_to_Makefile_folder>
Take care of the warning from devtool
NOTE: Creating workspace layer in /home/dbensoussan/new_poky/poky/build/workspace
NOTE: Enabling workspace layer in bblayers.conf
NOTE: Using source tree as build directory since that would be the default for this recipe
NOTE: Recipe /home/dbensoussan/new_poky/poky/build/workspace/recipes/project/project.bb has been automatically created; further editing may be required to make it fully functional
This is generating the recipe as follow:
# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)
#
# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is
# your responsibility to verify that the values are complete and correct.
LICENSE = "Unknown"
LIC_FILES_CHKSUM = "file://COPYING.LESSER;md5=e6a600fd5e1d9cbde2d983680233ad02"
# No information for SRC_URI yet (only an external source tree was specified)
SRC_URI = ""
# NOTE: this is a Makefile-only piece of software, so we cannot generate much of the
# recipe automatically - you will need to examine the Makefile yourself and ensure
# that the appropriate arguments are passed in.
do_configure () {
# Specify any needed configure commands here
:
}
do_compile () {
# You will almost certainly need to add additional arguments here
oe_runmake
}
do_install () {
# This is a guess; additional arguments may be required
oe_runmake install 'DESTDIR=${D}'
}
You can then edit your recipe to suit your configuration
With externalsrc
It is possible to use a directory present on the filesystem by using externalsrc.
I did not try it myself, nor have I the workspace ready to do, but #71GA in the comment tested the tutorial from the Koan software company https://wiki.koansoftware.com/index.php/Building_Software_from_an_External_Source and it worked. I will copy the content here:
in this case use the externalsrc class - you can inherit this in the original bb recipe or a bbappend:
inherit externalsrc
EXTERNALSRC = "/path/to/sources"
Depending on the type of build (eg, 'inherit module' for out of tree Linux kernel modules) you may or may not need to set EXTERNALSRC_BUILD.
inherit externalsrc
EXTERNALSRC = "/some/path"
EXTERNALSRC_BUILD = "/some/path"
If you're going to use it across a number of recipes you can inherit it globally at the configuration level (perhaps via an inc file that you include/require there):
INHERIT += "externalsrc"
EXTERNALSRC_pn-<recipename> = "/path/to/sources"
Recipe example using an external source for nInvaders package
#
# Recipe example with externalsrc
#
# (C)2019 Marco Cavallini - KOAN - <https://koansoftware.com>
#
LICENSE = "CLOSED"
LIC_FILES_CHKSUM = ""
inherit externalsrc
EXTERNALSRC = "/home/koan/yocto-qemuarm-sumo/ninvaders-0.1.1"
EXTERNALSRC_BUILD = "${EXTERNALSRC}"
DEPENDS = "ncurses"
EXTRA_OEMAKE = "-e"
do_install() {
install -d ${D}${bindir}
install -m 0755 nInvaders ${D}${bindir}
}
FILES_${PN} = "${bindir}/*"

You can just go to the official documentation to find your answer.
In the chapter 7.3 Writting a New Recipe of the yocto mega-manual, the very first example is exactly is what you need (Single .c File Package (Hello World!)).

Related

How to read and write input output files in yocto

Hello I am trying to create an custom application where I can read and write to the files. I can use it using stdio.h library in C code. How can use this operation while building with yocto. I can create an executable, when the flash the image on my microcontroller built with my application it says there is no input files (Yocto dosnt do file handling)
Do i need to do kernel configuration? (If yes how should i do it)
inherit autotools pkgconfig
inherit meson
PRIORITY = "optional"
SECTION = "examples"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "file://appxyz/"
S = "${WORKDIR}"
B = "${WORKDIR}/build_dir"
MESON_SOURCEPATH = "${S}/appxyz"
do_install() {
install -d ${D}${bindir}
install -d ${D}${libdir}
install -m 0755 ${B}/appxyz ${D}${bindir}
}
FILES_${PN} += "${bindir}/ ${bindir}/appxyz"
This is recipe for my application, appxyz is the executable, how can change it to reading files?

Create Yocto Filesystem of type rootfs.img

I'm trying to create filesystem of extension rootfs.img from Yocto. Adding IMAGE_FSTYPE="img" is failing, saying img is not recognized because its definition is not defined in any meta class.
I have looked into using wic, but cant find the command that should go in .wks file
Any ways in which I can create rootfs.img (instead of rootfs.tar.gz or rootfs.ext4) in Yocto?
Tried wic & IMAGE_FSTYPES="img"
Solved it this way :
Added function oe_mkimgfs() similar to https://git.yoctoproject.org/poky/tree/meta/classes/image_types.bbclass#n63
Modified mkfs cmd to mkfs.$fstype -F $extra_imagecmd ${IMGDEPLOYDIR}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.img -d ${IMAGE_ROOTFS}
Also added other macros :
EXTRA_IMAGECMD_img ?= "-i 4096"
do_image_img[depends] += "e2fsprogs-native:do_populate_sysroot"
RUNNABLE_IMAGE_TYPES ?= "ext2 ext3 ext4 img"
IMAGE_CMD_img = "oe_mkimgfs ext4 ${EXTRA_IMAGECMD}"

How to compile the C GNU Scientific Library (GSL) to web assembly using emscripten?

The goal is to compile the latest stable GSL to web assembly and make it available as a Node.js module.
I tried the following procedure inspired by this section of the emscripten manual:
git clone git://git.savannah.gnu.org/gsl.git
cd gsl
git checkout tags/release-2-6
autoreconf -i
emconfigure ./configure
emmake make
Unfortunately, I get multiple wasm-ld: error: duplicate symbol.
But compiling the GSL (make) works perfectly fine.
I am using emsdk version 2.0.16 on Ubuntu 18.04.
Does anyone know, how to fix this problem?
Help will be much appreciated.
Finally found a solution inspired by this gist. The problem had to do with dynamic linking and shared libraries.
Anyway, the following code successfully compiles the GSL to a Node.js module:
git clone git://git.savannah.gnu.org/gsl.git
cd gsl
git checkout tags/release-2-6
autoreconf -i
emconfigure ./configure
# Note the flag indicating STATIC linking:
# -------------------------======---------
emmake make LDFLAGS=-all-static
emcc -g -O2 -o .libs/gsl.js -s MODULARIZE -s EXPORTED_RUNTIME_METHODS=\[ccall\] -s LINKABLE=1 -s EXPORT_ALL=1 ./.libs/libgsl.a -lm
The above creates the node module ./.libs/gsl.js which can be used as shown in the following example script:
// test_gsl.js
var factory = require('./.libs/gsl.js');
factory().then((instance) => {
// Compute the value of the Bessel function for x = 5.0:
var besselRes = instance._gsl_sf_bessel_J0(5.0);
// Calculate the hypergeometric cumulative probability distribution for:
// 4: Number of successes (white balls among the taken)
// 7: Number of white balls in the urn
// 19: Number of black balls in the urn
// 13: Number of balls taken
var hg = instance._gsl_cdf_hypergeometric_P(4, 7, 19, 13);
// Do the same using `ccall`
var hg_ccal = instance.ccall("gsl_cdf_hypergeometric_P",
"number",
["number", "number", "number", "number" ],
[4, 7, 19, 13]);
console.log(`besselRes is: ${besselRes}`);
console.log(`gsl_cdf_hypergeometric_P(4,7,19,13): ${hg}`);
console.log(`ccall("gsl_cdf_hypergeometric_P",4,7,19,13): ${hg_ccal}`);
});
Please note that all GSL functions are prefixed with an underscore (_) in the generated Node.js module.
The above script (node ./test_gsl.js) generates this output:
besselRes is: -0.17759677131433826
gsl_cdf_hypergeometric_P(4,7,19,13): 0.8108695652173905
ccall("gsl_cdf_hypergeometric_P",4,7,19,13): 0.8108695652173905
I sincerely hope, this post helps any one.
Have a good one and Cheers!

Yocto: Adding Kernel Module to Image

I added iptables package to my device image, using CORE_IMAGE_EXTRA_INSTALL += "iptables".
I tried to run it on the device and get the following error message:
modprobe: FATAL: Module ip_tables not found in directory /lib/modules/4.9.11-1.0.0+gc27010d
iptables v1.6.1: can't initialize iptables table `filter': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
Seems like I have missing kernel module.
Need your help in adding standard kernel module to the image (Where can I find all modules files and how should I add and load it to the image).
You must add the iptables module to your kernel. I had the same problem and I could solve it with these steps:
Run bitbake -c menuconfig virtual/kernel
Activate CONFIG_IP_NF_IPTABLES module (you can search its location on that menu typing slash '/').
Save it and run bitbake -c savedefconfig virtual/kernel for saving that file as a defconfig.
Copy defconfig file from returned path to yocto-distro/layer-name/recipes-kernel/linux/files/ (make this directory if it does not exist).
Create a .bbappend file inside yocto-distro/layer-name/recipes-kernel/linux/ with the same name as your original recipe file from meta layer.
Edit your file and append lines below:
SRC_URI += "file://defconfig"
KERNEL_DEFCONFIG = "${WORKDIR}/defconfig"
FILESEXTRAPATHS_prepend := "${THISDIR}/files"
~
Relaunch bitbake your-image-name
It worked on my situation. Btw, I got that info from the following webs:
http://variwiki.com/index.php?title=Yocto_Customizing_the_Linux_kernel
https://www.linuxtopia.org/Linux_Firewall_iptables/x651.html
Have a nice day! :D

VIM with youcomplete me

I've been coding for a while and moving from IDE to IDE is a real pain when what I need most is just ctag and code completion. I finally decided to go to vim, well neovim in this case but that's beside the point.
I have ctags working and was following this tutorial from the YCM site along with this one
but I can't seem to get YCM to work for me.
I followed these step:
cd ~/.nvim/bundle
git clone https://github.com/Valloric/YouCompleteMe.git
cd YouCompleteMe
git submodule update --init --recursive
./install.sh --clang-completer --system-libclang
this went through downloaded, compiled, installed some thing
Then I created the .ycm_extra_conf.py file at "~/.nvim/.ycm_extra_conf.py"
and added: let g:ycm_global_ycm_extra_conf = "~/.nvim/.ycm_extra_conf.py"
to the top of my ~/.nvimrc file
This is what I added to my .ycm_extra_conf.py file
# This file is NOT licensed under the GPLv3, which is the license for the rest
# of YouCompleteMe.
#
# Here's the license text for this file:
#
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# For more information, please refer to <http://unlicense.org/>
import os
import ycm_core
# These are the compilation flags that will be used in case there's no
# compilation database set (by default, one is not set).
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
flags = [
'-Wall',
'-Wextra',
'-Werror',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-DNDEBUG',
'-ftrapv',
'-finstrument’-functions',
'-Wfloat’-equal',
'-Wundef',
'-Wshadow',
'-Wpointer-arith',
'-Wcast’-align',
'-Wstrict-prototypes',
'-Wstrict-overflow=5',
'-Wwrite-strings',
'-Waggregate-return',
'-Wcast-qual',
'-Wswitch-default',
'-Wswitch-enum',
'-Wconversion',
'-Wunreachable-code',
# You 100% do NOT need -DUSE_CLANG_COMPLETER in your flags; only the YCM
# source code needs it.
'-DUSE_CLANG_COMPLETER',
# THIS IS IMPORTANT! Without a "-std=<something>" flag, clang won't know which
# language to use when compiling headers. So it will guess. Badly. So C++
# headers will be compiled as C headers. You don\'t want that so ALWAYS specify
# a "-std=<something>".
# For a C project, you would set this to something like 'c99' instead of
# 'c99'.
'-std=c+99',
# ...and the same thing goes for the magic -x option which specifies the
# language that the files to be compiled are written in. This is mostly
# relevant for c headers.
'-x',
'c',
'-isystem',
'../BoostParts',
'-isystem',
# This path will only work on OS X, but extra paths that don't exist are not harmful
'/System/Library/Frameworks/Python.framework/Headers',
'-isystem',
'../llvm/include',
'-isystem',
'../llvm/tools/clang/include',
'-I',
'.',
'-I',
'./ClangCompleter',
'-isystem',
'./tests/gmock/gtest',
'-isystem',
'./tests/gmock/gtest/include',
'-isystem',
'./tests/gmock',
'-isystem',
'./tests/gmock/include',
]
# Set this to the absolute path to the folder (NOT the file!) containing the
# compile_commands.json file to use that instead of 'flags'. See here for
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
#
# You can get CMake to generate this file for you by adding:
# set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
# to your CMakeLists.txt file.
#
# Most projects will NOT need to set this to anything; you can just change the
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
compilation_database_folder = ''
if os.path.exists( compilation_database_folder ):
database = ycm_core.CompilationDatabase( compilation_database_folder )
else:
database = None
SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]
def DirectoryOfThisScript():
return os.path.dirname( os.path.abspath( __file__ ) )
def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
if not working_directory:
return list( flags )
new_flags = []
make_next_absolute = False
path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
for flag in flags:
new_flag = flag
if make_next_absolute:
make_next_absolute = False
if not flag.startswith( '/' ):
new_flag = os.path.join( working_directory, flag )
for path_flag in path_flags:
if flag == path_flag:
make_next_absolute = True
break
if flag.startswith( path_flag ):
path = flag[ len( path_flag ): ]
new_flag = path_flag + os.path.join( working_directory, path )
break
if new_flag:
new_flags.append( new_flag )
return new_flags
def IsHeaderFile( filename ):
extension = os.path.splitext( filename )[ 1 ]
return extension in [ '.h', '.hxx', '.hpp', '.hh' ]
def GetCompilationInfoForFile( filename ):
# The compilation_commands.json file generated by CMake does not have entries
# for header files. So we do our best by asking the db for flags for a
# corresponding source file, if any. If one exists, the flags for that file
# should be good enough.
if IsHeaderFile( filename ):
basename = os.path.splitext( filename )[ 0 ]
for extension in SOURCE_EXTENSIONS:
replacement_file = basename + extension
if os.path.exists( replacement_file ):
compilation_info = database.GetCompilationInfoForFile(
replacement_file )
if compilation_info.compiler_flags_:
return compilation_info
return None
return database.GetCompilationInfoForFile( filename )
def FlagsForFile( filename, **kwargs ):
if database:
# Bear in mind that compilation_info.compiler_flags_ does NOT return a
# python list, but a "list-like" StringVec object
compilation_info = GetCompilationInfoForFile( filename )
if not compilation_info:
return None
final_flags = MakeRelativePathsInFlagsAbsolute(
compilation_info.compiler_flags_,
compilation_info.compiler_working_dir_ )
else:
relative_to = DirectoryOfThisScript()
final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
return {
'flags': final_flags,
'do_cache': True
}
I have a project where I created ctags and I'm able to get around the file in vim using it's ctags support but, code completion just isn't working.
I went through the steps, went inside my ~/.nvim/bundle
This error was caused by typos in my .ycm_extras file
I run :YcmDebugInfo
and I get this error that my server has crashed:
Printing YouCompleteMe debug information...
-- Server crashed, no debug info from server
-- Server running at: http://127.0.0.1:64594
-- Server process ID: 47040
-- Server logfiles:
-- /var/folders/64/d3t4_pcs06943d651dfgp3m00000gn/T/ycm_temp/server_64594_stdout.log
-- /var/folders/64/d3t4_pcs06943d651dfgp3m00000gn/T/ycm_temp/server_64594_stderr.log
reading the stderr log I saw that I had some of these "\xe2" characters in my .ycm_extra_conf.py file.
Running a python script from this answer, I found the culprits.
I first changed to the proper directory where the .ycm_extra file was located then ran python:
Brother:.vim blubee$ python
Python 2.7.6 (default, Sep 9 2014, 15:04:36)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> with open(".ycm_extra_conf.py") as fp:
... for i, line in enumerate(fp):
... if "\xe2" in line:
... print i, repr(line)
...
45 "'-finstrument\xe2\x80\x99-functions',\n"
46 "'-Wfloat\xe2\x80\x99-equal',\n"
50 "'-Wcast\xe2\x80\x99-align',\n"
removing the quote marks fixed the problem, now YCM works just as expected.
you can see the file before:
'-finstrument’-functions',
'-Wfloat’-equal',
'-Wundef',
'-Wshadow',
'-Wpointer-arith',
'-Wcast’-align',
and after:
'-finstrument-functions', #removed quote after finstrument
'-Wfloat-equal', #removed quote after Wfloat
'-Wundef',
'-Wshadow',
'-Wpointer-arith',
'-Wcast-align', #removed quote after Wcast

Resources