# Copyright 1999-2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: /var/cvsroot/gentoo-x86/eclass/ccc.eclass,v 1.18 2005/07/11 15:08:06 swegener Exp $ # # Authors: Tavis Ormandy <taviso@gentoo.org> # Aron Griffis <agriffis@gentoo.org> # # functions to make ebuilds more ccc friendly. # # 16/6/2003 - Added otsify() # 18/6/2003 - regex tweaks. # 22/7/2003 - newdepend inherit flag-o-matic # define this to make this eclass noisy. #DEBUG_CCC_ECLASS=1 # #### hide-restrict-arr #### # Scan for and replace __restrict_arr with a ccc # supported equivalent. # # you might see an error like this if you need this: # # 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[]; # ---------------^ # #### replace-cc-hardcode #### # Look for common cc hardcodes in Makefiles. # #### replace-cxx-hardcode #### # Look for common cxx hardcodes in Makefiles. # #### is-ccc #### # Returns success if dec compiler is being used. # # example: # # is-ccc && hide-restrict-arr # #### is-cxx #### # Returns success if dec c++ compiler is being used. # #### replace-ccc-g #### # Try to replace -g with -g3 # #### ccc-elf-check </path/to/binary> #### # Return success if binary was compiled with ccc # # example: # if ! is-ccc; then # ccc-elf-check /usr/lib/libglib.a && \ # append-ldflags -lots # fi # # NOTE: i think the binary and shared library detection # is pretty safe, but the archive detection may not # be as reliable. #### create-so </usr/lib/library.a> <library.so> #### # 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: # is-ccc && \ # create-so /usr/lib/libcoolstuff.a libcoolstuff.so.${PV} # dosym /usr/lib/libcoolstuff.so.${PV} /usr/lib/libcoolstuff.so # # 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 #### append-ldflags <flag> #### #### is-ldflag <flag> #### #### filter-ldflags <flag> #### # flag-o-matic doesnt provide LDFLAGS utilities. # Some replacements for ccc porting. These functions # mimic the flag-o-matic equivalents, look in there for # documentation. # #### otsify <archive> #### # Add the functions from libots to <archive>, this means # that if you use gcc to build an application that links with # <archive>, 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 # #### # 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 } 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' } 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" } 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" } is-ccc() { # return true if ccc is being used. [ "${ARCH}:`basename ${CC:-gcc}`" == "alpha:ccc" ] } is-cxx() { # return true if cxx is being used [ "${ARCH}:`basename ${CXX:-g++}`" == "alpha:cxx" ] } 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! } 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 } 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##*/} } append-ldflags() { LDFLAGS="${LDFLAGS} ${1}" } # flag-o-matic clone # #is-ldflags() #{ # for x in ${LDFLAGS} # do # if [ "${x}" = "${1}" ]; then # echo true # break # fi # done #} is-ldflags() { local x for x in ${LDFLAGS} do if [ "${x}" == "${1}" ]; then tty --quiet < /dev/stdout || echo "true" return 0 fi done return 1 } filter-ldflags() { for x in ${1} do LDFLAGS="${LDFLAGS/${x}}" done } 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 }