-
-
Save zed/735d280eec2a5124279a to your computer and use it in GitHub Desktop.
A Hello, world standalone program with embed Python that uses Boost.Python to expose C++ class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/main | |
/.do_built* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
redo test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# remove non-git files | |
git clean -x -f -d |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# A minimal alternative to djb redo that doesn't support incremental builds. | |
# For the full version, visit http://github.com/apenwarr/redo | |
# | |
# The author disclaims copyright to this source file and hereby places it in | |
# the public domain. (2010 12 14) | |
# | |
# By default, no output coloring. | |
green="" | |
bold="" | |
plain="" | |
if [ -n "$TERM" -a "$TERM" != "dumb" ] && tty <&2 >/dev/null 2>&1; then | |
green="$(printf '\033[32m')" | |
bold="$(printf '\033[1m')" | |
plain="$(printf '\033[m')" | |
fi | |
_dirsplit() | |
{ | |
base=${1##*/} | |
dir=${1%$base} | |
} | |
dirname() | |
( | |
_dirsplit "$1" | |
dir=${dir%/} | |
echo "${dir:-.}" | |
) | |
_dirsplit "$0" | |
export REDO=$(cd "${dir:-.}" && echo "$PWD/$base") | |
DO_TOP= | |
if [ -z "$DO_BUILT" ]; then | |
DO_TOP=1 | |
[ -n "$*" ] || set all # only toplevel redo has a default target | |
export DO_BUILT=$PWD/.do_built | |
: >>"$DO_BUILT" | |
echo "Removing previously built files..." >&2 | |
sort -u "$DO_BUILT" | tee "$DO_BUILT.new" | | |
while read f; do printf "%s\0%s.did\0" "$f" "$f"; done | | |
xargs -0 rm -f 2>/dev/null | |
mv "$DO_BUILT.new" "$DO_BUILT" | |
DO_PATH=$DO_BUILT.dir | |
export PATH=$DO_PATH:$PATH | |
rm -rf "$DO_PATH" | |
mkdir "$DO_PATH" | |
for d in redo redo-ifchange; do | |
ln -s "$REDO" "$DO_PATH/$d"; | |
done | |
[ -e /bin/true ] && TRUE=/bin/true || TRUE=/usr/bin/true | |
for d in redo-ifcreate redo-stamp redo-always; do | |
ln -s $TRUE "$DO_PATH/$d"; | |
done | |
fi | |
_find_dofile_pwd() | |
{ | |
dofile=default.$1.do | |
while :; do | |
dofile=default.${dofile#default.*.} | |
[ -e "$dofile" -o "$dofile" = default.do ] && break | |
done | |
ext=${dofile#default} | |
ext=${ext%.do} | |
base=${1%$ext} | |
} | |
_find_dofile() | |
{ | |
local prefix= | |
while :; do | |
_find_dofile_pwd "$1" | |
[ -e "$dofile" ] && break | |
[ "$PWD" = "/" ] && break | |
target=${PWD##*/}/$target | |
tmp=${PWD##*/}/$tmp | |
prefix=${PWD##*/}/$prefix | |
cd .. | |
done | |
base=$prefix$base | |
} | |
_run_dofile() | |
{ | |
export DO_DEPTH="$DO_DEPTH " | |
export REDO_TARGET=$PWD/$target | |
local line1 | |
set -e | |
read line1 <"$PWD/$dofile" || true | |
cmd=${line1#"#!/"} | |
if [ "$cmd" != "$line1" ]; then | |
/$cmd "$PWD/$dofile" "$@" >"$tmp.tmp2" | |
else | |
:; . "$PWD/$dofile" >"$tmp.tmp2" | |
fi | |
} | |
_do() | |
{ | |
local dir=$1 target=$2 tmp=$3 | |
if [ ! -e "$target" ] || [ -d "$target" -a ! -e "$target.did" ]; then | |
printf '%sdo %s%s%s%s\n' \ | |
"$green" "$DO_DEPTH" "$bold" "$dir$target" "$plain" >&2 | |
echo "$PWD/$target" >>"$DO_BUILT" | |
dofile=$target.do | |
base=$target | |
ext= | |
[ -e "$target.do" ] || _find_dofile "$target" | |
if [ ! -e "$dofile" ]; then | |
echo "do: $target: no .do file" >&2 | |
return 1 | |
fi | |
[ ! -e "$DO_BUILT" ] || [ ! -d "$(dirname "$target")" ] || | |
: >>"$target.did" | |
( _run_dofile "$target" "$base" "$tmp.tmp" ) | |
rv=$? | |
if [ $rv != 0 ]; then | |
printf "do: %s%s\n" "$DO_DEPTH" \ | |
"$dir$target: got exit code $rv" >&2 | |
rm -f "$tmp.tmp" "$tmp.tmp2" | |
return $rv | |
fi | |
mv "$tmp.tmp" "$target" 2>/dev/null || | |
! test -s "$tmp.tmp2" || | |
mv "$tmp.tmp2" "$target" 2>/dev/null | |
rm -f "$tmp.tmp2" | |
else | |
echo "do $DO_DEPTH$target exists." >&2 | |
fi | |
} | |
# Make corrections for directories that don't actually exist yet. | |
_dir_shovel() | |
{ | |
local dir base | |
xdir=$1 xbase=$2 xbasetmp=$2 | |
while [ ! -d "$xdir" -a -n "$xdir" ]; do | |
_dirsplit "${xdir%/}" | |
xbasetmp=${base}__$xbase | |
xdir=$dir xbase=$base/$xbase | |
echo "xbasetmp='$xbasetmp'" >&2 | |
done | |
} | |
_redo() | |
{ | |
set +e | |
for i in "$@"; do | |
_dirsplit "$i" | |
_dir_shovel "$dir" "$base" | |
dir=$xdir base=$xbase basetmp=$xbasetmp | |
( cd "$dir" && _do "$dir" "$base" "$basetmp" ) | |
[ "$?" = 0 ] || return 1 | |
done | |
} | |
_redo "$@" | |
[ "$?" = 0 ] || exit 1 | |
if [ -n "$DO_TOP" ]; then | |
echo "Removing stamp files..." >&2 | |
[ ! -e "$DO_BUILT" ] || | |
while read f; do printf "%s.did\0" "$f"; done <"$DO_BUILT" | | |
xargs -0 rm -f 2>/dev/null | |
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
$ sudo apt-get install libboost-python-dev | |
$ ./do | |
*/ | |
#include <boost/python.hpp> | |
struct World | |
{ | |
void set(std::string msg) { this->msg = msg; } | |
std::string greet() { return msg; } | |
std::string msg; | |
}; | |
namespace py = boost::python; | |
BOOST_PYTHON_MODULE(hello) | |
{ | |
py::class_<World>("World") | |
.def("greet", &World::greet) | |
.def("set", &World::set) | |
; | |
} | |
int main(int argc, char* argv[]) { | |
Py_Initialize(); | |
inithello(); | |
PySys_SetArgv(argc, argv); // use later in Python | |
if (PyRun_SimpleString("import hello\n" | |
"planet = hello.World()\n" | |
"planet.set('howdy')\n" | |
"print(planet.greet())\n" | |
// start interactive Python shell if `-i` | |
"import sys\n" | |
"if '-i' in sys.argv:\n" | |
" import code\n" | |
" code.interact()\n" //NOTE: namespace may be provided | |
) < 0) | |
return 1; // an exception is raised in Python | |
Py_Finalize(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# create a standalone executable with embed Python | |
exec >&2 | |
set -x | |
DEPS=$1.cpp | |
redo-ifchange $DEPS | |
c++ $DEPS -o $3 `python-config --cflags` \ | |
`python-config --ldflags` -lboost_python | |
#XXX should it be -lboost_python-mt-pyXY? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
exec >&2 | |
set -x | |
DEPS=main | |
redo-ifchange $DEPS | |
./$DEPS |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment