From ddf4b39e96596d8ec97d87995d1d3525766b266a Mon Sep 17 00:00:00 2001 From: Serban Udrea Date: Sun, 11 Dec 2011 17:14:17 -0600 Subject: libraries/lapack-atlas: Added (LAPACK customized for build against ATLAS) Signed-off-by: Robby Workman --- libraries/lapack-atlas/README | 14 ++ libraries/lapack-atlas/README.SLACKWARE | 49 +++++ libraries/lapack-atlas/lapack-atlas.SlackBuild | 289 +++++++++++++++++++++++++ libraries/lapack-atlas/lapack-atlas.info | 10 + libraries/lapack-atlas/make.inc.atlas | 70 ++++++ libraries/lapack-atlas/slack-desc | 19 ++ 6 files changed, 451 insertions(+) create mode 100644 libraries/lapack-atlas/README create mode 100644 libraries/lapack-atlas/README.SLACKWARE create mode 100644 libraries/lapack-atlas/lapack-atlas.SlackBuild create mode 100644 libraries/lapack-atlas/lapack-atlas.info create mode 100644 libraries/lapack-atlas/make.inc.atlas create mode 100644 libraries/lapack-atlas/slack-desc diff --git a/libraries/lapack-atlas/README b/libraries/lapack-atlas/README new file mode 100644 index 0000000000..876f7570b3 --- /dev/null +++ b/libraries/lapack-atlas/README @@ -0,0 +1,14 @@ +LAPACK provides routines for solving systems of simultaneous linear +equations, least-squares solutions of linear systems of equations, +eigenvalue problems, and singular value problems. + +This script builds LAPACK against ATLAS. As such it requires ATLAS as installed +by the appropriate SlackBuild. This build conflicts with the lapack.SlackBuild +but you may try to have both installed if you definitely want, see below. + +Do read over README.SLACKWARE *before* building this. + +NOTE: The download link provides a package with lapack-3.3.1 patched against +some of the presently known bugs of the 3.3.1 release. Please consult the +LAPACK-3.3.1 errata file (http://www.netlib.org/lapack/Errata/index2.html) for +more details about the corrected bugs. diff --git a/libraries/lapack-atlas/README.SLACKWARE b/libraries/lapack-atlas/README.SLACKWARE new file mode 100644 index 0000000000..fccc6b12b6 --- /dev/null +++ b/libraries/lapack-atlas/README.SLACKWARE @@ -0,0 +1,49 @@ +The following notes apply just for LAPACK built against ATLAS. + +IMPORTANT NOTES: + + +1) If you update ATLAS, you MUST also rebuild and reinstall LAPACK, even if + there is no update available for LAPACK! Otherwise you end up with a + broken/incomplete LAPACK library! + +2) This SlackBuild conflicts with the lapack.SlackBuild which is meant mainly + for compilation against the reference BLAS. You may install LAPACK by + this SlackBuild in parallel with the LAPACK built against the reference BLAS + if you use the SYS_DESTDIR and DEFAULT_DOCS variables (see below), but then + you are on your own, especially when compiling other software against LAPACK + and BLAS/ATLAS. + +3) There are a few extra variables which you may want or need to give + appropriate values when calling the lapack-atlas.SlackBuild: SYS_DESTDIR, + DEFAULT_DOCS, USE_ATLAS_PT_LIBS and TEST_LAPACK. + + SYS_DESTDIR is set by default to "/usr" and is the system destination + directory. When installing the package produced by this SlackBuild, + LAPACK's files will be written to $SYS_DESTDIR/lib (or lib64). + Documentation files are written to /usr/doc/lapack-atlas-$VERSION if not + otherwise stated (see below). + You may want to change the value of SYS_DESTDIR to avoid conflicts (see + the notes above). IMPORTANT: SYS_DESTDIR has to have an absolute + path as value. + + DEFAULT_DOCS has the default value "yes", which means that docs go + to /usr/doc/lapack-atlas-$VERSION, but you may want to let the docs to + go to $SYS_DESTDIR/doc/lapack-atlas-$VERSION. For this, just set this + variable to something like "no". + + USE_ATLAS_PT_LIBS is set by default to "yes" which means that this script + will try to build LAPACK against the threaded ATLAS libs. On a single + processor machine these are missing and you will get a WARNING which you + can ignore, since ATLAS will not create these libraries on such a machine. + On a multi processor machine the WARNING should not be there and you need to + set this variable to "no" if you want to force LAPACK to build against the + single threaded ATLAS libraries. At this point in time this is discouraged + and you are on your own if you do it, especially when compiling other + software which depends on LAPACK and ATLAS. + + TEST_LAPACK is set by default to "no" which means that this script will not + try to run the LAPACK test suite. Set it to "yes" if you want the opposite. + + All these settings may be done the usual way on the command line when + calling this SlackBuild, you do not have to edit the script. diff --git a/libraries/lapack-atlas/lapack-atlas.SlackBuild b/libraries/lapack-atlas/lapack-atlas.SlackBuild new file mode 100644 index 0000000000..4659a7f7e6 --- /dev/null +++ b/libraries/lapack-atlas/lapack-atlas.SlackBuild @@ -0,0 +1,289 @@ +#!/bin/sh + +# Slackware script to build the LAPACK libraries against ATLAS. + +# Written by Serban Udrea +# Includes the code to make dynamic libs from the lapack.SlackBuild by +# Eugene Suter + +# Licence: LICENCE file in the tarball + +PRGNAM=lapack-atlas +VERSION=${VERSION:-3.3.1} +BUILD=${BUILD:-1} +TAG=${TAG:-_SBo} + +SRCNAM=lapack # The source is still that of LAPACK + +if [ -z "$ARCH" ]; then + case "$( uname -m )" in + i?86) ARCH=i486 ;; + arm*) ARCH=arm ;; + *) ARCH=$( uname -m ) ;; + esac +fi + +CWD=$(pwd) +TMP=${TMP:-/tmp/SBo} +PKG=$TMP/package-${PRGNAM} +OUTPUT=${OUTPUT:-/tmp} + +if [ "$ARCH" = "i486" ]; then + SLKCFLAGS="-O2 -march=i486 -mtune=i686" + LIBDIRSUFFIX="" +elif [ "$ARCH" = "i686" ]; then + SLKCFLAGS="-O2 -march=i686 -mtune=i686" + LIBDIRSUFFIX="" +elif [ "$ARCH" = "x86_64" ]; then + SLKCFLAGS="-O2 -fPIC" + NOOPTFLAGS="-fPIC" + LIBDIRSUFFIX="64" +fi + +set -e # Exit on most errors + +# This is the system destination directory. When installing the +# package produced by this script, LAPACK's files will be written to +# $SYS_DESTDIR/lib or $SYS_DESTDIR/lib64 on appropriate platforms, etc. +# Nevertheless, by default the documentation files go to +# /usr/doc/$PRGNAM-$VERSION. You may change this through the variable +# DEFAULT_DOCS, see below. +SYS_DESTDIR=${SYS_DESTDIR:-/usr} + +# Check if SYS_DESTDIR is an absolute path. If not, exit with error. +# NOTE: The $ is used because echo adds a \n at the end of the string. +echo "$SYS_DESTDIR" | grep -vE '/\.\./|/\.\.$' | grep -qE '^/' || \ +{ echo "ERROR: The system destination directory has no absolute path!" \ +&& echo " The value of SYS_DESTDIR is $SYS_DESTDIR" \ +&& echo " Please set it properly! " \ +&& exit 1; } + +# You may want to have the documentation files installed under +# $SYS_DESTDIR/doc/$PRGNAM-$VERSION not /usr/doc/$PRGNAM-$VERSION. +# To achieve this just set the following variable to something like +# "no". +DEFAULT_DOCS=${DEFAULT_DOCS:-yes} +DEFAULT_DOCS=$(echo "$DEFAULT_DOCS"|cut -b 1|tr a-z A-Z) # Make Y or N out of yes, Yes, No, no, etc. +if [ "$DEFAULT_DOCS" = "Y" ]; then + DOC_DIR="$PKG/usr/doc/${PRGNAM}-$VERSION" +else + DOC_DIR="$PKG$SYS_DESTDIR/doc/${PRGNAM}-$VERSION" +fi + +rm -rf $PKG +mkdir -p $TMP $PKG $OUTPUT +cd $TMP +rm -rf $SRCNAM-$VERSION +tar xvf $CWD/$SRCNAM-$VERSION.tgz +cd $SRCNAM-$VERSION + +chown -R root:root . +find . \ + \( -perm 777 -o -perm 775 -o -perm 711 -o -perm 555 -o -perm 511 \) \ + -exec chmod 755 {} \; -o \ + \( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \ + -exec chmod 644 {} \; + +# Within Makefile it is asumed that lapack_testing.py is executable. +# This is not the case, thus if TEST_LAPACK is enabled, make fails. +chmod 755 ./lapack_testing.py + +# If you say "no" here, the script will NOT try to link LAPACK against +# the multi-threaded ATLAS libraries. If you leave it to "yes" and the +# multi-threaded ATLAS libraries are not available, the script will default +# to linking against the single threaded ones and raise a warning. +USE_ATLAS_PT_LIBS="${USE_ATLAS_PT_LIBS:-yes}" +USE_ATLAS_PT_LIBS=$(echo "$USE_ATLAS_PT_LIBS"|cut -b 1|tr a-z A-Z) # Make Y or N out of yes, Yes, No, no, etc. + +# Change the following to yes if you would like to run the tests for LAPACK. +TEST_LAPACK="${TEST_LAPACK:-no}" +# Make Y or N out of yes, Yes, No, no, etc. +TEST_LAPACK=$(echo "$TEST_LAPACK"|cut -b 1|tr a-z A-Z) + +# Search for the latest installed atlas package +# (not necessarily the one with the latest version). +# For this to work the system clock should also work properly. +# NOTE: The echo statement below is for getting around "set -e" this time. +ATLAS_PKG="$(ls -1 -dc /var/log/packages/atlas* 2>/dev/null | \ + head -n 1 || echo -n)" + +# Check if an atlas package was found. Exit if not! +[ ! "$ATLAS_PKG" ] && \ +echo "ERROR: Couldn't find the ATLAS package." && exit 1 + +# Pick up the SETTINGS file containing the appropriate flags, use again the +# echo trick against "set -e". You may also provide your own path to a file +# containing apropriate settings, see the README for details +ATLAS_SETTINGS_FILE=${ATLAS_SETTINGS_FILE:-"/$(grep SETTINGS "$ATLAS_PKG" || echo -n)"} + +[ "${ATLAS_SETTINGS_FILE}1" = "/1" ] && \ +echo "ERROR: No location available for the file with ATLAS settings." && exit 1 + +# Check that we deal with a regular file which is readable +[ -f "$ATLAS_SETTINGS_FILE" -a -r "$ATLAS_SETTINGS_FILE" ] || \ +{ echo "ERROR: $ATLAS_SETTINGS_FILE is not a regular file or is not readable by us." && exit 1; } + +# Source the atlas settings. +. "$ATLAS_SETTINGS_FILE" + +# Check for the presence of variables provided by the ATLAS_SETTINGS_FILE +{ [ "$ATLAS_COMPILER" ] && \ + [ "$ATLAS_F77FLAGS" ] && \ + [ "$ATLAS_NOOPT" ]; } || +{ echo "ERROR: Improper ATLAS settings; empty or undefined variables." && exit 1; } + +# This is the timer to be used for LAPACK. If you stay with gfortran, +# presently the default compiler on Slackware, you can leave the value as is. +# Otherwise, please read LAPACK's make.inc for more informations. +LAPACK_TIMER="${LAPACK_TIMER:-INT_ETIME}" + +# Looking for the libraries provided by ATLAS. If one asks for threaded +# libraries and these are available we will try to link against them. +if [ "$USE_ATLAS_PT_LIBS" = "Y" ]; then + # Set proper library names for the threaded ATLAS libs. + ATLAS_BLASLIB="libptf77blas.a" + ATLAS_CBLASLIB="libptcblas.a" + # Find out the full paths to the ATLAS libraries + ATLAS_BLASLIB_P="/$(grep "$ATLAS_BLASLIB" "$ATLAS_PKG" || echo -n)" + # We need this to finally link against the mixed LAPACK library, resulting + # from the full LAPACK and the optimized LAPACK routines provided by ATLAS. + ATLAS_CBLASLIB_P="/$(grep "$ATLAS_CBLASLIB" "$ATLAS_PKG" || echo -n)" + if [ "${ATLAS_BLASLIB_P}1" = "/1" -o "${ATLAS_CBLASLIB_P}1" = "/1" ]; then + # Oops! The threaded libraries are not available! + echo "" + echo "WARNING: No threaded ATLAS libraries available!" + echo "WARNING: Linking against non-threaded libraries!" + echo "" + ATLAS_BLASLIB="libf77blas.a" + ATLAS_CBLASLIB="libcblas.a" + USE_ATLAS_PT_LIBS="N" + fi +else + # Set proper library names for the unthreaded ATLAS libs. + ATLAS_BLASLIB="libf77blas.a" + ATLAS_CBLASLIB="libcblas.a" +fi + +# Find out the full paths to the ATLAS libraries +ATLAS_BLASLIB="/$(grep "$ATLAS_BLASLIB" "$ATLAS_PKG" || echo -n)" +ATLAS_CBLASLIB="/$(grep "$ATLAS_CBLASLIB" "$ATLAS_PKG" || echo -n)" +ATLAS_EXTRA_LIB="/$(grep libatlas.a "$ATLAS_PKG" || echo -n)" +ATLAS_LAPACK="/$(grep liblapack.a "$ATLAS_PKG" || echo -n)" + +# Check that we got what we expected +{ [ "${ATLAS_BLASLIB}1" = "/1" ] || \ + [ "${ATLAS_CBLASLIB}1" = "/1" ] || \ + [ "${ATLAS_EXTRA_LIB}1" = "/1" ] || \ + [ "${ATLAS_LAPACK}1" = "/1" ]; } && \ +{ echo "ERROR: ATLAS libraries missing from the Slackware ATLAS package log." && exit 1; } + +# Check that the library files are there. +# NOTE: After the installation of this package, the incomplete LAPACK library +# installed by ATLAS gets substituted by the complete one provided by us +[ -f "$ATLAS_BLASLIB" -a -r "$ATLAS_BLASLIB" ] || \ +{ echo "ERROR: $ATLAS_BLASLIB is not a regular file or is not readable by us." && exit 1; } + +[ -f "$ATLAS_CBLASLIB" -a -r "$ATLAS_CBLASLIB" ] || \ +{ echo "ERROR: $ATLAS_CBLASLIB is not a regular file or is not readable by us." && exit 1; } + +[ -f "$ATLAS_EXTRA_LIB" -a -r "$ATLAS_EXTRA_LIB" ] || \ +{ echo "ERROR: $ATLAS_EXTRA_LIB is not a regular file or is not readable by us." && exit 1; } + +[ -f "$ATLAS_LAPACK" -a -r "$ATLAS_LAPACK" ] || \ +{ echo "ERROR: $ATLAS_LAPACK is not a regular file or is not readable by us." && exit 1; } + +ATLAS_LIBS="${ATLAS_BLASLIB} ${ATLAS_EXTRA_LIB}" + +# Copy the pre-configured make.inc file but edit it accordingly +sed $CWD/make.inc.atlas \ + -e s%XXX_FORTRAN_XXX%"$ATLAS_COMPILER"% \ + -e s%XXX_TIMER_XXX%"$LAPACK_TIMER"% \ + -e s%XXX_BLASLIB_XXX%"$ATLAS_LIBS"% > \ + make.inc + +# Set the compilation flags. +LAPACK_OPTS="$ATLAS_F77FLAGS $NOOPTFLAGS" +LAPACK_NOOPT="$ATLAS_NOOPT $NOOPTFLAGS" + +# Build objects and static library files +make cleanlib +make OPTS="$LAPACK_OPTS" NOOPT="$LAPACK_NOOPT" lapacklib + +# Merge the ATLAS incomplete LAPACK library with the +# just built full LAPACK. +mkdir -p merging_dir +( cd merging_dir + ar x "$ATLAS_LAPACK" + ar r "../lib${SRCNAM}.a" *.o +) +rm -rf merging_dir + +if [ "$TEST_LAPACK" = "Y" ]; then + # We want to test LAPACK, thus we have to build tmglib and then run the tests + make OPTS="$LAPACK_OPTS" NOOPT="$LAPACK_NOOPT" tmglib + + # Update make.inc taking into account that the LAPACK library has + # been merged with the optimized LAPACK routines provided by ATLAS. + ATLAS_LIBS="${ATLAS_BLASLIB} ${ATLAS_CBLASLIB} ${ATLAS_EXTRA_LIB}" + + if [ "$USE_ATLAS_PT_LIBS" = "Y" ]; then + # Add the threads library + ATLAS_LIBS=${ATLAS_LIBS}" -lpthread" + fi + + cat "$CWD/make.inc.atlas" | \ + sed -e s%XXX_FORTRAN_XXX%"$ATLAS_COMPILER"% \ + -e s%XXX_TIMER_XXX%"$LAPACK_TIMER"% \ + -e s%XXX_BLASLIB_XXX%"$ATLAS_LIBS"% > \ + make.inc + + make OPTS="$LAPACK_OPTS" NOOPT="$LAPACK_NOOPT" lapack_testing + + # Put the test results together + TEST_OUTPUT="TEST.RESULTS.tgz" + tar czf "$TEST_OUTPUT" TESTING/*.out +fi + +#LAPACK only. +( mkdir "shared_$SRCNAM" + cd "shared_$SRCNAM" + ar -x "../lib$SRCNAM.a" + gcc -fPIC -lgfortran -shared *.o -Wl,-soname,"$SRCNAM.so.$VERSION" \ + -o "lib$SRCNAM.so.$VERSION" +) + +mkdir -p "$PKG$SYS_DESTDIR/lib${LIBDIRSUFFIX}" +cp "lib$SRCNAM.a" "$PKG$SYS_DESTDIR/lib${LIBDIRSUFFIX}" +cp "shared_$SRCNAM/lib$SRCNAM.so.$VERSION" "$PKG$SYS_DESTDIR/lib${LIBDIRSUFFIX}" +( cd "$PKG$SYS_DESTDIR/lib${LIBDIRSUFFIX}" + chmod 755 "lib$SRCNAM.so.$VERSION" + ln -s "lib$SRCNAM.so.$VERSION" "lib$SRCNAM.so" +) + +find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | \ + grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true + +mkdir -p "$DOC_DIR" +cat "$CWD/${PRGNAM}.SlackBuild" > "$DOC_DIR/${PRGNAM}.SlackBuild" +cat README > "$DOC_DIR/README" +cat "$CWD/README.SLACKWARE" > "$DOC_DIR/README.SLACKWARE" +cat LICENSE > "$DOC_DIR/LICENSE" + +# If the tests have been performed, also copy the results to the doc directory. +if [ -f "$TEST_OUTPUT" ]; then + cp -p "$TEST_OUTPUT" "$DOC_DIR" +fi + +# Signal that lapack got compiled against atlas +# echo "Y" > "$DOC_DIR/WITH_ATLAS" + +if [ "$USE_ATLAS_PT_LIBS" = "Y" ]; then + # Signal that lapack got compiled with thread support + echo "$USE_ATLAS_PT_LIBS" > "$DOC_DIR/WITH_THREADS" +fi + +mkdir -p "$PKG/install" +cat $CWD/slack-desc > $PKG/install/slack-desc + +cd "$PKG" +/sbin/makepkg -l y -c n $OUTPUT/${PRGNAM}-$VERSION-$ARCH-$BUILD$TAG.${PKGTYPE:-tgz} diff --git a/libraries/lapack-atlas/lapack-atlas.info b/libraries/lapack-atlas/lapack-atlas.info new file mode 100644 index 0000000000..2497c5379e --- /dev/null +++ b/libraries/lapack-atlas/lapack-atlas.info @@ -0,0 +1,10 @@ +PRGNAM="lapack-atlas" +VERSION="3.3.1" +HOMEPAGE="http://www.netlib.org/lapack/" +DOWNLOAD="http://skmail.ikp.physik.tu-darmstadt.de/lapack/lapack-3.3.1.tgz" +MD5SUM="cb0790c96c72752e3f292bf85a7fbef0" +DOWNLOAD_x86_64="" +MD5SUM_x86_64="" +MAINTAINER="Serban Udrea" +EMAIL="S.Udrea@gsi.de" +APPROVED="rworkman" diff --git a/libraries/lapack-atlas/make.inc.atlas b/libraries/lapack-atlas/make.inc.atlas new file mode 100644 index 0000000000..48fe44c03f --- /dev/null +++ b/libraries/lapack-atlas/make.inc.atlas @@ -0,0 +1,70 @@ +# -*- Makefile -*- +#################################################################### +# LAPACK make include file. # +# LAPACK, Version 3.2.1 # +# April 2009 # +#################################################################### +# +# See the INSTALL/ directory for more examples. +# +SHELL = /bin/sh +# +# The machine (platform) identifier to append to the library names +# +#PLAT = _LINUX +# +# Modify the FORTRAN and OPTS definitions to refer to the +# compiler and desired compiler options for your machine. NOOPT +# refers to the compiler options desired when NO OPTIMIZATION is +# selected. Define LOADER and LOADOPTS to refer to the loader +# and desired load options for your machine. +# +FORTRAN = XXX_FORTRAN_XXX +OPTS = +DRVOPTS = $(OPTS) +NOOPT = +LOADER = $(FORTRAN) +LOADOPTS = $(OPTS) +# +# Timer for the SECOND and DSECND routines +# +# Default : SECOND and DSECND will use a call to the EXTERNAL FUNCTION ETIME +# TIMER = EXT_ETIME +# For RS6K : SECOND and DSECND will use a call to the EXTERNAL FUNCTION ETIME_ +# TIMER = EXT_ETIME_ +# For gfortran compiler: SECOND and DSECND will use a call to the INTERNAL FUNCTION ETIME +# TIMER = INT_ETIME +# If your Fortran compiler does not provide etime (like Nag Fortran Compiler, etc...) +# SECOND and DSECND will use a call to the Fortran standard INTERNAL FUNCTION CPU_TIME +#TIMER = INT_CPU_TIME +# If neither of this works...you can use the NONE value... In that case, SECOND and DSECND will always return 0 +TIMER = XXX_TIMER_XXX +# +# The archiver and the flag(s) to use when building archive (library) +# If you system has no ranlib, set RANLIB = echo. +# +ARCH = ar +ARCHFLAGS= cr +RANLIB = ranlib +# +# The location of BLAS library for linking the testing programs. +# The target's machine-specific, optimized BLAS library should be +# used whenever possible. +# +BLASLIB = XXX_BLASLIB_XXX +# +# Location of the extended-precision BLAS (XBLAS) Fortran library +# used for building and testing extended-precision routines. The +# relevant routines will be compiled and XBLAS will be linked only if +# USEXBLAS is defined. +# +# USEXBLAS = Yes +XBLASLIB = +# XBLASLIB = -lxblas +# +# Names of generated libraries. +# +LAPACKLIB = liblapack$(PLAT).a +TMGLIB = libtmglib$(PLAT).a +EIGSRCLIB = libeigsrc$(PLAT).a +LINSRCLIB = liblinsrc$(PLAT).a diff --git a/libraries/lapack-atlas/slack-desc b/libraries/lapack-atlas/slack-desc new file mode 100644 index 0000000000..1999509c4d --- /dev/null +++ b/libraries/lapack-atlas/slack-desc @@ -0,0 +1,19 @@ +# HOW TO EDIT THIS FILE: +# The "handy ruler" below makes it easier to edit a package description. Line +# up the first '|' above the ':' following the base package name, and the '|' +# on the right side marks the last column you can put a character in. You must +# make exactly 11 lines for the formatting to be correct. It's also +# customary to leave one space after the ':'. + + |-----handy-ruler------------------------------------------------------| +lapack-atlas: LAPACK-ATLAS (LAPACK customized for build against ATLAS) +lapack-atlas: +lapack-atlas: LAPACK provides routines for solving systems of simultaneous linear +lapack-atlas: equations, least-squares solutions of linear systems of equations, +lapack-atlas: eigenvalue problems, and singular value problems. The associated matrix +lapack-atlas: factorizations (LU, Cholesky, QR, SVD, Schur, generalized Schur) are +lapack-atlas: also provided, as are related computations such as reordering of the +lapack-atlas: Schur factorizations and estimating condition numbers. Dense and banded +lapack-atlas: matrices are handled, but not general sparse matrices. In all areas, +lapack-atlas: similar functionality is provided for real and complex matrices, in +lapack-atlas: both single and double precision. -- cgit v1.2.3