export LANG='C.UTF-8'
export LANGUAGE="${LANG}"
+_sed () {
+ case "${system_name}" in
+ 'macos')
+ gsed "${@}"
+ ;;
+ *)
+ sed "${@}"
+ ;;
+ esac
+}
+
+_cpr () {
+ case "${system_name}" in
+ 'macos')
+ cp -R ${@}
+ ;;
+ *)
+ cp -R --preserve=timestamps ${@}
+ ;;
+ esac
+}
+
Common::noOp () {
true
}
printf '%s\n' "${file_path}"
fi
fi \
- | sed -e 's|/*$||'
+ | _sed -e 's|/*$||'
}
Common::grepLdd () {
- egrep ' => '
+ case "${system_name}" in
+ 'macos')
+ egrep '^\t/'
+ ;;
+ *)
+ egrep ' => '
+ ;;
+ esac
}
Common::stripLdd () {
- sed -e 's/ (0x[0-9a-f]*)$//;s/^.* => //'
+ case "${system_name}" in
+ 'macos')
+ _sed -e 's/^\t\(.*\) (compatibility version .*/\1/'
+ ;;
+ *)
+ _sed -e 's/ (0x[0-9a-f]*)$//;s/^.* => //'
+ ;;
+ esac
}
Multi::excludeLdd () {
'windows')
egrep -i '\.dll => [A-Z]:\\msys64\\'
;;
+ 'macos')
+ egrep -v '^\t/System/|^\t/usr/lib/'
+ ;;
esac
}
'windows')
ntldd --recursive "${exe_file}"
;;
+ 'macos')
+ otool -L "${exe_file}"
esac
}
'windows')
echo 'MS-Windows'
;;
+ *)
+ echo 'Default'
+ ;;
esac
}
'windows')
echo 'libgtk-win32-2.0-0.dll'
;;
+ 'macos')
+ echo 'libgtk-quartz-2.0.0.dylib'
+ ;;
esac
}
| xargs -n1 -P1 which \
| cut -f2 -d'/'
;;
+ 'macos')
+ echo 'usr/local'
esac
}
'windows')
echo 'lib'
;;
+ 'macos')
+ echo 'lib'
+ ;;
esac
}
local lib_prefix="${1}"
local gtk_theme_name="${2}"
- cat <<-EOF
- share/themes/${gtk_theme_name}/gtk-2.0
- share/icons/hicolor
- ${lib_prefix}/gdk-pixbuf-2.0
- ${lib_prefix}/gtk-2.0
- EOF
+ case "${system_name}" in
+ 'linux'|'windows')
+ cat <<-EOF
+ share/themes/${gtk_theme_name}/gtk-2.0
+ share/icons/hicolor
+ ${lib_prefix}/gdk-pixbuf-2.0
+ ${lib_prefix}/gtk-2.0
+ EOF
+ ;;
+ 'macos')
+ cat <<-EOF
+ share/icons/hicolor
+ share/locale
+ ${lib_prefix}/gdk-pixbuf-2.0
+ ${lib_prefix}/gtk-2.0
+ EOF
+ ;;
+ esac
case "${system_name}" in
'linux')
esac
}
+Multi::rewriteLoadersCache () {
+ local bundle_component_path="${1}"
+ local cache_file
+
+ find "${bundle_component_path}" \
+ -type f \
+ \( \
+ -name 'loaders.cache' \
+ -o -name 'immodules.cache' \
+ \) \
+ | while read cache_file
+ do
+ _sed \
+ -e 's|^"/[^"]*/lib/|"lib/|;s| "/[^"]*/share/| "share/|;/^# ModulesPath = /d;/^# Created by /d;/^#$/d' \
+ -i "${cache_file}"
+ done
+}
+
Multi::bundleGtkDepsFromFile () {
local lib_file="${1}"
+ local component_dir
+ local real_component_dir
+ local bundle_component_dir
lib_basename="$(basename "${lib_file}")"
for component_dir in $(Multi::getGtkDeps "${lib_prefix}" "${gtk_theme_name}")
do
- bundle_component_dir="$(echo "${component_dir}" | sed -e 's|^'"${lib_prefix}"'|lib|')"
+ bundle_component_dir="$(echo "${component_dir}" | _sed -e 's|^'"${lib_prefix}"'|lib|')"
if ! [ -e "${bundle_dir}/${bundle_component_dir}" ]
then
- mkdir --parents "${bundle_dir}/$(dirname "${bundle_component_dir}")"
+ real_component_dir="$(realpath "/${root_prefix}/${component_dir}")"
+
+ mkdir -p "${bundle_dir}/$(dirname "${bundle_component_dir}")"
+
+ _cpr -H -L \
+ "${real_component_dir}" \
+ "${bundle_dir}/${bundle_component_dir}"
- cp -H -r --preserve=timestamps \
- "/${root_prefix}/${component_dir}" \
+ touch -r \
+ "/${real_component_dir}" \
"${bundle_dir}/${bundle_component_dir}"
+
+ Multi::rewriteLoadersCache "${bundle_dir}/${bundle_component_dir}"
fi
done
fi
continue
fi
- cp --preserve=timestamps \
+ cp -H \
+ "${lib_file}" \
+ "${lib_dir}/${lib_basename}"
+
+ touch -r \
"${lib_file}" \
"${lib_dir}/${lib_basename}"
Multi::bundleGtkDepsFromFile "${lib_file}"
+
+ case "${system_name}" in
+ 'macos')
+ Multi::bundleLibFromFile "${lib_file}"
+ ;;
+ esac
done
}
find "${bundle_dir}/lib" \
-type f \
-name '*.a' \
- -exec rm {} \;
+ -exec rm -f {} \;
find "${bundle_dir}/lib" \
-type f \
-name '*.h' \
- -exec rm {} \;
+ -exec rm -f {} \;
find "${bundle_dir}/lib" \
-depth \
-type d \
- -exec rmdir --ignore-fail-on-non-empty {} \;
+ -exec rmdir {} \; \
+ || true
}
Linux::getRpath () {
local path_start="$(printf '%s' "${bundle_dir}" | wc -c)"
path_start="$((${path_start} + 1))"
- local exe_subdir="$(echo "${exe_dir}" | cut -c "${path_start}-" | sed -e 's|//*|/|;s|^/||')"
+ local exe_subdir="$(echo "${exe_dir}" | cut -c "${path_start}-" | _sed -e 's|//*|/|;s|^/||')"
local rpath_origin='$ORIGIN'
done
}
+Darwin::patchExe () {
+ local exe_file="${1}"
+
+ Multi::printLdd "${exe_file}" \
+ | Multi::filterLib \
+ | while read lib_file
+ do
+ new_path="$(echo "${lib_file}" | _sed -e 's|^/.*/lib/|@executable_path/lib/|')"
+ id_name="$(echo "${lib_file}" | _sed -e 's|.*/||g')"
+ chmod u+w,go-w "${exe_file}"
+ install_name_tool -change "${lib_file}" "${new_path}" "${exe_file}"
+ install_name_tool -id "${id_name}" "${exe_file}"
+ done
+}
+
+Darwin::patchLib () {
+ local lib_dir="${1}"
+ local exe_file
+
+ find "${lib_dir}" \
+ -type f \
+ \( \
+ -name '*.dylib' \
+ -o -name '*.so' \
+ \) \
+ | while read exe_file
+ do
+ Darwin::patchExe "${exe_file}"
+ chmod ugo-x "${exe_file}"
+ done
+}
+
Windows::listLibForManifest () {
local lib_dir="${1}"
case "${system_name}" in
'register')
- mkdir --parents "${registry_dir}"
+ mkdir -p "${registry_dir}"
Common::getPath "${exe_file}" > "${registry_dir}/$(uuidgen)"
exit
;;
'windows')
lib_action='Windows::writeManifest'
;;
+ 'macos')
+ exe_action='Darwin::patchExe'
+ lib_action='Darwin::patchLib'
+ ;;
*)
printf 'ERROR: unsupported system: %s\n' "${system_name}" >&2
exit 1
;;
esac
-mkdir --parents "${lib_dir}"
+mkdir -p "${lib_dir}"
if [ -d "${registry_dir}" ]
then