Skip to content

Instantly share code, notes, and snippets.

@pabloko
Created March 18, 2020 18:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pabloko/43cbdef71d19046a2249e1889d908d34 to your computer and use it in GitHub Desktop.
Save pabloko/43cbdef71d19046a2249e1889d908d34 to your computer and use it in GitHub Desktop.
(C/C++) Embed file assets into binaries automaticly with VisualStudio build tasks

(C/C++) Embed file assets into binaries automaticly with VisualStudio build tasks

Sometimes developing apps, we need to reduce the build to a single exe containing handful of asset files, in this scenario, you can use the great library PhysFS that will let you zip everithing and load those files on runtime. We can further automatize this process by adding a VisualStudio Pre-build event that zips a custom folder, but also packs it on the final executable.

To start, locate your project folder and add a www asset directory and vendor directory, where we will put neccessary files 7z.exe, 7z.dll, objcopy.exe, www.bat 7zip will pack the files on a generated "resources.zip" this can be edited or even removed, it may even include the usage of zip password as PhysFS supports it. Objcopy, its part of some VS distributions and generated a .lib static library with the asset, exporting its start and end address.

Pre-build event: call "$(MSBuildProjectDirectory)\vendor\www.bat"

/vendor/www.bat (notice you will need to edit this for x64 build)

del "www\resources.zip"
call "vendor\7z.exe" a -r -tzip "www\resources.zip" ".\www\*" -mx9
call "vendor\objcopy.exe" --prefix-symbol=_ --rename-section .data=.rdata,CONTENTS,ALLOC,LOAD,READONLY,DATA --input-target binary --output-target pe-i386 --binary-architecture i386 "www\resources.zip" "%resources.lib"
EXIT 0

Get the other assets here: https://mega.nz/#!VU5jwDJa!oDax4fOLVGt7p3MnJX1dKqv63hbv9cVZqX9Q7l0gf8o

Usage:

#pragma comment( lib, "resources.lib" )
extern "C" byte _binary_www_resources_zip_start[];
extern "C" byte _binary_www_resources_zip_end[];
//...
//Example of loading on physfs
PHYSFS_init(NULL);
//PHYSFS_addToSearchPath("resources.zip", 1); //Loading from zip
//PHYSFS_addToSearchPath("resources", 1); //Loading from folder
//Calculate the size
int _binary_www_resources_zip_size = _binary_www_resources_zip_end - _binary_www_resources_zip_start;
//Loading from executable's mem
if (!PHYSFS_mountMemory(_binary_www_resources_zip_start, _binary_www_resources_zip_size, NULL, "resources.zip", "/", 1)) { 
     LOG("mount error code %d", PHYSFS_getLastErrorCode());
     return FALSE;
}
//...

So, anytime you build your project, is ensured you have latest assets ready without hassle. Also VS build outputs relevant info of the process:

1>------ Operación Compilar iniciada: proyecto: EMBEDINGFILES, configuración: Debug Win32 ------
1>7-Zip [32] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
1>Scanning the drive:
1>3 files, 643135 bytes (629 KiB)
1>Creating archive: www\resources.zip
1>Items to compress: 3
1>Files read from disk: 3
1>Archive size: 641227 bytes (627 KiB)
1>Everything is Ok
... rest omitted ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment