Last active
January 3, 2021 10:36
-
-
Save pgaskin/6af44db4ac6b7fa538d8acc85ff67dcc to your computer and use it in GitHub Desktop.
Deprecated, use https://github.com/pgaskin/pulseaudio-win32 instead.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FROM opensuse/tumbleweed AS mingw32 | |
RUN zypper --non-interactive addrepo https://download.opensuse.org/repositories/windows:mingw:win32/openSUSE_Tumbleweed/windows:mingw:win32.repo && \ | |
zypper --non-interactive --gpg-auto-import-keys refresh | |
RUN zypper --non-interactive install \ | |
wget m4 git-core meson bsdtar gzip xmlstarlet \ | |
mingw32-filesystem mingw32-cross-gcc mingw32-cross-gcc-c++ mingw32-cross-binutils mingw32-cross-pkgconf && \ | |
zypper clean | |
FROM i386/alpine AS wine | |
ENV WINEDEBUG="-all" \ | |
WINEDLLOVERRIDES="mscoree,mshtml=" \ | |
WINEARCH="win32" \ | |
WINEPREFIX="/opt/wine" | |
RUN apk add --no-cache wine ncurses freetype | |
FROM wine AS inno-tmp | |
RUN apk add --no-cache xvfb ca-certificates | |
RUN set -x; \ | |
export DISPLAY=:0; \ | |
Xvfb :0 -screen 0 1024x768x16 & sleep .5 && \ | |
wineboot --init && \ | |
wget -q http://files.jrsoftware.org/is/6/innosetup-6.1.2.exe && \ | |
wine innosetup-6.1.2.exe /SP- /VERYSILENT /ALLUSERS /SUPPRESSMSGBOXES && \ | |
rm innosetup-6.1.2.exe && \ | |
wineboot --shutdown && \ | |
pkill Xvfb && sleep .5 | |
FROM wine AS inno | |
RUN touch /bin/iscc && \ | |
chmod +x /bin/iscc && \ | |
echo '#!/bin/sh' >> /bin/iscc && \ | |
echo 'wine "C:\\Program Files\\Inno Setup 6\\ISCC.exe" "$*"' >> /bin/iscc | |
COPY --from=inno-tmp ${WINEPREFIX} ${WINEPREFIX} | |
FROM mingw32 AS build-pulseaudio-tmp | |
RUN zypper --non-interactive install \ | |
intltool gettext-tools mingw32-libsndfile-devel mingw32-libintl-devel mingw32-win_iconv-devel mingw32-pcre-devel \ | |
orc mingw32-libspeex-devel mingw32-liborc-devel mingw32-libtool && \ | |
zypper clean | |
RUN mkdir /src | |
RUN wget -qO /src/linux-mingw-w64-32bit.txt https://raw.githubusercontent.com/mesonbuild/meson/master/cross/linux-mingw-w64-32bit.txt | |
RUN git clone https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git /src/pulseaudio && \ | |
git -c advice.detachedHead=false -C /src/pulseaudio checkout 8f6029077a0c18f4d12105e9bd8c093c25ad7b38 | |
RUN sed -i 's/privlibdir = .*/privlibdir = bindir/' /src/pulseaudio/meson.build | |
RUN meson setup \ | |
--cross-file /src/linux-mingw-w64-32bit.txt \ | |
-Dtests=false \ | |
-Ddatabase=simple \ | |
-Drunning-from-build-tree=false \ | |
-Dlegacy-database-entry-format=false \ | |
-Dprefix=/pulseaudio \ | |
-Dbindir=/pulseaudio \ | |
-Dlibdir=/pulseaudio \ | |
-Dsysconfdir=/pulseaudio \ | |
-Dmodlibexecdir=/pulseaudio \ | |
-Dbluez5=false \ | |
/build/pulseaudio /src/pulseaudio | |
RUN ninja -C /build/pulseaudio | |
RUN meson install -C /build/pulseaudio | |
FROM mingw32 AS build-pulseaudio-polish | |
COPY --from=build-pulseaudio-tmp /pulseaudio /pulseaudio | |
RUN rm -r \ | |
# static libraries | |
/pulseaudio/*.a \ | |
# development files | |
/pulseaudio/pkgconfig /pulseaudio/include /pulseaudio/cmake /pulseaudio/share/vala \ | |
# manual pages | |
/pulseaudio/share/man \ | |
# shell completion | |
/pulseaudio/share/bash-completion /pulseaudio/share/zsh \ | |
# extra locales | |
/pulseaudio/share/locale \ | |
# configuration files (these won't even be loaded due to the fixed paths) | |
/pulseaudio/pulse \ | |
# misc scripts (not compatible with windows) | |
/pulseaudio/pa-info && \ | |
rmdir /pulseaudio/share | |
RUN echo '#!/bin/bash' >> /deps.sh && \ | |
echo 'set -eo pipefail' >> /deps.sh && \ | |
echo 'xml() { xmlstarlet sel -N p="http://linux.duke.edu/metadata/repo" -N m="http://linux.duke.edu/metadata/common" -N r="http://linux.duke.edu/metadata/rpm" -t -v "$1" ; }' >> /deps.sh && \ | |
echo 'repomd="$(wget -qO- "$1/repodata/repomd.xml" | xml "/p:repomd/p:data[@type=\"primary\"]/p:location/@href")"' >> /deps.sh && \ | |
echo 'repopk="$(wget -qO- "$1/$repomd" | zcat -)"' >> /deps.sh && \ | |
echo 'dlls_builtin="$(xml "/m:metadata/m:package[m:name=\"mingw32-runtime\"]/m:format/r:provides/r:entry/@name" <<< "$repopk" | sed -En "s/mingw32\(lib:(.+)\)/\1.dll/p")"' >> /deps.sh && \ | |
echo 'while true; do' >> /deps.sh && \ | |
echo ' dlls_deps="$(find "$2" -maxdepth 1 \( -name "*.exe" -o -name "*.dll" \) -exec i686-w64-mingw32-objdump --private-headers {} \; | sed -En "s/.*DLL Name: ([^ ]+).*/\\1/p" | sort | uniq)"' >> /deps.sh && \ | |
echo ' dlls_have="$(find "$2" -maxdepth 1 -name "*.dll" -exec basename {} \; )"' >> /deps.sh && \ | |
echo ' dll="$({ grep -ivxFf <(cat <<< "$dlls_have") -f <(cat <<< "$dlls_builtin") <<< "$dlls_deps" || true; } | head -n1)"' >> /deps.sh && \ | |
echo ' test -n "$dll" || break' >> /deps.sh && \ | |
echo ' pkg="$(xml "/m:metadata/m:package[m:format/r:provides/r:entry/@name=\"mingw32($(tr "[A-Z]" "[a-z]" <<< "$dll"))\"][last()]/m:location/@href" <<< "$repopk" || true)"' >> /deps.sh && \ | |
echo ' test -n "$pkg" || { echo "Error: No package for $dll." >&2; exit 1; }' >> /deps.sh && \ | |
echo ' wget -qO- "$1/$pkg" | rpm2cpio | bsdtar -xvf - -s "|.*/||" -C "$2" ./usr/i686-w64-mingw32/sys-root/mingw/bin/$dll' >> /deps.sh && \ | |
echo 'done' >> /deps.sh | |
RUN bash deps.sh "https://download.opensuse.org/repositories/windows:/mingw:/win32/openSUSE_Tumbleweed" /pulseaudio | |
FROM wine AS build-pulseaudio-icon | |
COPY --from=build-pulseaudio-polish /pulseaudio /pulseaudio | |
RUN apk add --no-cache inkscape imagemagick xvfb unzip | |
RUN echo '<?xml version="1.0" encoding="UTF-8"?><svg width="48" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink"> <metadata> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> <dc:title/> </cc:Work> </rdf:RDF> </metadata> <defs> <linearGradient id="f" x1="585" x2="585" y1="390.61" y2="85.377" gradientTransform="matrix(.15426 0 0 .15349 -67.321 -12.481)" gradientUnits="userSpaceOnUse"> <stop offset="0"/> <stop stop-color="#141413" offset="1"/> </linearGradient> <linearGradient id="h" x1="585" x2="585" y1="390.61" y2="85.377" gradientTransform="matrix(.15426 0 0 .15349 -67.321 -12.482)" gradientUnits="userSpaceOnUse" xlink:href="#d"/> <linearGradient id="d"> <stop stop-color="#fff" stop-opacity=".361" offset="0"/> <stop stop-color="#fff" stop-opacity="0" offset="1"/> </linearGradient> <linearGradient id="g" x1="532" x2="667.5" y1="131.41" y2="357.41" gradientTransform="matrix(.15426 0 0 .15349 -67.32 -12.482)" gradientUnits="userSpaceOnUse" xlink:href="#d"/> </defs> <rect x="1.0162" y="1.2747" width="45.815" height="45.586" ry="8.0042" stroke="url(#f)" stroke-linecap="round" stroke-width="1.2311"/> <g transform="matrix(1.2366 0 0 1.2305 -5.7556 -1.4643)" fill="#729fcf"> <path d="m28.81 20.75a4.81 4.81 0 1 1-9.62 0 4.81 4.81 0 1 1 9.62 0z"/> <path d="m21.496 11.326c-4.169 1.107-7.243 4.907-7.243 9.422 0 4.516 3.074 8.32 7.243 9.426-3.007-1.35-5.17-5.063-5.17-9.426s2.163-8.072 5.17-9.422zm5.009 0c3.007 1.35 5.169 5.06 5.169 9.422 0 4.363-2.162 8.076-5.17 9.426 4.17-1.107 7.244-4.91 7.244-9.426 0-4.515-3.075-8.315-7.243-9.422z"/> <path d="m20.09 6.034c-6.51 1.728-11.312 7.662-11.312 14.713s4.8 12.991 11.31 14.72c-4.696-2.108-8.072-7.907-8.072-14.72s3.376-12.605 8.072-14.713zm7.821 0c4.696 2.108 8.072 7.9 8.072 14.713s-3.376 12.612-8.072 14.72c6.51-1.729 11.31-7.669 11.31-14.72s-4.8-12.985-11.31-14.713z"/> </g> <path d="m9.0615 1.9221c-4.1085 0-7.3947 3.2655-7.3947 7.353v29.58c0 4.0874 3.2866 7.3578 7.3947 7.3578h29.724c4.1079 0 7.3947-3.2702 7.3947-7.3578v-29.58c0-4.0874-3.2862-7.353-7.3947-7.353z" fill="url(#linearGradient2395)" stroke-width=".15387"/> <path d="m44.978 17.3c-5.9275 6.3225-12.02 6.8205-20.998 6.8205-8.8379 0-15.552 4.1974-21.112 9.5307v5.2032c0 3.564 2.7856 6.1587 6.1944 6.1587l29.724 0.61886c3.7938 0 6.1896-3.0025 6.1896-6.7774l0.0023-21.555z" fill="url(#g)" fill-rule="evenodd" stroke-width=".15387"/> <path d="m9.0615 2.5024c-3.7948 0-6.8114 2.9976-6.8114 6.7727v29.58c0 3.7749 3.0176 6.7774 6.8114 6.7774h29.724c3.7938 0 6.8114-3.0025 6.8114-6.7774v-29.58c0-3.775-3.0167-6.7727-6.8114-6.7727z" fill="none" stroke="url(#h)" stroke-linecap="round" stroke-width="1.231"/></svg>' > /pulseaudio-flat.svg | |
RUN echo '<?xml version="1.0" encoding="UTF-8"?><svg width="48" height="48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink"> <metadata> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> <dc:title/> </cc:Work> </rdf:RDF> </metadata> <defs> <linearGradient id="f" x1="585" x2="585" y1="390.61" y2="85.377" gradientTransform="matrix(.15426 0 0 .15349 -67.321 -12.481)" gradientUnits="userSpaceOnUse"> <stop offset="0"/> <stop stop-color="#141413" offset="1"/> </linearGradient> <linearGradient id="h" x1="585" x2="585" y1="390.61" y2="85.377" gradientTransform="matrix(.15426 0 0 .15349 -67.321 -12.482)" gradientUnits="userSpaceOnUse" xlink:href="#d"/> <linearGradient id="d"> <stop stop-color="#fff" stop-opacity=".361" offset="0"/> <stop stop-color="#fff" stop-opacity="0" offset="1"/> </linearGradient> <linearGradient id="g" x1="532" x2="667.5" y1="131.41" y2="357.41" gradientTransform="matrix(.15426 0 0 .15349 -67.32 -12.482)" gradientUnits="userSpaceOnUse" xlink:href="#d"/> </defs> <rect x="1.0162" y="1.2747" width="45.815" height="45.586" ry="8.0042" stroke="url(#f)" stroke-linecap="round" stroke-width="1.2311"/> <g transform="matrix(1.2366 0 0 1.2305 -5.7556 -1.4643)" fill="#99cbf3"> <path d="m29.488 20.75c0 2.6565-2.832 5.6158-5.4884 5.6158s-5.3034-2.9593-5.3034-5.6158c0-1.4861 0.46107-2.6891 1.1926-3.594 2.8076-3.4732 9.5993-2.5565 9.5993 3.594z"/> <path d="m22.304 10.513c-4.169 1.107-8.8603 5.7197-8.8603 10.235 0 4.516 4.6913 9.1329 8.8603 10.239-4.1409-4.5935-5.7168-5.7883-5.7168-10.151s0.87811-4.4139 5.7168-10.322zm3.3923 0c2.0475 2.0513 5.8028 6.4863 5.8028 10.848 0 4.363-2.6456 4.7688-6.6131 9.6253 4.17-1.107 9.6698-5.7229 9.6698-10.239 0-4.515-4.6915-9.1277-8.8595-10.235z"/> <path d="m20.09 6.034c-6.51 1.728-12.929 7.662-12.929 14.713s6.417 12.991 12.927 14.72c-3.9559-3.2857-8.8805-7.907-8.8805-14.72s4.6779-11.055 8.8805-14.713zm7.821 0c3.7708 2.7279 8.8803 7.9 8.8803 14.713s-5.2328 11.558-8.8803 14.72c6.51-1.729 12.928-7.669 12.928-14.72s-6.4176-12.985-12.928-14.713z"/> </g> <path d="m9.0615 1.9221c-4.1085 0-7.3947 3.2655-7.3947 7.353v29.58c0 4.0874 3.2866 7.3578 7.3947 7.3578h29.724c4.1079 0 7.3947-3.2702 7.3947-7.3578v-29.58c0-4.0874-3.2862-7.353-7.3947-7.353z" fill="url(#linearGradient2395)" stroke-width=".15387"/> <path d="m44.978 17.3c-5.9275 6.3225-12.02 6.8205-20.998 6.8205-8.8379 0-15.552 4.1974-21.112 9.5307v5.2032c0 3.564 2.7856 6.1587 6.1944 6.1587l29.724 0.61886c3.7938 0 6.1896-3.0025 6.1896-6.7774l0.0023-21.555z" fill="url(#g)" fill-rule="evenodd" stroke-width=".15387"/> <path d="m9.0615 2.5024c-3.7948 0-6.8114 2.9976-6.8114 6.7727v29.58c0 3.7749 3.0176 6.7774 6.8114 6.7774h29.724c3.7938 0 6.8114-3.0025 6.8114-6.7774v-29.58c0-3.775-3.0167-6.7727-6.8114-6.7727z" fill="none" stroke="url(#h)" stroke-linecap="round" stroke-width="1.231"/></svg>' > /pulsaudio-flat-fat.svg | |
RUN set -x; \ | |
export DISPLAY=:0; \ | |
Xvfb :0 -screen 0 1024x768x16 & sleep .5 && \ | |
inkscape -w 16 -h 16 --export-filename=/pulseaudio-flat.16.png /pulseaudio-flat-fat.svg && \ | |
inkscape -w 32 -h 32 --export-filename=/pulseaudio-flat.32.png /pulseaudio-flat-fat.svg && \ | |
inkscape -w 48 -h 48 --export-filename=/pulseaudio-flat.48.png /pulseaudio-flat-fat.svg && \ | |
inkscape -w 64 -h 64 --export-filename=/pulseaudio-flat.64.png /pulseaudio-flat.svg && \ | |
inkscape -w 96 -h 96 --export-filename=/pulseaudio-flat.96.png /pulseaudio-flat.svg && \ | |
inkscape -w 128 -h 128 --export-filename=/pulseaudio-flat.96.png /pulseaudio-flat.svg && \ | |
convert /pulseaudio-flat.*.png /pulseaudio.ico && \ | |
rm /pulseaudio-flat.svg /pulseaudio-flat.*.png && \ | |
pkill Xvfb && sleep .5 | |
RUN wget -O /reshack.zip http://www.angusj.com/resourcehacker/resource_hacker.zip && \ | |
unzip /reshack.zip ResourceHacker.exe -d / && \ | |
rm /reshack.zip | |
RUN set -x; \ | |
export DISPLAY=:0; \ | |
Xvfb :0 -screen 0 1024x768x16 & sleep .5 && \ | |
wine 'Z:/ResourceHacker.exe' -open 'Z:\pulseaudio\pulseaudio.exe' -save 'Z:\pulseaudio\pulseaudio.exe' -action addskip -res 'Z:\pulseaudio.ico' -mask ICONGROUP,MAINICON, && \ | |
pkill Xvfb && sleep .5 | |
FROM mingw32 AS build-pulseaudio | |
COPY --from=build-pulseaudio-icon /pulseaudio /pulseaudio | |
RUN bsdtar -acf /pulseaudio.zip -C / pulseaudio | |
FROM inno AS build-pasetup | |
COPY --from=build-pulseaudio /pulseaudio /pulseaudio | |
# TODO: make a wrapper so it can run as a proper service with reduced permissions, maybe connect with a unix socket by default on recent win10 versions | |
RUN echo -en '\ | |
[Setup] \n\ | |
AppName=PulseAudio \n\ | |
AppVersion=14.0 \n\ | |
UninstallDisplayName=PulseAudio \n\ | |
AppPublisher=freedesktop.org \n\ | |
AppPublisherURL=https://www.freedesktop.org \n\ | |
AppSupportURL=https://www.freedesktop.org/software/pulseaudio \n\ | |
DefaultDirName={autopf}\PulseAudio \n\ | |
DisableDirPage=yes \n\ | |
DisableProgramGroupPage=yes \n\ | |
DisableReadyPage=yes \n\ | |
MinVersion=6.1sp1 \n\ | |
OutputBaseFilename=pasetup \n\ | |
PrivilegesRequired=admin \n\ | |
WizardStyle=classic \n\ | |
Uninstallable=IsComponentSelected('"'"'uninstall'"'"') \n\ | |
UninstallDisplayIcon={app}\pulseaudio.exe \n\ | |
SourceDir=pulseaudio \n\ | |
OutputDir=.. \n\ | |
\n\ | |
[Types] \n\ | |
Name: "full"; Description: "Full installation" \n\ | |
Name: "minimal"; Description: "Minimal installation" \n\ | |
Name: "custom"; Description: "Custom installation"; Flags: iscustom \n\ | |
\n\ | |
[Components] \n\ | |
Name: "pulseaudio"; Description: "PulseAudio"; Types: full minimal custom; Flags: fixed \n\ | |
Name: "service"; Description: "System service"; Types: full \n\ | |
Name: "uninstall"; Description: "Uninstall support"; Types: full minimal custom \n\ | |
\n\ | |
[Files] \n\ | |
Source: "*"; DestDir: "{app}"; Flags: recursesubdirs \n\ | |
\n\ | |
[Run] \n\ | |
Filename: "{sys}\\schtasks.exe"; Parameters: "/End /TN PulseAudio"; StatusMsg: "Stopping service if running"; Flags: runhidden; Components: service \n\ | |
Filename: "{sys}\\taskkill.exe"; Parameters: "/F /IM pulseaudio.exe"; StatusMsg: "Stopping process if running"; Flags: runhidden; Components: service \n\ | |
Filename: "{sys}\\schtasks.exe"; Parameters: "/Delete /TN PulseAudio /F"; StatusMsg: "Deleting service if exists"; Flags: runhidden; Components: service \n\ | |
Filename: "{sys}\\schtasks.exe"; Parameters: "/Create /TN PulseAudio /RU ""NT AUTHORITY\SYSTEM"" /SC ONSTART /TR ""\\""{app}\pulseaudio.exe\\"" \\""--disallow-exit\\"" \\""--exit-idle-time=-1\\"" \\""--load=module-native-protocol-tcp auth-anonymous=1\\"" \\""--load=module-waveout\\"" \\""--log-target=file:{app}\\pulseaudio.log\\"""" /F"; StatusMsg: "Registering service"; Flags: runhidden runascurrentuser; Components: service \n\ | |
Filename: "{sys}\\schtasks.exe"; Parameters: "/Run /TN PulseAudio"; StatusMsg: "Starting service"; Flags: runhidden; Components: service \n\ | |
Filename: "{sys}\\netsh.exe"; Parameters: "firewall set portopening protocol=TCP port=4713 name=PulseAudio mode=ENABLE"; StatusMsg: "Adding firewall exception for tcp/4713"; Flags: runhidden runascurrentuser; Components: service \n\ | |
\n\ | |
[UninstallDelete] \n\ | |
Type: files; Name: "{app}\pulseaudio.log" \n\ | |
\n\ | |
[UninstallRun] \n\ | |
Filename: "{sys}\\schtasks.exe"; Parameters: "/End /TN PulseAudio"; Flags: runhidden; Components: service \n\ | |
Filename: "{sys}\\taskkill.exe"; Parameters: "/F /IM pulseaudio.exe"; Flags: runhidden; Components: service \n\ | |
Filename: "{sys}\\schtasks.exe"; Parameters: "/Delete /TN PulseAudio /F"; Flags: runhidden; Components: service \n\ | |
Filename: "{sys}\\netsh.exe"; Parameters: "firewall delete portopening protocol=TCP port=4713"; Flags: runhidden runascurrentuser; Components: service \n\ | |
\n\ | |
[Code] \n\ | |
function PrepareToInstall(var NeedsRestart: Boolean): String; \n\ | |
var \n\ | |
ResultCode: Integer; \n\ | |
begin \n\ | |
Exec(ExpandConstant('"'"'{sys}\\taskkill.exe'"'"'), '"'"'/F /IM pulseaudio.exe'"'"', '"'"''"'"', SW_HIDE, ewWaitUntilTerminated, ResultCode); \n\ | |
end; \n\ | |
\n\ | |
' | sed -Ee 's/^(\t| )//g' -e 's/ ?$/\r/g' | tee /pasetup.iss | |
RUN iscc 'Z:\pasetup.iss' | |
FROM scratch AS final-tmp | |
COPY --from=build-pulseaudio /pulseaudio.zip / | |
COPY --from=build-pasetup /pasetup.exe / | |
FROM scratch AS final | |
COPY --from=final-tmp / / | |
# docker build . && docker save "$(docker build --quiet .)" | tar -xOf - --wildcards '*/layer.tar' | tar xf - |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment