Compare commits

...

23 Commits

Author SHA1 Message Date
Andrew Eikum
b4969b6b2e update vkd3d-proton to v2.3.1-39-gec5b4cce 2021-06-02 12:56:12 -05:00
Andrew Eikum
d19df7e1e8 update wine 2021-06-02 10:55:48 -05:00
Liam Middlebrook
99276ff00f proton: Copy DLLs provided by the NVIDIA driver into prefix
The upcoming NVIDIA 470 driver series will introduce a DLL (nvngx.dll)
for the support of NVIDIA DLSS in Proton. This change adds logic for
discovering the location of DLL files provided by the NVIDIA driver, and
copies them to C:\Windows\System32\

Reviewed-by: Adam Moss <amoss@nvidia.com>
2021-06-02 10:55:48 -05:00
Liam Middlebrook
9e555b222c dxvk-nvapi: Add to Proton
Add https://github.com/jp7677/dxvk-nvapi as a submodule. dxvk-nvapi will
not be copied into Proton prefixes by default, but instead will be
controlled via the environment variable PROTON_ENABLE_NVAPI. This is
done to avoid any potential adverse effects of the nvapi DLL existing
in cases where an application may require a function that is not
implemented by dxvk-nvapi.

This new functionality can be enabled by setting the following environment
variable to a value of `1`:
    `PROTON_ENABLE_NVAPI`

This functionality is needed in order to support DLSS within Proton.

Reviewed-by: Adam Moss <amoss@nvidia.com>
2021-06-02 10:40:59 -05:00
Andrew Eikum
aeecd6e2e9 proton: Use DXVK's DXGI by default 2021-06-02 10:40:59 -05:00
Andrew Eikum
c3102a9fa2 update dxvk to v1.8.1-137-gf4cbc9ae 2021-06-02 10:40:59 -05:00
Andrew Eikum
517d9edf1a Makefile: Don't consider proton-sdk tags for build name 2021-06-02 10:40:59 -05:00
Giovanni Mascellani
c6fa32fcff
docker: Install Capstone development files. 2021-05-27 16:40:49 +02:00
Andrew Eikum
0a5eb64509 update wine 2021-05-21 10:58:34 -05:00
Andrew Eikum
6a945cf0d6 update dxvk to v1.8.1-84-gc5108006 2021-05-21 10:15:42 -05:00
Andrew Eikum
3bcd985ee1 proton: Add PROTON_CRASH_REPORT_DIR runtime config
CW-Bug-Id: 18905
2021-05-21 10:13:39 -05:00
Renaud Lepage
657105b1eb proton: Assume STEAM_COMPAT_CLIENT_INSTALL_PATH is always set 2021-05-21 10:13:38 -05:00
Rémi Bernon
29f66cc1fd
docker: Add python3-pefile package to SDK image. 2021-05-21 10:23:02 +02:00
Rémi Bernon
1ece01b6cc
docker: Don't install tini, it's already there now. 2021-05-21 10:23:02 +02:00
Rémi Bernon
f93d5a355a
docker: Install libxpresent-dev packages. 2021-05-21 10:23:02 +02:00
Rémi Bernon
1bcc015a0e
docker: Bump steamrt version to 0.20210505.0. 2021-05-21 10:23:02 +02:00
Andrew Eikum
9bbfa41b86 update wine 2021-05-17 10:00:09 -05:00
Andrew Eikum
cb02bf9963 update dxvk 2021-05-14 12:18:44 -05:00
Andrew Eikum
976573ffae update vkd3d-proton to v2.3.1-8-g8734589e 2021-05-14 12:18:44 -05:00
Paul Gofman
f6b1410ab6 build: Fixup PE section headers.
For FH4.
2021-05-14 12:18:44 -05:00
Andrew Eikum
42fc3f48cc Handle steampipe quirks in deploy builds 2021-05-14 12:18:44 -05:00
Andrew Eikum
73847480a7 Don't ship filenames with colons in them 2021-05-14 12:18:44 -05:00
Andrew Eikum
3e8f844095 Don't ship proton dist files in a tarball anymore 2021-05-14 12:18:44 -05:00
16 changed files with 401 additions and 68 deletions

3
.gitmodules vendored
View File

@ -31,3 +31,6 @@
[submodule "OpenXR-SDK"] [submodule "OpenXR-SDK"]
path = OpenXR-SDK path = OpenXR-SDK
url = https://github.com/KhronosGroup/OpenXR-SDK url = https://github.com/KhronosGroup/OpenXR-SDK
[submodule "dxvk-nvapi"]
path = dxvk-nvapi
url = https://github.com/jp7677/dxvk-nvapi

View File

@ -17,7 +17,7 @@ STEAM_DIR := $(HOME)/.steam/root
BUILD_DIR := $(_build_name) BUILD_DIR := $(_build_name)
ifeq ($(build_name),) ifeq ($(build_name),)
DEPLOY_DIR := $(shell git describe --tags --always) DEPLOY_DIR := $(shell git describe --tags --always --exclude proton-sdk*)
else else
DEPLOY_DIR := $(_build_name) DEPLOY_DIR := $(_build_name)
endif endif
@ -124,17 +124,20 @@ proton: configure
install: configure install: configure
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) STEAM_DIR=/vagrant/ install' vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) STEAM_DIR=/vagrant/ install'
mkdir -p $(STEAM_DIR)/compatibilitytools.d/ mkdir -p $(STEAM_DIR)/compatibilitytools.d/
rm -rf $(STEAM_DIR)/compatibilitytools.d/$(_build_name)/files/ #remove proton's internal files, but preserve user_settings etc from top-level
cp -Rf --no-dereference --preserve=mode,links vagrant_share/compatibilitytools.d/$(_build_name) $(STEAM_DIR)/compatibilitytools.d/ cp -Rf --no-dereference --preserve=mode,links vagrant_share/compatibilitytools.d/$(_build_name) $(STEAM_DIR)/compatibilitytools.d/
echo "Proton installed to your local Steam installation" echo "Proton installed to your local Steam installation"
redist: configure redist: configure
mkdir -p vagrant_share/$(DEPLOY_DIR) mkdir -p vagrant_share/$(DEPLOY_DIR)
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) redist && cp $(BUILD_DIR)/redist/* /vagrant/$(DEPLOY_DIR)' rm -rf vagrant_share/$(DEPLOY_DIR)/*
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) redist && cp -Rf $(BUILD_DIR)/redist/* /vagrant/$(DEPLOY_DIR)'
echo "Proton build available at vagrant_share/$(DEPLOY_DIR)" echo "Proton build available at vagrant_share/$(DEPLOY_DIR)"
deploy: configure deploy: configure
mkdir -p vagrant_share/$(DEPLOY_DIR)-deploy mkdir -p vagrant_share/$(DEPLOY_DIR)-deploy
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) deploy && cp $(BUILD_DIR)/deploy/* /vagrant/$(DEPLOY_DIR)-deploy' rm -rf vagrant_share/$(DEPLOY_DIR)-deploy/*
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) deploy && cp -Rf $(BUILD_DIR)/deploy/* /vagrant/$(DEPLOY_DIR)-deploy'
echo "Proton deployed to vagrant_share/$(DEPLOY_DIR)-deploy" echo "Proton deployed to vagrant_share/$(DEPLOY_DIR)-deploy"
module: configure module: configure
@ -142,6 +145,7 @@ module: configure
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) module=$(module) module && \ vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) module=$(module) module && \
cp -f $(BUILD_DIR)/obj-wine32/dlls/$(module)/$(module)$(MODULE_SFX)* /vagrant/$(module)/lib/wine/ && \ cp -f $(BUILD_DIR)/obj-wine32/dlls/$(module)/$(module)$(MODULE_SFX)* /vagrant/$(module)/lib/wine/ && \
cp -f $(BUILD_DIR)/obj-wine64/dlls/$(module)/$(module)$(MODULE_SFX)* /vagrant/$(module)/lib64/wine/ && \ cp -f $(BUILD_DIR)/obj-wine64/dlls/$(module)/$(module)$(MODULE_SFX)* /vagrant/$(module)/lib64/wine/ && \
find /vagrant/$(module)/ -type f -name "*.dll" -printf "%p\0" | xargs --verbose -0 -r -P8 -n3 proton/make/pefixup.py && \
if [ -e $(BUILD_DIR)/obj-wine64/dlls/$(module)/$(module).so ]; then \ if [ -e $(BUILD_DIR)/obj-wine64/dlls/$(module)/$(module).so ]; then \
cp -f $(BUILD_DIR)/obj-wine32/dlls/$(module)/$(module).so /vagrant/$(module)/lib/wine/ && \ cp -f $(BUILD_DIR)/obj-wine32/dlls/$(module)/$(module).so /vagrant/$(module)/lib/wine/ && \
cp -f $(BUILD_DIR)/obj-wine64/dlls/$(module)/$(module).so /vagrant/$(module)/lib64/wine/; \ cp -f $(BUILD_DIR)/obj-wine64/dlls/$(module)/$(module).so /vagrant/$(module)/lib64/wine/; \
@ -152,31 +156,41 @@ dxvk: configure
mkdir -p vagrant_share/dxvk/lib/wine/dxvk/ mkdir -p vagrant_share/dxvk/lib/wine/dxvk/
mkdir -p vagrant_share/dxvk/lib64/wine/dxvk/ mkdir -p vagrant_share/dxvk/lib64/wine/dxvk/
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) dxvk && \ vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) dxvk && \
cp -f $(BUILD_DIR)/dist/dist/lib/wine/dxvk/*.dll /vagrant/dxvk/lib/wine/dxvk/ && \ cp -f $(BUILD_DIR)/dist/files/lib/wine/dxvk/*.dll /vagrant/dxvk/lib/wine/dxvk/ && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/dxvk/*.dll /vagrant/dxvk/lib64/wine/dxvk/' cp -f $(BUILD_DIR)/dist/files/lib64/wine/dxvk/*.dll /vagrant/dxvk/lib64/wine/dxvk/ && \
find /vagrant/dxvk/ -type f -name "*.dll" -printf "%p\0" | xargs --verbose -0 -r -P8 -n3 proton/make/pefixup.py'
dxvk-nvapi: configure
mkdir -p vagrant_share/dxvk-nvapi/lib/wine/nvapi/
mkdir -p vagrant_share/dxvk-nvapi/lib64/wine/nvapi/
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) dxvk-nvapi && \
cp -f $(BUILD_DIR)/dist/files/lib/wine/nvapi/*.dll /vagrant/dxvk-nvapi/lib/wine/nvapi/ && \
cp -f $(BUILD_DIR)/dist/files/lib64/wine/nvapi/*.dll /vagrant/dxvk-nvapi/lib64/wine/nvapi/ && \
find /vagrant/dxvk-nvapi/ -type f -name "*.dll" -printf "%p\0" | xargs --verbose -0 -r -P8 -n3 proton/make/pefixup.py'
vkd3d-proton: configure vkd3d-proton: configure
mkdir -p vagrant_share/vkd3d-proton/lib/wine/vkd3d-proton/ mkdir -p vagrant_share/vkd3d-proton/lib/wine/vkd3d-proton/
mkdir -p vagrant_share/vkd3d-proton/lib64/wine/vkd3d-proton/ mkdir -p vagrant_share/vkd3d-proton/lib64/wine/vkd3d-proton/
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) vkd3d-proton && \ vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) vkd3d-proton && \
cp -f $(BUILD_DIR)/dist/dist/lib/wine/vkd3d-proton/*.dll /vagrant/vkd3d-proton/lib/wine/vkd3d-proton/ && \ cp -f $(BUILD_DIR)/dist/files/lib/wine/vkd3d-proton/*.dll /vagrant/vkd3d-proton/lib/wine/vkd3d-proton/ && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/vkd3d-proton/*.dll /vagrant/vkd3d-proton/lib64/wine/vkd3d-proton/' cp -f $(BUILD_DIR)/dist/files/lib64/wine/vkd3d-proton/*.dll /vagrant/vkd3d-proton/lib64/wine/vkd3d-proton/ && \
find /vagrant/vkd3d-proton/ -type f -name "*.dll" -printf "%p\0" | xargs --verbose -0 -r -P8 -n3 proton/make/pefixup.py'
lsteamclient: configure lsteamclient: configure
mkdir -p vagrant_share/lsteamclient/lib/wine mkdir -p vagrant_share/lsteamclient/lib/wine
mkdir -p vagrant_share/lsteamclient/lib64/wine mkdir -p vagrant_share/lsteamclient/lib64/wine
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) lsteamclient && \ vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) lsteamclient && \
cp -f $(BUILD_DIR)/dist/dist/lib/wine/lsteamclient.dll.so /vagrant/lsteamclient/lib/wine && \ cp -f $(BUILD_DIR)/dist/files/lib/wine/lsteamclient.dll.so /vagrant/lsteamclient/lib/wine && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/lsteamclient.dll.so /vagrant/lsteamclient/lib64/wine' cp -f $(BUILD_DIR)/dist/files/lib64/wine/lsteamclient.dll.so /vagrant/lsteamclient/lib64/wine'
vrclient: configure vrclient: configure
mkdir -p vagrant_share/vrclient/lib/wine mkdir -p vagrant_share/vrclient/lib/wine
mkdir -p vagrant_share/vrclient/lib64/wine mkdir -p vagrant_share/vrclient/lib64/wine
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) vrclient && \ vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) vrclient && \
cp -f $(BUILD_DIR)/dist/dist/lib/wine/vrclient.dll.so /vagrant/vrclient/lib/wine && \ cp -f $(BUILD_DIR)/dist/files/lib/wine/vrclient.dll.so /vagrant/vrclient/lib/wine && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/vrclient_x64.dll.so /vagrant/vrclient/lib64/wine' cp -f $(BUILD_DIR)/dist/files/lib64/wine/vrclient_x64.dll.so /vagrant/vrclient/lib64/wine'
wineopenxr: configure wineopenxr: configure
mkdir -p vagrant_share/wineopenxr/lib64/wine mkdir -p vagrant_share/wineopenxr/lib64/wine
vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) wineopenxr && \ vagrant ssh -c 'make -C $(BUILD_DIR)/ $(UNSTRIPPED) $(CCACHE_FLAG) wineopenxr && \
cp -f $(BUILD_DIR)/dist/dist/lib64/wine/wineopenxr.dll.so /vagrant/wineopenxr/lib64/wine' cp -f $(BUILD_DIR)/dist/files/lib64/wine/wineopenxr.dll.so /vagrant/wineopenxr/lib64/wine'

View File

@ -270,12 +270,14 @@ the Wine prefix. Removing the option will revert to the previous behavior.
| | <tt>PROTON_LOG_DIR</tt> | Output log files into the directory specified. Defaults to your home directory. | | | <tt>PROTON_LOG_DIR</tt> | Output log files into the directory specified. Defaults to your home directory. |
| | <tt>PROTON_DUMP_DEBUG_COMMANDS</tt> | When running a game, Proton will write some useful debug scripts for that game into `$PROTON_DEBUG_DIR/proton_$USER/`. | | | <tt>PROTON_DUMP_DEBUG_COMMANDS</tt> | When running a game, Proton will write some useful debug scripts for that game into `$PROTON_DEBUG_DIR/proton_$USER/`. |
| | <tt>PROTON_DEBUG_DIR</tt> | Root directory for the Proton debug scripts, `/tmp` by default. | | | <tt>PROTON_DEBUG_DIR</tt> | Root directory for the Proton debug scripts, `/tmp` by default. |
| | <tt>PROTON_CRASH_REPORT_DIR</tt> | Write crash logs into this directory. Does not clean up old logs, so may eat all your disk space eventually. |
| <tt>wined3d</tt> | <tt>PROTON_USE_WINED3D</tt> | Use OpenGL-based wined3d instead of Vulkan-based DXVK for d3d11, d3d10, and d3d9. | | <tt>wined3d</tt> | <tt>PROTON_USE_WINED3D</tt> | Use OpenGL-based wined3d instead of Vulkan-based DXVK for d3d11, d3d10, and d3d9. |
| <tt>nod3d11</tt> | <tt>PROTON_NO_D3D11</tt> | Disable <tt>d3d11.dll</tt>, for d3d11 games which can fall back to and run better with d3d9. | | <tt>nod3d11</tt> | <tt>PROTON_NO_D3D11</tt> | Disable <tt>d3d11.dll</tt>, for d3d11 games which can fall back to and run better with d3d9. |
| <tt>nod3d10</tt> | <tt>PROTON_NO_D3D10</tt> | Disable <tt>d3d10.dll</tt> and <tt>dxgi.dll</tt>, for d3d10 games which can fall back to and run better with d3d9. | | <tt>nod3d10</tt> | <tt>PROTON_NO_D3D10</tt> | Disable <tt>d3d10.dll</tt> and <tt>dxgi.dll</tt>, for d3d10 games which can fall back to and run better with d3d9. |
| <tt>noesync</tt> | <tt>PROTON_NO_ESYNC</tt> | Do not use eventfd-based in-process synchronization primitives. | | <tt>noesync</tt> | <tt>PROTON_NO_ESYNC</tt> | Do not use eventfd-based in-process synchronization primitives. |
| <tt>nofsync</tt> | <tt>PROTON_NO_FSYNC</tt> | Do not use futex-based in-process synchronization primitives. (Automatically disabled on systems with no `FUTEX_WAIT_MULTIPLE` support.) | | <tt>nofsync</tt> | <tt>PROTON_NO_FSYNC</tt> | Do not use futex-based in-process synchronization primitives. (Automatically disabled on systems with no `FUTEX_WAIT_MULTIPLE` support.) |
| <tt>noxim</tt> | <tt>PROTON_NO_XIM</tt> | Enabled by default. Do not attempt to use XIM (X Input Methods) support. XIM support is known to cause crashes with libx11 older than version 1.7. | | <tt>noxim</tt> | <tt>PROTON_NO_XIM</tt> | Enabled by default. Do not attempt to use XIM (X Input Methods) support. XIM support is known to cause crashes with libx11 older than version 1.7. |
| <tt>enablenvapi</tt> | <tt>PROTON_ENABLE_NVAPI</tt> | Enable NVIDIA's NVAPI GPU support library. |
| <tt>nativevulkanloader</tt> | | Use the Vulkan loader shipped with the game instead of Proton's built-in Vulkan loader. This breaks VR support, but is required by a few games. | | <tt>nativevulkanloader</tt> | | Use the Vulkan loader shipped with the game instead of Proton's built-in Vulkan loader. This breaks VR support, but is required by a few games. |
| <tt>forcelgadd</tt> | <tt>PROTON_FORCE_LARGE_ADDRESS_AWARE</tt> | Force Wine to enable the LARGE_ADDRESS_AWARE flag for all executables. Enabled by default. | | <tt>forcelgadd</tt> | <tt>PROTON_FORCE_LARGE_ADDRESS_AWARE</tt> | Force Wine to enable the LARGE_ADDRESS_AWARE flag for all executables. Enabled by default. |
| <tt>heapdelayfree</tt>| <tt>PROTON_HEAP_DELAY_FREE</tt>| Delay freeing some memory, to work around application use-after-free bugs. | | <tt>heapdelayfree</tt>| <tt>PROTON_HEAP_DELAY_FREE</tt>| Delay freeing some memory, to work around application use-after-free bugs. |

2
Vagrantfile vendored
View File

@ -77,7 +77,7 @@ Vagrant.configure(2) do |config|
#install host build-time dependencies #install host build-time dependencies
apt-get update apt-get update
apt-get install -y ccache texinfo gpgv2 gnupg2 git docker-ce docker-ce-cli containerd.io \ apt-get install -y ccache texinfo gpgv2 gnupg2 git docker-ce docker-ce-cli containerd.io \
fontforge-nox python-debian python-pip fontforge-nox python-debian python-pip python3-pefile
#install adobe font devkit to build source san hans #install adobe font devkit to build source san hans
pip install afdko pip install afdko

View File

@ -113,7 +113,7 @@ endif
## ##
DST_BASE := $(OBJ)/dist DST_BASE := $(OBJ)/dist
DST_DIR := $(DST_BASE)/dist DST_DIR := $(DST_BASE)/files
DST_LIBDIR32 := $(DST_DIR)/lib DST_LIBDIR32 := $(DST_DIR)/lib
DST_LIBDIR64 := $(DST_DIR)/lib64 DST_LIBDIR64 := $(DST_DIR)/lib64
DEPLOY_DIR := ./deploy DEPLOY_DIR := ./deploy
@ -155,6 +155,7 @@ CARGO_BUILD_ARG := --release
COMPAT_MANIFEST_TEMPLATE := $(SRCDIR)/compatibilitytool.vdf.template COMPAT_MANIFEST_TEMPLATE := $(SRCDIR)/compatibilitytool.vdf.template
LICENSE := $(SRCDIR)/dist.LICENSE LICENSE := $(SRCDIR)/dist.LICENSE
OFL_LICENSE := $(SRCDIR)/fonts/liberation-fonts/LICENSE OFL_LICENSE := $(SRCDIR)/fonts/liberation-fonts/LICENSE
STEAMPIPE_FIXUPS_PY := $(SRCDIR)/steampipe_fixups.py
GECKO_VER := 2.47.2 GECKO_VER := 2.47.2
GECKO32_TARBALL := wine-gecko-$(GECKO_VER)-x86.tar.xz GECKO32_TARBALL := wine-gecko-$(GECKO_VER)-x86.tar.xz
@ -241,8 +242,9 @@ DIST_TARGETS := $(DIST_COPY_TARGETS) $(DIST_OVR32) $(DIST_OVR64) \
$(DIST_GECKO32) $(DIST_GECKO64) $(DIST_WINEMONO) \ $(DIST_GECKO32) $(DIST_GECKO64) $(DIST_WINEMONO) \
$(DIST_COMPAT_MANIFEST) $(DIST_LICENSE) $(DIST_TOOLMANIFEST) $(DIST_OFL_LICENSE) $(DIST_FONTS) $(DIST_COMPAT_MANIFEST) $(DIST_LICENSE) $(DIST_TOOLMANIFEST) $(DIST_OFL_LICENSE) $(DIST_FONTS)
DEPLOY_COPY_TARGETS := $(DIST_COPY_TARGETS) $(DIST_VERSION) $(DIST_LICENSE) $(DIST_TOOLMANIFEST) $(DIST_OFL_LICENSE) BASE_COPY_TARGETS := $(DIST_COPY_TARGETS) $(DIST_VERSION) $(DIST_LICENSE) $(DIST_TOOLMANIFEST) $(DIST_OFL_LICENSE) $(DST_DIR)
REDIST_COPY_TARGETS := $(DEPLOY_COPY_TARGETS) $(DIST_COMPAT_MANIFEST) DEPLOY_COPY_TARGETS := $(BASE_COPY_TARGETS) $(STEAMPIPE_FIXUPS_PY)
REDIST_COPY_TARGETS := $(BASE_COPY_TARGETS) $(DIST_COMPAT_MANIFEST)
$(DIST_LICENSE): $(LICENSE) $(DIST_LICENSE): $(LICENSE)
cp -a $< $@ cp -a $< $@
@ -331,24 +333,20 @@ dist: $(DIST_TARGETS) all-dist dist_wineopenxr | $(DST_DIR)
echo `date '+%s'` `GIT_DIR=$(abspath $(SRCDIR)/.git) git describe --tags` > $(DIST_VERSION) echo `date '+%s'` `GIT_DIR=$(abspath $(SRCDIR)/.git) git describe --tags` > $(DIST_VERSION)
deploy: dist | $(filter-out dist deploy install redist,$(MAKECMDGOALS)) deploy: dist | $(filter-out dist deploy install redist,$(MAKECMDGOALS))
mkdir -p $(DEPLOY_DIR) && \ mkdir -p $(DEPLOY_DIR)
cp -a $(DEPLOY_COPY_TARGETS) $(DEPLOY_DIR) && \ cp -af --no-dereference --preserve=mode,links $(DEPLOY_COPY_TARGETS) $(DEPLOY_DIR)
tar -C $(DST_DIR) -c . > $(DEPLOY_DIR)/proton_dist.tar python3 $(STEAMPIPE_FIXUPS_PY) process $(DEPLOY_DIR)
@echo "Created deployment archive at "$(DEPLOY_DIR)"/proton_dist.tar"
install: dist | $(filter-out dist deploy install redist,$(MAKECMDGOALS)) install: dist | $(filter-out dist deploy install redist,$(MAKECMDGOALS))
if [ ! -d $(STEAM_DIR) ]; then echo >&2 "!! "$(STEAM_DIR)" does not exist, cannot install"; return 1; fi if [ ! -d $(STEAM_DIR) ]; then echo >&2 "!! "$(STEAM_DIR)" does not exist, cannot install"; return 1; fi
mkdir -p $(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME) mkdir -p $(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME)
cp -rf --no-dereference --preserve=mode,links $(DST_BASE)/* $(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME) cp -af --no-dereference --preserve=mode,links $(DST_BASE)/* $(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME)
cp -f $(DIST_VERSION) $(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME)/dist/
@echo "Installed Proton to "$(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME) @echo "Installed Proton to "$(STEAM_DIR)/compatibilitytools.d/$(BUILD_NAME)
@echo "You may need to restart Steam to select this tool" @echo "You may need to restart Steam to select this tool"
redist: dist | $(filter-out dist deploy install redist,$(MAKECMDGOALS)) redist: dist | $(filter-out dist deploy install redist,$(MAKECMDGOALS))
mkdir -p $(REDIST_DIR) mkdir -p $(REDIST_DIR)
cp -a $(REDIST_COPY_TARGETS) $(REDIST_DIR) cp -af --no-dereference --preserve=mode,links $(REDIST_COPY_TARGETS) $(REDIST_DIR)
tar -C $(DST_DIR) -c . | gzip -c -1 > $(REDIST_DIR)/proton_dist.tar.gz
@echo "Created redistribution tarball at "$(REDIST_DIR)"/proton_dist.tar.gz"
.PHONY: module32 module64 module .PHONY: module32 module64 module
@ -701,6 +699,32 @@ $(OBJ)/.dxvk-post-build32:
touch $@ touch $@
##
## dxvk-nvapi
##
DXVK_NVAPI_MESON_ARGS32 = \
--bindir=$(DXVK_NVAPI_DST32)/lib/wine/nvapi \
--cross-file=$(DXVK_NVAPI_OBJ32)/build-win32.txt
DXVK_NVAPI_MESON_ARGS64 = \
--bindir=$(DXVK_NVAPI_DST64)/lib64/wine/nvapi \
--cross-file=$(DXVK_NVAPI_OBJ64)/build-win64.txt
$(eval $(call rules-source,dxvk-nvapi,$(SRCDIR)/dxvk-nvapi))
$(eval $(call rules-meson,dxvk-nvapi,32))
$(eval $(call rules-meson,dxvk-nvapi,64))
$(OBJ)/.dxvk-nvapi-post-build64:
mkdir -p "$(DST_DIR)"/lib64/wine/nvapi
rm -f "$(DST_DIR)"/lib64/wine/nvapi/version && if test -e $(SRCDIR)/.git; then ( cd $(SRCDIR) && git submodule status -- dxvk-nvapi ) > "$(DST_DIR)"/lib64/wine/nvapi/version; fi
touch $@
$(OBJ)/.dxvk-nvapi-post-build32:
mkdir -p "$(DST_DIR)"/lib/wine/nvapi
rm -f "$(DST_DIR)"/lib/wine/nvapi/version && if test -e $(SRCDIR)/.git; then ( cd $(SRCDIR) && git submodule status -- dxvk-nvapi ) > "$(DST_DIR)"/lib/wine/nvapi/version; fi
touch $@
## ##
## vkd3d-proton ## vkd3d-proton
## ##

View File

@ -73,6 +73,14 @@ def setup_dll_symlinks(default_pfx_dir, dist_dir):
os.unlink(filename) os.unlink(filename)
make_relative_symlink(target, filename) make_relative_symlink(target, filename)
#steampipe can't handle filenames with colons, so we remove them here
#and restore them in the proton script
def fixup_drive_links(default_pfx_dir):
for walk_dir, dirs, files in os.walk(os.path.join(default_pfx_dir, "dosdevices")):
for dir_ in dirs:
if ":" in dir_:
os.remove(os.path.join(walk_dir, dir_))
def make_default_pfx(default_pfx_dir, dist_dir, runtime): def make_default_pfx(default_pfx_dir, dist_dir, runtime):
local_env = dict(os.environ) local_env = dict(os.environ)
@ -96,6 +104,7 @@ def make_default_pfx(default_pfx_dir, dist_dir, runtime):
env=local_env, check=True) env=local_env, check=True)
setup_dll_symlinks(default_pfx_dir, dist_dir) setup_dll_symlinks(default_pfx_dir, dist_dir)
fixup_drive_links(default_pfx_dir)
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys

View File

@ -1,4 +1,4 @@
STEAMRT_VERSION = 0.20210126.1 STEAMRT_VERSION = 0.20210505.0
STEAMRT_URLBASE = registry.gitlab.steamos.cloud STEAMRT_URLBASE = registry.gitlab.steamos.cloud
PROTONSDK_URLBASE = $(STEAMRT_URLBASE)/proton/soldier/sdk PROTONSDK_URLBASE = $(STEAMRT_URLBASE)/proton/soldier/sdk

View File

@ -52,9 +52,14 @@ RUN bash -c 'mkdir -p /usr/lib/ccache && ls /usr/bin/{,*-}{cc,c++,gcc,g++}{,-[0-
ENV PATH=/usr/lib/ccache:$PATH ENV PATH=/usr/lib/ccache:$PATH
RUN apt-get install -y \ RUN apt-get install -y \
tini \ libxpresent-dev \
libxpresent-dev:i386 \
python3-pefile \
libcapstone-dev \
libcapstone-dev:i386 \
&& rm -rf /opt/usr/share/doc /opt/usr/share/info /opt/usr/share/man \ && rm -rf /opt/usr/share/doc /opt/usr/share/info /opt/usr/share/man \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["/usr/bin/tini-static", "-s", "-g", "--"] ENTRYPOINT ["/usr/bin/tini-static", "-s", "-g", "--"]
CMD ["/bin/bash"] CMD ["/bin/bash"]

2
dxvk

@ -1 +1 @@
Subproject commit f8a4ca555a6e5d89f5162a042bbae550902f4e49 Subproject commit ed3aacadb27918e7988e479a275088a78e18cfa8

1
dxvk-nvapi Submodule

@ -0,0 +1 @@
Subproject commit fcd8ce2a0e5eef81148cedcb572fe6d1e667da94

27
make/pefixup.py Executable file
View File

@ -0,0 +1,27 @@
#!/usr/bin/env python3
import sys
import os
import stat
import pefile
for path in sys.argv[1:]:
pe = pefile.PE(path)
for section in pe.sections:
if section.Name.decode("utf-8")[0:5] == ".text":
section.Characteristics &= ~pefile.SECTION_CHARACTERISTICS['IMAGE_SCN_CNT_INITIALIZED_DATA']
section.Characteristics &= ~pefile.SECTION_CHARACTERISTICS['IMAGE_SCN_ALIGN_MASK']
pe.OPTIONAL_HEADER.CheckSum = pe.generate_checksum()
perm = stat.S_IMODE(os.stat(path).st_mode)
if (perm & stat.S_IWUSR) == 0:
os.chmod(path, perm | stat.S_IWUSR)
pe.write(path)
if (perm & stat.S_IWUSR) == 0:
os.chmod(path, perm)
print("Fixed up PE: ", path)

View File

@ -82,6 +82,14 @@ endif
$(1)-dist$(3): $$(OBJ)/.$(1)-dist$(3) $(1)-dist$(3): $$(OBJ)/.$(1)-dist$(3)
.INTERMEDIATE: $(1)-dist$(3) .INTERMEDIATE: $(1)-dist$(3)
ifeq ($(CONTAINER),)
$(1)-dist$(3): $$(OBJ)/.$(1)-fixup$(3)
$$(OBJ)/.$(1)-fixup$(3): $$(OBJ)/.$(1)-dist$(3)
cd $$($(2)_LIBDIR$(3)) && find -type f -name '*.dll' -printf '$$(DST_LIBDIR$(3))/%p\0' | xargs --verbose -0 -r -P8 -n3 $$(SRC)/make/pefixup.py
touch $$@
endif
all-dist$(3) $(1)-dist: $(1)-dist$(3) all-dist$(3) $(1)-dist: $(1)-dist$(3)
.PHONY: all-dist$(3) $(1)-dist .PHONY: all-dist$(3) $(1)-dist

200
proton
View File

@ -15,6 +15,16 @@ import subprocess
import sys import sys
import tarfile import tarfile
from ctypes import CDLL
from ctypes import POINTER
from ctypes import Structure
from ctypes import addressof
from ctypes import cast
from ctypes import c_int
from ctypes import c_char_p
from ctypes import c_void_p
from ctypes.util import find_library
from filelock import FileLock from filelock import FileLock
#To enable debug logging, copy "user_settings.sample.py" to "user_settings.py" #To enable debug logging, copy "user_settings.sample.py" to "user_settings.py"
@ -127,6 +137,83 @@ def try_get_game_library_dir():
return None return None
# Function to find the installed location of DLL files for use by Wine/Proton
# from the NVIDIA Linux driver
#
# See https://gitlab.steamos.cloud/steamrt/steam-runtime-tools/-/issues/71 for
# background on the chosen method of DLL discovery.
#
# On success, returns a str() of the absolute-path to the directory at which DLL
# files are stored
#
# On failure, returns None
def find_nvidia_wine_dll_dir():
libdl = CDLL(find_library("libdl"))
libglx_nvidia = CDLL("libGLX_nvidia.so.0")
if libdl is None or libglx_nvidia is None:
return None
# from dlinfo(3)
#
# struct link_map {
# ElfW(Addr) l_addr; /* Difference between the
# address in the ELF file and
# the address in memory */
# char *l_name; /* Absolute pathname where
# object was found */
# ElfW(Dyn) *l_ld; /* Dynamic section of the
# shared object */
# struct link_map *l_next, *l_prev;
# /* Chain of loaded objects */
#
# /* Plus additional fields private to the
# implementation */
# };
RTLD_DI_LINKMAP = 2
class link_map(Structure):
_fields_ = [("l_addr", c_void_p), ("l_name", c_char_p), ("l_ld", c_void_p)]
# from dlinfo(3)
#
# int dlinfo (void *restrict handle, int request, void *restrict info)
dlinfo_func = libdl.dlinfo
dlinfo_func.argtypes = c_void_p, c_int, c_void_p
dlinfo_func.restype = c_int
# Allocate a link_map object
glx_nvidia_info_ptr = POINTER(link_map)()
# Run dlinfo(3) on the handle to libGLX_nvidia.so.0, storing results at the
# address represented by glx_nvidia_info_ptr
if dlinfo_func(libglx_nvidia._handle,
RTLD_DI_LINKMAP,
addressof(glx_nvidia_info_ptr)) != 0:
return None
# Grab the contents our of our pointer
glx_nvidia_info = cast(glx_nvidia_info_ptr, POINTER(link_map)).contents
# Decode the path to our library to a str()
if glx_nvidia_info.l_name is None:
return None
try:
libglx_nvidia_path = os.fsdecode(glx_nvidia_info.l_name)
except UnicodeDecodeError:
return None
# Follow any symlinks to the actual file
libglx_nvidia_realpath = os.path.realpath(libglx_nvidia_path)
# Go to the relative path ./nvidia/wine from our library
nvidia_wine_dir = os.path.join(os.path.dirname(libglx_nvidia_realpath), "nvidia", "wine")
# Check that nvngx.dll exists here, or fail
if os.path.exists(os.path.join(nvidia_wine_dir, "nvngx.dll")):
return nvidia_wine_dir
return None
EXT2_IOC_GETFLAGS = 0x80086601 EXT2_IOC_GETFLAGS = 0x80086601
EXT2_IOC_SETFLAGS = 0x40086602 EXT2_IOC_SETFLAGS = 0x40086602
@ -149,14 +236,14 @@ def set_dir_casefold_bit(dir_path):
class Proton: class Proton:
def __init__(self, base_dir): def __init__(self, base_dir):
self.base_dir = base_dir + "/" self.base_dir = base_dir + "/"
self.dist_dir = self.path("dist/") self.dist_dir = self.path("files/")
self.bin_dir = self.path("dist/bin/") self.bin_dir = self.path("files/bin/")
self.lib_dir = self.path("dist/lib/") self.lib_dir = self.path("files/lib/")
self.lib64_dir = self.path("dist/lib64/") self.lib64_dir = self.path("files/lib64/")
self.fonts_dir = self.path("dist/share/fonts/") self.fonts_dir = self.path("files/share/fonts/")
self.wine_fonts_dir = self.path("dist/share/wine/fonts/") self.wine_fonts_dir = self.path("files/share/wine/fonts/")
self.version_file = self.path("version") self.version_file = self.path("version")
self.default_pfx_dir = self.path("dist/share/default_pfx/") self.default_pfx_dir = self.path("files/share/default_pfx/")
self.user_settings_file = self.path("user_settings.py") self.user_settings_file = self.path("user_settings.py")
self.wine_bin = self.bin_dir + "wine" self.wine_bin = self.bin_dir + "wine"
self.wineserver_bin = self.bin_dir + "wineserver" self.wineserver_bin = self.bin_dir + "wineserver"
@ -165,28 +252,34 @@ class Proton:
def path(self, d): def path(self, d):
return self.base_dir + d return self.base_dir + d
def need_tarball_extraction(self): def cleanup_legacy_dist(self):
'''Checks if the proton_dist tarball archive must be extracted. Returns true if extraction is needed, false otherwise''' old_dist_dir = self.path("dist/")
return not os.path.exists(self.dist_dir) or \ if os.path.exists(old_dist_dir):
not os.path.exists(self.path("dist/version")) or \ with self.dist_lock:
not filecmp.cmp(self.version_file, self.path("dist/version")) if os.path.exists(old_dist_dir):
shutil.rmtree(old_dist_dir)
def extract_tarball(self): def do_steampipe_fixups(self):
with self.dist_lock: fixups_json = self.path("steampipe_fixups.json")
if self.need_tarball_extraction(): fixups_mtime = self.path("files/steampipe_fixups_mtime")
if os.path.exists(self.dist_dir):
shutil.rmtree(self.dist_dir) if os.path.exists(fixups_json):
tar = None with self.dist_lock:
for sf in ["", ".xz", ".bz2", ".gz"]: import steampipe_fixups
if os.path.exists(self.path("proton_dist.tar" + sf)):
tar = tarfile.open(self.path("proton_dist.tar" + sf), mode="r:*") current_fixup_mtime = None
break if os.path.exists(fixups_mtime):
if not tar: with open(fixups_mtime, "r") as f:
log("No proton_dist tarball??") current_fixup_mtime = f.readline().strip()
sys.exit(1)
tar.extractall(path=self.dist_dir) new_fixup_mtime = getmtimestr(fixups_json)
tar.close()
try_copy(self.version_file, self.dist_dir) if current_fixup_mtime != new_fixup_mtime:
result_code = steampipe_fixups.do_restore(self.base_dir, fixups_json)
if result_code == 0:
with open(fixups_mtime, "w") as f:
f.write(new_fixup_mtime + "\n")
def missing_default_prefix(self): def missing_default_prefix(self):
'''Check if the default prefix dir is missing. Returns true if missing, false if present''' '''Check if the default prefix dir is missing. Returns true if missing, false if present'''
@ -432,16 +525,18 @@ class CompatData:
if not os.path.exists(self.prefix_dir + "/user.reg"): if not os.path.exists(self.prefix_dir + "/user.reg"):
self.copy_pfx() self.copy_pfx()
if not os.path.lexists(self.prefix_dir + "/dosdevices/c:"):
os.symlink("../drive_c", self.prefix_dir + "/dosdevices/c:")
if not os.path.lexists(self.prefix_dir + "/dosdevices/z:"):
os.symlink("/", self.prefix_dir + "/dosdevices/z:")
# collect configuration info # collect configuration info
if "STEAM_COMPAT_CLIENT_INSTALL_PATH" in os.environ: steamdir = os.environ["STEAM_COMPAT_CLIENT_INSTALL_PATH"]
#modern steam client sets this
steamdir = os.environ["STEAM_COMPAT_CLIENT_INSTALL_PATH"]
else:
#linux-only fallback, really shouldn't get here
steamdir = os.environ["HOME"] + ".steam/root/"
use_wined3d = "wined3d" in g_session.compat_config use_wined3d = "wined3d" in g_session.compat_config
use_dxvk_dxgi = "WINEDLLOVERRIDES" in g_session.env and "dxgi=n" in g_session.env["WINEDLLOVERRIDES"] use_dxvk_dxgi = not ("WINEDLLOVERRIDES" in g_session.env and "dxgi=b" in g_session.env["WINEDLLOVERRIDES"])
use_nvapi = 'enablenvapi' in g_session.compat_config
builtin_dll_copy = os.environ.get("PROTON_DLL_COPY", builtin_dll_copy = os.environ.get("PROTON_DLL_COPY",
#dxsetup redist #dxsetup redist
@ -486,6 +581,7 @@ class CompatData:
str(use_wined3d), str(use_wined3d),
str(use_dxvk_dxgi), str(use_dxvk_dxgi),
builtin_dll_copy, builtin_dll_copy,
str(use_nvapi),
)) ))
if old_ver == CURRENT_PREFIX_VERSION: if old_ver == CURRENT_PREFIX_VERSION:
@ -561,7 +657,6 @@ class CompatData:
dxvkfiles = ["dxvk_config", "d3d11", "d3d10", "d3d10core", "d3d10_1", "d3d9"] dxvkfiles = ["dxvk_config", "d3d11", "d3d10", "d3d10core", "d3d10_1", "d3d9"]
wined3dfiles = [] wined3dfiles = []
#if the user asked for dxvk's dxgi (dxgi=n), then copy it into place
if use_dxvk_dxgi: if use_dxvk_dxgi:
dxvkfiles.append("dxgi") dxvkfiles.append("dxgi")
else: else:
@ -580,6 +675,31 @@ class CompatData:
self.prefix_dir + "drive_c/windows/syswow64/" + f + ".dll") self.prefix_dir + "drive_c/windows/syswow64/" + f + ".dll")
g_session.dlloverrides[f] = "n" g_session.dlloverrides[f] = "n"
# If the user requested the NVAPI be available, copy it into place.
# If they didn't, clean up any stray nvapi DLLs.
if use_nvapi:
try_copy(g_proton.lib64_dir + "wine/nvapi/nvapi64.dll",
self.prefix_dir + "drive_c/windows/system32/nvapi64.dll")
try_copy(g_proton.lib_dir + "wine/nvapi/nvapi.dll",
self.prefix_dir + "drive_c/windows/syswow64/nvapi.dll")
g_session.dlloverrides["nvapi64"] = "n"
g_session.dlloverrides["nvapi"] = "n"
else:
nvapi64_dll = self.prefix_dir + "drive_c/windows/system32/nvapi64.dll"
nvapi32_dll = self.prefix_dir + "drive_c/windows/syswow64/nvapi.dll"
if os.path.exists(nvapi64_dll):
os.unlink(nvapi64_dll)
if os.path.exists(nvapi32_dll):
os.unlink(nvapi32_dll)
# Try to detect known DLLs that ship with the NVIDIA Linux Driver
# and add them into the prefix
nvidia_wine_dll_dir = find_nvidia_wine_dll_dir()
if nvidia_wine_dll_dir:
for dll in ["_nvngx.dll", "nvngx.dll"]:
try_copy(nvidia_wine_dll_dir + "/" + dll,
self.prefix_dir + "drive_c/windows/system32/" + dll)
try_copy(g_proton.lib64_dir + "wine/vkd3d-proton/d3d12.dll", try_copy(g_proton.lib64_dir + "wine/vkd3d-proton/d3d12.dll",
self.prefix_dir + "drive_c/windows/system32/d3d12.dll") self.prefix_dir + "drive_c/windows/system32/d3d12.dll")
try_copy(g_proton.lib_dir + "wine/vkd3d-proton/d3d12.dll", try_copy(g_proton.lib_dir + "wine/vkd3d-proton/d3d12.dll",
@ -745,6 +865,7 @@ class Session:
self.check_environment("PROTON_SET_GAME_DRIVE", "gamedrive") self.check_environment("PROTON_SET_GAME_DRIVE", "gamedrive")
self.check_environment("PROTON_NO_XIM", "noxim") self.check_environment("PROTON_NO_XIM", "noxim")
self.check_environment("PROTON_HEAP_DELAY_FREE", "heapdelayfree") self.check_environment("PROTON_HEAP_DELAY_FREE", "heapdelayfree")
self.check_environment("PROTON_ENABLE_NVAPI", "enablenvapi")
if "noesync" in self.compat_config: if "noesync" in self.compat_config:
self.env.pop("WINEESYNC", "") self.env.pop("WINEESYNC", "")
@ -784,6 +905,9 @@ class Session:
if "hidenvgpu" in self.compat_config: if "hidenvgpu" in self.compat_config:
self.env["WINE_HIDE_NVIDIA_GPU"] = "1" self.env["WINE_HIDE_NVIDIA_GPU"] = "1"
if "PROTON_CRASH_REPORT_DIR" in self.env:
self.env["WINE_CRASH_REPORT_DIR"] = self.env["PROTON_CRASH_REPORT_DIR"]
if "SteamGameId" in self.env: if "SteamGameId" in self.env:
if self.env["WINEDEBUG"] != "-all": if self.env["WINEDEBUG"] != "-all":
basedir = self.env.get("PROTON_LOG_DIR", os.environ["HOME"]) basedir = self.env.get("PROTON_LOG_DIR", os.environ["HOME"])
@ -972,8 +1096,8 @@ if __name__ == "__main__":
g_proton = Proton(os.path.dirname(sys.argv[0])) g_proton = Proton(os.path.dirname(sys.argv[0]))
if g_proton.need_tarball_extraction(): g_proton.cleanup_legacy_dist()
g_proton.extract_tarball() g_proton.do_steampipe_fixups()
g_compatdata = CompatData(os.environ["STEAM_COMPAT_DATA_PATH"]) g_compatdata = CompatData(os.environ["STEAM_COMPAT_DATA_PATH"])

116
steampipe_fixups.py Executable file
View File

@ -0,0 +1,116 @@
#!/usr/bin/env python3
#Steampipe doesn't support certain unix-y things which may be required by
#native Linux applications. This file will process a directory of Linux files
#and store the file properties into a manifest file. After a round trip through
#Steampipe, the original file properties can be restored using this same
#script.
import json
import os
import secrets
import stat
DEFAULT_MANIFEST_NAME = "steampipe_fixups.json"
def usage():
print("Usage:")
print("\t" + sys.argv[0] + "\tprepare\t<path to directory to process>\t[manifest output file]")
print("\t\tProcess the given path and output the manifest file to the given path, or <path/" + DEFAULT_MANIFEST_NAME + "> if unspecified.")
print("")
print("\t" + sys.argv[0] + "\trestore\t<path to directory to process>\t[manifest file]")
print("\t\tRestore the given path using the manifest file, or <path/" + DEFAULT_MANIFEST_NAME + "> if unspecified.")
empty_dirs = []
no_write_paths = []
def canonicalize(path, prefix):
return path.replace(prefix, "", 1).lstrip('/')
def process_dir(path):
for root, subdirs, files in os.walk(path):
if len(subdirs) == 0 and len(files) == 0:
empty_dirs.append(canonicalize(root, path))
for file_ in files:
this_file = os.path.join(root, file_)
stat_result = os.lstat(this_file)
if (stat_result.st_mode & stat.S_IWUSR) == 0:
no_write_paths.append(canonicalize(this_file, path))
return 0
def write_manifest(manifest):
out = open(manifest, "w")
json.dump(
{
"id": str(secrets.randbits(32)), #we need steampipe to update this file for every build
"empty_dirs": empty_dirs,
"no_write_paths": no_write_paths,
},
out,
indent = 4,
sort_keys = True
)
return 0
def do_process(path, manifest):
if os.path.exists(manifest):
os.remove(manifest)
ret = process_dir(path)
if ret != 0:
return ret
#output should be deterministic
empty_dirs.sort()
no_write_paths.sort()
ret = write_manifest(manifest)
if ret != 0:
return ret
return 0
def do_restore(path, manifest):
loaded = json.load(open(manifest, "r"))
empty_dirs = loaded["empty_dirs"]
no_write_paths = loaded["no_write_paths"]
for empty_dir in empty_dirs:
try:
os.makedirs(os.path.join(path, empty_dir))
except OSError:
#already exists
pass
for file_ in no_write_paths:
this_file = os.path.join(path, file_)
stat_result = os.lstat(this_file)
os.chmod(this_file,
stat_result.st_mode & ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH))
return 0
if __name__ == '__main__':
import sys
if len(sys.argv) < 3 or len(sys.argv) > 4:
usage()
sys.exit(1)
verb = sys.argv[1]
path = sys.argv[2]
if len(sys.argv) >= 4:
manifest = sys.argv[3]
else:
manifest = os.path.join(path, DEFAULT_MANIFEST_NAME)
if verb == "process":
sys.exit(do_process(path, manifest))
if verb == "restore":
sys.exit(do_restore(path, manifest))
usage()
sys.exit(1)

@ -1 +1 @@
Subproject commit 3ed3526332f53d7d35cf1b685fa8096b01f26ff0 Subproject commit ec5b4ccecf799e7593dd3c6e8b13dc4f04e77228

2
wine

@ -1 +1 @@
Subproject commit f94b0f7590d43bb3e6aefcc6e16cf69bffc25122 Subproject commit 5b82ac53192d32fe28516abf4161d2174817b164