OpenWrt Forum Archive

Topic: need help for crosscompiling

The content of this topic has been archived on 6 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Hello folks!

I had Compiled Binary Images for several routers, several times. ( i think the toolchain is up as it schould)
Now i need to Compile a package which is called cntlm.
It is an light weight Authenticator for Microsoft ISA servers.

So here we go:

This is my Makefile located in /home/cyberpunk/build/trunk/package/cntlm

include $(TOPDIR)/rules.mk
PKG_NAME:=cntlm
PKG_RELEASE:=1
PKG_VERSION:=0.35.1
PKG_SOURCES:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://10.8.0.1:81/
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=utils
CATEGORY:=Utilities
TITLE:=A authenticator for Microsoft ISA Server
TITLE:=$(PKG_NAME)
endef
MAKE_FLAGS += \
    CFLAGS="$(TARGET_CFLAGS)" \
    CXXFLAGS="$(TARGET_CXXFLAGS) -fno-builtin -fno-rtti -nostdinc++" \
    CPPFLAGS="$(TARGET_CPPFLAGS) -I$(STAGING_DIR)/usr/include/uClibc++ -I$(LINUX_DIR)/include" \
    LDFLAGS="$(TARGET_LDFLAGS) $(LDFLAGS)" \
    LIBS="$(TARGET_LIBS) -nodefaultlibs -luClibc++ -lm" \
    DESTDIR="$(PKG_INSTALL_DIR)"
define Build/Prepare
    mkdir -p $(PKG_BUILD_DIR)
    $(CP) $(PKG_SOURCES)/* $(PKG_BUILD_DIR)/
endef
define Build/Compile
    $(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_FLAGS);
endef
define Package/$(PKG_NAME)/install
    $(INSTALL_DIR) $(1)/bin
    $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/bin/
endef
$(eval$(callBuildPackage,$(PKG_NAME)))

The http server is there with the file on it. But at first the package isn schown in menuconfig.

Strange:
Package is displayed when i name the Folder /home/cyberpunk/build/trunk/package/helloworld (Makefile lives here) and the PKG_NAME:=helloworld (as i startet through an toturial)
am i stupid?
Does it matter what its named ?
as i noticed the package is only displayed in Menuconfig when i named like this


Ok so far so good. so i named the tar.gz on my httpserver helloworld.tar.gz :]]
Inside the tarball there is a Configure and a make file as i often Compiled packages for my ubuntu laptop.

When i launch :

make package/helloworld/clean V=99

i get:

make[1]: Entering directory `/home/cyberpunk/build/trunk'
make[1]: *** No rule to make target `package/helloworld/clean'.  Stop.
make[1]: Leaving directory `/home/cyberpunk/build/trunk'
make: *** [package/helloworld/clean] Fehler 2

whats wrong here ?

Cheers!

I tried also This:

http://wiki.openwrt.org/doc/devel/crosscompile

But i dont understand at all, maybe people that are working several years with cross compiling wink

    Follow the build instructions outlined in Building OpenWrt                                                                               
# Yes Sir! no problem! thats an easy step by step
    Locate the toolchain binaries in the staging_dir/toolchain-architecture_gcc-compilerver_uClibc-libcver/bin/ directory
# Yes Sir! binary oh uh, there are no binarys oohhmm and what is a staging dir?
    Add the toolchain directory to the $PATH environment variable
# Yes $PATH of course, who knows it not? :] *ironic Anyone ever trie to google it? Try and have fun Really!!
    Download and unpack the code to be compiled, change into the unpacked directory
# Check
    Pass the target to the build system of the package to compile
        For GNU configure, use --target=architecture-openwrt-linux-uclibc
        For GNU make, override the CC and LD environment variables
            make CC=architecture-openwrt-linux-uclibc-gcc LD=architecture-openwrt-linux-uclibc-ld
# should be ok and doneable
    If compilation aborts due to missing header files or shared objects, you might need to override CFLAGS and LDFLAGS to point to the staging_dir/target-architecture_uClibc-libcver/usr/include and …/usr/lib directories
    Debugging requires gdb in the toolchain. Default config does not include it. Include using make menuconfig. [Advanced configuration options?Toolchain Options?Build gdb]
    Remote debugging can be done using script ./scripts/remote-gdb

(Last edited by derdigge on 18 Aug 2011, 10:42)

@derübergewichtige:
Hmm, try this page:   http://wiki.openwrt.org/about/toolchain

Afaik http://wiki.openwrt.org/doc/devel/crosscompile is meant as a short guide to quickly cross-compile stuff.


@arokh: I think I see what you mean by "lacking organization". I hope you also see, that without such FEEDBACK I do not see where things are bumpy. Also, I am no the only one able to edit that wiki.

I think organizing the current wiki would be like polishing a turd smile

There's lots of information about the buildroot on the wiki, but try following any of the articles and you'll soon find that most are incorrect and outdated.

arokh wrote:

I think organizing the current wiki would be like polishing a turd smile

What does "turd" mean? Oh, "poop", well, that's a pictographic analogy.  But could you be more specific?

arokh wrote:

There's lots of information about the buildroot on the wiki, but try following any of the articles and you'll soon find that most are incorrect and outdated.

Yeah... I'll get right to it...

danke, ich grab mich mal durch

ok i read through the postes sites / wiki / examples now my Makefile will look like this.
Not all questions are clear to me now, i commented it.

include $(TOPDIR)/rules.mk

PKG_NAME:=cntlm
PKG_VERSION:=0.35.1
PKG_RELEASE:=1

PKG_BUILD_DIR:=$(BUILD_DIR)/cntlm-$PKG_VERSION
PKG_SOURCE:=$PKG_NAME-$PKG_VERSION.tar.gz
PKG_SOURCE_URL:=@SF                                      # is this enough for SF hosted tarballs? 
PKG_MD5SUM:=2547c73a1159062fdaa1877cc03a22f6
PKG_CAT:=zcat                                                # not sure about that!

include $(INCLUDE_DIR)/package.mk

define Package/cntlm
  SECTION:=base
  CATEGORY:=Network
  TITLE:=An ISA-Server Authentication tool for linux with socks support
  URL:=http://cntlm.sourceforge.net/
endef

define Package/cntlm/description
 It Connects to an ISA-Server with NTLM authentication support and provides an
 http proxy on local port instead.
endef

define Package/bridge/install
        $(INSTALL_DIR) $(1)/usr/bin
endef

$(eval $(call BuildPackage,bridge))

i had not tried it yet.
Now i should see a cntlm package in Menuconfig /base/network.?

cheers
derdigge

EDIT:

This Makefile is really shitty but dont know why !!!
Its a complete copy of the might WORKING wiki one.
I cant see what i am doing wrong.

You truly never will find a more simple an dependless package to compile.
Please someone help me out!

cheers

(Last edited by derdigge on 20 Aug 2011, 18:04)

I am still hammering my had against the wall!!
But i think i am closer to the solution!
The File is Downloaded from SF and it is unziped by Make.
But it wont be compiled
Please can someone point me in the right direction??

I think i know where my Problem is, but i cant imagine any next step to do.

it anywhere arround here:

define Build/compile
    $(MAKE) -C $(PKG_BUILD_DIR)
endef

Cause i get this error when i do make package/cntlm/compile V=99:

make[1]: Entering directory `/home/cyberpunk/build/backfire'
make[2]: Entering directory `/home/cyberpunk/build/backfire/package/cntlm'
make[2]: Nothing to be done for `compile'.
make[2]: Leaving directory `/home/cyberpunk/build/backfire/package/cntlm'
make[1]: Leaving directory `/home/cyberpunk/build/backfire'

The completeMakefile in ./packages :

include $(TOPDIR)/rules.mk

PKG_NAME:=cntlm
PKG_VERSION:=0.35.1
PKG_RELEASE:=1

PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SF/cntlm
PKG_MD5SUM:=2547c73a1159062fdaa1877cc03a22f6

PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)

include $(INCLUDE_DIR)/package.mk

define Package/cntlm
    SECTION:=net
    CATEGORY:=Network
    SUBMENU:=Firewall Tunnel
    TITLE:=NTLM Authentication Proxy for MS ISA Server
endef

define Package/cntlm/description
endef

define Build/compile
    $(MAKE) -C $(PKG_BUILD_DIR)
endef

define Package/cntml/install
    $(INSTALL_DIR) $(1)/usr/bin
    $(CP) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/sbin/
endef

$(eval $(call BuildPackage,cntlm))

The cntlm Makefile from the tarball:

#
# You can tweak these three variables to make things install where you
# like, but do not touch more unless you know what you are doing. ;)
#
SYSCONFDIR=/usr/local/etc
BINDIR=/usr/local/bin
MANDIR=/usr/local/man

#
# Careful now...
# __BSD_VISIBLE is for FreeBSD AF_* constants
# _ALL_SOURCE is for AIX 5.3 LOG_PERROR constant
#
CC=gcc
OBJS=utils.o ntlm.o xcrypt.o config.o socket.o acl.o auth.o http.o proxy.o 
CFLAGS=$(FLAGS) -std=c99 -Wall -pedantic -O3 -D__BSD_VISIBLE -D_ALL_SOURCE -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200112 -D_ISOC99_SOURCE -D_REENTRANT -DVERSION=\"`cat VERSION`\"
LDFLAGS=-lpthread
NAME=cntlm
VER=`cat VERSION`
DIR=`pwd`

$(NAME): configure-stamp $(OBJS)
    @echo "Linking $@"
    @$(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS)

proxy.o: proxy.c
    @echo "Compiling $<"
    @if [ -z "$(SYSCONFDIR)" ]; then \
        $(CC) $(CFLAGS) -c proxy.c -o $@; \
    else \
        $(CC) $(CFLAGS) -DSYSCONFDIR=\"$(SYSCONFDIR)\" -c proxy.c -o $@; \
    fi

.c.o:
    @echo "Compiling $<"
    @$(CC) $(CFLAGS) -c -o $@ $<

install: $(NAME)
    # AIX?
    if [ -f /usr/bin/oslevel ]; then \
        install -O root -G system -M 755 -S -f $(BINDIR) $(NAME); \
        install -O root -G system -M 644 -f $(MANDIR)/man1 doc/$(NAME).1; \
        install -O root -G system -M 600 -c $(SYSCONFDIR) doc/$(NAME).conf; \
    else \
        install -D -o root -g root -m 755 -s $(NAME) $(BINDIR)/$(NAME); \
        install -D -o root -g root -m 644 doc/$(NAME).1 $(MANDIR)/man1/$(NAME).1; \
        [ -f $(SYSCONFDIR)/$(NAME).conf -o -z "$(SYSCONFDIR)" ] \
            || install -D -o root -g root -m 600 doc/$(NAME).conf $(SYSCONFDIR)/$(NAME).conf; \
    fi
    @echo; echo "Cntlm will look for configuration in $(SYSCONFDIR)/$(NAME).conf"

rpm:
    if [ `id -u` = 0 ]; then \
        redhat/rules binary; \
        redhat/rules clean; \
    else \
        fakeroot redhat/rules binary; \
        fakeroot redhat/rules clean; \
    fi

tgz:
    mkdir -p tmp
    rm -f tmp/$(NAME)-$(VER)
    ln -s $(DIR) tmp/$(NAME)-$(VER)
    sed "s/^\./$(NAME)-$(VER)/" doc/files.txt | tar zchf $(NAME)-$(VER).tar.gz --no-recursion -C tmp -T -
    rm tmp/$(NAME)-$(VER)
    rmdir tmp 2>/dev/null || true

win:
    groff -t -e -mandoc -Tps doc/cntlm.1 | ps2pdf - win32/cntlm_manual.pdf
    cat doc/cntlm.conf | unix2dos > win32/cntlm.ini
    cp /bin/cygwin1.dll /bin/cygrunsrv.exe win32/
    strip cntlm.exe
    cp cntlm.exe win32/
    rm -f cntlm-install
    ln -s win32 cntlm-install
    zip -r cntlm-$(VER)-win32.zip cntlm-install -x *.svn/*
    rm -f cntlm-install cntlm-$(VER)-win32.zip.sig

uninstall:
    rm -f $(BINDIR)/$(NAME) $(MANDIR)/man1/$(NAME).1 2>/dev/null || true

clean:
    @rm -f *.o cntlm cntlm.exe configure-stamp build-stamp config/config.h 2>/dev/null
    @rm -f cntlm-install win32/cyg* win32/cntlm* 2>/dev/null
    @rm -f config/endian config/gethostname config/strdup config/socklen_t config/*.exe
    @if [ -h Makefile ]; then rm -f Makefile; mv Makefile.gcc Makefile; fi

cleanp: clean
    @rm -f *.deb *.tgz *.tar.gz *.rpm *.o tags cntlm pid massif* callgrind* 2>/dev/null

distclean: clean
    if [ `id -u` = 0 ]; then \
        redhat/rules clean; \
    else \
        fakeroot redhat/rules clean; \
    fi

cheers

(Last edited by derdigge on 23 Aug 2011, 03:28)

I lack the knowledge to help you, sorry.

When you found the solution, you could bother to mend the wiki, so others do not have to go through this again and again and again.

derdigge wrote:

I am still hammering my had against the wall!!
But i think i am closer to the solution!
The File is Downloaded from SF and it is unziped by Make.
But it wont be compiled
Please can someone point me in the right direction??

I think i know where my Problem is, but i cant imagine any next step to do.

select your package for inclusion in the compilation process through "make menuconfig"

Hans.

Thanks verry much for the replys!

The package is selected as <M> inside menuconfig!

change "define Build/compile" to "define Build/Compile"

Hans.

(Last edited by zandbelt on 23 Aug 2011, 15:45)

Thanks for your time!

I am Getting now :

make pakage/cntlm/compile V=99
Collecting package info: done
make[1]: Entering directory `/home/cyberpunk/build/backfire'
make[1]: *** No rule to make target `pakage/cntlm/compile'.  Stop.
make[1]: Leaving directory `/home/cyberpunk/build/backfire'
make: *** [pakage/cntlm/compile] Fehler 2

Package is still selected in menuconfig,
and btw i am using the Backfire svn for this toolchain.

another typo: type "make package/cntlm/compile V=99" instead of "make pakage/cntlm/compile V=99"

Hans.

(Last edited by zandbelt on 23 Aug 2011, 16:49)

I am really happy that someone takes the time to help me!

Now i corrected the typos. Thanks for the advice!!

- The tarball is downloaded by typing 'make package/cntlm/download'
- The tarball is extracted by typing 'make package/cntlm/'


- The source wont do by typing 'make package/cntlm/compile' :

derdigge@ubuntu:~/openwrt/backfire$ make package/cntlm/compile V=99
make[1]: Entering directory `/home/derdigge/openwrt/backfire'
make[2]: Entering directory `/home/derdigge/openwrt/backfire/package/cntlm'
make[2]: Nothing to be done for `compile'.
make[2]: Leaving directory `/home/derdigge/openwrt/backfire/package/cntlm'
make[1]: Leaving directory `/home/derdigge/openwrt/backfire'
derdigge@ubuntu:~/openwrt/backfire$

my Makefile located in ./Packages looks now like this:

include $(TOPDIR)/rules.mk

PKG_NAME:=cntlm
PKG_VERSION:=0.35.1
PKG_RELEASE:=1

PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SF/cntlm
PKG_MD5SUM:=2547c73a1159062fdaa1877cc03a22f6

PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)

include $(INCLUDE_DIR)/package.mk

define Package/cntlm
    SECTION:=net
    CATEGORY:=Network
    SUBMENU:=Firewall Tunnel
    TITLE:=NTLM Authentication Proxy for MS ISA Server
endef

define Package/cntlm/description
endef

define Build/Compile
    $(MAKE) -C $(PKG_BUILD_DIR)
endef

define Package/cntml/install
    $(INSTALL_DIR) $(1)/usr/bin
    $(CP) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/sbin/
endef

$(eval $(call BuildPackage,cntlm))

Please someone help me out here! cntlm is one of the greatest tools to picking holes into firewalls
if its combined with ssh or openvpn. (tested under ubuntu - ten times better than ntlmaps or crorksrew)
Instead of other tools from this section this one here is really performant!!
It would be an enrichment for the openwrt repository i think :]

cheers!
derdigge

(Last edited by derdigge on 24 Aug 2011, 04:58)

there are 3 typos left:

* "define Package/cntml/install" should read "define Package/cntlm/install" (switch l and m)
* commands (cq. in sections Build/Compile and Package/cntml/install) should be preceded by a tab instead of spaces
* section Package/cntml/install should contain "$(INSTALL_DIR) $(1)/usr/sbin" (sbin instead of bin)

the first one really set you on the wrong foot because it suppresses errors on the second one

Hans.

I Never mind that the solution is that damn simple.
All over the time i simply had misstiping problems!
I am such an idiot .....

he needs to do ./configure before doing make,
i am googling it as while you read:]

Now the problem is here:  (i think)

make[3]: *** No rule to make target `configure-stamp', needed by `cntlm'.  Stop.

Complete output:

derdigge@ubuntu:~/openwrt/backfire$ make package/cntlm/compile V=99
make[1]: Entering directory `/home/derdigge/openwrt/backfire'
make[2]: Entering directory `/home/derdigge/openwrt/backfire/package/cntlm'
gzip -dc /home/derdigge/openwrt/backfire/dl/cntlm-0.35.1.tar.gz | /bin/tar -C /home/derdigge/openwrt/backfire/build_dir/target-mips_r2_uClibc-0.9.30.1/cntlm-0.35.1/.. -xf - 
ls: cannot access ./patches: No such file or directory
touch /home/derdigge/openwrt/backfire/build_dir/target-mips_r2_uClibc-0.9.30.1/cntlm-0.35.1/.prepared_4105704930ceb65e05df5970e24fefa3
touch /home/derdigge/openwrt/backfire/build_dir/target-mips_r2_uClibc-0.9.30.1/cntlm-0.35.1/.configured_
make -C /home/derdigge/openwrt/backfire/build_dir/target-mips_r2_uClibc-0.9.30.1/cntlm-0.35.1/
make[3]: Entering directory `/home/derdigge/openwrt/backfire/build_dir/target-mips_r2_uClibc-0.9.30.1/cntlm-0.35.1'
make[3]: *** No rule to make target `configure-stamp', needed by `cntlm'.  Stop.
make[3]: Leaving directory `/home/derdigge/openwrt/backfire/build_dir/target-mips_r2_uClibc-0.9.30.1/cntlm-0.35.1'
make[2]: *** [/home/derdigge/openwrt/backfire/build_dir/target-mips_r2_uClibc-0.9.30.1/cntlm-0.35.1/.built] Error 2
make[2]: Leaving directory `/home/derdigge/openwrt/backfire/package/cntlm'
make[1]: *** [package/cntlm/compile] Error 2
make[1]: Leaving directory `/home/derdigge/openwrt/backfire'
make: *** [package/cntlm/compile] Fehler 2
derdigge@ubuntu:~/openwrt/backfire$

(Last edited by derdigge on 24 Aug 2011, 22:21)

I think "he" is using the wrong Compiler.
I cntlm binary is buil but not in mips, cause i can run it normaly under ubuntu.

Configure is running now, but with following Output:

Using /usr/bin/gcc to compile Cntlm
Checking endian... little endian
Checking strdup... yes
Checking socklen_t... yes
Checking gethostname... ubuntu

Makefile now looks like this:

include $(TOPDIR)/rules.mk

PKG_NAME:=cntlm
PKG_VERSION:=0.35.1
PKG_RELEASE:=1

PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@SF/cntlm
PKG_MD5SUM:=2547c73a1159062fdaa1877cc03a22f6

PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)

include $(INCLUDE_DIR)/package.mk

define Package/cntlm
    SECTION:=net
    CATEGORY:=Network
    SUBMENU:=Firewall Tunnel
    TITLE:=NTLM Authentication Proxy for MS ISA Server
endef

define Package/cntlm/description
endef

define Build/Configure
    $(call Build/Configure/Default)
endef

define Build/Compile
    $(MAKE) -C $(PKG_BUILD_DIR)/
endef

define Package/cntlm/install
    $(INSTALL_DIR) $(1)/usr/bin
    $(CP) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/bin/
endef

$(eval $(call BuildPackage,cntlm))

now ive tried:

define Build/Configure
    $(call Build/Configure/Default,--target=$(GNU_TARGET_NAME))
endef

but still getting:

./configure --target=mips-openwrt-linux --host=mips-openwrt-linux --build=i686-linux-gnu --program-prefix="" --program-suffix="" --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/lib --sysconfdir=/etc --datadir=/usr/share --localstatedir=/var --mandir=/usr/man --infodir=/usr/info --disable-nls   --target=mips-openwrt-linux; fi; )
Using /usr/bin/gcc to compile Cntlm
Checking endian... little endian
Checking strdup... yes
Checking socklen_t... yes
Checking gethostname... ubuntu

it isnt crosscompiled, cause i can execute it, using ubuntu

thats an issue with the package's configure script; you need to fix that manually to allow crosscompiling by correctly interpreting the configure environment parameters

Hans.

Thanks for your reply!

I am not verry familar with all that stuff! Any idea how to do so?

configure script:

!/bin/sh
#
# Search for GCC or XL C/C++, former if both exist
#
# To add another compiler, just create Makefile.XXX and add XXX to $CCS
#
# To prevent ugly Makefile extensions, underscore and chars following it
# in the name XXX are automatically removed before locating relevant
# Makefile. This is why compiler "xlc_r" has automatic Makefile extension
# just "xlc". This can be disabled if neccessary.
#

CCS="xlc_r gcc"

for c in $CCS; do
    if CCPATH=`which $c 2>&1`; then
        CC="$c"
        break
    fi
done

if [ -z "$CC" ]; then
    echo "Unable to find GNU GCC or IBM XL C/C++. Fix your PATH!"
    exit 1
else
    echo "Using $CCPATH to compile Cntlm"
    [ -h Makefile ] && rm -f Makefile 2>/dev/null
    case "$CC" in
        gcc)
            # default Makefile is for GCC; just revert back to
            # GCC if Makefile is linked to other compiler version
            if [ ! -f Makefile ]; then
                mv Makefile.gcc Makefile
            fi
            ;;
        *)
            # backup default GCC Makefile and create a link to other
            if [ -f Makefile ]; then
                mv Makefile Makefile.gcc
            fi

            EXT=`echo "$CC" | sed 's/_.*//'`
            ln -s Makefile.$EXT Makefile
            ;;
    esac
fi

STAMP=configure-stamp
CONFIG=config/config.h
TESTS="endian strdup socklen_t gethostname"

#[ -f $STAMP ] && exit 0
touch $STAMP

rm -f $CONFIG
for i in $TESTS; do
    printf "Checking $i... "
    printf "#define config_$i " >> $CONFIG
    OUT=`$CC -D_POSIX_C_SOURCE=199506L -D_ISOC99_SOURCE -D_REENTRANT -o config/$i config/$i.c 2>&1`
    rc=$?

    if [ $rc -ne 0 ]; then # -o -n "$OUT" ]; then
        rc=0
        RET=no
    else
        RET=`./config/$i`
        rc=$?
        [ -z "$RET" ] && if [ $rc -eq 0 ]; then RET="no"; else RET=yes; fi
    fi

    echo $rc >> $CONFIG
    echo $RET
done

The discussion might have continued from here.