0
\$\begingroup\$

I am now creating a 64 bit and 32 bit executable of my game.

How could I achieve so that the executable and dlls lie in a separate folder without changing all the path variables in the game?

To clarify I want to have a folder structure like this:

  • Game
    • Bin
      • exe
      • dll, so, etc.
    • Data
      • textures and everything else.

My current is:

  • Game
    • exes
    • dlls
    • data

So my path variables use something like: ./data/ ....

How could I move my exes so they would find all dlls and data, so I wouldn't need to replicate the data folder for each version and have them nicely separated?

I am mainly looking for answers for Windows, but I am also interested in Unix solutions.

\$\endgroup\$
  • \$\begingroup\$ expand your search path for data to include both, ./data/.. and ../data/*. \$\endgroup\$ – planetmaker Oct 26 '15 at 16:37
3
\$\begingroup\$

On Windows, you can shove everything under an architecture directory:

YourGame/
  x86/
    game.exe
    lib.dll
    data/
  x64/
    game.exe
    lib.dll
    data/

You need 64-bit DLLs to go with the 64-bit .executable, you can't load 32-bit ones into a 64-bit process. The Windows DLL search order will check the .exe directory.

This does mean duplicating your data though; if this isn't otherwise necessary (it may be if you're baking in pointers that are fixed up on load, for example), it's wasteful. You could solve this by creating hardlinks from one of the architecture data folders to the other, though.

Or you can move the data directory down:

YourGame/
  x86/
    game.exe
    lib.dll
  x64/
    game.exe
    lib.dll
  data/

...and then use "../data" for your data paths, relative to the application location, or stick launch shims (shortcuts, aliases, batch files, whatever) in the root of YourGame that do x64/game.exe -data-path data, to specify the data path on the command line).

You could also leverage the fact that, for native languages at least, you always know what architecture you're compiling for when you compile and it's generally a distinct project configuration. This means you can rename everything, and embed those names as appropriate:

YourGame/
  game32.exe
  game64.exe
  lib32.dll
  lib64.dll
  data/

You'd just need to change the names of the import libraries you link against for each architecture variant. This would also work for the data folder if you did need 32 and 64 bit copies, just fix up the subdirectory based on the compile-time architecture constant.

Linux and Unix environments use fairly different conventions for shared library search (see here for an example). You can adapt the above for those conventions, or use OS level functions to manually load shared libraries from the locations you store them in.

In short, there's no single solution that will work ideally on all platforms out of the box; the way to achieve "cross platform" functionality here is to either do it differently per platform in accordance with that platforms guidelines or use the platform's OS APIs to try to force it into adopting the convention of the other platforms.

\$\endgroup\$
1
\$\begingroup\$

The final solution I chose is very simple, and avoids any changes to existing code / path files:

In the main function, first make a call to chdir("../")

This will make static DLL loading work from the x32/ or x64/ folder, while all runtime data can be loaded as if the executable was in the main folder.

Such a method is even necessary if you have a DLL you can't recompile that has the same name on multiple architectures(Instead of libfoox32.dll just libfoo.dll)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.