site  contact  subhomenews

Nim 1.6.8 compiled in OE with simplified recipe

September 28, 2022 — BarryK

I posted about cross-compiling Nim 1.6.6 in OpenEmbedded/Yocto:

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

I learnt a bit more since that attempt. Now have compiled Nim 1.6.8 and the recipe is greatly simplified and more logical. Firstly, here is recipe file 'nim-native_1.6.8.bb':

# Recipe created by recipetool
# recipetool create -o nim_1.6.8.bb https://nim-lang.org/download/nim-1.6.8.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] = "d2a445ba7deeb27375e145826f35033e"
SRC_URI[sha256sum] = "0f5b65cdb60f78af41cb075c238983689a1e1f7e25c819f179862c18a484cf57"

# 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
}

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
)

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"' > nim.cfg
install -d ${D}${sysconfdir}/nim
install -m644 nim.cfg ${D}${sysconfdir}/nim/
}

...nothing new there. The next recipe cross-compiles for the target, and this is where the improvements are. Recipe file 'nim_1.6.8.bb':

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

# ref: https://github.com/aguspiza/meta-nim
# ref: https://bkhome.org/news/202208/considering-adopting-nim-language.html

## 20220823 PR_NUM is defined in local.conf, currently r9
#PR = "r${@int(PR_NUM) + 1}"

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 openssl-native openssl"

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

SRC_URI[md5sum] = "d2a445ba7deeb27375e145826f35033e"
SRC_URI[sha256sum] = "0f5b65cdb60f78af41cb075c238983689a1e1f7e25c819f179862c18a484cf57"

# 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}

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

yCC="${CC}"
xCC="${CC#* }"
export CC="${CC/ */}"
#note: nim will read etc/nim/nim.cfg installed by nim-native

nim c --lib:${WORKDIR}/recipe-sysroot-native/usr/lib/nim --opt:size --mm:orc -d:useMalloc --passC:"-flto ${xCC}" --passL:"-flto ${xCC} -ldl" --cpu:${xTARGET_ARCH} --os:linux -d:release --cc:env --skipUserCfg --skipParentCfg --skipProjCfg --nimcache:nimcache1 koch

nim c --noNimblePath -p:compiler --lib:${WORKDIR}/recipe-sysroot-native/usr/lib/nim --opt:size --mm:orc --passC:"-flto ${xCC}" --passL:"-flto ${xCC} -ldl" --cpu:${xTARGET_ARCH} --os:linux -d:release --cc:env --skipUserCfg --skipParentCfg --nimcache:nimcache2 dist/nimble/src/nimble.nim

nim c --noNimblePath -p:compiler --lib:${WORKDIR}/recipe-sysroot-native/usr/lib/nim --opt:size --mm:orc --passC:"-flto ${xCC}" --passL:"-flto ${xCC} -ldl" --cpu:${xTARGET_ARCH} --os:linux -d:release --cc:env --skipUserCfg --skipParentCfg --nimcache:nimcache3 tools/nimgrep.nim

#"-p:compiler" doesn't work, reports
# "Error: cannot open file: compiler/options" hmmm, "-p:." has fixed it...
nim c --noNimblePath -p:compiler -p:. --lib:${WORKDIR}/recipe-sysroot-native/usr/lib/nim --opt:size --mm:orc --passC:"-flto ${xCC}" --passL:"-flto ${xCC} -ldl" --cpu:${xTARGET_ARCH} --os:linux -d:release --cc:env --skipUserCfg --skipParentCfg --nimcache:nimcache4 nimsuggest/nimsuggest.nim

export CC="${yCC}"
}

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 dist/nimble/src/nimble ${D}${bindir}/
install -m 755 tools/nimgrep ${D}${bindir}/
install -m 755 nimsuggest/nimsuggest ${D}${bindir}/
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
)
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
}

Not only is Nim an extremely elegant language, it is also quite simple to cross-compile, once the build system is understood. I am still a beginner, but was able to figure things out to create the above build recipe.

Unlike Rust; cross-compiling in OE is incredibly complicated. The developers have been working on it for years, and still haven't succeeded in compiling 'rustc' and tools for the target (perhaps they did succeed previously?). I had a go at building it; failure. They are quite open about it, quoting from here:

https://github.com/meta-rust/meta-rust

"What doesn't work: rust built for target"

Note, I did succeed in compiling 'libstd-rs' and 'rust-llvm' for the target architecture.    

Tags: easy