mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Cleanup and refactor the macOS build scripts. Fixes #5525
This commit is contained in:
21
README
21
README
@@ -255,7 +255,7 @@ icon and select the Configuration option to open the configuration dialogue.
|
|||||||
On a Linux/Mac system, the Python Path will typically consist of a single path
|
On a Linux/Mac system, the Python Path will typically consist of a single path
|
||||||
to the virtual environment's site-packages directory, e.g.
|
to the virtual environment's site-packages directory, e.g.
|
||||||
|
|
||||||
/Users/<USERNAME>/.virtualenvs/pgadmin4/lib/python2.7/site-packages
|
/Users/<USERNAME>/.virtualenvs/pgadmin4/lib/python3.8/site-packages
|
||||||
|
|
||||||
On Windows, multiple paths are likely to be required, e.g.
|
On Windows, multiple paths are likely to be required, e.g.
|
||||||
|
|
||||||
@@ -297,24 +297,7 @@ run:
|
|||||||
|
|
||||||
(pgadmin4) $ make pip
|
(pgadmin4) $ make pip
|
||||||
|
|
||||||
On a Mac, build an application bundle in a disk image (DMG file) with:
|
To build the macOS AppBundle, please see pkg/mac/README.
|
||||||
|
|
||||||
(pgadmin4) $ make appbundle
|
|
||||||
|
|
||||||
Configure the framework.conf to match the QT and Python versions the app is
|
|
||||||
being built with:
|
|
||||||
|
|
||||||
$ cp $PGADMIN4_SRC/pkg/mac/framework.conf.in $PGADMIN4_SRC/pkg/mac/framework.conf
|
|
||||||
$ vi $PGADMIN4_SRC/pkg/mac/framework.conf
|
|
||||||
|
|
||||||
If you have an Apple code signing certificate, both the app bundle and disk
|
|
||||||
image can be automatically signed by configuring signing:
|
|
||||||
|
|
||||||
$ cp $PGADMIN4_SRC/pkg/mac/codesign.conf.in $PGADMIN4_SRC/pkg/mac/codesign.conf
|
|
||||||
$ vi $PGADMIN4_SRC/pkg/mac/codesign.conf
|
|
||||||
|
|
||||||
Edit the file as appropriate, ensuring the various version numbers are correct
|
|
||||||
and that the appropriate developer ID is specified.
|
|
||||||
|
|
||||||
On Windows, the InnoSetup tool is required to create an installer. Download the
|
On Windows, the InnoSetup tool is required to create an installer. Download the
|
||||||
Unicode version from:
|
Unicode version from:
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ Housekeeping
|
|||||||
| `Issue #5444 <https://redmine.postgresql.org/issues/5444>`_ - Cleanup Python detection in the runtime project file.
|
| `Issue #5444 <https://redmine.postgresql.org/issues/5444>`_ - Cleanup Python detection in the runtime project file.
|
||||||
| `Issue #5455 <https://redmine.postgresql.org/issues/5455>`_ - Refactor pgAdmin4.py so it can be imported and is a lot more readable.
|
| `Issue #5455 <https://redmine.postgresql.org/issues/5455>`_ - Refactor pgAdmin4.py so it can be imported and is a lot more readable.
|
||||||
| `Issue #5493 <https://redmine.postgresql.org/issues/5493>`_ - Search object UI improvements.
|
| `Issue #5493 <https://redmine.postgresql.org/issues/5493>`_ - Search object UI improvements.
|
||||||
|
| `Issue #5525 <https://redmine.postgresql.org/issues/5525>`_ - Cleanup and refactor the macOS build scripts.
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
*********
|
*********
|
||||||
|
|||||||
@@ -15,20 +15,23 @@ similar):
|
|||||||
|
|
||||||
Building:
|
Building:
|
||||||
|
|
||||||
1. Set the PYTHON_HOME environment variable to the Python root installation
|
1. If a value different from the default of /usr/local/python is required, set
|
||||||
|
the PGADMIN_PYTHON_DIR environment variable to the Python root installation
|
||||||
directory, e.g.
|
directory, e.g.
|
||||||
|
|
||||||
export PYTHON_HOME=/opt/local
|
export PGADMIN_PYTHON_DIR=/opt/local
|
||||||
|
|
||||||
2. Set the QTDIR environment variable to the QT root installation directory,
|
2. If a value different from the default of ~/Qt/5.13.2/clang_64, is required,
|
||||||
e.g.
|
set the PGADMIN_QT_DIR environment variable to the QT root installation
|
||||||
|
directory, e.g.
|
||||||
|
|
||||||
export QTDIR=~/Qt/5.14.2/clang_64
|
export PGADMIN_QT_DIR=~/Qt/5.14.2/clang_64
|
||||||
|
|
||||||
3. Set the PGDIR environment variable to the PostgreSQL installation directory,
|
3. If a value different from the default of /usr/local/pgsql is required, set
|
||||||
e.g.
|
the PGADMIN_POSTGRES_DIR environment variable to the PostgreSQL installation
|
||||||
|
directory, e.g.
|
||||||
|
|
||||||
export PGDIR=/usr/local/pgsql
|
export PGADMIN_POSTGRES_DIR=/opt/local/pgsql
|
||||||
|
|
||||||
4. Copy framework.conf.in to framework.conf, and edit the values accordingly.
|
4. Copy framework.conf.in to framework.conf, and edit the values accordingly.
|
||||||
|
|
||||||
|
|||||||
380
pkg/mac/build-functions.sh
Normal file
380
pkg/mac/build-functions.sh
Normal file
@@ -0,0 +1,380 @@
|
|||||||
|
_setup_env() {
|
||||||
|
APP_RELEASE=`grep "^APP_RELEASE" web/config.py | cut -d"=" -f2 | sed 's/ //g'`
|
||||||
|
APP_REVISION=`grep "^APP_REVISION" web/config.py | cut -d"=" -f2 | sed 's/ //g'`
|
||||||
|
APP_NAME=`grep "^APP_NAME" web/config.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //'`
|
||||||
|
APP_LONG_VERSION=${APP_RELEASE}.${APP_REVISION}
|
||||||
|
APP_SHORT_VERSION=`echo ${APP_LONG_VERSION} | cut -d . -f1,2`
|
||||||
|
APP_SUFFIX=`grep "^APP_SUFFIX" web/config.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g"`
|
||||||
|
if [ ! -z ${APP_SUFFIX} ]; then
|
||||||
|
APP_LONG_VERSION=${APP_LONG_VERSION}-${APP_SUFFIX}
|
||||||
|
fi
|
||||||
|
BUNDLE_DIR="${BUILD_ROOT}/${APP_NAME}.app"
|
||||||
|
}
|
||||||
|
|
||||||
|
_cleanup() {
|
||||||
|
echo Cleaning up the old environment and app bundle...
|
||||||
|
rm -rf ${SOURCE_DIR}/runtime/*.app
|
||||||
|
rm -rf ${BUILD_ROOT}
|
||||||
|
rm -f ${DIST_ROOT}/*.dmg
|
||||||
|
}
|
||||||
|
|
||||||
|
_create_venv() {
|
||||||
|
PATH=${PGADMIN_POSTGRES_DIR}/bin:${PATH}
|
||||||
|
LD_LIBRARY_PATH=${PGADMIN_POSTGRES_DIR}/lib:${LD_LIBRARY_PATH}
|
||||||
|
|
||||||
|
test -d ${BUILD_ROOT} || mkdir ${BUILD_ROOT}
|
||||||
|
cd ${BUILD_ROOT}
|
||||||
|
|
||||||
|
${PYTHON_EXE} -m venv --copies venv
|
||||||
|
|
||||||
|
source venv/bin/activate
|
||||||
|
pip install --no-cache-dir --no-binary psycopg2 -r ${SOURCE_DIR}/requirements.txt
|
||||||
|
|
||||||
|
# Figure the source path for use when completing the venv
|
||||||
|
SOURCE_PYMODULES_PATH=$(dirname $("${PYTHON_EXE}" -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"))
|
||||||
|
|
||||||
|
# Figure the target path for use when completing the venv
|
||||||
|
# Use "python" here as we want the venv path
|
||||||
|
TARGET_PYMODULES_PATH=$(dirname $(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"))
|
||||||
|
|
||||||
|
# Copy in the additional system python modules
|
||||||
|
cp -R ${SOURCE_PYMODULES_PATH}/* "${TARGET_PYMODULES_PATH}/"
|
||||||
|
|
||||||
|
# Link the python<version> directory to python so that the private environment path is found by the application.
|
||||||
|
ln -s "$(basename ${TARGET_PYMODULES_PATH})" "${TARGET_PYMODULES_PATH}/../python"
|
||||||
|
|
||||||
|
# Remove tests
|
||||||
|
find venv -name "test" -type d -print0 | xargs -0 rm -rf
|
||||||
|
find venv -name "tests" -type d -print0 | xargs -0 rm -rf
|
||||||
|
}
|
||||||
|
|
||||||
|
_build_runtime() {
|
||||||
|
cd ${SOURCE_DIR}/runtime
|
||||||
|
make clean
|
||||||
|
${QMAKE}
|
||||||
|
make
|
||||||
|
cp -r pgAdmin4.app "${BUNDLE_DIR}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_build_docs() {
|
||||||
|
cd ${SOURCE_DIR}/docs/en_US
|
||||||
|
test -d "${BUNDLE_DIR}/Contents/Resources/docs/en_US" || mkdir -p "${BUNDLE_DIR}/Contents/Resources/docs/en_US"
|
||||||
|
cp -r _build/html "${BUNDLE_DIR}/Contents/Resources/docs/en_US/"
|
||||||
|
}
|
||||||
|
|
||||||
|
_complete_bundle() {
|
||||||
|
cd ${SCRIPT_DIR}
|
||||||
|
|
||||||
|
# Copy the binary utilities into place
|
||||||
|
mkdir -p "${BUNDLE_DIR}/Contents/SharedSupport/"
|
||||||
|
cp "${PGADMIN_POSTGRES_DIR}/bin/pg_dump" "${BUNDLE_DIR}/Contents/SharedSupport/"
|
||||||
|
cp "${PGADMIN_POSTGRES_DIR}/bin/pg_dumpall" "${BUNDLE_DIR}/Contents/SharedSupport/"
|
||||||
|
cp "${PGADMIN_POSTGRES_DIR}/bin/pg_restore" "${BUNDLE_DIR}/Contents/SharedSupport/"
|
||||||
|
cp "${PGADMIN_POSTGRES_DIR}/bin/psql" "${BUNDLE_DIR}/Contents/SharedSupport/"
|
||||||
|
|
||||||
|
# Replace the place holders with the current version
|
||||||
|
sed -e "s/PGADMIN_LONG_VERSION/${APP_LONG_VERSION}/g" -e "s/PGADMIN_SHORT_VERSION/${APP_SHORT_VERSION}/g" pgadmin.Info.plist.in > pgadmin.Info.plist
|
||||||
|
|
||||||
|
# copy Python private environment to app bundle
|
||||||
|
cp -PR ${BUILD_ROOT}/venv "${BUNDLE_DIR}/Contents/Resources/"
|
||||||
|
|
||||||
|
# Remove any TCL-related files that may cause us problems
|
||||||
|
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name "_tkinter*" -print0 | xargs -0 rm -f
|
||||||
|
|
||||||
|
test -d "${BUNDLE_DIR}/Contents/Resources" || mkdir -p "${BUNDLE_DIR}/Contents/Resources"
|
||||||
|
# Create qt.conf so that app knows where the Plugins are present
|
||||||
|
cat >> "${BUNDLE_DIR}/Contents/Resources/qt.conf" << EOF
|
||||||
|
[Paths]
|
||||||
|
Plugins = PlugIns
|
||||||
|
EOF
|
||||||
|
|
||||||
|
test -d "${BUNDLE_DIR}/Contents/Frameworks" || mkdir -p "${BUNDLE_DIR}/Contents/Frameworks"
|
||||||
|
test -d "${BUNDLE_DIR}/Contents/PlugIns/platforms" || mkdir -p "${BUNDLE_DIR}/Contents/PlugIns/platforms"
|
||||||
|
test -d "${BUNDLE_DIR}/Contents/PlugIns/imageformats" || mkdir -p "${BUNDLE_DIR}/Contents/PlugIns/imageformats"
|
||||||
|
cp -f ${PGADMIN_QT_DIR}/plugins/platforms/libqcocoa.dylib "${BUNDLE_DIR}/Contents/PlugIns/platforms"
|
||||||
|
cp -f ${PGADMIN_QT_DIR}/plugins/imageformats/libqsvg.dylib "${BUNDLE_DIR}/Contents/PlugIns/imageformats"
|
||||||
|
cp -f ${PGADMIN_POSTGRES_DIR}/lib/libpq.5.dylib "${BUNDLE_DIR}/Contents/Frameworks"
|
||||||
|
|
||||||
|
local todo todo_old fw_relpath lib lib_bn
|
||||||
|
|
||||||
|
pushd "${BUNDLE_DIR}" > /dev/null
|
||||||
|
|
||||||
|
# We skip nested apps here - those are treated specially
|
||||||
|
todo=$(file `find ./ -perm +0111 ! -type d ! -path "*.app/*" ! -name "*.app"` | grep -E "Mach-O 64-bit" | awk -F ':| ' '{ORS=" "; print $1}')
|
||||||
|
|
||||||
|
echo "Found executables: ${todo}"
|
||||||
|
while test "${todo}" != ""; do
|
||||||
|
todo_old=${todo} ;
|
||||||
|
todo="" ;
|
||||||
|
for todo_obj in ${todo_old}; do
|
||||||
|
echo "Post-processing: ${todo_obj}"
|
||||||
|
|
||||||
|
# Figure out the relative path from todo_obj to Contents/Frameworks
|
||||||
|
fw_relpath=$(echo "${todo_obj}" | sed -n 's|^\(\.//*\)\(\([^/][^/]*/\)*\)[^/][^/]*$|\2|gp' | sed -n 's|[^/][^/]*/|../|gp')"Contents/Frameworks"
|
||||||
|
fw_relpath_old=${fw_relpath}
|
||||||
|
|
||||||
|
# Find all libraries $todo_obj depends on, but skip system libraries
|
||||||
|
for lib in $(otool -L ${todo_obj} | grep "Qt\|dylib\|Frameworks\|PlugIns" | grep -v ":" | sed 's/(.*//' | egrep -v '(/usr/lib)|(/System)|@executable_path@'); do
|
||||||
|
if echo ${lib} | grep "PlugIns\|libqcocoa" > /dev/null; then
|
||||||
|
lib_loc="Contents/PlugIns/platforms"
|
||||||
|
elif echo ${lib} | grep "PlugIns\|libqsvg" > /dev/null; then
|
||||||
|
lib_loc="Contents/PlugIns/imageformats"
|
||||||
|
elif echo ${lib} | grep "Qt" > /dev/null; then
|
||||||
|
qtfw_path="$(dirname ${lib} | sed 's|.*\(Qt.*framework\)|\1|')"
|
||||||
|
lib_loc="Contents/Frameworks/${qtfw_path}"
|
||||||
|
if [ "$(basename ${todo_obj})" = "${lib}" ]; then
|
||||||
|
lib_loc="$(dirname ${todo_obj})"
|
||||||
|
qtfw_path=$(echo ${lib_loc} | sed 's/Contents\/Frameworks\///')
|
||||||
|
fi
|
||||||
|
elif echo ${lib} | grep "Python" > /dev/null; then
|
||||||
|
pyfw_path="$(dirname ${lib} | sed 's|.*\(Python.*framework\)|\1|')"
|
||||||
|
lib_loc="Contents/Frameworks/${pyfw_path}"
|
||||||
|
if [ "$(basename ${todo_obj})" = "${lib}" ]; then
|
||||||
|
lib_loc="$(dirname ${todo_obj})"
|
||||||
|
pyfw_path=$(echo ${lib_loc} | sed 's/Contents\/Frameworks\///')
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
lib_loc="Contents/Frameworks"
|
||||||
|
fi
|
||||||
|
lib_bn="$(basename "${lib}")" ;
|
||||||
|
if ! test -f "${lib_loc}/${lib_bn}"; then
|
||||||
|
target_file=""
|
||||||
|
target_path=""
|
||||||
|
echo "Adding symlink: ${lib_bn} (because of: ${todo_obj})"
|
||||||
|
|
||||||
|
# Copy the QT and Python framework
|
||||||
|
if echo ${lib} | grep Qt > /dev/null ; then
|
||||||
|
test -d ${lib_loc} || mkdir -p ${lib_loc}
|
||||||
|
echo Copying -R ${PGADMIN_QT_DIR}/lib/${qtfw_path}/${lib_bn} to ${lib_loc}/
|
||||||
|
cp ${PGADMIN_QT_DIR}/lib/${qtfw_path}/${lib_bn} ${lib_loc}/
|
||||||
|
elif echo ${lib} | grep Python > /dev/null ; then
|
||||||
|
test -d ${lib_loc} || mkdir -p ${lib_loc}
|
||||||
|
cp -R "${lib}" "${lib_loc}/${lib_bn}"
|
||||||
|
else
|
||||||
|
cp -R "${lib}" "${lib_loc}/${lib_bn}"
|
||||||
|
fi
|
||||||
|
if ! test -L "${lib_loc}/${lib_bn}"; then
|
||||||
|
chmod 755 "${lib_loc}/${lib_bn}"
|
||||||
|
else
|
||||||
|
target_file=$(readlink "${lib}")
|
||||||
|
target_path=$(dirname "${lib}")/${target_file}
|
||||||
|
|
||||||
|
echo "Adding symlink target: ${target_path}"
|
||||||
|
cp "${target_path}" "${lib_loc}/${target_file}"
|
||||||
|
chmod 755 "${lib_loc}/${target_file}"
|
||||||
|
fi
|
||||||
|
echo "Rewriting ID in ${lib_loc}/${lib_bn} to ${lib_bn}"
|
||||||
|
install_name_tool -id "${lib_bn}" "${lib_loc}/${lib_bn}"
|
||||||
|
|
||||||
|
todo="${todo} ./${lib_loc}/${lib_bn}"
|
||||||
|
fi
|
||||||
|
if echo ${lib} | grep Qt > /dev/null ; then
|
||||||
|
fw_relpath="${fw_relpath}/${qtfw_path}"
|
||||||
|
fi
|
||||||
|
if echo ${lib} | grep Python > /dev/null ; then
|
||||||
|
fw_relpath="${fw_relpath}/${pyfw_path}"
|
||||||
|
fi
|
||||||
|
chmod +w ${todo_obj}
|
||||||
|
echo "Rewriting library ${lib} to @loader_path/${fw_relpath}/${lib_bn} in ${todo_obj}"
|
||||||
|
|
||||||
|
install_name_tool -change "${lib}" "@loader_path/${fw_relpath}/${lib_bn}" "${todo_obj}"
|
||||||
|
install_name_tool -change "${target_path}" "@loader_path/${fw_relpath}/${target_file}" "${todo_obj}"
|
||||||
|
|
||||||
|
fw_relpath="${fw_relpath_old}"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
# Fix the rpaths for psycopg module
|
||||||
|
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name _psycopg.so -print0 | xargs -0 install_name_tool -change libpq.5.dylib @loader_path/../../../../../../Frameworks/libpq.5.dylib
|
||||||
|
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name _psycopg.so -print0 | xargs -0 install_name_tool -change libssl.1.0.0.dylib @loader_path/../../../../../../Frameworks/libssl.1.0.0.dylib
|
||||||
|
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name _psycopg.so -print0 | xargs -0 install_name_tool -change libcrypto.1.0.0.dylib @loader_path/../../../../../../Frameworks/libcrypto.1.0.0.dylib
|
||||||
|
|
||||||
|
echo "App completed: ${BUNDLE_DIR}"
|
||||||
|
popd > /dev/null
|
||||||
|
|
||||||
|
pushd ${SOURCE_DIR}/web > /dev/null
|
||||||
|
yarn install
|
||||||
|
yarn run bundle
|
||||||
|
|
||||||
|
curl https://curl.haxx.se/ca/cacert.pem -o cacert.pem -s
|
||||||
|
popd > /dev/null
|
||||||
|
|
||||||
|
# copy the web directory to the bundle as it is required by runtime
|
||||||
|
cp -r ${SOURCE_DIR}/web "${BUNDLE_DIR}/Contents/Resources/"
|
||||||
|
cd "${BUNDLE_DIR}/Contents/Resources/web"
|
||||||
|
rm -f pgadmin4.db config_local.*
|
||||||
|
rm -rf karma.conf.js package.json node_modules/ regression/ tools/ pgadmin/static/js/generated/.cache
|
||||||
|
find . -name "tests" -type d -print0 | xargs -0 rm -rf
|
||||||
|
find . -name "feature_tests" -type d -print0 | xargs -0 rm -rf
|
||||||
|
find . -name ".DS_Store" -print0 | xargs -0 rm -f
|
||||||
|
|
||||||
|
echo "SERVER_MODE = False" > config_distro.py
|
||||||
|
echo "HELP_PATH = '../../../docs/en_US/html/'" >> config_distro.py
|
||||||
|
echo "DEFAULT_BINARY_PATHS = {" >> config_distro.py
|
||||||
|
echo " 'pg': '\$DIR/../../SharedSupport'," >> config_distro.py
|
||||||
|
echo " 'ppas': ''" >> config_distro.py
|
||||||
|
echo "}" >> config_distro.py
|
||||||
|
|
||||||
|
# Remove the .pyc files if any
|
||||||
|
find "${BUNDLE_DIR}" -name "*.pyc" -print0 | xargs -0 rm -f
|
||||||
|
}
|
||||||
|
|
||||||
|
_framework_config() {
|
||||||
|
# Get the config
|
||||||
|
source ${SCRIPT_DIR}/framework.conf
|
||||||
|
|
||||||
|
echo Reorganising the framework structure...
|
||||||
|
|
||||||
|
# Create "Current" and "Current/Resources" inside each of the framework dirs
|
||||||
|
find "${BUNDLE_DIR}/Contents/Frameworks"/*framework -type d -name "Versions" | while read -r framework_dir; do
|
||||||
|
pushd "${framework_dir}" > /dev/null
|
||||||
|
|
||||||
|
# Create framework 'Current' soft link
|
||||||
|
VERSION_NUMBER=`ls -1`
|
||||||
|
ln -s ${VERSION_NUMBER} Current
|
||||||
|
|
||||||
|
# Create "Resources" subdirectory
|
||||||
|
if [ ! -d Current/Resources ]; then
|
||||||
|
mkdir Current/Resources
|
||||||
|
fi
|
||||||
|
|
||||||
|
popd > /dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
# Stuff for Qt framework files only
|
||||||
|
find "${BUNDLE_DIR}/Contents/Frameworks" -type d -name "Qt*framework" | while read -r framework_dir; do
|
||||||
|
pushd "${framework_dir}" > /dev/null
|
||||||
|
|
||||||
|
# Create soft link to the framework binary
|
||||||
|
ln -s Versions/Current/Qt*
|
||||||
|
|
||||||
|
# Create soft link to the framework Resources dir
|
||||||
|
ln -s Versions/Current/Resources
|
||||||
|
|
||||||
|
# Create the Info.plist files
|
||||||
|
MYNAME=`ls -1 Qt*`
|
||||||
|
if [ -f Resources/Info.plist ]; then
|
||||||
|
chmod +w Resources/Info.plist
|
||||||
|
fi
|
||||||
|
sed 's/__SHORT_VERSION__/${QT_SHORT_VERSION}/' "${SCRIPT_DIR}/Info.plist-template_Qt5" | sed 's/__FULL_VERSION__/${QT_FULL_VERSION}/' | sed "s/__FRAMEWORK_NAME__/${MYNAME}/" > "Resources/Info.plist"
|
||||||
|
|
||||||
|
popd > /dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
# Same thing, but specific to the Python framework dir
|
||||||
|
find "${BUNDLE_DIR}/Contents/Frameworks" -type d -name "P*framework" | while read -r framework_dir; do
|
||||||
|
pushd "${framework_dir}" > /dev/null
|
||||||
|
|
||||||
|
# Create soft link to the framework binary
|
||||||
|
ln -s Versions/Current/Py*
|
||||||
|
|
||||||
|
# Create soft link to the framework Resources dir
|
||||||
|
ln -s Versions/Current/Resources
|
||||||
|
|
||||||
|
# Create the Info.plist file
|
||||||
|
MYNAME=`ls -1 Py*`
|
||||||
|
sed 's/__SHORT_VERSION__/${PYTHON_SHORT_VERSION}/' "${SCRIPT_DIR}/Info.plist-template_Python" | sed 's/__FULL_VERSION__/${PYTHON_FULL_VERSION}/' | sed "s/__FRAMEWORK_NAME__/${MYNAME}/" > "Resources/Info.plist"
|
||||||
|
|
||||||
|
popd > /dev/null
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_codesign_binaries() {
|
||||||
|
if [ ${CODESIGN} -eq 0 ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${DEVELOPER_ID}" ] ; then
|
||||||
|
echo "Developer ID Application not found in codesign.conf" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${DEVELOPER_BUNDLE_ID}" ]; then
|
||||||
|
echo "Developer Bundle Identifier not found in codesign.conf" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo Signing ${BUNDLE_DIR} binaries...
|
||||||
|
IFS=$'\n'
|
||||||
|
for i in $(find "${BUNDLE_DIR}" -type f -perm +111 -exec file "{}" \; | grep -E "Mach-O executable|Mach-O 64-bit executable|Mach-O 64-bit bundle" | awk -F":| \\\(" '{print $1}' | uniq)
|
||||||
|
do
|
||||||
|
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "$i"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo Signing ${BUNDLE_DIR} libraries...
|
||||||
|
for i in $(find "${BUNDLE_DIR}" -type f -name "*.dylib*")
|
||||||
|
do
|
||||||
|
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "$i"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_codesign_bundle() {
|
||||||
|
if [ ${CODESIGN} -eq 0 ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Sign the .app
|
||||||
|
echo Signing ${BUNDLE_DIR}...
|
||||||
|
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "${BUNDLE_DIR}"
|
||||||
|
|
||||||
|
# Verify it worked
|
||||||
|
echo Verifying the signature...
|
||||||
|
codesign --verify --verbose --deep --force "${BUNDLE_DIR}"
|
||||||
|
echo ${BUNDLE_DIR} successfully signed.
|
||||||
|
}
|
||||||
|
|
||||||
|
_create_dmg() {
|
||||||
|
# move to the directory where we want to create the DMG
|
||||||
|
test -d ${DIST_ROOT} || mkdir ${DIST_ROOT}
|
||||||
|
cd ${DIST_ROOT}
|
||||||
|
|
||||||
|
DMG_LICENCE=./../pkg/mac/licence.rtf
|
||||||
|
DMG_VOLUME_NAME=${APP_NAME}
|
||||||
|
DMG_NAME=`echo ${DMG_VOLUME_NAME} | sed 's/ //g' | awk '{print tolower($0)}'`
|
||||||
|
DMG_IMAGE=${DMG_NAME}-${APP_LONG_VERSION}.dmg
|
||||||
|
|
||||||
|
DMG_DIR=./${DMG_IMAGE}.src
|
||||||
|
|
||||||
|
if test -e "${DMG_DIR}"; then
|
||||||
|
echo "Directory ${DMG_DIR} already exists. Please delete it manually." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Cleaning up"
|
||||||
|
rm -f "${DMG_IMAGE}"
|
||||||
|
mkdir "${DMG_DIR}"
|
||||||
|
|
||||||
|
echo "Copying data into temporary directory"
|
||||||
|
cp -R "${BUNDLE_DIR}" "${DMG_DIR}"
|
||||||
|
|
||||||
|
echo "Creating image"
|
||||||
|
hdiutil create -quiet -srcfolder "$DMG_DIR" -fs HFS+ -format UDZO -volname "${DMG_VOLUME_NAME}" -ov "${DMG_IMAGE}"
|
||||||
|
rm -rf "${DMG_DIR}"
|
||||||
|
|
||||||
|
echo Attaching License to image...
|
||||||
|
python ${SCRIPT_DIR}/dmg-license.py "${DMG_IMAGE}" "${DMG_LICENCE}" -c bz2
|
||||||
|
}
|
||||||
|
|
||||||
|
_codesign_dmg() {
|
||||||
|
if [ ${CODESIGN} -eq 0 ]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
DMG_VOLUME_NAME=${APP_NAME}
|
||||||
|
DMG_NAME=`echo ${DMG_VOLUME_NAME} | sed 's/ //g' | awk '{print tolower($0)}'`
|
||||||
|
DMG_IMAGE=${DIST_ROOT}/${DMG_NAME}-${APP_LONG_VERSION}.dmg
|
||||||
|
|
||||||
|
if ! test -f "${DMG_IMAGE}" ; then
|
||||||
|
echo "${DMG_IMAGE} is no disk image!" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Sign the .app
|
||||||
|
echo Signing ${DMG_IMAGE}...
|
||||||
|
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "${DMG_IMAGE}"
|
||||||
|
|
||||||
|
# Verify it worked
|
||||||
|
echo Verifying the signature...
|
||||||
|
codesign --verify --verbose --force "${DMG_IMAGE}"
|
||||||
|
echo ${DMG_IMAGE} successfully signed.
|
||||||
|
}
|
||||||
267
pkg/mac/build.sh
267
pkg/mac/build.sh
@@ -2,13 +2,19 @@
|
|||||||
|
|
||||||
# Build script to create Mac App Bundle and DMG for pgAdmin4 runtime
|
# Build script to create Mac App Bundle and DMG for pgAdmin4 runtime
|
||||||
|
|
||||||
export WD=$(cd `dirname $0` && pwd)
|
# Exit when any command fails
|
||||||
export SOURCEDIR=${WD}/../..
|
set -e -E
|
||||||
export BUILDROOT=${WD}/../../mac-build
|
|
||||||
export DISTROOT=${WD}/../../dist
|
|
||||||
export VIRTUALENV=venv
|
|
||||||
|
|
||||||
if [ ! -f ${SOURCEDIR}/pkg/mac/framework.conf ]; then
|
# Debugging shizz
|
||||||
|
trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG
|
||||||
|
trap 'if [ $? -ne 0 ]; then echo "\"${last_command}\" command filed with exit code $?."; fi' EXIT
|
||||||
|
|
||||||
|
SCRIPT_DIR=$(cd `dirname $0` && pwd)
|
||||||
|
SOURCE_DIR=$(realpath ${SCRIPT_DIR}/../..)
|
||||||
|
BUILD_ROOT=$(realpath ${SCRIPT_DIR}/../..)/mac-build
|
||||||
|
DIST_ROOT=$(realpath ${SCRIPT_DIR}/../..)/dist
|
||||||
|
|
||||||
|
if [ ! -f ${SCRIPT_DIR}/framework.conf ]; then
|
||||||
echo
|
echo
|
||||||
echo "Error: pkg/mac/framework.conf not found!"
|
echo "Error: pkg/mac/framework.conf not found!"
|
||||||
echo "Copy pkg/mac/framework.conf.in to pkg/mac/framework.conf and edit as required for the current system."
|
echo "Copy pkg/mac/framework.conf.in to pkg/mac/framework.conf and edit as required for the current system."
|
||||||
@@ -16,244 +22,61 @@ if [ ! -f ${SOURCEDIR}/pkg/mac/framework.conf ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "x${PYTHON_HOME}" == "x" ]; then
|
CODESIGN=1
|
||||||
echo "PYTHON_HOME not set. It must be set, and pointing to a Python 3 installation."
|
if [ ! -f ${SCRIPT_DIR}/codesign.conf ]; then
|
||||||
exit 1
|
echo
|
||||||
|
echo "******************************************************************"
|
||||||
|
echo "* ${SCRIPT_DIR}/codesign.conf not found. NOT signing the binaries."
|
||||||
|
echo "******************************************************************"
|
||||||
|
echo
|
||||||
|
CODESIGN=0
|
||||||
|
sleep 5
|
||||||
|
else
|
||||||
|
source ${SCRIPT_DIR}/codesign.conf
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "x${PGADMIN_PYTHON_DIR}" == "x" ]; then
|
||||||
|
echo "PGADMIN_PYTHON_DIR not set. Setting it to the default: /usr/local/python"
|
||||||
|
export PGADMIN_PYTHON_DIR=/usr/local/python
|
||||||
|
fi
|
||||||
|
PYTHON_EXE=${PGADMIN_PYTHON_DIR}/bin/python3
|
||||||
|
|
||||||
# Check if Python is working and calculate PYTHON_VERSION
|
# Check if Python is working and calculate PYTHON_VERSION
|
||||||
if ${PYTHON_HOME}/bin/python3 -V > /dev/null 2>&1; then
|
if ${PYTHON_EXE} -V > /dev/null 2>&1; then
|
||||||
export PYTHON_VERSION=`${PYTHON_HOME}/bin/python3 -V 2>&1 | awk '{print $2}' | cut -d"." -f1-2 | sed 's/\.//'`
|
PYTHON_VERSION=`${PYTHON_EXE} -V 2>&1 | awk '{print $2}' | cut -d"." -f1-2 | sed 's/\.//'`
|
||||||
else
|
else
|
||||||
echo "Error: Python installation missing!"
|
echo "Error: Python installation missing!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${PYTHON_VERSION}" -gt "38" -a "${PYTHON_VERSION}" -lt "34" ]; then
|
if [ "${PYTHON_VERSION}" -gt "38" ] && [ "${PYTHON_VERSION}" -lt "34" ]; then
|
||||||
echo "Python version not supported."
|
echo "Python version not supported."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export PYTHON=${PYTHON_HOME}/bin/python3
|
if [ "x${PGADMIN_QT_DIR}" == "x" ]; then
|
||||||
export PIP=pip3
|
echo "PGADMIN_QT_DIR not set. Setting it to the default: ~/Qt/5.13.2/clang_64"
|
||||||
|
export PGADMIN_QT_DIR=~/Qt/5.13.2/clang_64
|
||||||
if [ "x${QTDIR}" == "x" ]; then
|
|
||||||
echo "QTDIR not set. Setting it to default."
|
|
||||||
export QTDIR=~/Qt/5.8/clang_64
|
|
||||||
fi
|
fi
|
||||||
export QMAKE=${QTDIR}/bin/qmake
|
|
||||||
|
QMAKE=${PGADMIN_QT_DIR}/bin/qmake
|
||||||
if ! ${QMAKE} --version > /dev/null 2>&1; then
|
if ! ${QMAKE} --version > /dev/null 2>&1; then
|
||||||
echo "Error: qmake not found. QT installation is not present or incomplete."
|
echo "Error: qmake not found. QT installation is not present or incomplete."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "x${PGDIR}" == "x" ]; then
|
if [ "x${PGADMIN_POSTGRES_DIR}" == "x" ]; then
|
||||||
echo "PGDIR not set. Setting it to default."
|
echo "PGADMIN_POSTGRES_DIR not set. Setting it to the default: /usr/local/pgsql"
|
||||||
export PGDIR=/usr/local/pgsql
|
export PGADMIN_POSTGRES_DIR=/usr/local/pgsql
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_get_version() {
|
source ${SCRIPT_DIR}/build-functions.sh
|
||||||
export APP_RELEASE=`grep "^APP_RELEASE" web/config.py | cut -d"=" -f2 | sed 's/ //g'`
|
|
||||||
export APP_REVISION=`grep "^APP_REVISION" web/config.py | cut -d"=" -f2 | sed 's/ //g'`
|
|
||||||
export APP_NAME=`grep "^APP_NAME" web/config.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //'`
|
|
||||||
export APP_BUNDLE_NAME=${APP_NAME}.app
|
|
||||||
export APP_LONG_VERSION=${APP_RELEASE}.${APP_REVISION}
|
|
||||||
export APP_SHORT_VERSION=`echo ${APP_LONG_VERSION} | cut -d . -f1,2`
|
|
||||||
export APP_SUFFIX=`grep "^APP_SUFFIX" web/config.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g"`
|
|
||||||
if [ ! -z ${APP_SUFFIX} ]; then
|
|
||||||
export APP_LONG_VERSION=${APP_LONG_VERSION}-${APP_SUFFIX}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
_cleanup() {
|
_setup_env
|
||||||
echo "Cleaning up the old environment and app bundle"
|
|
||||||
rm -rf ${SOURCEDIR}/runtime/pgAdmin4.app
|
|
||||||
rm -rf ${BUILDROOT}
|
|
||||||
rm -f ${DISTROOT}/pgadmin4*.dmg
|
|
||||||
}
|
|
||||||
|
|
||||||
_create_venv() {
|
|
||||||
export PATH=${PGDIR}/bin:${PATH}
|
|
||||||
export LD_LIBRARY_PATH=${PGDIR}/lib:${LD_LIBRARY_PATH}
|
|
||||||
test -d ${BUILDROOT} || mkdir ${BUILDROOT} || exit 1
|
|
||||||
cd ${BUILDROOT}
|
|
||||||
|
|
||||||
test -d ${VIRTUALENV} || virtualenv -p ${PYTHON} --always-copy ${VIRTUALENV} || exit 1
|
|
||||||
|
|
||||||
source ${VIRTUALENV}/bin/activate
|
|
||||||
${PIP} install --no-cache-dir --no-binary psycopg2 -r ${SOURCEDIR}/requirements.txt || { echo PIP install failed. Please resolve the issue and rerun the script; exit 1; }
|
|
||||||
|
|
||||||
# Figure out some paths for use when completing the venv
|
|
||||||
# Use "python" here as we want the venv path
|
|
||||||
export PYMODULES_PATH=`python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"`
|
|
||||||
export DIR_PYMODULES_PATH=`dirname ${PYMODULES_PATH}`
|
|
||||||
|
|
||||||
# Use $PYTHON here as we want the system path
|
|
||||||
export PYSYSLIB_PATH=`${PYTHON} -c "import sys; print('%s/lib/python%d.%.d' % (sys.prefix, sys.version_info.major, sys.version_info.minor))"`
|
|
||||||
|
|
||||||
# Symlink in the rest of the Python libs. This is required because the runtime
|
|
||||||
# will clear PYTHONHOME for safety, which has the side-effect of preventing
|
|
||||||
# it from finding modules that are not explicitly included in the venv
|
|
||||||
cd ${DIR_PYMODULES_PATH}
|
|
||||||
|
|
||||||
# Files
|
|
||||||
for FULLPATH in ${PYSYSLIB_PATH}/*.py; do
|
|
||||||
FILE=${FULLPATH##*/}
|
|
||||||
if [ ! -e ${FILE} ]; then
|
|
||||||
cp ${FULLPATH} ${FILE}
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Paths
|
|
||||||
for FULLPATH in ${PYSYSLIB_PATH}/*/; do
|
|
||||||
FULLPATH=${FULLPATH%*/}
|
|
||||||
FILE=${FULLPATH##*/}
|
|
||||||
if [ ! -e ${FILE} ]; then
|
|
||||||
cp -R ${FULLPATH} ${FILE}
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Remove tests
|
|
||||||
cd site-packages
|
|
||||||
find . -name "test" -type d -print0 | xargs -0 rm -rf
|
|
||||||
find . -name "tests" -type d -print0 | xargs -0 rm -rf
|
|
||||||
|
|
||||||
# Link the python<version> directory to python so that the private environment path is found by the application.
|
|
||||||
if test -d ${DIR_PYMODULES_PATH}; then
|
|
||||||
ln -s $(basename ${DIR_PYMODULES_PATH}) ${DIR_PYMODULES_PATH}/../python
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
_build_runtime() {
|
|
||||||
cd ${SOURCEDIR}/runtime
|
|
||||||
make clean
|
|
||||||
PGADMIN_PYTHON_DIR=${PYTHON_HOME} ${QMAKE} || { echo qmake failed; exit 1; }
|
|
||||||
make || { echo make failed; exit 1; }
|
|
||||||
cp -r pgAdmin4.app "${BUILDROOT}/${APP_BUNDLE_NAME}"
|
|
||||||
}
|
|
||||||
|
|
||||||
_build_doc() {
|
|
||||||
cd ${SOURCEDIR}/docs/en_US
|
|
||||||
test -d "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources" || "mkdir -p ${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources"
|
|
||||||
test -d "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/docs/en_US" || mkdir -p "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/docs/en_US"
|
|
||||||
cp -r _build/html "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/docs/en_US/" || exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
_complete_bundle() {
|
|
||||||
cd ${SOURCEDIR}/pkg/mac
|
|
||||||
|
|
||||||
# Copy the binary utilities into place
|
|
||||||
mkdir -p "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/SharedSupport/" || exit 1
|
|
||||||
cp "${PGDIR}/bin/pg_dump" "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/SharedSupport/" || exit 1
|
|
||||||
cp "${PGDIR}/bin/pg_dumpall" "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/SharedSupport/" || exit 1
|
|
||||||
cp "${PGDIR}/bin/pg_restore" "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/SharedSupport/" || exit 1
|
|
||||||
cp "${PGDIR}/bin/psql" "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/SharedSupport/" || exit 1
|
|
||||||
|
|
||||||
# Replace the place holders with the current version
|
|
||||||
sed -e "s/PGADMIN_LONG_VERSION/${APP_LONG_VERSION}/g" -e "s/PGADMIN_SHORT_VERSION/${APP_SHORT_VERSION}/g" pgadmin.Info.plist.in > pgadmin.Info.plist
|
|
||||||
|
|
||||||
# copy Python private environment to app bundle
|
|
||||||
cp -PR ${BUILDROOT}/${VIRTUALENV} "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/" || exit 1
|
|
||||||
|
|
||||||
# Remove any TCL-related files that may cause us problems
|
|
||||||
find "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/${VIRTUALENV}/" -name "_tkinter*" -print0 | xargs -0 rm -f
|
|
||||||
|
|
||||||
# run complete-bundle to copy the dependent libraries and frameworks and fix the rpaths
|
|
||||||
./complete-bundle.sh "${BUILDROOT}/${APP_BUNDLE_NAME}" || { echo complete-bundle.sh failed; exit 1; }
|
|
||||||
|
|
||||||
pushd ${SOURCEDIR}/web
|
|
||||||
yarn install || exit 1
|
|
||||||
yarn run bundle || exit 1
|
|
||||||
|
|
||||||
curl https://curl.haxx.se/ca/cacert.pem -o cacert.pem -s || { echo Failed to download cacert.pem; exit 1; }
|
|
||||||
popd
|
|
||||||
|
|
||||||
# copy the web directory to the bundle as it is required by runtime
|
|
||||||
cp -r ${SOURCEDIR}/web "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/" || exit 1
|
|
||||||
cd "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/web"
|
|
||||||
rm -f pgadmin4.db config_local.*
|
|
||||||
rm -rf karma.conf.js package.json node_modules/ regression/ tools/ pgadmin/static/js/generated/.cache
|
|
||||||
find . -name "tests" -type d -print0 | xargs -0 rm -rf
|
|
||||||
find . -name "feature_tests" -type d -print0 | xargs -0 rm -rf
|
|
||||||
find . -name ".DS_Store" -print0 | xargs -0 rm -f
|
|
||||||
|
|
||||||
echo "SERVER_MODE = False" > config_distro.py
|
|
||||||
echo "HELP_PATH = '../../../docs/en_US/html/'" >> config_distro.py
|
|
||||||
echo "DEFAULT_BINARY_PATHS = {" >> config_distro.py
|
|
||||||
echo " 'pg': '\$DIR/../../SharedSupport'," >> config_distro.py
|
|
||||||
echo " 'ppas': ''" >> config_distro.py
|
|
||||||
echo "}" >> config_distro.py
|
|
||||||
|
|
||||||
# Remove the .pyc files if any
|
|
||||||
cd "${BUILDROOT}/${APP_BUNDLE_NAME}"
|
|
||||||
find . -name *.pyc -print0 | xargs -0 rm -f
|
|
||||||
}
|
|
||||||
|
|
||||||
_framework_config() {
|
|
||||||
cd ${SOURCEDIR}/pkg/mac
|
|
||||||
./framework-config.sh "${BUILDROOT}/${APP_BUNDLE_NAME}" || { echo "framework-config.sh failed"; exit 1; }
|
|
||||||
}
|
|
||||||
|
|
||||||
_codesign_binaries() {
|
|
||||||
cd ${SOURCEDIR}/pkg/mac
|
|
||||||
|
|
||||||
if [ ! -f codesign.conf ]; then
|
|
||||||
echo
|
|
||||||
echo "******************************************************************"
|
|
||||||
echo "* codesign.conf not found. NOT signing the binaries."
|
|
||||||
echo "******************************************************************"
|
|
||||||
echo
|
|
||||||
sleep 5
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
./codesign-binaries.sh "${BUILDROOT}/${APP_BUNDLE_NAME}" || { echo codesign-binaries.sh failed; exit 1; }
|
|
||||||
}
|
|
||||||
|
|
||||||
_codesign_bundle() {
|
|
||||||
cd ${SOURCEDIR}/pkg/mac
|
|
||||||
|
|
||||||
if [ ! -f codesign.conf ]; then
|
|
||||||
echo
|
|
||||||
echo "******************************************************************"
|
|
||||||
echo "* codesign.conf not found. NOT signing the bundle."
|
|
||||||
echo "******************************************************************"
|
|
||||||
echo
|
|
||||||
sleep 5
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
./codesign-bundle.sh "${BUILDROOT}/${APP_BUNDLE_NAME}" || { echo codesign-bundle.sh failed; exit 1; }
|
|
||||||
}
|
|
||||||
|
|
||||||
_create_dmg() {
|
|
||||||
cd ${SOURCEDIR}
|
|
||||||
./pkg/mac/create-dmg.sh || { echo create-dmg.sh failed; exit 1; }
|
|
||||||
# Clean the mac-build/ on successful build
|
|
||||||
rm -rf ${BUILDROOT}/*
|
|
||||||
}
|
|
||||||
|
|
||||||
_codesign_dmg() {
|
|
||||||
cd ${SOURCEDIR}/pkg/mac
|
|
||||||
|
|
||||||
if [ ! -f codesign.conf ]; then
|
|
||||||
echo
|
|
||||||
echo "******************************************************************"
|
|
||||||
echo "* codesign.conf not found. NOT signing the disk image."
|
|
||||||
echo "******************************************************************"
|
|
||||||
echo
|
|
||||||
sleep 5
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
./codesign-dmg.sh || { echo codesign-bundle.sh failed; exit 1; }
|
|
||||||
}
|
|
||||||
|
|
||||||
_get_version || { echo Could not get versioning; exit 1; }
|
|
||||||
_cleanup
|
_cleanup
|
||||||
_create_venv || { echo venv creation failed; exit 1; }
|
_create_venv
|
||||||
_build_runtime || { echo Runtime build failed; exit 1; }
|
_build_runtime
|
||||||
_build_doc
|
_build_docs
|
||||||
_complete_bundle
|
_complete_bundle
|
||||||
_framework_config
|
_framework_config
|
||||||
_codesign_binaries
|
_codesign_binaries
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
BUNDLE="$1"
|
|
||||||
|
|
||||||
if ! test -d "${BUNDLE}" ; then
|
|
||||||
echo "${BUNDLE} is no bundle!" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get the config
|
|
||||||
source codesign.conf
|
|
||||||
|
|
||||||
if [ -z "${DEVELOPER_ID}" ] ; then
|
|
||||||
echo "Developer ID Application not found in codesign.conf" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "${DEVELOPER_BUNDLE_ID}" ]; then
|
|
||||||
echo "Developer Bundle Identifier not found in codesign.conf" >&2
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo Signing ${BUNDLE} binaries
|
|
||||||
IFS=$'\n'
|
|
||||||
for i in $(find "${BUNDLE}" -type f)
|
|
||||||
do
|
|
||||||
file "${i}" | grep -E "Mach-O executable|Mach-O 64-bit executable|Mach-O 64-bit bundle"
|
|
||||||
if [ $? -eq 0 ] ; then
|
|
||||||
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "$i"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo Signing ${BUNDLE} libraries
|
|
||||||
for i in $(find "${BUNDLE}" -type f -name "*.dylib*")
|
|
||||||
do
|
|
||||||
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "$i"
|
|
||||||
done
|
|
||||||
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
BUNDLE="$1"
|
|
||||||
|
|
||||||
if ! test -d "${BUNDLE}" ; then
|
|
||||||
echo "${BUNDLE} is no bundle!" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get the config
|
|
||||||
source codesign.conf
|
|
||||||
|
|
||||||
# Sign the .app
|
|
||||||
echo Signing ${BUNDLE}
|
|
||||||
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "${BUNDLE}"
|
|
||||||
|
|
||||||
# Verify it worked
|
|
||||||
echo Verifying the signature
|
|
||||||
codesign --verify --verbose --deep --force "${BUNDLE}"
|
|
||||||
RETURN_STATUS=$?
|
|
||||||
if [ ${RETURN_STATUS} -ne 0 ]; then
|
|
||||||
echo Code signing did not work, check the log
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo ${BUNDLE} successfully signed
|
|
||||||
fi
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
DMG_VOLUME_NAME=${APP_NAME}
|
|
||||||
DMG_NAME=`echo ${DMG_VOLUME_NAME} | sed 's/ //g' | awk '{print tolower($0)}'`
|
|
||||||
DMG_IMAGE=${DISTROOT}/${DMG_NAME}-${APP_LONG_VERSION}.dmg
|
|
||||||
|
|
||||||
if ! test -f "${DMG_IMAGE}" ; then
|
|
||||||
echo "${DMG_IMAGE} is no disk image!" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get the config
|
|
||||||
source codesign.conf
|
|
||||||
|
|
||||||
SCRIPT_DIR=`pwd`
|
|
||||||
|
|
||||||
# Sign the .app
|
|
||||||
echo Signing ${DMG_IMAGE}
|
|
||||||
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "${DMG_IMAGE}"
|
|
||||||
|
|
||||||
# Verify it worked
|
|
||||||
echo Verifying the signature
|
|
||||||
codesign --verify --verbose --force "${DMG_IMAGE}"
|
|
||||||
RETURN_STATUS=$?
|
|
||||||
if [ ${RETURN_STATUS} -ne 0 ]; then
|
|
||||||
echo ERROR: Code signing did not work
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo ${DMG_IMAGE} successfully signed
|
|
||||||
fi
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
# move to the directory where we want to create the DMG
|
|
||||||
test -d ${DISTROOT} || mkdir ${DISTROOT}
|
|
||||||
cd ${DISTROOT}
|
|
||||||
|
|
||||||
DMG_SOURCES="./../mac-build/${APP_BUNDLE_NAME}"
|
|
||||||
DMG_LICENCE=./../pkg/mac/licence.rtf
|
|
||||||
DMG_VOLUME_NAME=${APP_NAME}
|
|
||||||
DMG_NAME=`echo ${DMG_VOLUME_NAME} | sed 's/ //g' | awk '{print tolower($0)}'`
|
|
||||||
DMG_IMAGE=${DMG_NAME}-${APP_LONG_VERSION}.dmg
|
|
||||||
HDIUTIL=/usr/bin/hdiutil
|
|
||||||
REZ="/usr/bin/Rez"
|
|
||||||
|
|
||||||
DMG_DIR=./${DMG_IMAGE}.src
|
|
||||||
|
|
||||||
if test -e "${DMG_DIR}"; then
|
|
||||||
echo "Directory ${DMG_DIR} already exists. Please delete it manually." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Cleaning up"
|
|
||||||
rm -f "${DMG_IMAGE}" || exit 1
|
|
||||||
mkdir "${DMG_DIR}" || exit 1
|
|
||||||
|
|
||||||
echo "Copying data into temporary directory"
|
|
||||||
for src in "${DMG_SOURCES}"; do
|
|
||||||
cp -R "${src}" "${DMG_DIR}" || exit 1
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Creating image"
|
|
||||||
${HDIUTIL} create -quiet -srcfolder "$DMG_DIR" -fs HFS+ -format UDZO -volname "${DMG_VOLUME_NAME}" -ov "${DMG_IMAGE}" || exit 1
|
|
||||||
rm -rf "${DMG_DIR}" || exit 1
|
|
||||||
|
|
||||||
echo "Attaching License to image"
|
|
||||||
python ./../pkg/mac/dmg-license.py "${DMG_IMAGE}" "${DMG_LICENCE}" -c bz2
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
BUNDLE="$1"
|
|
||||||
|
|
||||||
if ! test -d "${BUNDLE}" ; then
|
|
||||||
echo "${BUNDLE} is no bundle!" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get the config
|
|
||||||
source framework.conf
|
|
||||||
|
|
||||||
SCRIPT_DIR=`pwd`
|
|
||||||
|
|
||||||
echo Reorganising the framework structure
|
|
||||||
|
|
||||||
# Create "Current" and "Current/Resources" inside each of the framework dirs
|
|
||||||
MYDIR=`pwd`
|
|
||||||
find "${BUNDLE}/Contents/Frameworks"/*framework -type d -name "Versions" | while read -r framework_dir; do
|
|
||||||
cd "${framework_dir}"
|
|
||||||
|
|
||||||
# Create framework 'Current' soft link
|
|
||||||
VERSION_NUMBER=`ls -1`
|
|
||||||
ln -s ${VERSION_NUMBER} Current || { echo "link creation in framework-config.sh failed"; exit 1; }
|
|
||||||
|
|
||||||
# Create "Resources" subdirectory
|
|
||||||
if [ ! -d Current/Resources ]; then
|
|
||||||
mkdir Current/Resources
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd "${MYDIR}"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Stuff for Qt framework files only
|
|
||||||
find "${BUNDLE}/Contents/Frameworks" -type d -name "Qt*framework" | while read -r framework_dir; do
|
|
||||||
cd "${framework_dir}"
|
|
||||||
|
|
||||||
# Create soft link to the framework binary
|
|
||||||
ln -s Versions/Current/Qt* || { echo "link creation in framework-config.sh failed"; exit 1; }
|
|
||||||
|
|
||||||
# Create soft link to the framework Resources dir
|
|
||||||
ln -s Versions/Current/Resources || { echo "link creation in framework-config.sh failed"; exit 1; }
|
|
||||||
|
|
||||||
# Create the Info.plist files
|
|
||||||
MYNAME=`ls -1 Qt*`
|
|
||||||
if [ -f Resources/Info.plist ]; then
|
|
||||||
chmod +w Resources/Info.plist
|
|
||||||
fi
|
|
||||||
sed 's/__SHORT_VERSION__/${QT_SHORT_VERSION}/' "${SCRIPT_DIR}/Info.plist-template_Qt5" | sed 's/__FULL_VERSION__/${QT_FULL_VERSION}/' | sed "s/__FRAMEWORK_NAME__/${MYNAME}/" > "Resources/Info.plist" || { echo "sed replacement in framework-config.sh failed"; exit 1; }
|
|
||||||
|
|
||||||
cd "${MYDIR}"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Same thing, but specific to the Python framework dir
|
|
||||||
find "${BUNDLE}/Contents/Frameworks" -type d -name "P*framework" | while read -r framework_dir; do
|
|
||||||
cd "${framework_dir}"
|
|
||||||
|
|
||||||
# Create soft link to the framework binary
|
|
||||||
ln -s Versions/Current/Py* || { echo "link creation in framework-config.sh failed"; exit 1; }
|
|
||||||
|
|
||||||
# Create soft link to the framework Resources dir
|
|
||||||
ln -s Versions/Current/Resources || { echo "link creation in framework-config.sh failed"; exit 1; }
|
|
||||||
|
|
||||||
# Create the Info.plist file
|
|
||||||
MYNAME=`ls -1 Py*`
|
|
||||||
sed 's/__SHORT_VERSION__/${PYTHON_SHORT_VERSION}/' "${SCRIPT_DIR}/Info.plist-template_Python" | sed 's/__FULL_VERSION__/${PYTHON_FULL_VERSION}/' | sed "s/__FRAMEWORK_NAME__/${MYNAME}/" > "Resources/Info.plist" || { echo "sed replacement in framework-config.sh failed"; exit 1; }
|
|
||||||
|
|
||||||
cd "${MYDIR}"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ${BUNDLE} framework config finished
|
|
||||||
Reference in New Issue
Block a user