# Copyright 1999-2009 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: /var/cvsroot/gentoo-x86/eclass/ccc.eclass,v 1.21 2009/02/08 17:16:02 vapier Exp $ # @ECLASS: ccc.eclass # @MAINTAINER: # alpha@gentoo.org # @BLURB: functions to make ebuilds more ccc friendly. # # Authors: # Tavis Ormandy # Aron Griffis inherit flag-o-matic # define this to make this eclass noisy. #DEBUG_CCC_ECLASS=1 ccc-fixup() { # helper function to fixup files # and show differences when debugging # # store the backup suffix. local files list suffix=ccc-fixup-${$} while read files do sed --in-place=.${suffix} ${1} ${files} || return 1 list="${list} ${files}" done [ ! "$DEBUG_CCC_ECLASS" ] && return 0 # if theres a backup, diff it. for i in ${list} do einfo "Checking for changes to `basename ${i}` ..." if [ -e "${i}.${suffix}" ]; then diff -u ${i}.${suffix} ${i} # sleep 1 fi done } # @FUNCTION: hide-restrict-arr # @DESCRIPTION: # Scan for and replace __restrict_arr with a ccc # supported equivalent. # # You might see an error like this if you need this: # @CODE # cc: Error: regexec.c, line 209: In the definition of the function "regexec", # the promoted type of pmatch is incompatible with the type of the corresponding # parameter in a prior declaration. (promotmatch) # regmatch_t pmatch[]; # ---------------^ # @CODE hide-restrict-arr() { # __restrict_arr causes trouble with ccc, __restrict # is a supported equivalent. # # example: # regmatch_t __pmatch[__restrict_arr] # find ${WORKDIR} -iname '*.h' | \ xargs | ccc-fixup 's#\(\[__restrict\)_arr\]#\1\]#g' } # @FUNCTION: replace-cc-hardcode # @DESCRIPTION: # Look for common cc hardcodes in Makefiles. replace-cc-hardcode() { # lots of developers hardcode gcc into their # Makefiles. Try and fix these. # find ${WORKDIR} -iname Makefile | \ xargs | ccc-fixup "s#^\(CC.*=\).*g\?cc#\1${CC:-gcc}#g" } # @FUNCTION: replace-cxx-hardcode # @DESCRIPTION: # Look for common cxx hardcodes in Makefiles. replace-cxx-hardcode() { # lots of developers hardcode g++ into thier # Makefiles. Try and fix these. find ${WORKDIR} -iname Makefile | \ xargs | ccc-fixup "s#^\(CXX.*=\).*[gc]\{1\}++#\1${CXX:-g++}#g" } # @FUNCTION: is-ccc # @RETURN: Returns success if dec compiler is being used. # @DESCRIPTION: # example: # # is-ccc && hide-restrict-arr is-ccc() { # return true if ccc is being used. [ "${ARCH}:`basename ${CC:-gcc}`" == "alpha:ccc" ] } # @FUNCTION: is-cxx # @RETURN: Returns success if dec c++ compiler is being used. is-cxx() { # return true if cxx is being used [ "${ARCH}:`basename ${CXX:-g++}`" == "alpha:cxx" ] } # @FUNCTION: replace-ccc-g # @DESCRIPTION: # Try to replace -g with -g3 replace-ccc-g() { # -g will stop ccc/cxx performing optimisation # replacing it with -g3 will let them co-exist. find ${WORKDIR} -iname Makefile | \ xargs | ccc-fixup \ "s#\(^\CX\{,2\}FLAGS[[:space:]]*=.*[\'\"\x20\t]*\)-g\([\'\"\x20\t]\|$\)#\1-g3\2#g" # FIXME: my eyes! it burns! } # @FUNCTION: ccc-elf-check # @RETURN: Return success if binary was compiled with ccc # @DESCRIPTION: # example: # @CODE # if ! is-ccc; then # ccc-elf-check /usr/lib/libglib.a && \ # append-ldflags -lots # fi # @CODE # # NOTE: i think the binary and shared library detection # is pretty safe, but the archive detection may not # be as reliable. ccc-elf-check() { # check if argument is a ccc created executable. # this is useful for libraries compiled with ccc, # which might require -lots/-lcpml if a linking binary # isnt being compiled with ccc. local myBINARY=${1:-a.out} if [[ ! "${myBINARY}" == *.a ]]; then # find the offset and size of the elf .note section. # example contents: 000132d2 00000dc8 # ^- offset ^- size local elf_note_offset=`objdump -h ${myBINARY} | \ grep -E '^\ [0-9]{2,}\ .note\ ' | \ awk '{print $6,$3}' | \ line` # check if that got anything. [ ! "${elf_note_offset}" ] && return 1 # dump contents of section, and check for compaq signature. hexdump -s 0x${elf_note_offset% *} -n $((0x${elf_note_offset#* })) -e '"%_p"' ${myBINARY} | \ grep -E 'Compaq Computer Corp.' &>/dev/null && return 0 # no compaq message, return 1 else # just grep it for the Compaq sig. hexdump -e '"%_p"' ${myBINARY} | \ grep -E 'Compaq Computer Corp.' &>/dev/null && return 0 fi return 1 } # @FUNCTION: create-so # @USAGE: < /usr/lib/library.a > < library.so > # @DESCRIPTION: # Make the shared library (.so) specified from the archive (.a) # specified. LDFLAGS will be honoured. if you need a different # `soname` (DT_SONAME) from the shared lib filename, you will have # to do it manually ;) # # example: # @CODE # is-ccc && \ # create-so /usr/lib/libcoolstuff.a libcoolstuff.so.${PV} # dosym /usr/lib/libcoolstuff.so.${PV} /usr/lib/libcoolstuff.so # @CODE # # NOTE: -lots will be used by default, this is ccc.eclass after all :) # NOTE: .${PV} is optional, of course. # NOTE: dolib.so will manage installation create-so() { # some applications check for .so, but ccc wont # create one by default if [[ "${2}" == *.so ]]; then # no version suffix. ${LD:-ld} -shared -o ${T}/${2##*/} -soname ${2##*/} \ -whole-archive ${1} -no-whole-archive -lots ${LDFLAGS} else # version suffix local so_version=${2##*.so} ${LD:-ld} -shared -o ${T}/${2##*/} -soname `basename ${2/${so_version}}` \ -whole-archive ${1} -no-whole-archive -lots ${LDFLAGS} fi # hand installation over to dolib.so dolib.so ${T}/${2##*/} } # @FUNCTION: otsify # @USAGE: < archive > # @DESCRIPTION: # Add the functions from libots to , this means # that if you use gcc to build an application that links with # , you wont need -lots. # Use this on libraries that you want maximum performance from, # but might not be using ccc when linking against it (eg zlib, openssl, etc) # # example: # # is-ccc && otsify ${S}/libz.a otsify() { [ "$DEBUG_CCC_ECLASS" ] && local ar_args="v" # confirm argument exists, and is an archive (eg *.a) # if it is, extract libots members into tempdir, then # append them to argument, regenerate index and then return. if [ "${1##*.}" == "a" ] && [ -f "${1}" ]; then einfo "otsifying `basename ${1}` ..." mkdir ${T}/ccc-otsify-${$} cd ${T}/ccc-otsify-${$} einfo " extracting archive members from libots ..." ar ${ar_args}x /usr/lib/libots.a || { eerror " unable to extract libots members." return 1 } einfo " appending libots members to `basename ${1}` ..." ar ${ar_args}q ${1} ${T}/ccc-otsify-${$}/*.o || { eerror " failed to append libots members to ${1}." return 1 } einfo " regenerating `basename ${1}` archive index ..." ranlib ${1} || ewarn " ranlib returned an error, probably not important." einfo "otsification completed succesfully." cd ${OLDPWD:-.} return 0 else ewarn "called otsify() with bad argument ..." cd ${OLDPWD:-.} return 1 fi }