summaryrefslogblamecommitdiffstats
path: root/core/modules/vbox-src/module.build
blob: f8c0395601b6f21ed3e955e8f7b7956966df1f2f (plain) (tree)
1
2
3
4
5
6
7
8
           





                                             
                                                                                               



                                                                       



                                                                                       























                                                                                                        
 







                                                                                                                      

 
         
                                                                                                     


                                                                                           
                                                                                 














                                                                                                          

                                                 
                                                                 
                                                                 
                                                               

                                                                                                                   



                                                                                                                         
                                                  
                                                                                                       
                                                         




                                                                                                          

                                                                               
                                                                      
 



                                                                                                            
 

                                                           
                                                       



                                                                        
 









                                                                                         
                  







                                                                                                                     
 
                       
                                                                                             


                                                                                                                    
                  





























                                                                                                                                  

             

                                   
 
#!/bin/bash

vbox_build_id() {
	{
		echo "$REQUIRED_VBOX_VERSION"
		gcc --version 2>&1
		echo "${TARGET_KERNEL_LONG}"
		echo "2" # incrase this in case something relevant changes in this build script
		grep -E '^(# )?CONFIG_' "${KERNEL_HEADERS_DIR}/.config"
	} | md5sum | cut -c1-32
}

fetch_source() {
	[ -d "${MODULE_WORK_DIR}/src" ] && rm -rf "${MODULE_WORK_DIR}/src"
	[ -z "${REQUIRED_VBOX_VERSION}" ] && perror "REQUIRED_VBOX_VERSION is not set!"

	local done=
	if nfs_cache_avail; then
		local id tar
		id="$( vbox_build_id )"
		pinfo "Build id is $id"
		tar="${NFS_CACHE_DIR}/cache/${id}.tar.zstd"
		if [ -s "$tar" ]; then
			pinfo "Extracting cached vbox build"
			if < "$tar" zstd -d -T0 | tar -C "${MODULE_WORK_DIR}" -x; then
				touch "$tar" # We use last modified as last used, as atime is unreliable
				done=1
			fi
			pwarning "Extracting cached kernel failed, building..."
		fi
	fi
	if [ -z "$done" ]; then
		local BASEVER="${REQUIRED_VBOX_VERSION}"
		# In case we have something like 1.2.3a, we need 1.2.3 for the directory name below
		[[ "${BASEVER: -1}" =~ ^[0-9]$ ]] || BASEVER="${BASEVER:0:-1}"
		local BASE_URL="http://download.virtualbox.org/virtualbox"
		local DOWNLOAD_URL="${BASE_URL}/${BASEVER}/VirtualBox-${REQUIRED_VBOX_VERSION}.tar.bz2"
		download_untar "$DOWNLOAD_URL" "${MODULE_WORK_DIR}/src" || \
			perror "Could not download_untar '$DOWNLOAD_URL' to '${MODULE_WORK_DIR}/src'."
	fi

	if [ -n "$REQUIRED_EXTPACK" ]; then
		# oracle's extension pack
		DOWNLOAD_URL="${DOWNLOAD_URL%/*}/Oracle_VM_VirtualBox_Extension_Pack-${BASEVER}.vbox-extpack"
		download_untar "$DOWNLOAD_URL" "${MODULE_WORK_DIR}/extpack" || \
			perror "Could not download_untar '$DOWNLOAD_URL' to '${MODULE_WORK_DIR}/extpack'."
		# Nice, Oracle - files in the tarball are world writable, but vbox refuses to use the extpack that way
		chmod -R go-w "${MODULE_WORK_DIR}/extpack"
	fi
}

build() (
	[ -n "${KERNEL_HEADERS_DIR}" ] || perror "KERNEL_HEADERS_DIR not set, kernel module present?"
	local BASEVER="${REQUIRED_VBOX_VERSION}"
	# In case we have something like 1.2.3a, we need 1.2.3 for the directory name below
	[[ "${BASEVER: -1}" =~ ^[0-9]$ ]] || BASEVER="${BASEVER:0:-1}"
	local VBOX_BUILD_DIR="${MODULE_WORK_DIR}/src/VirtualBox-${BASEVER}/build"
	# Cached?
	local bf="${MODULE_WORK_DIR}/src/.mltk-build-flag"
	if [ -e "$bf"  ]; then
		# Cached, setup vars
		source "${VBOX_BUILD_DIR}/env.sh" || perror "Failed to source '${VBOX_BUILD_DIR}/env.sh'."
		local VBOX_RELEASE_BUILD_DIR="${VBOX_BUILD_DIR}/linux.${BUILD_PLATFORM_ARCH}/release"
	else
		cd "${MODULE_WORK_DIR}/src/VirtualBox-${BASEVER}" || \
			perror "Could not cd to '${MODULE_WORK_DIR}/src/VirtualBox-${BASEVER}'."
		mkdir -p "$VBOX_BUILD_DIR" || perror "Failed to mkdir '$VBOX_BUILD_DIR'."
		./configure \
			--disable-docs				\
			--disable-java				\
			--disable-python			\
			--disable-libvpx			\
			--enable-vnc            \
			--disable-udptunnel     \
			--with-linux="${KERNEL_HEADERS_DIR}"	\
			--out-base-dir="${VBOX_BUILD_DIR}"	\
				|| perror "'configure' failed."
		# Newer version SUCK because they ignore --with-linux and require KERN_DIR to be set,
		# and forthermode require it to end in "<version>/build", so we need to create a symlink *facepalm*
		mkdir -p "kernel/${TARGET_KERNEL_LONG}"
		ln -nfs "${KERNEL_HEADERS_DIR}" "kernel/${TARGET_KERNEL_LONG}/build" \
			|| perror "Kernel symlink fail ('${KERNEL_HEADERS_DIR}' <- 'kernel/${TARGET_KERNEL_LONG}/build')"
		export KERN_DIR="$( readlink -f "kernel" )/${TARGET_KERNEL_LONG}/build"
		# Limit job count - can easily OOM
		num="$( awk '$1 == "MemTotal:" { print int(0.25 + $2 / (1024*1024)) }' /proc/meminfo )"
		(( num > CPU_CORES )) && num="$CPU_CORES"
		# the configure script should have created a file called 'env.sh'
		source "${VBOX_BUILD_DIR}/env.sh" || perror "Failed to source '${VBOX_BUILD_DIR}/env.sh'."
		# copy the LocalConfig.kmk to the build dir to be more LSB-compliant
		cp "${MODULE_DIR}/LocalConfig.kmk" "${VBOX_BUILD_DIR}" || \
			perror "Failed to cp LocalConfig.kmk to build dir"
		cp "${MODULE_DIR}/LocalConfig.kmk" "${VBOX_BUILD_DIR}/../" || \
			perror "Failed to cp LocalConfig.kmk to build/../ dir"
		kmk -j "$num" all || perror "Failed to execute 'kmk'."

		# check the generated build directory, use BUILD_PLATFORM_ARCH defined in env.sh
		local VBOX_RELEASE_BUILD_DIR="${VBOX_BUILD_DIR}/linux.${BUILD_PLATFORM_ARCH}/release"
		[ -d "${VBOX_RELEASE_BUILD_DIR}" ] || \
			perror "No release build dir found under '${VBOX_RELEASE_BUILD_DIR}'. Build failed?"

		## Kernel modules
		# build kernel modules from the release dir
		cde "${VBOX_RELEASE_BUILD_DIR}/bin/src"
		make \
			KERN_DIR="${KERNEL_HEADERS_DIR}" \
			KERN_VER="${TARGET_KERNEL_LONG}" \
				|| perror "Build kernel modules failed."

		# Cache
		touch "$bf"
		if nfs_cache_avail; then
			local id tar
			id="$( vbox_build_id )"
			tar="${NFS_CACHE_DIR}/cache/${id}.tar.zstd"
			pinfo "Copying built vbox to NFS cache with id $id"
			mkdir -p "$( dirname "$tar" )"
			tar -C "${MODULE_WORK_DIR}" -c -k src | zstd -T0 -2 -z > "$tar" \
				|| pwarning "Could not write vbox to NFS cache"
		fi
	fi

	# the resulting linux.<arch>/release/bin folder contains the whole build,
	# copy it over to usr/lib/virtualbox
	mkdir -p "${MODULE_BUILD_DIR}/usr/lib/virtualbox" || \
		perror "Failed to mkdir '${MODULE_BUILD_DIR}/usr/lib/virtualbox'."
	cp -r "${VBOX_RELEASE_BUILD_DIR}/bin/"* "${MODULE_BUILD_DIR}/usr/lib/virtualbox" || \
		perror "Failed to cp -r '${VBOX_RELEASE_BUILD_DIR}/bin' to '${MODULE_BUILD_DIR}/usr/lib/virtualbox'."

	# set suid bits
	for BIN in VBoxHeadless VBoxNetAdpCtl VBoxNetDHCP VBoxNetNAT VBoxSDL VirtualBoxVM; do
		if ! [ -e "${MODULE_BUILD_DIR}/usr/lib/virtualbox/$BIN" ]; then
			pwarning "No such file: '${MODULE_BUILD_DIR}/usr/lib/virtualbox/$BIN', cannot add suid bit."
			continue
		fi
		chmod u+s "${MODULE_BUILD_DIR}/usr/lib/virtualbox/${BIN}" || perror "Failed to set suid bit on '${BIN}'."
	done

	# Copy kernel modules
	cde "${VBOX_RELEASE_BUILD_DIR}/bin/src"
	mkdir -p "${MODULE_BUILD_DIR}/lib/modules/vbox" || \
		perror "Failed to mkdir '${MODULE_BUILD_DIR}/lib/modules/vbox'."
	for MOD in $(find ./* -maxdepth 0 -type d); do
		[ -e "$MOD.ko" ] || perror "Module '$MOD' was not built!"
		cp "$MOD.ko" "${MODULE_BUILD_DIR}/lib/modules/vbox/" || \
			perror "Failed to cp $MOD.ko to '${MODULE_BUILD_DIR}/lib/modules/vbox/'."
	done

	if [ -n "$REQUIRED_EXTPACK" ]; then
		# finally copy the extension pack files, everthing is needed as the subfolders
		# target the guest architectures and not that of the host!
		local VBOX_EXTPACK_DIR="${MODULE_BUILD_DIR}/usr/lib/virtualbox/ExtensionPacks/Oracle_VM_VirtualBox_Extension_Pack"
		cp -ar "${MODULE_WORK_DIR}/extpack" "${VBOX_EXTPACK_DIR}" || \
			perror "Failed to cp '${MODULE_WORK_DIR}/extpack' to '${VBOX_EXTPACK_DIR}'."
		chown -R root:root "${VBOX_EXTPACK_DIR}" || \
			perror "Failed to chown '${VBOX_EXTPACK_DIR}' to root:root."
	fi

	# od binary
	local OD_BIN="$(which od 2>/dev/null)"
	if [ -n "$OD_BIN" ] && [ -f "$OD_BIN" ]; then
		tarcopy "$OD_BIN" "$MODULE_BUILD_DIR"
	fi
	true
)

post_copy() {
	groupadd --system vboxusers
	add_to_group demo vboxusers
}