From 2f89e1c7795e31ed87457c3f1c02356d5c60d73d Mon Sep 17 00:00:00 2001 From: Joseph Werle Date: Thu, 12 Oct 2023 17:54:28 +0200 Subject: [PATCH] refactor(bin): generate 'pkgconfig' files --- bin/build-runtime-library.sh | 4 + bin/functions.sh | 2 +- bin/generate-socket-runtime-pkg-config.sh | 167 ++++++++++++++++++++ bin/install.sh | 14 +- bin/ldflags.sh | 4 +- bin/mush.sh | 176 ++++++++++++++++++++++ bin/publish-npm-modules.sh | 4 + socket-runtime.pc.in | 7 + 8 files changed, 370 insertions(+), 8 deletions(-) create mode 100755 bin/generate-socket-runtime-pkg-config.sh create mode 100755 bin/mush.sh create mode 100644 socket-runtime.pc.in diff --git a/bin/build-runtime-library.sh b/bin/build-runtime-library.sh index 72ac3970f5..ca5872ddd3 100755 --- a/bin/build-runtime-library.sh +++ b/bin/build-runtime-library.sh @@ -237,6 +237,10 @@ function main () { fi fi + if [[ "$host" = "Linux" ]] && [[ "$platform" = "desktop" ]]; then + "$root/bin/generate-socket-runtime-pkg-config.sh" + fi + if [[ "$platform" == "android" ]]; then # This is a sanity check to confirm that the static_library is > 8 bytes # If an empty ${objects[@]} is provided to ar, it will still spit out a header without an error code. diff --git a/bin/functions.sh b/bin/functions.sh index ea5cb18ce5..17f57e6c6c 100755 --- a/bin/functions.sh +++ b/bin/functions.sh @@ -92,7 +92,7 @@ function quiet () { if [ -n "$VERBOSE" ]; then echo "$command" "$@" "$command" "$@" - else + else "$command" "$@" > /dev/null 2>&1 fi diff --git a/bin/generate-socket-runtime-pkg-config.sh b/bin/generate-socket-runtime-pkg-config.sh new file mode 100755 index 0000000000..87c5eea46f --- /dev/null +++ b/bin/generate-socket-runtime-pkg-config.sh @@ -0,0 +1,167 @@ +#!/usr/bin/env bash +# vim: set syntax=bash: + +declare root="$(cd "$(dirname "$(dirname "${BASH_SOURCE[0]}")")" && pwd)" + +source "$root/bin/mush.sh" +source "$root/bin/functions.sh" +source "$root/bin/android-functions.sh" + +declare platform="desktop" +declare host="$(host_os)" +declare arch="$(host_arch)" + +if (( TARGET_OS_IPHONE )); then + arch="arm64" + platform="iPhoneOS" +elif (( TARGET_IPHONE_SIMULATOR )); then + arch="x86_64" + platform="iPhoneSimulator" +elif (( TARGET_OS_ANDROID )); then + arch="aarch64" + platform="android" +elif (( TARGET_ANDROID_EMULATOR )); then + arch="x86_64" + platform="android" +fi + +while (( $# > 0 )); do + declare arg="$1"; shift + if [[ "$arg" = "--arch" ]]; then + arch="$1"; shift; continue + fi + + if [[ "$arg" = "--force" ]] || [[ "$arg" = "-f" ]]; then + pass_force="$arg" + force=1; continue + fi + + if [[ "$arg" = "--platform" ]]; then + if [[ "$1" = "ios" ]] || [[ "$1" = "iPhoneOS" ]] || [[ "$1" = "iphoneos" ]]; then + arch="arm64" + platform="iPhoneOS"; + export TARGET_OS_IPHONE=1 + elif [[ "$1" = "ios-simulator" ]] || [[ "$1" = "iPhoneSimulator" ]] || [[ "$1" = "iphonesimulator" ]]; then + [[ -z "$arch" ]] && arch="x86_64" + platform="iPhoneSimulator"; + export TARGET_IPHONE_SIMULATOR=1 + elif [[ "$1" = "android" ]] || [[ "$1" = "android-emulator" ]]; then + platform="android"; + export TARGET_OS_ANDROID=1 + else + platform="$1"; + fi + shift + continue + fi + + # Don't rebuild if header mtimes are newer than .o files - Be sure to manually delete affected assets as required + if [[ "$arg" == "--ignore-header-mtimes" ]]; then + ignore_header_mtimes=1; continue + fi + + args+=("$arg") +done + +declare input="$root/socket-runtime.pc.in" +declare output="$root/build/$arch-$platform/pkgconfig/socket-runtime.pc" + +mkdir -p "$(dirname "$output")" + +declare version="$(cat "$root/VERSION.txt")" +declare lib_directory="$root/build/$arch-$platform/lib" +declare include_directory="$root/build/$arch-$platform/include" + +declare ldflags=() +declare dependencies=() +declare cflags=( + "-0s" + "-std=c++2a" + "-fvisibility=hidden" +) + +if [ "$platform" == "iPhoneOS" ]; then + platform="ios" +elif [ "$platform" == "iPhoneSimulator" ]; then + platform="ios-simulator" +fi + +if [ "$host" == "Linux" ]; then + if [ "$platform" == "desktop" ]; then + if [[ "$(basename "$CXX")" =~ clang ]]; then + cflags+=("-stdlib=libstdc++") + cflags+=("-Wno-unused-command-line-argument") + fi + cflags+=("-fPIC") + ldflags+=("-ldl") + dependencies+=("gtk+-3.0" "webkit2gtk-4.1") + fi +elif [ "$host" == "Win32" ]; then + if [ "$platform" == "desktop" ]; then + if [[ "$(basename "$CXX")" =~ clang ]]; then + cflags+=("-Wno-unused-command-line-argument") + cflags+=("-stdlib=libstdc++") + fi + + # https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-170 + # Because we can't pass /MT[d] directly, we have to manually set the flags + cflags+=( + "-D_MT" + "-D_DLL" + "-DWIN32" + "-DWIN32_LEAN_AND_MEAN" + "-Xlinker" "/NODEFAULTLIB:libcmt" + "-Wno-nonportable-include-path" + ) + fi +elif [ "$host" == "Darwin" ]; then + if [ "$platform" == "desktop" ]; then + cflags+=("-ObjC++") + cflags+=("-fPIC") + fi +fi + +if [ "$platform" == "android" ]; then + android_fte > /dev/null 2>&1 + cflags+=("-DANDROID -pthreads -fexceptions -fPIC -frtti -fsigned-char -D_FILE_OFFSET_BITS=64 -Wno-invalid-command-line-argument -Wno-unused-command-line-argument") + cflags+=("-I$(dirname $NDK_BUILD)/sources/cxx-stl/llvm-libc++/include") + cflags+=("-I$(dirname $NDK_BUILD)/sources/cxx-stl/llvm-libc++abi/include") +fi + +if [ "$platform" == "ios" ] || [ "$platform" == "ios-simulator" ]; then + if [ "$host" != "Darwin" ]; then + echo "error: Cannot generate pkgconfig file for iPhoneOS or iPhoneSimulator on '$host'" >&2 + exit 1 + fi + + if [ "$platform" == "ios" ]; then + ios_sdk_path="$(xcrun -sdk iphoneos -show-sdk-path)" + cflags+=("-arch arm64") + cflags+=("-target arm64-apple-ios") + cflags+=("-Wno-unguarded-availability-new") + cflags+=("-miphoneos-version-min=$IPHONEOS_VERSION_MIN") + elif [ "$platform" == "ios-simulator" ]; then + ios_sdk_path="$(xcrun -sdk iphonesimulator -show-sdk-path)" + cflags+=("-arch $arch") + cflags+=("-mios-simulator-version-min=$IPHONEOS_VERSION_MIN") + fi + cflags+=("-iframeworkwithsysroot /System/Library/Frameworks") + cflags+=("-isysroot $ios_sdk_path/") + cflags+=("-F $ios_sdk_path/System/Library/Frameworks/") + cflags+=("-fembed-bitcode") +fi + +export CFLAGS="${cflags[@]}" +export LDFLAGS="${ldflags[@]}" +export DEPENDENCIES="${dependencies[@]}" +export VERSION="$version" +export LIB_DIRECTORY="$lib_directory" +export INCLUDE_DIRECTORY="$include_directory" + +rm -f "$output" + +if ! cat "$input" | mush > "$output"; then + exit $? +fi + +echo "Wrote pkgconfig file to '$output'" diff --git a/bin/install.sh b/bin/install.sh index feb89315be..850a03d056 100755 --- a/bin/install.sh +++ b/bin/install.sh @@ -234,7 +234,6 @@ function _build_cli { local test_headers=() if [[ -z "$ignore_header_mtimes" ]]; then test_headers+=("$(find "$src"/cli/*.hh 2>/dev/null)") - test_headers+=("$(ls "$src"/*.hh)") fi test_headers+=("$src"/../VERSION.txt) local newest_mtime=0 @@ -487,10 +486,10 @@ function _prebuild_ios_simulator_main () { function _prepare { echo "# preparing directories..." local arch="$(host_arch)" - rm -rf "$SOCKET_HOME"/{lib$d,src,bin,include,objects,api} + rm -rf "$SOCKET_HOME"/{lib$d,src,bin,include,objects,api,pkgconfig} rm -rf "$SOCKET_HOME"/{lib$d,objects}/"$arch-desktop" - mkdir -p "$SOCKET_HOME"/{lib$d,src,bin,include,objects,api} + mkdir -p "$SOCKET_HOME"/{lib$d,src,bin,include,objects,api,pkgconfig} mkdir -p "$SOCKET_HOME"/{lib$d,objects}/"$arch-desktop" if [[ "$host" = "Darwin" ]]; then @@ -572,6 +571,13 @@ function _install { exit 1 fi + if [ "$host" == "Linux" ]; then + echo "# copying pkgconfig to $SOCKET_HOME/pkgconfig" + rm -rf "$SOCKET_HOME/pkgconfig" + mkdir -p "$SOCKET_HOME/pkgconfig" + cp -rfp "$BUILD_DIR/$arch-$platform/pkgconfig"/* "$SOCKET_HOME/pkgconfig" + fi + if [ "$platform" == "desktop" ]; then echo "# copying js api to $SOCKET_HOME/api" mkdir -p "$SOCKET_HOME/api" @@ -897,7 +903,6 @@ function onsignal () { exit "$status" } -_check_compiler_features _prepare cd "$BUILD_DIR" || exit 1 @@ -966,6 +971,7 @@ if [[ "$host" == "Win32" ]]; then wait $_compile_libuv_pid fi +_check_compiler_features _build_runtime_library _build_cli & pids+=($!) diff --git a/bin/ldflags.sh b/bin/ldflags.sh index 915efe0d83..4d4eee4919 100755 --- a/bin/ldflags.sh +++ b/bin/ldflags.sh @@ -113,9 +113,7 @@ if [[ "$host" = "Darwin" ]]; then ldflags+=("-ldl") elif [[ "$host" = "Linux" ]]; then ldflags+=("-ldl") - if [ -z "$BUILDING_SSC_CLI" ]; then - ldflags+=($(pkg-config --libs gtk+-3.0 webkit2gtk-4.1)) - fi + ldflags+=($(pkg-config --libs gtk+-3.0 webkit2gtk-4.1)) elif [[ "$host" = "Win32" ]]; then if [[ -n "$DEBUG" ]]; then # https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-170 diff --git a/bin/mush.sh b/bin/mush.sh new file mode 100755 index 0000000000..e0c61742c8 --- /dev/null +++ b/bin/mush.sh @@ -0,0 +1,176 @@ +#!/usr/bin/env bash + +## +# Mustache templates for bash (https://github.com/jwerle/mush) +# +# The MIT License (MIT) +# +# Copyright (c) 2013 Joseph Werle +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +## + +mush_version () { + echo "0.1.4" +} + +mush_usage () { + echo "usage: mush [-ehV] [-f ] [-o ]" + + if [ "$1" = "1" ]; then + echo + echo "examples:" + echo " $ cat file.ms | FOO=BAR mush" + echo " $ VALUE=123 mush -f file.ms -o file" + echo " $ echo \"Today's date is {{DATE}}\" | DATE=\`date +%D\` mush" + echo " $ cat ./template.ms | VAR=VALUE mush" + echo + echo "options:" + echo " -f, --file file to parse" + echo " -o, --out output file" + echo " -e, --escape escapes html html entities" + echo " -h, --help display this message" + echo " -V, --version output version" + fi +} + +mush () { + # shellcheck disable=SC2034 + local SELF="$0" + # shellcheck disable=SC2034 + local NULL=/dev/null + # shellcheck disable=SC2034 + local STDIN=0 + local STDOUT=1 + local STDERR=2 + local LEFT_DELIM="{{" + local RIGHT_DELIM="}}" + # shellcheck disable=SC2034 + local INDENT_LEVEL=" " + local ESCAPE=0 + local ENV="" + local out=">&$STDOUT" + + ENV="$(env)" + + ## parse opts + while true; do + arg="$1" + + if [ "" = "$1" ]; then + break; + fi + + if [ "${arg:0:1}" != "-" ]; then + shift + continue + fi + + case $arg in + -f|--file) + file="$2"; + shift 2; + ;; + -o|--out) + out="> $2"; + shift 2; + ;; + -e|--escape) + ESCAPE=1 + shift + ;; + -h|--help) + mush_usage 1 + exit 1 + ;; + -V|--version) + mush_version + exit 0 + ;; + *) + { + echo "unknown option \`$arg'" + } >&$STDERR + mush_usage + exit 1 + ;; + esac + done + + ## read each line + while IFS= read -r line; do + printf '%q\n' "${line}" | { + ## read each ENV variable + echo "$ENV" | { + while read -r var; do + ## split each ENV variable by '=' + ## and parse the line replacing + ## occurrence of the key with + ## guarded by the values of + ## `LEFT_DELIM' and `RIGHT_DELIM' + ## with the value of the variable + case "$var" in + (*"="*) + key=${var%%"="*} + val=${var#*"="*} + ;; + + (*) + key=$var + val= + ;; + esac + + line="${line//${LEFT_DELIM}$key${RIGHT_DELIM}/$val}" + done + + if [ "1" = "$ESCAPE" ]; then + line="${line//&/&}" + line="${line//\"/"}" + line="${line//\/>}" + fi + + ## output to stdout + echo "$line" | { + ## parse undefined variables + sed -e "s#${LEFT_DELIM}[A-Za-z]*${RIGHT_DELIM}##g" | \ + ## parse comments + sed -e "s#${LEFT_DELIM}\!.*${RIGHT_DELIM}##g" + }; + } + }; + done +} + + +if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then + export -f mush +else + if [ ! -t 0 ]; then + eval "mush $out" + elif [ -n "$file" ]; then + eval "cat $file | mush $out" + elif (( $# > 0 )); then + mush "$@" + else + mush_usage + exit 1 + fi + exit $? +fi diff --git a/bin/publish-npm-modules.sh b/bin/publish-npm-modules.sh index a1ad05c1cc..74f8bca420 100755 --- a/bin/publish-npm-modules.sh +++ b/bin/publish-npm-modules.sh @@ -174,6 +174,10 @@ if (( !only_top_level )); then cp -rf "$SOCKET_HOME/src"/* "$SOCKET_HOME/packages/$package/src" cp -rf "$SOCKET_HOME/include"/* "$SOCKET_HOME/packages/$package/include" + if test -d "$SOCKET_HOME/pkgconfig"; then + cp -rf "$SOCKET_HOME/pkgconfig" "$SOCKET_HOME/packages/$package/pkgconfig" + fi + # don't copy debug files, too large rm -rf $SOCKET_HOME/lib/*-android/objs-debug cp -rf $SOCKET_HOME/lib/*-android "$SOCKET_HOME/packages/$package/lib" diff --git a/socket-runtime.pc.in b/socket-runtime.pc.in new file mode 100644 index 0000000000..a608c699f2 --- /dev/null +++ b/socket-runtime.pc.in @@ -0,0 +1,7 @@ +Name: socket-runtime +Version: {{VERSION}} +Description: Build and package lean, fast, native desktop and mobile applications using the web technologies you already know. +URL: https://github.com/socketsupply/socket +Requires: {{DEPENDENCIES}} +Libs: -L{{LIB_DIRECTORY}} -lsocket-runtime -luv {{LDFLAGS}} +Cflags: -I{{INCLUDE_DIRECTORY}} {{CFLAGS}}