From 61c246d27eba72820090706f4a3b8d7709f24da3 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sun, 24 Jul 2011 21:03:17 -0500 Subject: [PATCH] Initial commit. --- AUTHORS | 1 + Makefile | 10 + autogen.sh | 83 ++++++++ buildsys.mk.in | 513 +++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 16 ++ m4/buildsys.m4 | 185 ++++++++++++++++++ parse.c | 175 +++++++++++++++++ pkg.c | 51 +++++ pkg.h | 93 +++++++++ 9 files changed, 1127 insertions(+) create mode 100644 AUTHORS create mode 100644 Makefile create mode 100755 autogen.sh create mode 100644 buildsys.mk.in create mode 100644 configure.ac create mode 100644 m4/buildsys.m4 create mode 100644 parse.c create mode 100644 pkg.c create mode 100644 pkg.h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..2debc8a --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +William Pitcock diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..edf4fb5 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +PROG = pkgconf${PROG_SUFFIX} +SRCS = parse.c pkg.c +LIBS = -lpopt + +include buildsys.mk + +install-extra: + ${LN} ${bindir}/pkgconf ${DESTDIR}/${bindir}/pkg-config + +include .deps diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..5df5cb1 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,83 @@ +#! /bin/sh + +TOP_DIR=$(dirname $0) +LAST_DIR=$PWD + +if test ! -f $TOP_DIR/configure.ac ; then + echo "You must execute this script from the top level directory." + exit 1 +fi + +AUTOCONF=${AUTOCONF:-autoconf} +ACLOCAL=${ACLOCAL:-aclocal} +AUTOHEADER=${AUTOHEADER:-autoheader} + +dump_help_screen () +{ + echo "Usage: $0 [options]" + echo + echo "options:" + echo " -n skip CVS changelog creation" + echo " -h,--help show this help screen" + echo + exit 0 +} + +parse_options () +{ + while test "$1" != "" ; do + case $1 in + -h|--help) + dump_help_screen + ;; + -n) + SKIP_CVS_CHANGELOG=yes + ;; + *) + echo Invalid argument - $1 + dump_help_screen + ;; + esac + shift + done +} + +run_or_die () +{ + COMMAND=$1 + + # check for empty commands + if test -z "$COMMAND" ; then + echo "*warning* no command specified" + return 1 + fi + + shift; + + OPTIONS="$@" + + # print a message + echo -n "*info* running $COMMAND" + if test -n "$OPTIONS" ; then + echo " ($OPTIONS)" + else + echo + fi + + # run or die + $COMMAND $OPTIONS ; RESULT=$? + if test $RESULT -ne 0 ; then + echo "*error* $COMMAND failed. (exit code = $RESULT)" + exit 1 + fi + + return 0 +} + +parse_options "$@" + +cd $TOP_DIR + +run_or_die $ACLOCAL -I m4 +run_or_die $AUTOHEADER +run_or_die $AUTOCONF diff --git a/buildsys.mk.in b/buildsys.mk.in new file mode 100644 index 0000000..aa0e716 --- /dev/null +++ b/buildsys.mk.in @@ -0,0 +1,513 @@ +# +# Copyright (c) 2007 - 2009, Jonathan Schleifer +# +# https://webkeks.org/hg/buildsys/ +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice is present in all copies. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +PACKAGE = @PACKAGE@ +AS = @AS@ +CC = @CC@ +CXX = @CXX@ +CPP = @CPP@ +DC = @DC@ +ERLC = @ERLC@ +OBJC = @OBJC@ +OBJCXX = @OBJCXX@ +AR = @AR@ +LD = ${CC} +RANLIB = @RANLIB@ +PYTHON = @PYTHON@ +ASFLAGS = @ASFLAGS@ +CFLAGS = @CFLAGS@ +CXXFLAGS = @CXXFLAGS@ +CPPFLAGS = @CPPFLAGS@ +DFLAGS = @DFLAGS@ +ERLCFLAGS = @ERLCFLAGS@ +OBJCFLAGS = @OBJCFLAGS@ +OBJCXXFLAGS = @OBJCXXFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +PYTHON_FLAGS = @PYTHON_FLAGS@ +PROG_IMPLIB_NEEDED = @PROG_IMPLIB_NEEDED@ +PROG_IMPLIB_LDFLAGS = @PROG_IMPLIB_LDFLAGS@ +PROG_SUFFIX = @EXEEXT@ +LIB_CPPFLAGS = @LIB_CPPFLAGS@ +LIB_CFLAGS = @LIB_CFLAGS@ +LIB_LDFLAGS = @LIB_LDFLAGS@ +LIB_PREFIX = @LIB_PREFIX@ +LIB_SUFFIX = @LIB_SUFFIX@ +PLUGIN_CPPFLAGS = @PLUGIN_CPPFLAGS@ +PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ +PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ +PLUGIN_SUFFIX = @PLUGIN_SUFFIX@ +RPATH_LDFLAGS = @RPATH_LDFLAGS@ +INSTALL_LIB = @INSTALL_LIB@ +UNINSTALL_LIB = @UNINSTALL_LIB@ +CLEAN_LIB = @CLEAN_LIB@ +LN_S = @LN_S@ +USE_NLS = @USE_NLS@ +MKDIR_P = mkdir -p +INSTALL = @INSTALL@ +SHELL = @SHELL@ +MSGFMT = @MSGFMT@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +libdir = @libdir@ +plugindir ?= ${libdir}/${PACKAGE} +datarootdir = @datarootdir@ +datadir = @datadir@ +includedir = @includedir@ +includesubdir ?= ${PACKAGE} +localedir = @localedir@ +localename ?= ${PACKAGE} +mandir = @mandir@ +mansubdir ?= man1 + +OBJS1 = ${SRCS:.c=.o} +OBJS2 = ${OBJS1:.cc=.o} +OBJS3 = ${OBJS2:.cxx=.o} +OBJS4 = ${OBJS3:.d=.o} +OBJS5 = ${OBJS4:.erl=.beam} +OBJS6 = ${OBJS5:.m=.o} +OBJS7 = ${OBJS6:.mm=.o} +OBJS8 = ${OBJS7:.py=.pyc} +OBJS9 = ${OBJS8:.xpm=.o} +OBJS += ${OBJS9:.S=.o} + +MO_FILES = ${LOCALES:.po=.mo} + +.SILENT: +.SUFFIXES: +.SUFFIXES: .beam .c .cc .cxx .d .dep .erl .mo .m .mm .o .po .py .pyc .xpm .S +.PHONY: all subdirs pre-depend depend install install-extra uninstall uninstall-extra clean distclean + +build: all + +all: + for i in depend subdirs "${STATIC_LIB} ${STATIC_LIB_NOINST} ${LIB} ${LIB_NOINST}" "${PLUGIN} ${PLUGIN_NOINST} ${PROG} ${PROG_NOINST} locales"; do \ + set -- $$i; \ + [ "$$#" -gt 0 ] || continue; \ + ${MAKE} ${MFLAGS} $$i || exit 1; \ + done + +subdirs: + for i in ${SUBDIRS}; do \ + ${DIR_ENTER}; \ + ${MAKE} ${MFLAGS} || exit 1; \ + ${DIR_LEAVE}; \ + done + +depend: pre-depend ${SRCS} + regen=0; \ + deps=""; \ + test -f .deps || regen=1; \ + for i in ${SRCS}; do \ + case $$i in \ + *.c) \ + test $$i -nt .deps && regen=1; \ + deps="$$deps $${i%.c}.dep"; \ + ;; \ + *.cc) \ + test $$i -nt .deps && regen=1; \ + deps="$$deps $${i%.cc}.dep"; \ + ;; \ + *.cxx) \ + test $$i -nt .deps && regen=1; \ + deps="$$deps $${i%.cxx}.dep"; \ + ;; \ + *.m) \ + test $$i -nt .deps && regen=1; \ + deps="$$deps $${i%.m}.dep"; \ + ;; \ + *.mm) \ + test $$i -nt .deps && regen=1; \ + deps="$$deps $${i%.mm}.dep"; \ + ;; \ + *.S) \ + test $$i -nt .deps && regen=1; \ + deps="$$deps $${i%.S}.dep"; \ + ;; \ + esac; \ + done; \ + if test x"$$regen" = x"1" -a x"$$deps" != "x"; then \ + ${DEPEND_STATUS}; \ + if ${MAKE} ${MFLAGS} $$deps && cat $$deps >.deps; then \ + rm -f $$deps; \ + ${DEPEND_OK}; \ + else \ + :> .deps; \ + touch -t 0001010000 .deps; \ + ${DEPEND_FAILED}; \ + fi; \ + fi + +.c.dep .cc.dep .cxx.dep .m.dep .mm.dep .S.dep: + ${CPP} ${CFLAGS} ${CPPFLAGS} -M $< >$@ || (rm -f $@; exit 1) + +.d.dep: +.xpm.dep: + +pre-depend: + +${PROG} ${PROG_NOINST}: ${EXT_DEPS} ${OBJS} + ${LINK_STATUS} + if ${LD} -o $@ ${OBJS} ${LDFLAGS} ${LIBS}; then \ + ${LINK_OK}; \ + else \ + ${LINK_FAILED}; \ + fi + +${LIB} ${LIB_NOINST}: ${EXT_DEPS} ${OBJS} + case $@ in \ + *.a) \ + ${MAKE} ${MFLAGS} STATIC_LIB=${LIB} LIB= $@ || exit 1 \ + ;; \ + *) \ + ${LINK_STATUS}; \ + if ${LD} -o $@ ${OBJS} ${LIB_LDFLAGS} ${LDFLAGS} ${LIBS}; then \ + ${LINK_OK}; \ + else \ + ${LINK_FAILED}; \ + fi \ + ;; \ + esac + +${PLUGIN} ${PLUGIN_NOINST}: ${EXT_DEPS} ${OBJS} + ${LINK_STATUS} + if ${LD} -o $@ ${OBJS} ${PLUGIN_LDFLAGS} ${LDFLAGS} ${LIBS}; then \ + ${LINK_OK}; \ + else \ + ${LINK_FAILED}; \ + fi + +${STATIC_LIB} ${STATIC_LIB_NOINST}: ${EXT_DEPS} ${OBJS} + ${LINK_STATUS} + if ${AR} cr $@ ${OBJS} && ${RANLIB} $@; then \ + ${LINK_OK}; \ + else \ + ${LINK_FAILED}; \ + rm -f $@; \ + fi + +locales: ${MO_FILES} + +.c.o: + ${COMPILE_STATUS} + if ${CC} ${CFLAGS} ${CPPFLAGS} -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi + +.cc.o .cxx.o: + ${COMPILE_STATUS} + if ${CXX} ${CXXFLAGS} ${CPPFLAGS} -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi + +.d.o: + ${COMPILE_STATUS} + if test x"$(basename ${DC})" = x"dmd"; then \ + if ${DC} ${DFLAGS} -c -of$@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi \ + else \ + if ${DC} ${DFLAGS} -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi \ + fi + +.erl.beam: + ${COMPILE_STATUS} + if ${ERLC} ${ERLCFLAGS} -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi + +.m.o: + ${COMPILE_STATUS} + if ${OBJC} ${OBJCFLAGS} ${CPPFLAGS} -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi + +.mm.o: + ${COMPILE_STATUS} + if ${OBJCXX} ${OBJCXXFLAGS} ${OBJCFLAGS} ${CXXFLAGS} ${CPPFLAGS} -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi + +.po.mo: + ${COMPILE_STATUS} + if ${MSGFMT} -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi + +.py.pyc: + ${COMPILE_STATUS} + if ${PYTHON} ${PYTHON_FLAGS} -c "import py_compile; py_compile.compile('$<')"; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi + +.xpm.o: + ${COMPILE_STATUS} + if ${CC} ${CFLAGS} ${CPPFLAGS} -x c -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi + +.S.o: + ${COMPILE_STATUS} + if ${AS} ${ASFLAGS} ${CPPFLAGS} -c -o $@ $<; then \ + ${COMPILE_OK}; \ + else \ + ${COMPILE_FAILED}; \ + fi + +install: ${LIB} ${STATIC_LIB} ${PLUGIN} ${PROG} locales install-extra + for i in ${SUBDIRS}; do \ + ${DIR_ENTER}; \ + ${MAKE} ${MFLAGS} install || exit 1; \ + ${DIR_LEAVE}; \ + done + + for i in ${LIB}; do \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${libdir} && ${INSTALL_LIB}; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + + for i in ${STATIC_LIB}; do \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${libdir} && ${INSTALL} -m 644 $$i ${DESTDIR}${libdir}/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + + for i in ${PLUGIN}; do \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${plugindir} && ${INSTALL} -m 755 $$i ${DESTDIR}${plugindir}/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + + for i in ${DATA}; do \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} $$(dirname ${DESTDIR}${datadir}/${PACKAGE}/$$i) && ${INSTALL} -m 644 $$i ${DESTDIR}${datadir}/${PACKAGE}/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + + for i in ${PROG}; do \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${bindir} && ${INSTALL} -m 755 $$i ${DESTDIR}${bindir}/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + + for i in ${INCLUDES}; do \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${includedir}/${includesubdir} && ${INSTALL} -m 644 $$i ${DESTDIR}${includedir}/${includesubdir}/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + + if test x"${USE_NLS}" = x"yes"; then \ + for i in ${MO_FILES}; do \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${localedir}/$${i%.mo}/LC_MESSAGES && ${INSTALL} -m 644 $$i ${DESTDIR}${localedir}/$${i%.mo}/LC_MESSAGES/${localename}.mo; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done \ + fi + for i in ${MAN}; do \ + ${INSTALL_STATUS}; \ + if ${MKDIR_P} ${DESTDIR}${mandir}/${mansubdir} && ${INSTALL} -m 644 $$i ${DESTDIR}${mandir}/${mansubdir}/$$i; then \ + ${INSTALL_OK}; \ + else \ + ${INSTALL_FAILED}; \ + fi \ + done + +install-extra: + +uninstall: uninstall-extra + for i in ${SUBDIRS}; do \ + ${DIR_ENTER}; \ + ${MAKE} ${MFLAGS} uninstall || exit 1; \ + ${DIR_LEAVE}; \ + done + + for i in ${LIB}; do \ + if test -f ${DESTDIR}${libdir}/$$i; then \ + if ${UNINSTALL_LIB}; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi; \ + done + + for i in ${STATIC_LIB}; do \ + if test -f ${DESTDIR}${libdir}/$$i; then \ + if rm -f ${DESTDIR}${libdir}/$$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + + for i in ${PLUGIN}; do \ + if test -f ${DESTDIR}${plugindir}/$$i; then \ + if rm -f ${DESTDIR}${plugindir}/$$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + -rmdir ${DESTDIR}${plugindir} >/dev/null 2>&1 + + for i in ${DATA}; do \ + if test -f ${DESTDIR}${datadir}/${PACKAGE}/$$i; then \ + if rm -f ${DESTDIR}${datadir}/${PACKAGE}/$$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + + for i in ${PROG}; do \ + if test -f ${DESTDIR}${bindir}/$$i; then \ + if rm -f ${DESTDIR}${bindir}/$$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + + for i in ${INCLUDES}; do \ + if test -f ${DESTDIR}${includedir}/${includesubdir}/$$i; then \ + if rm -f ${DESTDIR}${includedir}/${includesubdir}/$$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + -rmdir ${DESTDIR}${includedir}/${includesubdir} >/dev/null 2>&1 + + for i in ${MAN}; do \ + if test -f ${DESTDIR}${mandir}/${mansubdir}/$$i; then \ + if rm -f ${DESTDIR}${mandir}/${mansubdir}/$$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + +uninstall-extra: + +clean: + for i in ${SUBDIRS}; do \ + ${DIR_ENTER}; \ + ${MAKE} ${MFLAGS} clean || exit 1; \ + ${DIR_LEAVE}; \ + done + + for i in ${DEPS} ${OBJS} ${PROG} ${PROG_NOINST} ${LIB} ${LIB_NOINST} ${STATIC_LIB} ${STATIC_LIB_NOINST} ${PLUGIN} ${PLUGIN_NOINST} ${CLEAN} ${CLEAN_LIB} ${MO_FILES}; do \ + if test -f $$i -o -d $$i; then \ + if rm -fr $$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + +distclean: clean + for i in ${SUBDIRS}; do \ + ${DIR_ENTER}; \ + ${MAKE} ${MFLAGS} distclean || exit 1; \ + ${DIR_LEAVE}; \ + done + + for i in ${DISTCLEAN} .deps *~; do \ + if test -f $$i -o -d $$i; then \ + if rm -fr $$i; then \ + ${DELETE_OK}; \ + else \ + ${DELETE_FAILED}; \ + fi \ + fi \ + done + +DIR_ENTER = printf "\033[K\033[0;36mEntering directory \033[1;36m$$i\033[0;36m.\033[0m\n"; cd $$i || exit 1 +DIR_LEAVE = printf "\033[K\033[0;36mLeaving directory \033[1;36m$$i\033[0;36m.\033[0m\n"; cd .. || exit 1 +DEPEND_STATUS = printf "\033[K\033[0;33mGenerating dependencies...\033[0m\r" +DEPEND_OK = printf "\033[K\033[0;32mSuccessfully generated dependencies.\033[0m\n" +DEPEND_FAILED = printf "\033[K\033[0;31mFailed to generate dependencies!\033[0m\n"; exit 1 +COMPILE_STATUS = printf "\033[K\033[0;33mCompiling \033[1;33m$<\033[0;33m...\033[0m\r" +COMPILE_OK = printf "\033[K\033[0;32mSuccessfully compiled \033[1;32m$<\033[0;32m.\033[0m\n" +COMPILE_FAILED = printf "\033[K\033[0;31mFailed to compile \033[1;31m$<\033[0;31m!\033[0m\n"; exit 1 +LINK_STATUS = printf "\033[K\033[0;33mLinking \033[1;33m$@\033[0;33m...\033[0m\r" +LINK_OK = printf "\033[K\033[0;32mSuccessfully linked \033[1;32m$@\033[0;32m.\033[0m\n" +LINK_FAILED = printf "\033[K\033[0;31mFailed to link \033[1;31m$@\033[0;31m!\033[0m\n"; exit 1 +INSTALL_STATUS = printf "\033[K\033[0;33mInstalling \033[1;33m$$i\033[0;33m...\033[0m\r" +INSTALL_OK = printf "\033[K\033[0;32mSuccessfully installed \033[1;32m$$i\033[0;32m.\033[0m\n" +INSTALL_FAILED = printf "\033[K\033[0;31mFailed to install \033[1;31m$$i\033[0;31m!\033[0m\n"; exit 1 +DELETE_OK = printf "\033[K\033[0;34mDeleted \033[1;34m$$i\033[0;34m.\033[0m\n" +DELETE_FAILED = printf "\033[K\033[0;31mFailed to delete \033[1;31m$$i\033[0;31m!\033[0m\n"; exit 1 + +include .deps diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..c3189bb --- /dev/null +++ b/configure.ac @@ -0,0 +1,16 @@ +AC_PREREQ([2.68]) +AC_INIT([pkgconf], [0.1], [http://jira.atheme.org/]) +AC_CONFIG_SRCDIR([pkg.c]) +AC_CONFIG_HEADERS([config.h]) + +AC_PROG_CPP +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_LN_S + +BUILDSYS_SHARED_LIB +BUILDSYS_PROG_IMPLIB +BUILDSYS_TOUCH_DEPS + +AC_CONFIG_FILES([buildsys.mk]) +AC_OUTPUT diff --git a/m4/buildsys.m4 b/m4/buildsys.m4 new file mode 100644 index 0000000..a302fe6 --- /dev/null +++ b/m4/buildsys.m4 @@ -0,0 +1,185 @@ +dnl +dnl Copyright (c) 2007 - 2009, Jonathan Schleifer +dnl +dnl https://webkeks.org/hg/buildsys/ +dnl +dnl Permission to use, copy, modify, and/or distribute this software for any +dnl purpose with or without fee is hereby granted, provided that the above +dnl copyright notice and this permission notice is present in all copies. +dnl +dnl THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +dnl AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +dnl IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +dnl ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +dnl LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +dnl CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +dnl SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +dnl INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +dnl CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +dnl ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +dnl POSSIBILITY OF SUCH DAMAGE. +dnl + +AC_DEFUN([BUILDSYS_LIB], [ + AC_ARG_ENABLE(shared, + AS_HELP_STRING([--disable-shared], [don't build shared libraries])) + + AS_IF([test x"$enable_shared" = x"no"], + [BUILDSYS_STATIC_LIB_ONLY], + [BUILDSYS_SHARED_LIB]) +]) + +AC_DEFUN([BUILDSYS_PROG_IMPLIB], [ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_MSG_CHECKING(whether we need an implib) + case "$host_os" in + cygwin* | mingw*) + AC_MSG_RESULT(yes) + PROG_IMPLIB_NEEDED='yes' + PROG_IMPLIB_LDFLAGS='-Wl,-export-all-symbols,--out-implib,lib${PROG}.a' + ;; + *) + AC_MSG_RESULT(no) + PROG_IMPLIB_NEEDED='no' + PROG_IMPLIB_LDFLAGS='' + ;; + esac + + AC_SUBST(PROG_IMPLIB_NEEDED) + AC_SUBST(PROG_IMPLIB_LDFLAGS) +]) + +AC_DEFUN([BUILDSYS_SHARED_LIB], [ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_MSG_CHECKING(for shared library system) + case "$host_os" in + darwin*) + AC_MSG_RESULT(Darwin) + LIB_CPPFLAGS='-DPIC' + LIB_CFLAGS='-fPIC' + LIB_LDFLAGS='-dynamiclib -flat_namespace' + LIB_PREFIX='lib' + LIB_SUFFIX='.dylib' + LDFLAGS_RPATH='-Wl,-rpath,${libdir}' + PLUGIN_CPPFLAGS='-DPIC' + PLUGIN_CFLAGS='-fPIC' + PLUGIN_LDFLAGS='-bundle -flat_namespace -undefined suppress' + PLUGIN_SUFFIX='.impl' + INSTALL_LIB='${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib && ${LN_S} -f $${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.dylib ${DESTDIR}${libdir}/$${i%.dylib}.${LIB_MAJOR}.${LIB_MINOR}.dylib' + CLEAN_LIB='' + ;; + solaris*) + AC_MSG_RESULT(Solaris) + LIB_CPPFLAGS='-DPIC' + LIB_CFLAGS='-fPIC' + LIB_LDFLAGS='-shared -fPIC -Wl,-soname=${LIB}.${LIB_MAJOR}.${LIB_MINOR}' + LIB_PREFIX='lib' + LIB_SUFFIX='.so' + LDFLAGS_RPATH='-Wl,-rpath,${libdir}' + PLUGIN_CPPFLAGS='-DPIC' + PLUGIN_CFLAGS='-fPIC' + PLUGIN_LDFLAGS='-shared -fPIC' + PLUGIN_SUFFIX='.so' + INSTALL_LIB='${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR} && rm -f ${DESTDIR}${libdir}/$$i && ${LN_S} $$i.${LIB_MAJOR}.${LIB_MINOR} ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}' + CLEAN_LIB='' + ;; + openbsd* | mirbsd*) + AC_MSG_RESULT(OpenBSD) + LIB_CPPFLAGS='-DPIC' + LIB_CFLAGS='-fPIC' + LIB_LDFLAGS='-shared -fPIC' + LIB_PREFIX='lib' + LIB_SUFFIX='.so.${LIB_MAJOR}.${LIB_MINOR}' + LDFLAGS_RPATH='-Wl,-rpath,${libdir}' + PLUGIN_CPPFLAGS='-DPIC' + PLUGIN_CFLAGS='-fPIC' + PLUGIN_LDFLAGS='-shared -fPIC' + PLUGIN_SUFFIX='.so' + INSTALL_LIB='${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='rm -f ${DESTDIR}${libdir}/$$i' + CLEAN_LIB='' + ;; + cygwin* | mingw*) + AC_MSG_RESULT(Win32) + LIB_CPPFLAGS='-DPIC' + LIB_CFLAGS='' + LIB_LDFLAGS='-shared -Wl,--out-implib,${LIB}.a' + LIB_PREFIX='lib' + LIB_SUFFIX='.dll' + LDFLAGS_RPATH='-Wl,-rpath,${libdir}' + PLUGIN_CPPFLAGS='' + PLUGIN_CFLAGS='' + PLUGIN_LDFLAGS='-shared' + PLUGIN_SUFFIX='.dll' + INSTALL_LIB='${MKDIR_P} ${DESTDIR}${bindir} && ${INSTALL} -m 755 $$i ${DESTDIR}${bindir}/$$i && ${INSTALL} -m 755 $$i.a ${DESTDIR}${libdir}/$$i.a' + UNINSTALL_LIB='rm -f ${DESTDIR}${bindir}/$$i ${DESTDIR}${libdir}/$$i.a' + CLEAN_LIB='${LIB}.a' + ;; + *) + AC_MSG_RESULT(GNU) + LIB_CPPFLAGS='-DPIC' + LIB_CFLAGS='-fPIC' + LIB_LDFLAGS='-shared -fPIC -Wl,-soname=${LIB}.${LIB_MAJOR}' + LIB_PREFIX='lib' + LIB_SUFFIX='.so' + LDFLAGS_RPATH='-Wl,-rpath,${libdir}' + PLUGIN_CPPFLAGS='-DPIC' + PLUGIN_CFLAGS='-fPIC' + PLUGIN_LDFLAGS='-shared -fPIC' + PLUGIN_SUFFIX='.so' + INSTALL_LIB='${INSTALL} -m 755 $$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0 && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} && ${LN_S} -f $$i.${LIB_MAJOR}.${LIB_MINOR}.0 ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='rm -f ${DESTDIR}${libdir}/$$i ${DESTDIR}${libdir}/$$i.${LIB_MAJOR} ${DESTDIR}${libdir}/$$i.${LIB_MAJOR}.${LIB_MINOR}.0' + CLEAN_LIB='' + ;; + esac + + AC_SUBST(LIB_CPPFLAGS) + AC_SUBST(LIB_CFLAGS) + AC_SUBST(LIB_LDFLAGS) + AC_SUBST(LIB_PREFIX) + AC_SUBST(LIB_SUFFIX) + AC_SUBST(LDFLAGS_RPATH) + AC_SUBST(PLUGIN_CPPFLAGS) + AC_SUBST(PLUGIN_CFLAGS) + AC_SUBST(PLUGIN_LDFLAGS) + AC_SUBST(PLUGIN_SUFFIX) + AC_SUBST(INSTALL_LIB) + AC_SUBST(UNINSTALL_LIB) + AC_SUBST(CLEAN_LIB) +]) + +AC_DEFUN([BUILDSYS_STATIC_LIB_ONLY], [ + AC_REQUIRE([AC_PROG_RANLIB]) + AC_PATH_TOOL(AR, ar) + + LIB_CPPFLAGS='' + LIB_CFLAGS='' + LIB_LDFLAGS='' + LIB_PREFIX='lib' + LIB_SUFFIX='.a' + LDFLAGS_RPATH='' + INSTALL_LIB='${INSTALL} -m 644 $$i ${DESTDIR}${libdir}/$$i' + UNINSTALL_LIB='rm -f ${DESTDIR}${libdir}/$$i' + CLEAN_LIB='' + + AC_SUBST(LIB_CPPFLAGS) + AC_SUBST(LIB_CFLAGS) + AC_SUBST(LIB_LDFLAGS) + AC_SUBST(LIB_PREFIX) + AC_SUBST(LIB_SUFFIX) + AC_SUBST(LDFLAGS_RPATH) + AC_SUBST(INSTALL_LIB) + AC_SUBST(UNINSTALL_LIB) + AC_SUBST(CLEAN_LIB) +]) + +AC_DEFUN([BUILDSYS_TOUCH_DEPS], [ + ${as_echo:="echo"} "${as_me:="configure"}: touching .deps files" + for i in $(find . -name Makefile); do + DEPSFILE="$(dirname $i)/.deps" + test -f "$DEPSFILE" && rm "$DEPSFILE" + touch "$DEPSFILE" + done +]) diff --git a/parse.c b/parse.c new file mode 100644 index 0000000..b3bf392 --- /dev/null +++ b/parse.c @@ -0,0 +1,175 @@ +/* + * parse.c + * Parser for .pc file. + * + * Copyright (c) 2011 William Pitcock . + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pkg.h" + +static pkg_tuple_t * +tuple_add(pkg_tuple_t *parent, const char *key, const char *value) +{ + pkg_tuple_t *tuple = calloc(sizeof(pkg_tuple_t), 1); + + tuple->key = strdup(key); + tuple->value = strdup(value); + + tuple->next = parent; + if (tuple->next != NULL) + tuple->next->prev = tuple; + + return tuple; +} + +static char * +tuple_find(pkg_tuple_t *head, const char *key) +{ + pkg_tuple_t *node; + + foreach_list_entry(head, node) + { + if (!strcasecmp(node->key, key)) + return node->value; + } + + return NULL; +} + +static char * +strdup_parse(pkg_t *pkg, const char *value) +{ + char buf[BUFSIZ]; + const char *ptr; + char *bptr = buf; + + for (ptr = value; *ptr != '\0' && bptr - buf < BUFSIZ; ptr++) + { + if (*ptr != '$') + *bptr++ = *ptr; + else if (*(ptr + 1) == '{') + { + static char varname[BUFSIZ]; + char *vptr = varname; + const char *pptr; + char *kv, *parsekv; + + *vptr = '\0'; + + for (pptr = ptr + 2; *pptr != '\0'; pptr++) + { + if (*pptr != '}') + *vptr++ = *pptr; + else + { + *vptr = '\0'; + break; + } + } + + ptr += (pptr - ptr); + kv = tuple_find(pkg->vars, varname); + + if (kv != NULL) + { + parsekv = strdup_parse(pkg, kv); + + strncpy(bptr, parsekv, BUFSIZ - (bptr - buf)); + bptr += strlen(parsekv); + + free(parsekv); + } + } + } + + *bptr = '\0'; + + return strdup(buf); +} + +/* + * parse_file(filename) + * + * Parse a .pc file into a pkg_t object structure. + */ +pkg_t * +parse_file(const char *filename) +{ + FILE *f; + pkg_t *pkg; + char readbuf[BUFSIZ]; + + f = fopen(filename, "r"); + if (f == NULL) + return NULL; + + pkg = calloc(sizeof(pkg_t), 1); + pkg->filename = strdup(filename); + + while (fgets(readbuf, BUFSIZ, f) != NULL) + { + char *p, *key = NULL, *value = NULL; + + readbuf[strlen(readbuf) - 1] = '\0'; + + p = readbuf; + while (*p && (isalpha(*p) || isdigit(*p) || *p == '_' || *p == '.')) + p++; + + key = strndup(readbuf, p - readbuf); + if (!isalpha(*key) && !isdigit(*p)) + goto cleanup; + + while (*p && isspace(*p)) + p++; + + value = strdup(p + 1); + + switch (*p) + { + case ':': + if (!strcasecmp(key, "Name")) + pkg->realname = strdup_parse(pkg, value); + if (!strcasecmp(key, "Description")) + pkg->description = strdup_parse(pkg, value); + if (!strcasecmp(key, "Version")) + pkg->version = strdup_parse(pkg, value); + if (!strcasecmp(key, "CFLAGS")) + pkg->cflags = strdup_parse(pkg, value); + if (!strcasecmp(key, "LIBS")) + pkg->libs = strdup_parse(pkg, value); + break; + case '=': + pkg->vars = tuple_add(pkg->vars, key, value); + break; + default: + break; + } + +cleanup: + if (key) + free(key); + + if (value) + free(value); + } + + fclose(f); + return pkg; +} diff --git a/pkg.c b/pkg.c new file mode 100644 index 0000000..5418450 --- /dev/null +++ b/pkg.c @@ -0,0 +1,51 @@ +/* + * pkg.c + * main() routine and basic dependency solving... + * + * Copyright (c) 2011 William Pitcock . + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pkg.h" + +pkg_t * +pkg_find(const char *name) +{ + char locbuf[BUFSIZ]; + + snprintf(locbuf, sizeof locbuf, "/usr/lib/pkgconfig/%s.pc", name); + + return parse_file(locbuf); +} + +int main(int argc, const char *argv[]) +{ + pkg_t *pkg; + + pkg = pkg_find(argv[1]); + if (pkg) + printf("%s %s\n", pkg->cflags, pkg->libs); + else + { + printf("%s not found\n", argv[1]); + return -1; + } + + return 0; +} + diff --git a/pkg.h b/pkg.h new file mode 100644 index 0000000..6552b7c --- /dev/null +++ b/pkg.h @@ -0,0 +1,93 @@ +/* + * pkg.h + * Global include file for everything. + * + * Copyright (c) 2011 William Pitcock . + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __PKG_H +#define __PKG_H + +#include "config.h" + +#define _GNU_SOURCE +#include +#include +#include + +#ifndef BUFSIZ +#define BUFSIZ 65535 +#endif + +typedef enum { + PKG_ANY = 0, + PKG_LESS_THAN, + PKG_GREATER_THAN, + PKG_LESS_THAN_EQUAL, + PKG_GREATER_THAN_EQUAL, + PKG_EQUAL, + PKG_NOT_EQUAL, + PKG_ALWAYS_MATCH +} pkg_comparator_t; + +typedef struct pkg_ pkg_t; +typedef struct dependency_ pkg_dependency_t; +typedef struct tuple_ pkg_tuple_t; + +#define foreach_list_entry(head, value) \ + for ((value) = (head); (value) != NULL; (value) = (value)->next) + +struct dependency_ { + struct dependency_ *prev, *next; + + char *name; + pkg_comparator_t compare; + char *version; + pkg_t *parent; +}; + +struct tuple_ { + struct tuple_ *prev, *next; + + char *key; + char *value; +}; + +struct pkg_ { + char *filename; + char *realname; + char *version; + char *description; + char *url; + char *pc_filedir; + char *libs; + char *cflags; + + pkg_dependency_t *requires; + pkg_dependency_t *conflicts; + pkg_tuple_t *vars; +}; + +pkg_t *pkg_find(const char *name); +pkg_t *pkg_find_matching_dep(pkg_dependency_t *dep); + +/* parse.c */ +pkg_t *parse_file(const char *path); + +#endif