diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..25a5189 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +# Cytoplasm .gitignore + +build +out +*-leaked.txt +*.orig + +Makefile diff --git a/configure b/configure new file mode 100755 index 0000000..daa324c --- /dev/null +++ b/configure @@ -0,0 +1,209 @@ +#!/usr/bin/env sh + +# +# Argument Parsing +# + +echo "Build Configuration" +echo "-------------------" + +CFLAGS="-Wall -Wextra -pedantic -std=c89 -O3 -pipe -D_DEFAULT_SOURCE -Isrc/include" +LDFLAGS="-lm -pthread" + +# Set default args for all platforms +SCRIPT_ARGS="--lib-rtstub=RtStub --prefix=/usr/local --enable-ld-extra --lib-name=Cytoplasm --lib-version=0.4.0 --static $@" + +# Set platform specific args +case "$(uname)" in + OpenBSD) + SCRIPT_ARGS="--with-libressl $SCRIPT_ARGS" + ;; + *) + SCRIPT_ARGS="--with-openssl $SCRIPT_ARGS" + ;; +esac + +echo "Processing options..." +echo "Ran with arguments: $SCRIPT_ARGS" + +# Process all arguments +for arg in $SCRIPT_ARGS; do + case "$arg" in + --with-openssl) + TLS_IMPL="OPENSSL" + TLS_LIBS="-lcrypto -lssl" + ;; + --with-libressl) + TLS_IMPL="LIBRESSL" + TLS_LIBS="-ltls -lcrypto -lssl" + ;; + --disable-tls) + TLS_LIBS="" + ;; + --prefix=*) + PREFIX=$(echo "$arg" | cut -d '=' -f 2-) + ;; + --enable-ld-extra) + LD_EXTRA="-flto -fdata-sections -ffunction-sections -s -Wl,-gc-sections" + ;; + --disable-ld-extra) + LD_EXTRA="" + ;; + --lib-name=*) + LIB_NAME=$(echo "$arg" | cut -d '=' -f 2-) + ;; + --lib-version=*) + LIB_VERSION=$(echo "$arg" | cut -d '=' -f 2-) + ;; + --enable-debug) + DEBUG="-O0 -g" + echo "Notice: --enable-debug implies --disable-ld-extra and --no-static." + echo "You must explicitly provide --enable-ld-extra and/or --static after" + echo "specifying --enable-debug if you wish to enable these features in debug mode." + LD_EXTRA="" + STATIC="" + ;; + --disable-debug) + DEBUG="" + ;; + --lib-rtstub=*) + STUB=$(echo "$arg" | cut -d '=' -f 2-) + ;; + --static) + STATIC="-static -Wl,-static" + ;; + --no-static) + STATIC="" + ;; + *) + echo "Invalid argument: $1" + exit 1 + ;; + esac +done + +if [ -n "$TLS_IMPL" ]; then + CFLAGS="${CFLAGS} -DTLS_IMPL=${TLS_IMPL}" + LDFLAGS="${LDFLAGS} ${TLS_LIBS}" +fi + +CFLAGS="${CFLAGS} '-DLIB_NAME=\"${LIB_NAME}\"' '-DLIB_VERSION=\"${LIB_VERSION}\"' ${DEBUG}" +LDFLAGS="${LDFLAGS} ${LD_EXTRA}" + +# +# Makefile generation +# + +echo "Generating Makefile..." + +find_objs() { + obj_prefix="$1" + find src -name '*.c' | while IFS= read -r src; do + src=$(echo "$src" | cut -d '/' -f 2-) + obj=$(echo "$src" | sed -e 's/\.c$/.o/') + if [ "$(basename ${obj} .o)" != "${STUB}" ]; then + printf "${obj_prefix}${obj} " + fi + done +} + +OBJS=$(find_objs "build/") +TAB=$(printf '\t') + +find_tools() { + tools_prefix="$1" + find tools -name '*.c' | while IFS= read -r src; do + src=$(echo "$src" | cut -d '/' -f 2-) + bin=$(basename "$src" .c) + printf "${tools_prefix}${bin} " + done +} + +find_docs() { + prefix="$1" + find src/include -name '*.h' | while IFS= read -r src; do + src=$(echo "$src" | cut -d '/' -f 3-) + doc=$(echo "$src" | sed -e 's/\.h$/.3/') + printf "${prefix}${doc} " + done +} + +cat << EOF > Makefile +.POSIX: + +# Generated by '$0' on $(date). +# This file should generally not be manually edited. + +PREFIX = ${PREFIX} +CFLAGS = ${CFLAGS} +LDFLAGS = ${LDFLAGS} + +all: ${LIB_NAME} docs tools + +docs: $(find_docs "out/man/man3/Cytoplasm-") + +tools: $(find_tools "out/bin/") + +format: +${TAB}find . -name '*.c' | while IFS= read -r src; do \\ +${TAB} if indent "\$\$src"; then \\ +${TAB} rm \$\$(basename "\$\$src").BAK; \\ +${TAB} fi \\ +${TAB}done + +license: +${TAB}find . -name '*.[ch]' | while IFS= read -r src; do \\ +${TAB} srcHeader=\$\$(grep -n -m 1 '^ \*/' "\$\$src" | cut -d ':' -f 1); \\ +${TAB} head -n\$\$srcHeader \$\$src | \\ +${TAB} diff -u -p - "LICENSE.txt" | \\ +${TAB} patch "\$\$src" | grep -v "^Hmm"; \\ +${TAB}done + +${LIB_NAME}: out/lib/${LIB_NAME}.o out/lib/lib${LIB_NAME}.a out/lib/lib${LIB_NAME}.so + +clean: +${TAB}rm -r build out + +out/lib/${LIB_NAME}.o: build/${STUB}.o +${TAB}@mkdir -p out/lib +${TAB}cp build/${STUB}.o out/lib/${LIB_NAME}.o + +out/lib/lib${LIB_NAME}.a: ${OBJS} +${TAB}@mkdir -p out/lib +${TAB}\$(AR) rcs out/lib/lib${LIB_NAME}.a ${OBJS} + +out/lib/lib${LIB_NAME}.so: ${OBJS} +${TAB}@mkdir -p out/lib +${TAB}\$(CC) -shared -o out/lib/lib${LIB_NAME}.so ${OBJS} ${LDFLAGS} + +EOF + +find src -name '*.c' | while IFS= read -r src; do + src=$(echo "$src" | cut -d '/' -f 2-) + obj=$(echo "$src" | sed -e 's/\.c$/.o/') + + src="src/${src}" + obj="build/${obj}" + cc -Isrc/include -MM -MT "${obj}" "${src}" >> Makefile + echo "${TAB}@mkdir -p $(dirname ${obj})" >> Makefile + echo "${TAB}\$(CC) \$(CFLAGS) -fPIC -c -o \"${obj}\" \"${src}\"" >> Makefile +done + +find tools -name '*.c' | while IFS= read -r src; do + out="out/bin/$(basename "$src" .c)" + + echo "${out}: out/lib/lib${LIB_NAME}.a out/lib/lib${LIB_NAME}.so out/lib/${LIB_NAME}.o ${src}" >> Makefile + echo "${TAB}@mkdir -p out/bin" >> Makefile + echo "${TAB}\$(CC) \$(CFLAGS) -o \"${out}\" \"${src}\" out/lib/${LIB_NAME}.o -Lout/lib \$(LDFLAGS) -l${LIB_NAME} ${STATIC}" >> Makefile +done + +find src/include -name '*.h' | while IFS= read -r header; do + src=$(echo "$header" | cut -d '/' -f 2-) + out=$(echo "$header" | cut -d '/' -f 3- | sed -e 's/\.h$/.3/') + + echo "out/man/man3/Cytoplasm-${out}: out/bin/hdoc src/${src}" >> Makefile + echo "${TAB}@mkdir -p out/man/man3" >> Makefile + echo "${TAB}out/bin/hdoc -D \"Os=${LIB_NAME}\" -i \"src/${src}\" -o \"out/man/man3/Cytoplasm-${out}\"" >> Makefile +done + +echo "Done. Run 'make' to build ${LIB_NAME}." diff --git a/make.sh b/make.sh deleted file mode 100755 index 82d18c2..0000000 --- a/make.sh +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/env sh - -addprefix() { - prefix="$1" - shift - for thing in "$@"; do - echo "${prefix}${thing}" - done - - unset prefix - unset thing -} - -: "${NAME:=Cytoplasm}" -: "${LIB_NAME:=$(echo ${NAME} | tr '[A-Z]' '[a-z]')}" -: "${VERSION:=0.4.0}" - -: "${CVS_TAG:=${NAME}-$(echo ${VERSION} | sed 's/\./_/g')}" - - -: "${SRC:=src}" -: "${TOOLS:=tools}" -: "${EXAMPLES:=examples}" -: "${BUILD:=build}" -: "${OUT:=out}" -: "${STUB:=RtStub}" -: "${LICENSE:=LICENSE.txt}" - -: "${CC:=cc}" -: "${AR:=ar}" - -: "${DEFINES:=-D_DEFAULT_SOURCE -DLIB_NAME=\"${NAME}\" -DLIB_VERSION=\"${VERSION}\"}" -: "${INCLUDE:=${SRC}/include}" - -: "${CFLAGS:=-Wall -Wextra -pedantic -std=c89 -O3 -pipe}" -: "${LD_EXTRA:=-flto -fdata-sections -ffunction-sections -s -Wl,-gc-sections}" -: "${LDFLAGS:=-lm -pthread}" - -if [ "${DEBUG}" = "1" ]; then - CFLAGS="${CFLAGS} -O0 -g" - LD_EXTRA="" -fi - -if [ -n "${TLS_IMPL}" ]; then - case "${TLS_IMPL}" in - "LIBRESSL") - TLS_LIBS="-ltls -lcrypto -lssl" - ;; - "OPENSSL") - TLS_LIBS="-lcrypto -lssl" - ;; - *) - echo "Unrecognized TLS implementation: ${TLS_IMPL}" - echo "Consult Tls.h for supported implementations." - echo "Note that the TLS_ prefix is omitted in TLS_IMPL." - exit 1 - ;; - esac - - DEFINES="${DEFINES} -DTLS_IMPL=TLS_${TLS_IMPL}" - LDFLAGS="${LDFLAGS} ${TLS_LIBS}" -fi - -CFLAGS="${CFLAGS} ${DEFINES} $(addprefix -I$(pwd)/ ${INCLUDE})" -LDFLAGS="${LDFLAGS} ${LD_EXTRA}" - -# Check the modificiation time of a file. This is used to do -# incremental builds; we only want to rebuild files that have -# have changed. -mod_time() { - if [ -n "$1" ] && [ -f "$1" ]; then - case "$(uname)" in - Linux | CYGWIN_NT* | Haiku) - stat -c %Y "$1" - ;; - *BSD | DragonFly | Minix) - stat -f %m "$1" - ;; - *) - # Platform unknown, force rebuilding the whole - # project every time. - echo "0" - ;; - esac - else - echo "0" - fi -} - -# Substitute shell variables in a stream with their actual value -# in this shell. -setsubst() { - SED="/tmp/sed-$RANDOM.txt" - - ( - set | while IFS='=' read -r var val; do - val=$(echo "$val" | cut -d "'" -f 2- | rev | cut -d "'" -f 2- | rev) - echo "s|\\\${$var}|$val|g" - done - - echo "s|\\\${[a-zA-Z_]*}||g" - echo "s|'''|'|g" - ) >"$SED" - - sed -f "$SED" $@ - rm "$SED" -} - -recipe_docs() { - export LD_LIBRARY_PATH="${OUT}/lib" - mkdir -p "${OUT}/man/man3" - - for header in $(find ${INCLUDE} -name '*.h'); do - basename=$(basename "$header") - man=$(echo "${OUT}/man/man3/$basename" | sed -e 's/\.h$/\.3/') - - if [ $(mod_time "$header") -ge $(mod_time "$man") ]; then - echo "DOC $basename" - if ! "${OUT}/bin/hdoc" -D "Os=${NAME}" -i "$header" -o "$man"; then - rm "$man" - exit 1 - fi - fi - done - - if which makewhatis 2>&1 > /dev/null; then - makewhatis "${OUT}/man" - fi -} - -recipe_libs() { - echo "-lm -pthread ${TLS_LIBS}" -} - -recipe_build() { - mkdir -p "${BUILD}" "${OUT}/bin" "${OUT}/lib" - cd "${SRC}" - - - echo "CC = ${CC}" - echo "CFLAGS = ${CFLAGS}" - echo "LDFLAGS = ${LDFLAGS}" - echo - - do_rebuild=0 - objs="" - for src in $(find . -name '*.c' | cut -d '/' -f 2-); do - obj=$(echo "${BUILD}/$src" | sed -e 's/\.c$/\.o/') - - if [ $(basename "$obj" .o) != "${STUB}" ]; then - objs="$objs $obj" - fi - - if [ $(mod_time "$src") -ge $(mod_time "../$obj") ]; then - echo "CC $(basename $obj)" - obj_dir=$(dirname "../$obj") - mkdir -p "$obj_dir" - if ! $CC $CFLAGS -fPIC -c -o "../$obj" "$src"; then - exit 1 - fi - do_rebuild=1 - fi - done - - cd .. - - if [ $do_rebuild -eq 1 ] || [ ! -f "${OUT}/lib/lib${LIB_NAME}.a" ]; then - echo "AR lib${LIB_NAME}.a" - if ! $AR rcs "${OUT}/lib/lib${LIB_NAME}.a" $objs; then - exit 1 - fi - fi - - if [ $do_rebuild -eq 1 ] || [ ! -f "${OUT}/lib/lib${LIB_NAME}.so" ]; then - echo "LD lib${LIB_NAME}.so" - if ! $CC -shared -o "${OUT}/lib/lib${LIB_NAME}.so" $objs ${LDFLAGS}; then - exit 1 - fi - fi - - cp "${BUILD}/${STUB}.o" "${OUT}/lib/${LIB_NAME}.o" - - for src in $(find "${TOOLS}" -name '*.c'); do - out=$(basename "$src" .c) - out="${OUT}/bin/$out" - - if [ $(mod_time "$src") -ge $(mod_time "$out") ] || [ $do_rebuild -eq 1 ]; then - echo "CC $(basename $out)" - mkdir -p "$(dirname $out)" - if ! $CC $CFLAGS -o "$out" "$src" "${OUT}/lib/${LIB_NAME}.o" "-L${OUT}/lib" "-l${LIB_NAME}" ${LDFLAGS}; then - exit 1 - fi - fi - done - - recipe_docs -} - -recipe_examples() { - for src in $(find "${EXAMPLES}" -name '*.c'); do - out=$(basename "$src" .c) - out="${OUT}/bin/$out" - - if [ $(mod_time "$src") -ge $(mod_time "$out") ]; then - echo "CC $(basename $out)" - mkdir -p "$(dirname $out)" - if ! $CC $CFLAGS -o "$out" "$src" "${OUT}/lib/${LIB_NAME}.o" "-L${OUT}/lib" "-l${LIB_NAME}" ${LDFLAGS}; then - exit 1 - fi - fi - done - -} - -recipe_clean() { - rm -r "${BUILD}" "${OUT}" -} - -# Update copyright comments in sources and header files. -recipe_license() { - find . -name '*.[ch]' | while IFS= read -r src; do - if [ -t 1 ]; then - printf "LICENSE %s%*c\r" $(basename "$src") "16" " " - fi - srcHeader=$(grep -n -m 1 '^ \*/' "$src" | cut -d ':' -f 1) - head "-n$srcHeader" "$src" | - diff -u -p - "${LICENSE}" | - patch "$src" | grep -v "^Hmm" - done - if [ -t 1 ]; then - printf "%*c\n" "50" " " - fi -} - -# Format source code files by running indent(1) on them. -recipe_format() { - find . -name '*.c' | while IFS= read -r src; do - if [ -t 1 ]; then - printf "FMT %s%*c\r" $(basename "$src") "16" " " - fi - if indent "$src"; then - rm $(basename "$src").BAK - fi - done - if [ -t 1 ]; then - printf "%*c\n" "50" " " - fi -} - -# Generate a release tarball, checksum and sign it, and push it to -# the web root. -recipe_release() { - # Tag the release at this point in time. - cvs tag "$CVS_TAG" - - mkdir -p "${OUT}/release" - cd "${OUT}/release" - - # Generate the release tarball. - cvs export "-r$CVS_TAG" "${NAME}" - mv "${NAME}" "${NAME}-v${VERSION}" - tar -czf "${NAME}-v${VERSION}.tar.gz" "${NAME}-v${VERSION}" - rm -r "${NAME}-v${VERSION}" - - # Checksum the release tarball. - sha256 "${NAME}-v${VERSION}.tar.gz" > "${NAME}-v${VERSION}.tar.gz.sha256" - - # Sign the release tarball. - if [ ! -z "${SIGNIFY_SECRET}" ]; then - signify -S -s "${SIGNIFY_SECRET}" \ - -m "${NAME}-v${VERSION}.tar.gz" \ - -x "${NAME}-v${VERSION}.tar.gz.sig" - else - echo "Warning: SIGNIFY_SECRET not net." - echo "The built tarball will not be signed." - fi -} - -recipe_patch() { - # If the user has not set their MXID, try to deduce one from - # their system. - if [ -z "$MXID" ]; then - MXID="@${USER}:$(hostname)" - fi - - # If the user has not set their EDITOR, use a safe default. - # (vi should be available on any POSIX system) - if [ -z "$EDITOR" ]; then - EDITOR=vi - fi - - NORMALIZED_MXID=$(echo "$MXID" | sed -e 's/@//g' -e 's/:/-/g') - PATCH_FILE="${NORMALIZED_MXID}_$(date +%s).patch" - - # Generate the actual patch file - # Here we write some nice headers, and then do a cvs diff. - ( - printf 'From: "%s" <%s>\n' "$DISPLAY_NAME" "$MXID" - echo "Date: $(date)" - echo "Subject: " - echo - cvs -q diff -uNp $PATCHSET | grep -v '^\? ' - ) >"$PATCH_FILE" - - "$EDITOR" "$PATCH_FILE" - echo "$PATCH_FILE" -} - -recipe_diff() { - tmp_patch="/tmp/${NAME}-$(date +%s).patch" - cvs -q diff -uNp $PATCHSET >"$tmp_patch" - if [ -z "$PAGER" ]; then - PAGER="less -F" - fi - - $PAGER "$tmp_patch" - rm "$tmp_patch" -} - -# Execute the user-specified recipes. -for recipe in $@; do - recipe_$recipe -done - -# If no recipe was provided, run a build. -if [ -z "$1" ]; then - recipe_build -fi