Enhancement: Fixes #182, Packaging port for Arch Linux

This commit is contained in:
Rory Fewell
2023-06-30 20:51:34 +01:00
parent c23e7bb08d
commit ab3d5eca30
15 changed files with 303 additions and 87 deletions

View File

@@ -6,16 +6,20 @@ The contents of this directory is as follows:
`cmake-inc/` - common CMake scripts to be included by components in their builds
`archpkg/` - Arch Linux (`.pkg.tar.zst`) packaging implementation
`deb/` - Debian (`.deb`) packaging implementation
`build.sh` - build script for compiling a single component
`buildall.sh` - build script for compiling all components in the project
`buildall.sh` - build script for compiling and packaging all components in the project
`chkdeps.sh` - script for checking dependencies for building components are installed
`distid.sh` - helper script for identifying the distribution in use
`package.sh` - script for packaging a single component (that has been built with `build.sh`)
`targets` - default build list for all components in the project
## TL;DR on Building
@@ -29,6 +33,7 @@ This is intended to *Just Work(TM)*, if you have any problems, please raise an i
## Support?
Supported distros/package formats:
- Arch Linux (`.pkg.tar.zst`)
- Debian (`.deb`)
Please check under the `packaging` tag to see if there is an open issue for your favourite distro/package format. You can help speed up the process by providing a simple example package script or TL;DR so that the porting process is easier (I'm not familiar with every distro out there!)

41
packaging/archpkg/pkgimpl.sh Executable file
View File

@@ -0,0 +1,41 @@
#!/bin/bash
#
# pkgimpl.sh - Packaging Implementation (Arch Linux)
#
# This source-code is part of Windows XP stuff for XFCE:
# <<https://www.oddmatics.uk>>
#
# Author(s): Rory Fewell <roryf@oddmatics.uk>
#
#
# FUNCTIONS
#
do_packaging()
{
# Build package now
#
cd "${full_component_dir}"
makepkg -f --repackage
pkg_res=$?
cd "${CURDIR}"
if [[ $pkg_res -gt 0 ]]
then
echo "Package build failure!"
exit 1
fi
# Move package to output
#
clean_pkg_name=`cat ${full_component_dir}/PKGBUILD | grep 'pkgname' | cut -d'=' -f2 | xargs echo -n`
find "${full_component_dir}" -iname "${clean_pkg_name}*.pkg.tar.zst" -exec mv '{}' "${OPT_OUTPUT_DIR}/${clean_pkg_name}.pkg.tar.zst" \;
echo "Packaged ${clean_pkg_name}"
}

View File

@@ -125,8 +125,7 @@ cmake --fresh \
"${full_component_dir}"
((build_result+=$?))
rm -rf ./out
make DESTDIR=./out all install
make -j$(nproc)
((build_result+=$?))
cd "${CURDIR}"

View File

@@ -21,6 +21,7 @@ TARGETS_PATH="${SCRIPTDIR}/targets"
SH_BUILD="${SCRIPTDIR}/build.sh"
SH_CHKDEPS="${SCRIPTDIR}/chkdeps.sh"
SH_DISTID="${SCRIPTDIR}/distid.sh"
SH_PACKAGE="${SCRIPTDIR}/package.sh"
@@ -30,8 +31,9 @@ SH_DISTID="${SCRIPTDIR}/distid.sh"
OPT_BUILDLIST="${TARGETS_PATH}"
OPT_OUTPUT_DIR=""
OPT_SKU="xpclient-pro"
OPT_SKIP_PACKAGING=0
while getopts "c:ho:s:" opt;
while getopts "c:ho:s:z" opt;
do
case "${opt}" in
c)
@@ -44,6 +46,7 @@ do
echo " -h : display this help screen"
echo " -o : specify output directory for packages"
echo " -s : specify SKU to build (default xpclient-pro)"
echo " -z : skip packaging steps, compile only"
echo ""
exit 0
@@ -56,6 +59,10 @@ do
s)
OPT_SKU="${OPTARG}"
;;
z)
OPT_SKIP_PACKAGING=1
;;
esac
done
@@ -69,26 +76,10 @@ declare -a g_built_libs
build_component()
{
local dist="${1}"
local rel_dir="${2}"
local rel_dir="${1}"
local target_dir="${REPO_ROOT}/${rel_dir}"
local deps_path="${target_dir}/deps"
# Ensure package script available
#
local sh_package="${SCRIPTDIR}/${dist}/package.sh"
if [[ g_checked_pkg_sh -eq 0 ]]
then
if [[ ! -f "${sh_package}" ]]
then
echo "package.sh missing for ${dist}, cannot continue."
exit 1
fi
g_checked_pkg_sh=1
fi
# All good, continue build
#
echo "buildall: Building ${rel_dir}"
@@ -120,7 +111,7 @@ build_component()
#
if [[ -d "${REPO_ROOT}/shared/${lib_shortname}" ]]
then
build_component "${dist}" "shared/${lib_shortname}"
build_component "shared/${lib_shortname}"
g_built_libs+=("${lib_shortname}")
fi
fi
@@ -139,7 +130,12 @@ build_component()
# Package the component
#
"${sh_package}" -o "${OPT_OUTPUT_DIR}" "${rel_dir}"
if [[ $OPT_SKIP_PACKAGING -eq 1 ]]
then
return
fi
"${SH_PACKAGE}" -o "${OPT_OUTPUT_DIR}" "${rel_dir}"
if [[ $? -gt 0 ]]
then
@@ -185,6 +181,12 @@ then
exit 1
fi
if [[ ! -f "${SH_PACKAGE}" ]]
then
echo "package.sh not found - this should never happen!!"
exit 1
fi
if [[ ! -f "${OPT_BUILDLIST}" ]]
then
echo "Build list not found or readable: ${OPT_BUILDLIST}"
@@ -212,17 +214,24 @@ tag="${cur_hash}.${cur_arch}.${cur_branch}.${OPT_SKU}(${cur_user},${dist_id})"
echo "Doing full system build for ${tag}"
if [[ "${OPT_OUTPUT_DIR}" == "" ]]
# Handle output dir for packaging
#
if [[ $OPT_SKIP_PACKAGING -eq 0 ]]
then
OPT_OUTPUT_DIR="${CURDIR}/xptc/${cur_hash}.${cur_branch}/${cur_arch}/${dist_id}"
if [[ "${OPT_OUTPUT_DIR}" == "" ]]
then
OPT_OUTPUT_DIR="${CURDIR}/xptc/${cur_hash}.${cur_branch}/${cur_arch}/${dist_id}"
mkdir -p "${OPT_OUTPUT_DIR}"
fi
mkdir -p "${OPT_OUTPUT_DIR}"
fi
if [[ ! -d "${OPT_OUTPUT_DIR}" ]]
then
echo "Cannot ensure output directory "${OPT_OUTPUT_DIR}" exists."
exit 1
if [[ ! -d "${OPT_OUTPUT_DIR}" ]]
then
echo "Cannot ensure output directory "${OPT_OUTPUT_DIR}" exists."
exit 1
fi
else
echo "Packaging will be skipped for this session."
fi
# Check system deps
@@ -239,7 +248,7 @@ fi
#
while IFS= read -u "${targets_fd}" -r rel_target_dir
do
build_component "${dist_id}" "${rel_target_dir}"
build_component "${rel_target_dir}"
done {targets_fd}<"${OPT_BUILDLIST}"
echo "Build complete for ${tag}"

View File

@@ -129,14 +129,18 @@ check_deps()
# It's a new dep, check whether it is already installed
#
case "${dist_id}" in
archpkg)
pacman -Q -k "${pkg_name}" >/dev/null 2>&1
;;
deb)
dpkg -s "${pkg_name}" >/dev/null 2>&1
if [[ $? -gt 0 ]]
then
g_needed_pkgs+=("${pkg_name}")
fi
;;
esac
if [[ $? -gt 0 ]]
then
g_needed_pkgs+=("${pkg_name}")
fi
done <<< "${required_deps}"
}

View File

@@ -36,13 +36,94 @@ else()
)
endif()
# Define dependency mapping function
#
function(wintc_map_dependencies)
if (${WINTC_PKGMGR} STREQUAL "raw")
return()
endif()
if (NOT EXISTS ${PROJECT_ROOT}/deps)
return()
endif()
find_package(PythonInterp 3.0 REQUIRED)
execute_process(
COMMAND ${PYTHON_EXECUTABLE} ${DEPMAP_TOOL_DIR}/depmap.py deps ${WINTC_PKGMGR}
WORKING_DIRECTORY ${PROJECT_ROOT}
OUTPUT_VARIABLE DEPENDENCIES_MAP_RAW
RESULT_VARIABLE DEPMAP_RET
)
if (DEPMAP_RET AND NOT DEPMAP_RET EQUAL 0)
message(
FATAL_ERROR
"Failed to map dependencies for packaging."
)
endif()
string(REPLACE "\n" ";" DEPENDENCIES_MAP_RAW ${DEPENDENCIES_MAP_RAW})
foreach (line ${DEPENDENCIES_MAP_RAW})
if (${line} MATCHES "^rt:(.+)$")
list(APPEND DEPENDENCIES_MAP ${CMAKE_MATCH_1})
endif()
endforeach()
set(DEPENDENCIES_MAP ${DEPENDENCIES_MAP} PARENT_SCOPE)
endfunction()
# Do special stuff for the target package format, if needed
#
set(WINTC_ARCH_PKGBUILD_IN_PATH ${CMAKE_CURRENT_LIST_DIR}/PKGBUILD.in)
set(WINTC_DEBIAN_CONTROL_IN_PATH ${CMAKE_CURRENT_LIST_DIR}/debian-control.in)
function(wintc_configure_and_install_packaging)
if (${WINTC_PKGMGR} STREQUAL "raw")
message(STATUS "Outputting raw build (no package manager)")
elseif (${WINTC_PKGMGR} STREQUAL "archpkg")
message(STATUS "Outputting build for Arch Linux packaging")
# LIB_DIR is always /lib - /lib64 is not a valid target on Arch
#
set(LIB_DIR lib PARENT_SCOPE)
# Set the project name, we drop the 'lib' prefix for Arch
#
set(ARCH_PROJECT_NAME ${PROJECT_NAME})
if (${PROJECT_NAME} MATCHES "^lib(.+)")
set(ARCH_PROJECT_NAME ${CMAKE_MATCH_1})
endif()
# Set the architecture
#
set(ARCH_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
if (${PROJECT_ANYARCH})
set(ARCH_ARCHITECTURE any)
endif()
# Set the licence
#
if (${PROJECT_FREESTATUS})
set(ARCH_LICENCE GPL)
else()
set(ARCH_LICENCE non-free)
endif()
# Map dependencies to Arch Linux
#
wintc_map_dependencies()
if (DEFINED DEPENDENCIES_MAP)
list(JOIN DEPENDENCIES_MAP " " ARCH_DEPENDENCIES)
string(PREPEND ARCH_DEPENDENCIES "depends=(")
string(APPEND ARCH_DEPENDENCIES ")")
endif()
configure_file(${WINTC_ARCH_PKGBUILD_IN_PATH} PKGBUILD @ONLY)
elseif (${WINTC_PKGMGR} STREQUAL "deb")
message(STATUS "Outputting build for Debian packaging")
@@ -96,34 +177,10 @@ function(wintc_configure_and_install_packaging)
# Map dependencies to Debian
#
if (EXISTS ${PROJECT_ROOT}/deps)
find_package(PythonInterp 3.0 REQUIRED)
wintc_map_dependencies()
execute_process(
COMMAND ${PYTHON_EXECUTABLE} ${DEPMAP_TOOL_DIR}/depmap.py deps deb
WORKING_DIRECTORY ${PROJECT_ROOT}
OUTPUT_VARIABLE DEB_DEPENDENCIES_RAW
RESULT_VARIABLE DEPMAP_RET
)
if (DEPMAP_RET AND NOT DEPMAP_RET EQUAL 0)
message(
FATAL_ERROR
"Failed to map dependencies for packaging."
)
endif()
string(REPLACE "\n" ";" DEB_DEPENDENCIES_RAW ${DEB_DEPENDENCIES_RAW})
foreach(line ${DEB_DEPENDENCIES_RAW})
if (${line} MATCHES "^rt:(.+)$")
list(APPEND DEB_DEPENDENCIES_LIST ${CMAKE_MATCH_1})
endif()
endforeach()
endif()
if (DEFINED DEB_DEPENDENCIES_LIST)
list(JOIN DEB_DEPENDENCIES_LIST ", " DEB_DEPENDENCIES)
if (DEFINED DEPENDENCIES_MAP)
list(JOIN DEPENDENCIES_MAP ", " DEB_DEPENDENCIES)
string(PREPEND DEB_DEPENDENCIES "Depends: ")
endif()

View File

@@ -0,0 +1,15 @@
pkgname="@ARCH_PROJECT_NAME@"
pkgver="@PROJECT_VERSION@"
pkgrel=1
pkgdesc="@PROJECT_DESCRIPTION@"
arch=("@ARCH_ARCHITECTURE@")
url="https://github.com/rozniak/xfce-winxp-tc"
license=("@ARCH_LICENCE@")
package()
{
@ARCH_DEPENDENCIES@
cd ..
make DESTDIR="$pkgdir/" install
}

View File

@@ -1,2 +0,0 @@
# Debian Packaging
This directory contains the packaging implementation for Debian.

53
packaging/deb/pkgimpl.sh Executable file
View File

@@ -0,0 +1,53 @@
#!/bin/bash
#
# pkgimpl.sh - Packaging Implementation (Debian)
#
# This source-code is part of Windows XP stuff for XFCE:
# <<https://www.oddmatics.uk>>
#
# Author(s): Rory Fewell <roryf@oddmatics.uk>
#
#
# FUNCTIONS
#
do_packaging()
{
pkg_dir="${full_component_dir}/out"
# Assemble package
#
cd "${full_component_dir}"
make DESTDIR="${pkg_dir}" install
ass_res=$?
cd "${CURDIR}"
if [[ $ass_res -gt 0 ]]
then
echo "Package assembly failure!"
exit 1
fi
# Build package now
#
fakeroot dpkg-deb -v --build "${pkg_dir}"
if [[ $? -gt 0 ]]
then
echo "Package build failure!"
exit 1
fi
# Move package to output
#
clean_pkg_name=`cat ${full_component_dir}/control | grep 'Package:' | cut -d":" -f2 | xargs echo -n`
mv "${pkg_dir}.deb" "${OPT_OUTPUT_DIR}/${clean_pkg_name}.deb"
echo "Packaged ${clean_pkg_name}"
}

View File

@@ -23,6 +23,10 @@ fi
distro_in_use=`cat /etc/os-release | grep "^ID" | cut -d"=" -f2`
case "${distro_in_use}" in
arch)
echo -n "archpkg"
;;
debian)
echo -n "deb"
;;

View File

@@ -1,7 +1,7 @@
#!/bin/bash
#
# package.sh - Packaging Script (Debian)
# package.sh - Packaging Script
#
# This source-code is part of Windows XP stuff for XFCE:
# <<https://www.oddmatics.uk>>
@@ -17,6 +17,8 @@ SCRIPTDIR=`dirname "$0"`
REPO_ROOT=`realpath -s "${SCRIPTDIR}/../.."`
SH_DISTID="${SCRIPTDIR}/distid.sh"
#
@@ -62,6 +64,11 @@ fi
#
# MAIN SCRIPT
#
if [[ ! -f "${SH_DISTID}" ]]
then
echo "distid.sh not found - this should never happen!!"
exit 1
fi
# Ensure the output containing dir exists
#
@@ -76,32 +83,39 @@ then
fi
fi
# Identify our distro
#
dist_id=`${SH_DISTID}`
if [[ $? -gt 0 ]]
then
echo "Failed to identify distribution."
exit 1
fi
# Ensure packaging implementation available
#
sh_pkg_impl="${SCRIPTDIR}/${dist_id}/pkgimpl.sh"
if [[ ! -f "${sh_pkg_impl}" ]]
then
echo "Packaging implementation for ${dist_id} not found!"
exit 1
fi
# Ensure the built component exists
#
rel_component_dir="${1}"
full_component_dir="${OPT_BUILD_DIR}/${rel_component_dir}"
pkg_dir="${full_component_dir}/out"
if [[ ! -d "${pkg_dir}" ]]
if [[ ! -d "${full_component_dir}" ]]
then
"Expected component to be built at ${full_component_dir}, it's missing."
echo "Component doesn't seem to be built at ${full_component_dir}"
exit 1
fi
# Build package now
# Hand off to implementation
#
fakeroot dpkg-deb -v --build "${pkg_dir}"
. "${sh_pkg_impl}"
if [[ $? -gt 0 ]]
then
"Package build failure!"
exit 1
fi
# Move package to output
#
clean_pkg_name=`cat ${full_component_dir}/control | grep 'Package:' | cut -d":" -f2 | xargs echo -n`
mv "${pkg_dir}.deb" "${OPT_OUTPUT_DIR}/${clean_pkg_name}.deb"
echo "Packaged ${clean_pkg_name}"
do_packaging