Build Valve Proton in docker.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Andrey Arapov e10fe35d67
update script
2 months ago
data first commit 2 months ago
.dockerignore first commit 2 months ago
Dockerfile add wget back as it is required by dist target 2 months ago update readme 2 months ago
docker-compose.yml first commit 2 months ago
launch first commit 2 months ago update script 2 months ago

Build Proton in Docker

This image has all necessary dependencies for building the Proton.

Difference from official way of building Proton:

  • does not use VM;
  • does not rely on Steam runtime;
  • preconfigures ccache (incl. mingw32) to speed up the recompilation time;

1. Build this image and spawn in it

docker-compose build
docker-compose run --rm proton

2. Clone the Proton repository

git clone -b proton_3.16 proton
cd proton/
git submodule update --init

3. Configure your build environment

According to this FFMPEG is needed only for the WMA support in FAudio.

I will not build --with-ffmpeg in this example as it requires more changes.

./ --no-steam-runtime --build-name "Proton 3.16 My"

4. Configure and build the Proton

See what are the default targets should you like to make them one-by-one instead of all at once:

$ make help
Default targets      (make all):              faudio lsteamclient vrclient dxvk dist wine fonts

I prefer to build them one-by-one arch-by-arch since make all is trying to build lsteamclient and vrclient targets before building wine whilst both targets having wine as a build dependency. You can see it in build/makefile_base.mak file.

My preferred make order:

make -j$(getconf _NPROCESSORS_ONLN) cmake32
make -j$(getconf _NPROCESSORS_ONLN) cmake64

make -j$(getconf _NPROCESSORS_ONLN) faudio32
make -j$(getconf _NPROCESSORS_ONLN) faudio64

make -j$(getconf _NPROCESSORS_ONLN) wine32
make -j$(getconf _NPROCESSORS_ONLN) wine64

make -j$(getconf _NPROCESSORS_ONLN) dxvk

make -j$(getconf _NPROCESSORS_ONLN) lsteamclient32
make -j$(getconf _NPROCESSORS_ONLN) lsteamclient64

make -j$(getconf _NPROCESSORS_ONLN) vrclient32
make -j$(getconf _NPROCESSORS_ONLN) vrclient64

make -j$(getconf _NPROCESSORS_ONLN) dist
make -j$(getconf _NPROCESSORS_ONLN) fonts

After this you will get the result under ./dist directory. This is the Proton you have just built.

You can run make obj-wine32/Makefile and look in obj-wine32/config.log to see what is missing. DISABLED_SUBDIRS should be empty, otherwise you are going to miss some DLLs.

If you updated the dev dependencies or wine/ submodule repo and do not want wasting time recompiling the whole wine subrepo again, you can re-create Makefile rm obj-wine32/Makefile; make obj-wine32/Makefile, so next time you run make wine32 it will recompile only what is needed. The same applies to wine64.

5. Final steps

(Optional) You can archive your dist directory the same way Valve does:

$ tar -C ./dist/dist -c . | gzip -c -1 > ./dist/proton_dist.tar.gz

Copy your freshly built Proton to your Steam directory ~/.local/share/Steam/compatibilitytools.d/.

Since I am running Steam in a docker it has a custom home path ~/git/steam/data. This repo I have at ~/git/proton directory.

$ mkdir -p ~/git/steam/data/.local/share/Steam/compatibilitytools.d
$ rsync -avx --progress  ~/git/proton/data/proton/dist/ ~/git/steam/data/.local/share/Steam/compatibilitytools.d/proton-316-my/

At this point you are done building Proton from source code.

Now restart Steam, then go to Steam -> Settings -> Steam Play and pick your Proton 3.16 My from the compatibility tool list. This will restart Steam once more.



Tested on Proton 3.16

$ grep ^ .git/modules/*/HEAD .git/HEAD
.git/HEAD:ref: refs/heads/proton_3.16

Sanity checks

  • check there are no 64-bit libs under dist/dist/lib/ nor 32-bit libs under dist/dist/lib64/. This can happen when having issues with the Makefiles, e.g. unset FFMPEG_CROSS_LDFLAGS := -m32 in build/makefile_base.mak if building --with-ffmpeg:
  find dist/dist/lib/ -xdev -type f -exec sh -c "file '{}' | grep -vE 'ASCII|MS-DOS executable|PE32 executable|ELF 32-bit'" \;
  find dist/dist/lib64/ -xdev -type f -exec sh -c "file '{}' | grep -vE 'ASCII|MS-DOS executable|PE32\+ executable|ELF 64-bit'" \;
  • check ffmpeg (if built with --with-ffmpeg)
  ls -la dist/dist/lib{,64}/lib{avcodec,avutil,swresample}*
  • check xaudio2 (FAudio)
  ls -la dist/dist/lib{,64}/
  ls -la dist/dist/lib{,64}/wine/x3daudio1_{0..7}
  ls -la dist/dist/lib{,64}/wine/xactengine3_{0..7}
  ls -la dist/dist/lib{,64}/wine/xapofx1_{1..5}
  ls -la dist/dist/lib{,64}/wine/xaudio2_{0..9}

If xactengine3 is missing then apply,

  • check DXVK
  ls -la dist/dist/lib{,64}/wine/dxvk/*dll
  • check lsteamclient
  ls -la dist/dist/lib{,64}/wine/
  • check vrclient
  ls -la dist/dist/{lib/wine/,lib64/wine/}
  ls -la dist/dist/{lib/wine/fakedlls/vrclient.dll,lib64/wine/fakedlls/vrclient_x64.dll}


ccache is a compiler cache. It speeds up recompilation by caching previous compilations and detecting when the same compilation is being done again.

It is already installed in this docker image so no action is required from your side.

apt-get install ccache
echo 'export PATH="/usr/lib/ccache:$PATH"' | tee /home/user/.profile

No limit to the number of files and size of the cache:

ccache -F 0
ccache -M 0


ccache -s

Empty the cache and reset the stats:

ccache -C -z