site  contact  subhomenews

Nim compiled in OpenEmbedded

August 14, 2022 — BarryK

Nim is a systems programming language, introduced a few days ago:

https://bkhome.org/news/202208/considering-adopting-nim-language.html

Cross-compiling in OE has been a real struggle, even with help from some preliminary work done by 'aguspiza' on github (linked from above link).

Firstly, here is file 'nim-native_1.6.6.bb':

# Recipe created by recipetool
# recipetool create -o nim_1.6.6.bb https://nim-lang.org/download/nim-1.6.6.tar.xz

HOMEPAGE = "https://nim-lang.org/"
DESCRIPTION = "nim compiler"
SECTION = "languages"
SUMMARY = "nim language compiler"

LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://copying.txt;md5=e202ebcd59041b078a1f8cf66709081d"

inherit native

SRC_URI = "https://nim-lang.org/download/nim-${PV}.tar.xz"

SRC_URI[md5sum] = "e316eb7f961071c6aaa7e5376c576f90"
SRC_URI[sha256sum] = "67b111ce6f3861503b9fcc1cae59fc34d0122566d3ecfef3a064a2174121a452"

# ERROR: nim-native-1.6.6-r9 do_populate_sysroot: The recipe nim-native is trying to install files into a shared area when those files already exist. Those files and their manifest location are:
# /mnt/build/oe-builds/oe-quirky/build-amd64/tmp/sysroots-components/x86_64/nim-native/usr/bin/nim
# It could be the overlapping files detected are harmless in which case adding them to SSTATE_DUPWHITELIST may be the correct solution.
SSTATE_DUPWHITELIST = "/"

do_configure () {
true
}

do_compile () {
COMP_FLAGS="${CFLAGS}" LINK_FLAGS="${LDFLAGS}" ./build.sh --os linux --cpu ${BUILD_ARCH}
bin/nim c -d:release koch
}

# cp: cannot overwrite directory '/mnt/build/oe-builds/oe-quirky/build-amd64/tmp/sysroots-components/x86_64/nim-native/usr/bin/nim' with non-directory
# have to install as nim.bin... ...no, that was a previous attempt created nim folder.

do_install () {
./install.sh pkg
install -d ${D}${bindir}
install -d ${D}${includedir}
install -d ${D}${libdir}/nim
install -m 755 pkg/nim/bin/nim ${D}${bindir}/
install -m 644 pkg/nim/lib/cycle.h ${D}${includedir}/
install -m 644 pkg/nim/lib/nimbase.h ${D}${includedir}/
install -m 755 koch ${D}${bindir}/
(
cd pkg/nim/lib
for dir in $(find . -mindepth 1 -type d);do
install -d ${D}${libdir}/nim/${dir}
done
for file in $(find . -mindepth 1 -type f);do
install -m 755 "${file}" ${D}${libdir}/nim/${file}
done
)
}

This provides a 'nim' binary that will run on the host system. It can be used in OE to compile applications written in the Nim language, for the target architecture.

The next recipe compiles 'nim' binary again, this time to run on the target architecture. It also compiles the 'koch' binary. File 'nim_1.6.6.bb':

# Recipe created by recipetool
# recipetool create -o nim_1.6.6.bb https://nim-lang.org/download/nim-1.6.6.tar.xz
# ref: https://github.com/aguspiza/meta-nim
# ref: https://bkhome.org/news/202208/considering-adopting-nim-language.html

HOMEPAGE = "https://nim-lang.org/"
DESCRIPTION = "nim compiler"
SECTION = "languages"
SUMMARY = "nim language compiler"

LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://copying.txt;md5=e202ebcd59041b078a1f8cf66709081d"

DEPENDS = "nim-native flex-native m4-native"

SRC_URI = "https://nim-lang.org/download/nim-${PV}.tar.xz"

SRC_URI[md5sum] = "e316eb7f961071c6aaa7e5376c576f90"
SRC_URI[sha256sum] = "67b111ce6f3861503b9fcc1cae59fc34d0122566d3ecfef3a064a2174121a452"

# ERROR: nim-native-1.6.6-r9 do_populate_sysroot: The recipe nim-native is trying to install files into a shared area when those files already exist. Those files and their manifest location are:
# /mnt/build/oe-builds/oe-quirky/build-amd64/tmp/sysroots-components/x86_64/nim-native/usr/bin/nim
# It could be the overlapping files detected are harmless in which case adding them to SSTATE_DUPWHITELIST may be the correct solution.
SSTATE_DUPWHITELIST = "/"

do_configure () {
true
}

do_compile () {
#compile nim...
#COMP_FLAGS="${CFLAGS}" LINK_FLAGS="${LDFLAGS}" ./build.sh --os linux --cpu ${TARGET_ARCH}
./build.sh --os linux --cpu ${TARGET_ARCH}

#bad hack...
cp -a -f ${WORKDIR}/recipe-sysroot-native/usr/lib/nim/* ${WORKDIR}/recipe-sysroot-native/usr/lib/

case "${TARGET_ARCH}" in
x86_64) xTARGET_ARCH=amd64 ;;
aarch64) xTARGET_ARCH=arm64 ;;
i686) xTARGET_ARCH=i386 ;;
*) xTARGET_ARCH="${TARGET_ARCH}"
esac

#compile koch...
echo "${xTARGET_ARCH}.linux.gcc.exe = \"${CC/ */}\"" > koch.nim.cfg
echo 'path="$lib/deprecated/core"
path="$lib/deprecated/pure"
path="$lib/pure/collections"
path="$lib/pure/concurrency"
path="$lib/impure"
path="$lib/wrappers"
path="$lib/wrappers/linenoise"
path="$lib/windows"
path="$lib/posix"
path="$lib/js"
path="$lib/pure/unidecode"
path="$lib/arch"
path="$lib/core"
path="$lib/pure"' >> koch.nim.cfg
nim c --cpu:${xTARGET_ARCH} --os:linux -d:release --cc:gcc --skipCfg --skipUserCfg --skipParentCfg --compileOnly --genScript --nimcache:nimcache koch
cd nimcache
sed -i 's/gcc/$CC/' compile_koch.sh
chmod +x ./compile_koch.sh
./compile_koch.sh
cd ..

#UNABLE TO COMPILE...
##koch tools -d:release
#cat koch.nim.cfg >> dist/nimble/src/nimble.nim.cfg
#nim c --noNimblePath -p:compiler --cpu:${xTARGET_ARCH} --os:linux -d:release --cc:gcc --skipCfg --skipUserCfg --skipParentCfg --compileOnly --genScript --nimcache:nimcache2 dist/nimble/src/nimble.nim
#cd nimcache2
#sed -i 's/gcc/$CC/' compile_nimble.sh
## need "-dl" appended to last line, clever sed...
#sed -i '$s/$/ -dl/' compile_nimble.sh
#chmod +x ./compile_nimble.sh
#./compile_nimble.sh
#cd ..
}

do_install () {
./install.sh pkg
install -d ${D}${bindir}
install -d ${D}${includedir}
install -d ${D}${libdir}/nim
install -m 755 pkg/nim/bin/nim ${D}${bindir}/
install -m 644 pkg/nim/lib/cycle.h ${D}${includedir}/
install -m 644 pkg/nim/lib/nimbase.h ${D}${includedir}/
for FN in nimble nimgrep nimsuggest
do
if [ -f pkg/nim/bin/${FN} ];then
install -m 755 pkg/nim/bin/${FN} ${D}${bindir}/
fi
done
install -m 755 nimcache/koch ${D}${bindir}/
(
cd pkg/nim/lib
for dir in $(find . -mindepth 1 -type d);do
install -d ${D}${libdir}/nim/${dir}
done
for file in $(find . -mindepth 1 -type f);do
install -m 755 "${file}" ${D}${libdir}/nim/${file}
done
)
install -d ${D}/etc
install -d ${D}/etc/nim
install -m 644 pkg/nim/config/nim.cfg ${D}/etc/nim/nim.cfg.new
install -m 644 pkg/nim/config/nimdoc.cfg ${D}/etc/nim/nimdoc.cfg.new
install -m 644 pkg/nim/config/nimdoc.tex.cfg ${D}/etc/nim/nimdoc.tex.cfg.new
install -m 644 pkg/nim/config/rename.rules.cfg ${D}/etc/nim/rename.rules.cfg.new
}

Koch is a kind of replacement for makefiles, and can be used in the nim source package to compile some extra "tools". Except, I could not get koch to work in the OE environment. Aguspiza couldn't either.

Nim has a "home grown" build system, and from my newcomer perspective, it seems very clumsy.

The intention is to have Nim and BaCon compilers in the "devx" SFS in the next release of Easy, for us to play with.

EDIT 2022-08-23:
Take-2 success, have compiled 'nimble', etc.:

https://bkhome.org/news/202208/nim-compiled-in-openembedded-take-2.html    

Tags: easy