This is part of a series of small projects and tutorials using C++ and SFML
Library version: SFML 3.0.0
C++ Standard: ISO C++17
My Base Project: https://github.com/l-paz91/SFMLProjects/blob/main/main.cpp
In this tutorial we're not going to create another app, but rather, I'm going to take you through the process of creating an executable that you would use for release/shipping purposes. This tutorial focuses on creating a release version via Visual Studio, the process may be different for other compilers.
Contents:
Up until now, we've been using the SFML debug libraries and we've been building in debug. In release, the compiler does all kinds of optimisations to the code. However, those optimisations can make the program trickier to debug, which is why we always develop in debug mode. You should never really be shipping a debug build.
Now, there are two ways to build your program; with dynamic linking or static linking. Currently, even in debug mode, we've been using dynamic linking. This means, if I want to run my executable on a different pc that doesn't have SFML installed in the location I specified in the project configuration, you'll get an error about not being able to find DLL files. This is because dynamic linking still requires a whole bunch of files outside of the executable. This is why you'll see "install wizards" for certain programs. The wizard is basically extracting these files to places where the program expects it.
Static linking "fixes" this problem by bundling everything into one executable. This might sound better, however, neither is better than the other. It's up to you to decide which one is more suitable for your app. Here's some more info:
Dynamic Linking
- Pros
- Smaller exe size (but DLLs can be large)
- DLLs can be updated without having to recompile the app (patches etc)
- Faster compiling/linking times during development
- Cons
- DLLs need to be included with exe
- "DLL Hell" version conflicts - this happens when a user has more than one version of the library on their computer
- Slightly slower startup time (as the name suggest, it loads dynamically at startup)
Static Linking
- Pros
- Single exe file - easier to ship
- No runtime dependencies to worry about
- Slightly faster startup time (doesn't have to dynamically load libraries)
- Users can't accidentally/intentionally delete/move required DLLs
- Cons
- Larger exe size
- Can't update DLLs without shipping a new client
- Longer linking times during development
- Each program using the library has its own copy in memory. A easy way to think of this is, imagine you're running 3 games on your PC that all used SFML. If they were built using dynamic linking, they all share the same SFML DLLs as your PC is smart enough to load those DLLs into memory once. With Static, those DLLs are baked into the game so your PC thinks they must be 'special' and need their own version of SFML each. On modern PCs, this isn't really a problem, and most users will only run 1 instance of your app anyway but it's an interesting area of memory management that a lot of people don't tend to think about.
Alright, enough theory and waffling.
Github: N/A
1 - Dynamic Linking
Open up the properties for your chosen app and set the configuration to Release. The first thing to check is the language standard. In debug, I've been using C++17, and when switching to release, it changed it back to 14.
This is important because your program won't compile if you used language features that are available in 17 and not in an earlier version. So make sure you set it back to whatever version you were using.
Next, head to Configuration Properties -> VC++ Directories.
Now, we need to tell the release version to use the release libraries instead of debug. Go to Configuration Properties -> Linker -> Input
In debug, we use the "-d" on the ends of the library names. We can essentially just copy and paste these dependencies in release and remove the "-d" suffix.
Hit apply and ok. Now we can build a release version.
Set the build mode to release and build this project! (Note, if you've been creating all your projects inside of one Visual Studio project like I have, remember to only build this specific project. F7 will build all projects in release so you may end up with errors from other projects.)
There should now be another folder alongside your debug builds:
As we're building dynamically right now, there is one more thing we need to do. You will also need to do this for debug versions as well (if you want to run the debug exe outside of VS).
Head to wherever SFML is on your pc and locate the bin folder:
All you have to do is copy and paste the relevant DLLs into your release/debug folder, next to the executable:
Remember to also bring along any assets you're using. This is why I tend to stick assets in a "bin" folder instead of having them next to the code.
I'm not a fan of the copy/paste method, however it's fine for one off projects. You can write post-build scripts that VS will run to automatically copy them over or create a batch/powershell file that will do it for you.
And that's it! To share your program all you have to do is zip up that Release folder and send it over.
2 - Static Linking
So now we know how to build and release a dynamically linked project. What about static linking?
It's essentially the same process, only we use different libraries and don't need to copy and paste some DLLs afterwards. We do have to define a pre-processor macro though and link dependencies that SFML uses manually. I'm going to do this in a different project.
Set up your SFML project in the normal way, however when adding the additional dependencies, we now use the ones appended with "-s". Don't forget to set the language standard and include/library directories for release. If you want to use static linking in debug, the suffix is "-s-d".
We also need to add some extra libraries that SFML depends on. There is a list on their website of what to include.
And that's it! In my Release folder now there's just the executable. If I double click and run it, it doesn't require anything else.
3 - Removing The Console Window (Optional)
You may have noticed (if you're on windows that is), that the release build still launches with a console window. This can be useful if you still want to do some testing in your release build but you might not want it in your final distribution build. To disable the console window, simply go to the projects properties, ensure the configuration is set to release then modify the subsystem from console to windows:
We also need to change the entry point as well to mainCRTStartup:
Hit apply, ok and rebuild the project. The reason I chose to change the entry point in the project settings is so we don't have to change the function signature of main to something Windows specific like WinMain. This keeps the code cross-platform.
If you launch the app now, it won't have the console window.
And that's really all there is to creating "release" versions of your applications!
No comments:
Post a Comment