UWP Development Notes and Tips (Xbox) - worleydl
These notes provide guidance and tips for developing Universal Windows Platform (UWP) applications, particularly for deployment to an Xbox Series S/X in Developer Mode. They cover various aspects, including DLL dependencies, MinGW, OpenGL, SDL, and general UWP considerations.
Getting Started
- Clone Project: Clone the target project's source code repository.
- Review Build Config: Examine the existing build configuration (e.g., CMakeLists.txt, Visual Studio project files) to understand how the project is structured and built.
- Multithreaded DLL Runtime: Configure all project components to use the Multithreaded DLL runtime library (
/MDor/MDdin Visual Studio). Do not use the Multithreaded (/MT) runtime./MTis incompatible with UWP. All components must use the same runtime library. This setting is typically found in the project properties under "C/C++" -> "Code Generation" -> "Runtime Library".
It's been discovered you can utilize DLL's built with /MT with limited success.
DLL Dependencies
-
WINRT Compatibility: DLL dependencies often need to be built specifically for Windows Runtime (WINRT), the underlying technology of UWP. You can experiment by replacing non-WINRT DLLs one at a time to see if they cause issues.
-
Dependency Analysis:
-
dumpbin: If you encounter problems with dependent DLLs, use thedumpbinutility (available in a Visual Studio Developer Command Prompt) to analyze your executable and DLLs:dumpbin /DEPENDENTS [your_executable_or_dll.exe/dll]This command lists the DLLs that a given executable or DLL depends on.
-
Loader Snaps (gflags): For more detailed debugging information during local debugging, use the
gflagsutility (Global Flags Editor):- Run
gflags. - Go to the "Image File" tab.
- Enter the full name of your executable (e.g.,
uwp-project.exe). - Check the box labeled "Show loader snaps".
- Click "OK".
This will cause the debugger to output detailed information about DLL loading, which can help pinpoint issues.
- Run
-
-
VCRUNTIME140.dllvs.VCRUNTIME140_APP.dll: Pay close attention to the output ofdumpbin. Your UWP components should depend onVCRUNTIME140_APP.dll(note the_APPsuffix). If you see a dependency onVCRUNTIME140.dll(without_APP), it indicates a problem. The component is likely not built for UWP and will cause runtime errors on the Xbox.
The MinGW Solution
- Runtime Compatibility: Standard x64 DLLs built with Visual Studio often have runtime library conflicts in UWP. MinGW (Minimalist GNU for Windows) projects, however, typically include their own runtime DLLs, which can circumvent these issues. If you encounter problems with a Q"native" Visual Studio UWP project, consider using MinGW-compiled libraries or building the problematic components with MinGW.
Loading Restrictions
- DLL Load Paths: UWP applications on Xbox have restricted DLL loading paths. DLLs can typically only be loaded from:
- The application package itself (where your executable is).
- The
LocalStatefolder (used for application data). - Loading DLLs from the external drive (
E:\) does not appear to be supported.
CMake Dependencies
-
WINRT Configuration: If your project uses CMake and has dependencies with CMake configurations, you can configure them for WINRT using the following command:
cmake -S . -B build -G "Visual Studio 17 2022" -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0-S .: Specifies the source directory (current directory).-B build: Specifies the build directory (creates abuildfolder).-G "Visual Studio 17 2022": Specifies the generator (Visual Studio 2022).-DCMAKE_SYSTEM_NAME=WindowsStore: Crucially, this sets the target system to Windows Store (UWP).-DCMAKE_SYSTEM_VERSION=10.0: Specifies the Windows SDK version (10.0 is a common base version).
You can then open the generated
.slnfile in thebuildfolder or use CMake to build the project. Use these built libraries/DLLs as replacements for existing x64 libraries/DLLs in your main UWP project.
OpenGL Projects
-
Mesa-UWP:
- Obtain and build/install
aerisarns mesa-uwpproject: (https://github.com/aerisarn/mesa-uwp). This provides a UWP-compatible OpenGL implementation. Follow the project's README instructions carefully.
- Obtain and build/install
-
Include DLLs: In your final UWP application package, include the following DLLs (from the Mesa build):
libgallium_wgl.dlllibglapi.dllopengl32.dllz-1.dll(likely a zlib dependency)- Place these DLLs alongside your application's executable.
-
Link
opengl32.lib: If you are not using SDL or GLFW, you may need to explicitly link againstopengl32.libin your UWP project's linker settings. -
SDL (Optional): For SDL projects:
- Obtain and build
aerisarnsfork of SDL (https://github.com/aerisarn/SDL-uwp-gl). Build the WinRT project within the SDL solution. - Include
SDL2.libin your UWP project's linker settings (Additional Dependencies). - Include
SDL2.dllin your application package (alongside your executable).
- Obtain and build
SDL Notes
- Unexpected Keyboard: If you encounter unexpected keyboard behavior, check for calls to
SDL_StartTextInputin your code. This function can sometimes cause issues.
MinGW Projects
-
DLL/Implib Creation: Modify the MinGW makefile to produce a DLL (
.dll) and an import library (.lib). -
cv2pdb: Consider usingcv2pdb(Link unavailable - search for "cv2pdb github") to enable debugging MinGW code within Visual Studio. -
UWP Compatibility: MinGW libraries tend to be more UWP-friendly, but for SDL, you must configure the MinGW project to link against
aerisarn'sSDL fork (specifically, the VisualC-WinRT build). -
Modifying the Makefile:
- Find Executable Build: Locate the section in the makefile where the main executable is built.
- Add Flags: Add these flags to the linker command:
-shared: Creates a shared library (DLL).-Wl,--out-implib=$(B)/lib$(CLIENTBIN).lib: Creates an import library (.libfile) that you can link against in your Visual Studio project.$(B)and$(CLIENTBIN)are likely makefile variables; adjust as needed.
- Change Extension: Find where the final executable is named and change its extension from
.exeto.dll.
Standard UWP Considerations
-
Direct3D SwapChain: For Direct3D projects, you'll need to modify the swap chain creation. Use
CreateSwapChainForCoreWindowinstead of other swap chain creation methods. This is specific to UWP and its windowing model. -
File I/O:
-
LocalState: Provide hints to your application about the location of the
LocalStatefolder, which is where UWP applications can save data. Use this code to get the path:winrt::to_string(winrt::Windows::Storage::ApplicationData::Current().LocalFolder().Path()); -
External Drive: The external drive on Xbox is mapped to
E:\. You can use this path directly if you need to load files from a USB drive (although, as mentioned earlier, loading DLLs fromE:\is not supported).
-
-
Static Library Approach: If you don't have a pre-existing UWP entry point, consider changing the main executable project to a static library (
.lib). Then, create a new UWP project in Visual Studio and link against this static library. This can simplify the process and avoid errors related to switching an existing project to UWP. -
Linker Dependencies: Every third-party dependency (
.libfile) linked against in the original main executable often needs to be linked against in the UWP executable as well. If you see "unresolved external symbol" errors during linking, add the missing.libfiles to your UWP project's linker settings ("Additional Dependencies"). -
onecore.libandwindowsapp.lib: As a last resort for unresolved external symbol errors, try linking againstonecore.liband/orwindowsapp.lib. These libraries provide core Windows APIs. Add them to your UWP project's linker settings.