%define cross armv7l %define armv7l 1 # # spec file for package qemu-accel-ARCH, where ARCH = armv7l or aarch64 # # Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany. # Copyright (c) 2015 Tizen # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed # upon. The license for this file, and modifications and additions to the # file, is the same license as for the pristine package itself (unless the # license for the pristine package is not an Open Source License, in which # case the license is the MIT License). An "Open Source License" is a # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. # Please submit bugfixes or comments via http://bugs.tizen.org/ # # arm %define target_cpu %{cross} %define target_abi %{?armv7l:eabi} %define target_arch %{target_cpu}-tizen-linux-gnu%{?target_abi} %define libdir %{_prefix}/lib%{?aarch64:64} # default path in qemu %define our_path /emul Name: qemu-accel Version: 0.4 Release: 0 AutoReqProv: off BuildRequires: gcc-%{cross} BuildRequires: binutils-%{cross} #BuildRequires: expect BuildRequires: fdupes BuildRequires: gettext-runtime BuildRequires: gettext-tools BuildRequires: m4 # required for xxd BuildRequires: vim BuildRequires: patchelf BuildRequires: rpmlint-mini BuildRequires: rpmlint-tizen BuildRequires: elfutils BuildRequires: libxslt-tools BuildRequires: cmake BuildRequires: gawk BuildRequires: libstdc++ BuildRequires: python libpython BuildRequires: python-xml BuildRequires: python-magic BuildRequires: python-rpm BuildRequires: file BuildRequires: libasan BuildRequires: icecream BuildRequires: mono-core BuildRequires: libunwind BuildRequires: libuuid BuildRequires: clang Summary: Native binaries for speeding up cross compile License: GPL-2.0 Group: Development/Cross Compilation ExclusiveArch: x86_64 %{ix86} %ifarch x86_64 BuildRequires: libgcc-32bit BuildRequires: glibc-32bit %define multilib 1 %endif %description This package is used in %{cross} architecture builds using qemu to speed up builds with native binaries. This should not be installed on systems, it is just intended for qemu environments. %package -n python-accel AutoReqProv: off Requires: qemu-accel Provides: python-accel Version: %{version} Release: %{release} Summary: Binaries for python acceleration License: GPL-2.0 Group: Development/Cross Compilation %description -n python-accel This package is used in qemu-accel to accelerate python. %package -n clang-accel AutoReqProv: off Requires: qemu-accel Provides: clang-accel Version: %{version} Release: %{release} Summary: Binaries for clang acceleration License: GPL-2.0 Group: Development/Cross Compilation Requires: qemu-accel %description -n clang-accel This package is used in qemu-accel to accelerate clang compiler. %prep %build %install set +x gcc_version=`gcc --version | sed -ne '1s/[^0-9]*\(\([0-9]\.\?\)*\).*/\1/p'` # just like it is determided in python.spec python_version=`python --version 2>&1 | sed -ne '1s/.* //p' | head -c 3` binaries="%{_libdir}/libnsl.so.1 %{_libdir}/libnss_compat.so.2" # loaded via dlopen by glibc %ifarch %ix86 LD="/%{_lib}/ld-linux.so.2" %endif %ifarch x86_64 LD="/%{_lib}/ld-linux-x86-64.so.2" %endif # Check if we use toolchain with sanitizers support [ -f /usr/bin/gcc-force-options ] && sanitizer_enabled=1 if [ x"$sanitizer_enabled" == x"1" ]; then real_compiler=`find %{_bindir} -name '*-real' -printf '%{_bindir}/%%f '` fi for executable in $LD \ %{_bindir}/bash \ %{_bindir}/{rpm,rpm2cpio,rpmdb,rpmkeys,rpmqpack,rpmbuild,rpmsign,rpmspec} \ %{_libdir}/rpm-plugins/exec.so \ %{_libdir}/{libdb-4.8.so,libdb_cxx-4.8.so} \ %{_bindir}/{tar,gzip,bzip2,xz,xzdec} \ %{_bindir}/{grep,sed} \ %{_libdir}/libnssdbm3.so %{_libdir}/libsoftokn3.so %{_libdir}/libfreebl3.so \ %{_libdir}/lib*san.so* \ %{_bindir}/{cat,expr,mkdir,mv,rm,rmdir} \ %{_bindir}/{msgexec,msgfmt,msgcat,msgmerge} \ %{_bindir}/make \ %{_bindir}/m4 \ %{_bindir}/{awk,gawk} \ %{_bindir}/patch \ %{_bindir}/diff \ %{_bindir}/echo \ %{_bindir}/head \ %{_bindir}/eu-{addr2line,ar,elfcmp,elflint,findtextrel,ld,nm,objdump,ranlib,readelf,size,strings,strip,unstrip} \ %{_bindir}/xsltproc \ %{_bindir}/{ccmake,cmake,cpack,ctest} \ %{_bindir}/%{target_arch}-{addr2line,ar,as,c++filt,dwp,elfedit,gprof,ld,ld.bfd,ld.gold,nm,objcopy,objdump,ranlib,readelf,size,strings,strip} \ %{_bindir}/%{target_arch}-{c++,g++,cpp,gcc,gcc-${gcc_version},gcc-ar,gcc-nm,gcc-ranlib,gcov} \ %{libdir}/gcc/%{target_arch}/${gcc_version}/{cc1,cc1plus,collect2,lto1,lto-wrapper,liblto_plugin.so*} \ %{_bindir}/file \ %{_bindir}/icecc \ %{_bindir}/icerun \ ${real_compiler} \ %{_bindir}/{find,xargs,readlink,ls,cpio} \ %{_rpmconfigdir}/debugedit \ %{_rpmconfigdir}/*deps \ %{_bindir}/mono-sgen \ %{_libdir}/{libmonoboehm-*.so.*,libMonoPosixHelper.so,libmonosgen-*.so.*} \ %{_libdir}/{libunwind*.so*,libuuid*.so*} do binaries="$binaries $executable" done function prepare_package_list { local bins="" local name=$1 local executables=${@:2} echo "Setting up $name for $executables" ## Prepare the clang binaries separately for executable in $executables; do bins="$bins $executable `ldd $executable | sed -n 's,.*=> \(/[^ ]*\) .*,\1,p'`" done for b in $(echo "$bins" | tr ' ' '\n' | sort -u); do local orig_file=$(readlink -f $b) bins="$bins $orig_file" if [[ "$b" != *"/../"* ]]; then # Ignore relative paths echo $b >> $name.list fi; echo $orig_file >> $name.list done ## Store the resulting list for packaging, setting up the right prefix cat $name.list | sed -e 's|^|%{our_path}|;s| |\n%{our_path}|g' | sort -u > %{_sourcedir}/$name-accel.list binaries="$binaries $bins" } prepare_package_list all \ $binaries prepare_package_list clang \ %{_bindir}/{clang-*,clang++,opt,lli,llc,llvm-*} prepare_package_list python \ %{_bindir}/python${python_version} \ %{_libdir}/python${python_version}/lib-dynload/*.so \ %{_libdir}/python${python_version}/site-packages/*/*.so ## dump list of binaries and list of packages echo "### Binaries accelerated ###" echo $binaries | sed -e 's/[^ ]*\///g;s/[^ ]*.so[^ ]* \?//g' echo "### Packages used ###" for bin in $binaries do rpm -qf $bin done | grep -v "not owned" | sed -e "s/-[0-9].*//g" | sort -u echo "" function patch_binary { local binary=$1 local rtld=$2 # We don't need to accelerate shell scripts local filetype=`file --brief $binary` [[ x"$filetype" == x"POSIX shell script"* ]] && return local outfile=%{buildroot}/%{our_path}/$binary [[ ! -e $binary ]] && echo "WARNING: File '${binary}' not found, ignoring" && return [[ -f $outfile ]] && echo "WARNING: File '${outfile}' exists, ignoring" && return mkdir -p ${outfile%/*} cp -aL $binary $outfile objdump -s -j .rodata -j .data $outfile | sed 's/^ *\([a-z0-9]*\)/\1:/' | \ grep ': ' | grep -v 'file format' | grep -v 'Contents of section' | \ xxd -g4 -r - $outfile.data if grep -q "%{HOST_ARCH}"$outfile.data; then echo "ERROR file $binary leaks host information into the guest" exit 1 fi rm -f $outfile.data [ "$binary" == "$rtld" ] && return patchelf --set-rpath "%{our_path}/%{_libdir}" $outfile # not all binaries have an .interp section if patchelf --print-interpreter $outfile 1>/dev/null 2>/dev/null; then patchelf --set-interpreter %{our_path}$rtld $outfile fi } for binary in $binaries do patch_binary $binary $LD done set -x %{?multilib: # Detect name of current ld.so. E.g. ld-linux.so.2 cross_ld_symlink=$(basename `rpm -ql glibc-32bit | grep -E 'ld-linux\.so\.[[:digit:]]+'`) # Patch all 32bit binaries to use the right ld.so though symlink mkdir -p %{buildroot}%{our_path}%{_prefix}/lib mkdir -p %{buildroot}%{our_path}/lib for f in $(rpm -ql glibc-32bit) \ $(rpm -ql libgcc-32bit) do fdir=$(dirname $f) [ ! -d %{buildroot}/%{our_path}/$fdir ] && mkdir -p %{buildroot}/%{our_path}/$fdir cp -a $f %{buildroot}/%{our_path}/$f echo "%{our_path}$f" >> %{_sourcedir}/multilib-accel.list done # Now we have to change the ld.so name to prevent name clashing in armv7l repos i686_libdir="%{our_path}/lib" # 1. Rename the actual ld.so binary cross_ld_so=$(find %{buildroot}${i686_libdir} -name 'ld-*.so' -printf '%f') new_cross_ld_so=$(echo ${cross_ld_so} | sed -e 's,\.so,-i686.so,') mv %{buildroot}${i686_libdir}/${cross_ld_so} %{buildroot}${i686_libdir}/${new_cross_ld_so} sed -e "s|${cross_ld_so}|${new_cross_ld_so}|" -i %{_sourcedir}/multilib-accel.list # 2. Force the symlink to point the right file. ln -sf %{our_path}/lib/${new_cross_ld_so} %{buildroot}${i686_libdir}/${cross_ld_symlink} echo "${i686_libdir}/${cross_ld_symlink}" >> %{_sourcedir}/multilib-accel.list # create symlinks for libgcc-32bit # libgcc-32bit library is placed under %{_libdir}/gcc/%{target_arch}/${gcc_version}/32/ not just /lib for 32bit for f in $(rpm -ql libgcc-32bit) do filename=$(basename $f) ln -sf %{our_path}/$f %{buildroot}${i686_libdir}/${filename} echo "${i686_libdir}/${filename}" >> %{_sourcedir}/multilib-accel.list done } # create symlinks for bash ln -s usr/bin "%{buildroot}%{our_path}/bin" echo '%{our_path}/bin' >> %{_sourcedir}/all-accel.list ln -sf bash "%{buildroot}%{our_path}%{_bindir}sh" echo '%{our_path}%{_bindir}sh' >> %{_sourcedir}/all-accel.list mv %{buildroot}%{our_path}/%{_lib}/* %{buildroot}%{our_path}%{_libdir}/ rm -rf %{buildroot}%{our_path}/%{_lib} ln -sf usr/%{_lib} %{buildroot}%{our_path}/%{_lib} echo '%{our_path}/%{_lib}' >> %{_sourcedir}/all-accel.list %{?multilib: mv %{buildroot}%{our_path}/lib/* %{buildroot}%{our_path}%{_prefix}/lib/ rm -rf %{buildroot}%{our_path}/lib ln -sf usr/lib %{buildroot}%{our_path}/lib sed -e 's|%{our_path}/lib|%{our_path}/usr/lib|' -i %{_sourcedir}/multilib-accel.list echo '%{our_path}/usr/lib' >> %{_sourcedir}/multilib-accel.list } # rename binutils binaries for binary in addr2line ar as c++filt dwp elfedit gprof ld ld.bfd ld.gold nm objcopy objdump ranlib readelf size strings strip gcov do mv %{buildroot}%{our_path}%{_bindir}/%{target_arch}-$binary %{buildroot}%{our_path}%{_bindir}/$binary sed -e "\|%{our_path}%{_bindir}/%{target_arch}-$binary|d" -i %{_sourcedir}/all-accel.list echo "%{our_path}%{_bindir}/$binary" >> %{_sourcedir}/all-accel.list done mkdir -p %{buildroot}/%{our_path}/%{_prefix}/%{target_arch}/bin for binary in ar as ld{,.bfd,.gold} nm obj{copy,dump} ranlib strip; do ln -sf %{our_path}%{_bindir}/$binary %{buildroot}%{our_path}%{_prefix}/%{target_arch}/bin/$binary echo "%{our_path}%{_bindir}/$binary" >> %{_sourcedir}/all-accel.list echo "%{our_path}%{_prefix}/%{target_arch}/bin/$binary" >> %{_sourcedir}/all-accel.list done # create symlinks for python mv %{buildroot}%{our_path}%{_bindir}/python${python_version} %{buildroot}%{our_path}%{_bindir}/python${python_version}-orig cat > %{buildroot}%{our_path}%{_bindir}/python${python_version} << EOF #!/bin/bash if [ -z "\$PYTHONPATH" ]; then export PYTHONPATH="%{libdir}/python${python_version}" else export PYTHONPATH+=":%{libdir}/python${python_version}" fi export PYTHONHOME="%{our_path}%{_prefix}" %{our_path}%{_bindir}/python${python_version}-orig "\$@" EOF chmod +x %{buildroot}%{our_path}%{_bindir}/python${python_version} ln -s python${python_version} %{buildroot}%{our_path}%{_bindir}/python ln -s python${python_version} %{buildroot}%{our_path}%{_libdir}/python #create symlinks for Scons mkdir -p %{buildroot}%{our_path}%{libdir}/python${python_version}/site-packages ln -sf %{libdir}/python${python_version}/site-packages/SCons %{buildroot}%{our_path}%{libdir}/python${python_version}/site-packages/SCons # rpmlint acceleration mkdir -p %{buildroot}%{our_path}/opt/testing/bin ln -s %{our_path}%{_bindir}/python${python_version}-orig %{buildroot}%{our_path}/opt/testing/bin/ cat > %{buildroot}%{our_path}/opt/testing/bin/python${python_version} << EOF #!/bin/bash if [ -z "\$PYTHONPATH" ]; then export PYTHONPATH="%{libdir}/python${python_version}" else export PYTHONPATH+=":%{libdir}/python${python_version}" fi export PYTHONHOME="%{our_path}%{_prefix}" %{our_path}/opt/testing/bin/python${python_version}-orig "\$@" EOF chmod +x %{buildroot}%{our_path}/opt/testing/bin/python${python_version} ln -s python${python_version} %{buildroot}%{our_path}/opt/testing/bin/python mkdir -p %{buildroot}%{our_path}%{_libdir}/python${python_version}/site-packages/rpm/ mkdir -p %{buildroot}%{our_path}%{_libdir}/python${python_version}/encodings/ cp %{_libdir}/python${python_version}/site-packages/rpm/*.py %{buildroot}%{our_path}%{_libdir}/python${python_version}/site-packages/rpm/ cp %{_libdir}/python${python_version}/*.py %{buildroot}%{our_path}%{_libdir}/python${python_version}/ cp %{_libdir}/python${python_version}/encodings/*.py %{buildroot}%{our_path}%{_libdir}/python${python_version}/encodings/ find %{buildroot} -name 'python*' | sed -e 's|%{buildroot}%{our_path}||' | tee -a python.list # rename gcc binaries for bin in c++ g++ gcc do [ x"$sanitizer_enabled" == x"1" ] && bin+="-real" mv %{buildroot}%{our_path}%{_bindir}/%{target_arch}-$bin %{buildroot}/%{our_path}%{_bindir}/$bin ln -s $bin %{buildroot}%{our_path}%{_bindir}/%{target_arch}-$bin echo "%{our_path}%{_bindir}/$bin" >> %{_sourcedir}/all-accel.list done for bin in cpp gcc-ar gcc-nm gcc-ranlib do mv %{buildroot}%{our_path}%{_bindir}/%{target_arch}-$bin %{buildroot}/%{our_path}%{_bindir}/$bin ln -s $bin %{buildroot}%{our_path}%{_bindir}/%{target_arch}-$bin echo "%{our_path}%{_bindir}/$bin" >> %{_sourcedir}/all-accel.list done ln -s gcc %{buildroot}%{our_path}/%{_bindir}/cc echo '%{our_path}%{_bindir}/cc' >> %{_sourcedir}/all-accel.list # rpmbuild when generating 'requires' tag for gobject-introspection binaries # selects (64-bit) suffix for libs based on ${HOSTTYPE} bash variable # so we replace x86_64 to armv7l to avoid bogus dependencies %ifarch x86_64 %{?armv7l: sed -i -e "s/x86_64/armv7l/g" %{buildroot}%{our_path}%{_bindir}/bash } %endif # create symlinks for gcc build (CC_FOR_TARGET) mkdir -p %{buildroot}%{our_path}/home/abuild/rpmbuild/BUILD/gcc-${gcc_version}/obj/gcc for binary in as cpp gcc-ar gcc-nm gcc-ranlib gcov nm do ln -sf %{our_path}%{_bindir}/${binary} %{buildroot}%{our_path}/home/abuild/rpmbuild/BUILD/gcc-${gcc_version}/obj/gcc/${binary} echo "%{our_path}/home/abuild/rpmbuild/BUILD/gcc-${gcc_version}/obj/gcc/${binary}" >> %{_sourcedir}/all-accel.list done for binary in cc1 cc1plus collect2 lto1 lto-wrapper do ln -sf %{our_path}/usr/lib/gcc/%{target_arch}/${gcc_version}/${binary} %{buildroot}%{our_path}/home/abuild/rpmbuild/BUILD/gcc-${gcc_version}/obj/gcc/${binary} echo "%{our_path}/home/abuild/rpmbuild/BUILD/gcc-${gcc_version}/obj/gcc/${binary}" >> %{_sourcedir}/all-accel.list done ln -sf %{our_path}%{_bindir}/gcc %{buildroot}%{our_path}/home/abuild/rpmbuild/BUILD/gcc-${gcc_version}/obj/gcc/xgcc ln -sf %{our_path}%{_bindir}/g++ %{buildroot}%{our_path}/home/abuild/rpmbuild/BUILD/gcc-${gcc_version}/obj/gcc/xg++ echo "%{our_path}/home/abuild/rpmbuild/BUILD/gcc-${gcc_version}/obj/gcc/xgcc" >> %{_sourcedir}/all-accel.list echo "%{our_path}/home/abuild/rpmbuild/BUILD/gcc-${gcc_version}/obj/gcc/xg++" >> %{_sourcedir}/all-accel.list # support /lib/cpp ln -sf %{our_path}%{_bindir}/cpp %{buildroot}%{our_path}/usr/lib/cpp # generate baselibs.conf for current architecture to prevent rpm overwriting in download repo echo %{cross} cat > %{_sourcedir}/baselibs_prologue << EOF arch i686 targets %{cross}:%{cross} arch i686 targets %{cross}:x86-%{cross} arch x86_64 targets %{cross}:%{cross} arch x86_64 targets %{cross}:x86_64-%{cross} EOF cat %{_sourcedir}/baselibs_prologue %{_sourcedir}/baselibs_body > %{_sourcedir}/baselibs.conf # Find gcc install directory gcc_install_dir=$(%{target_arch}-gcc -print-search-dirs | sed -ne '/install: /s/install: //p') # update baselibs.conf, overwrite LTO plugin sed -i -e "s,#PLUGIN_POSTIN#,ln -sf %{our_path}${gcc_install_dir}/liblto_plugin.so %{libdir}/gcc/%{target_arch}/${gcc_version}/liblto_plugin.so," %{_sourcedir}/baselibs.conf sed -i -e "s,#PLUGIN_POSTUN#,ln -sf liblto_plugin.so.0 ${gcc_install_dir}/liblto_plugin.so," %{_sourcedir}/baselibs.conf # Use /usr/lib for cross clang libdir on armv7l architecture %{?armv7l: awk '/post "/ && !x {print $0; print " post \"echo export\\ CLANG_NO_LIBDIR_SUFFIX=1 >> /etc/profile\""; x=1;next} 1' %{_sourcedir}/baselibs.conf > baselibs_updated && mv baselibs_updated %{_sourcedir}/baselibs.conf } %{?multilib: awk '/post "/ && !x {print $0; print " post \"echo '%{our_path}/lib' >> /etc/ld.so.conf\"\n"; x=1;next} 1' %{_sourcedir}/baselibs.conf > baselibs_updated && mv baselibs_updated %{_sourcedir}/baselibs.conf } # Remove the ld-$VERSION.so to prevent name clashing with native ld.so find %{buildroot}%{our_path}%{_libdir} -name 'ld-*.so' -delete sed -e '\|%{our_path}%{_libdir}/ld-[[:digit:]].*\.so|d' -i %{_sourcedir}/all-accel.list # allow build of baselibs.conf sed -e "/targettype %{cross} block!/d" -i %{_sourcedir}/baselibs.conf ## Prepare file lists for packages # Change libdir to handle symlinks right find . %{_sourcedir} -name '*.list' -exec sed -e 's|%{our_path}/%{_lib}|%{our_path}%{_libdir}|' -i {} \; # Join native and multilib lists cat %{_sourcedir}/all-accel.list %{?multilib:%{_sourcedir}/multilib-accel.list} | sort -u > %{_sourcedir}/qemu-accel.list ## python-accel # Generate list of all python files find %{buildroot} -name '*.py' | sed -e 's|%{buildroot}%{our_path}||' >> python.list sed -e 's|^|%{our_path}|;s|%{our_path}/%{_lib}|%{our_path}%{_libdir}|' python.list | sort -u > python-full.list # Remove common files from python-accel comm -13 %{_sourcedir}/qemu-accel.list python-full.list | sort -u > %{_sourcedir}/python-accel.list ## clang-accel # Prepare clang files list sed -e 's|^|%{our_path}|;s|%{our_path}/%{_lib}|%{our_path}%{_libdir}|' clang.list | sort -u > clang-full.list # Remove common files from clang-accel comm -13 %{_sourcedir}/qemu-accel.list clang-full.list > %{_sourcedir}/clang-accel.list # Add symlinks to qemu-accel packaging echo '%{our_path}/bin' >> %{_sourcedir}/qemu-accel.list echo '%{our_path}/%{_lib}' >> %{_sourcedir}/qemu-accel.list %{?multilib:echo '%{our_path}/lib' >> %{_sourcedir}/qemu-accel.list} %fdupes %{buildroot} %filter_provides_in %{our_path} %post ldconfig %postun ldconfig %post -n python-accel ldconfig %postun -n python-accel ldconfig %files -f %{_sourcedir}/qemu-accel.list %defattr(-,root,root) %exclude %{our_path}%{py_libdir}/* %files -n python-accel -f %{_sourcedir}/python-accel.list %defattr(-,root,root) %files -n clang-accel -f %{_sourcedir}/clang-accel.list %defattr(-,root,root) %changelog