I am researching starting a development project running some native code on a Chumby, so I figured I’d dive in with some cross-compiling to see how much trouble it would be to get something up and running on (one of) my Chumby One(s). Turns out, it wasn’t too bad.
I use GNU screen extensively at work and at play, so I figured for this project it will be helpful. Getting it running will be the very first step in my quest to run my synchronized Christmas lights from a Chumby.
The first step was getting the toolchain up and running on my desktop machine, which was really simple using the toolchain instructions on the Chumby wiki.
Then, I ran through some issues due to screen’s configure script erroring out because it cannot run binaries for test programs. Turns out generating the configure using autoconf with the option “–warnings=cross” will spit out anything it thinks will give you trouble with cross compilation. Regenerating the configure using autoconf told me that AC_TRY_RUN wasn’t setup with a default for cross compile. The documentation for autoconf is somewhat easy to read and I simply had to add a default cross compile case in a few places in the configure.in for screen. I was lucky and didn’t have to add any other tests to get something working, with the exception of a choice of sockets or fifos. I chose fifos, although Chumby’s rootfs should also support using sockets.
Once I had that going, I ran into a problem where tgetent wasn’t being found. That is a function used to get the terminal entry for things like the screen size, color rendering, etc. and is available from a few packages. First I tried using ncurses, which resulted in a binary that compiled, but wouldn’t run. A few straces and I wasn’t getting anywhere so I cheated. I also found a thread on the Chumby forums with a binary somebody grabbed from a Debian armel build, which ran on my Chumby, but needed 2 shared libraries. I ran strings on the binary and saw some interesting things which led me to try termcap as the next source of tgetent() instead of ncurses when building screen.
As soon as I had this, screen compiled (statically linked) and ran on my Chumby. I haven’t done rigorous testing on the binary, but split works, and a few quick things I threw at it. Pretty neat! I was rebuilding enough after each little change that I wrote a script for the build, and have a patch for screen’s configure.in that generates the configure.
update_configure_in.patch: Patch to update screen’s configure.in to allow cross-compilation.
--- screen-4.0.3/configure.in.original 2011-03-21 22:28:36.613330001 -0700
+++ screen-4.0.3/configure.in 2011-03-21 22:56:13.837330001 -0700
@@ -54,14 +54,14 @@
export CC
exec $0 $configure_args
fi
-])
+],true)
AC_TRY_RUN(main(){exit(0);},,
exec 5>&2
eval $ac_link
AC_NOTE(CC=$CC; CFLAGS=$CFLAGS; LIBS=$LIBS;)
AC_NOTE($ac_compile)
-AC_MSG_ERROR(Can't run the compiler - sorry))
+AC_MSG_ERROR(Can't run the compiler - sorry),true)
AC_TRY_RUN([
main()
@@ -69,7 +69,7 @@
int __something_strange_();
__something_strange_(0);
}
-],AC_MSG_ERROR(Your compiler does not set the exit status - sorry))
+],AC_MSG_ERROR(Your compiler does not set the exit status - sorry),,true)
AC_PROG_AWK
@@ -358,7 +358,7 @@
exit(0);
}
], AC_NOTE(- your fifos are usable) fifo=1,
-AC_NOTE(- your fifos are not usable))
+AC_NOTE(- your fifos are not usable),fifo=1)
rm -f /tmp/conftest*
if test -n "$fifo"; then
@@ -408,7 +408,7 @@
exit(0);
}
], AC_NOTE(- your implementation is ok),
-AC_NOTE(- you have a broken implementation) AC_DEFINE(BROKEN_PIPE) fifobr=1)
+AC_NOTE(- you have a broken implementation) AC_DEFINE(BROKEN_PIPE) fifobr=1,true)
rm -f /tmp/conftest*
fi
@@ -470,7 +470,7 @@
exit(0);
}
], AC_NOTE(- your sockets are usable) sock=1,
-AC_NOTE(- your sockets are not usable))
+AC_NOTE(- your sockets are not usable),true)
rm -f /tmp/conftest*
if test -n "$sock"; then
@@ -502,7 +502,7 @@
}
],AC_NOTE(- you are normal),
AC_NOTE(- unix domain sockets are not kept in the filesystem)
-AC_DEFINE(SOCK_NOT_IN_FS) socknofs=1)
+AC_DEFINE(SOCK_NOT_IN_FS) socknofs=1,true)
rm -f /tmp/conftest*
fi
@@ -635,7 +635,7 @@
exit(0);
}
],AC_NOTE(- select is ok),
-AC_NOTE(- select can't count) AC_DEFINE(SELECT_BROKEN))
+AC_NOTE(- select can't count) AC_DEFINE(SELECT_BROKEN),true)
dnl
dnl **** termcap or terminfo ****
@@ -668,7 +668,7 @@
{
exit(strcmp(tgoto("%p1%d", 0, 1), "1") ? 0 : 1);
}], AC_NOTE(- you use the termcap database),
-AC_NOTE(- you use the terminfo database) AC_DEFINE(TERMINFO))
+AC_NOTE(- you use the terminfo database) AC_DEFINE(TERMINFO),true)
AC_CHECKING(ospeed)
AC_TRY_LINK(extern short ospeed;,ospeed=5;,,AC_DEFINE(NEED_OSPEED))
@@ -804,7 +804,7 @@
AC_NOTE(- can't determine - assume ptys are world accessable)
fi
]
-)
+,true)
rm -f conftest_grp
fi
@@ -947,7 +947,7 @@
exit(1);
exit(0);
}
- ],avensym=$av;break)
+ ],avensym=$av;break,,true)
if test "$av" = _Loadavg; then
nlist64='#define nlist nlist64'
fi
@@ -1080,7 +1080,7 @@
#endif
exit(0);
}
-],,AC_DEFINE(SYSVSIGS))
+],,AC_DEFINE(SYSVSIGS),true)
fi
@@ -1160,7 +1160,7 @@
if (strncmp(buf, "cdedef", 6))
exit(1);
exit(0); /* libc version works properly. */
-}], AC_DEFINE(USEBCOPY))
+}], AC_DEFINE(USEBCOPY),,true)
AC_TRY_RUN([
#define bcopy(s,d,l) memmove(d,s,l)
@@ -1175,7 +1175,7 @@
if (strncmp(buf, "cdedef", 6))
exit(1);
exit(0); /* libc version works properly. */
-}], AC_DEFINE(USEMEMMOVE))
+}], AC_DEFINE(USEMEMMOVE),,true)
AC_TRY_RUN([
@@ -1191,7 +1191,7 @@
if (strncmp(buf, "cdedef", 6))
exit(1);
exit(0); /* libc version works properly. */
-}], AC_DEFINE(USEMEMCPY))
+}], AC_DEFINE(USEMEMCPY),,true)
AC_MSG_CHECKING(long file names)
(echo 1 > /tmp/conftest9012345) 2>/dev/null
@@ -1266,7 +1266,7 @@
dnl Ptx bug workaround -- insert -lc after -ltermcap
test -n "$seqptx" && LIBS="-ltermcap -lc -lsocket -linet -lnsl -lsec -lseq"
-AC_TRY_RUN(main(){exit(0);},,AC_MSG_ERROR(Can't run the compiler - internal error. Sorry.))
+AC_TRY_RUN(main(){exit(0);},,AC_MSG_ERROR(Can't run the compiler - internal error. Sorry.),true)
ETCSCREENRC="\"/usr/local/etc/screenrc\""
if test -n "$prefix"; then
build.sh: Simple (hackish) shell script to cross-compile screen for chumby platforms using the chumby provided toolchain.
#!/bin/bash
die()
{
echo $1
exit
}
wget http://mirrors.kernel.org/gnu/termcap/termcap-1.3.1.tar.gz
tar xzpvf termcap-1.3.1.tar.gz || die "Failed ot untar termcap"
pushd termcap-1.3.1 || die "No termcap"
autoconf
./configure --host=arm-linux --prefix=$(pwd)/install || die "Failed termcap configure"
make && make install || die "Failed to make termcap"
popd
export LDFLAGS="-L$(pwd)/termcap-1.3.1/install/lib/"
export LIBS="-ltermcap"
export CFLAGS="-DDEBUG"
wget http://mirrors.kernel.org/gnu/screen/screen-4.0.3.tar.gz
tar xzpvf screen-4.0.3.tar.gz || die "Failed to untar screen"
pushd screen-4.0.3
rm -f configure
patch -p1 < ../update_configure_in.patch
autoconf --warnings=cross
./configure --host=arm-linux --prefix=$(pwd)/install || die "Failed screen configure"
make && make install || die "Failed to make screen"
popd
unset LDFLAGS
unset LIBS
unset CFLAGS
Part 1 of my “Chumby Remote” series will cover the Chumby classic proc entry for emulating touchscreen clicks and bend sensor presses.