I created Protobuild in July 2013 when I started having to manage targeting 3 desktop platforms for a game. At the time I had 3 project files for every library and executable, and it was no longer maintainable between keeping files and references in sync. I investigated project generators, but the only project generators that were developed were one-way; if you wanted to add new files to your project, you had to manually modify project definitions.
So I set out to build a project generator that would operate in a way that would allow for two-way synchronisation, provide very simple mechanisms for generating projects. I didn't want people to have to install anything either, hence the reason Protobuild ships as a single executable, included in repositories that use it for generation.
In March 2014, Protobuild was adopted by MonoGame. Protobuild is now capable of generating projects for 12 different platforms, and is used by a variety of open and closed source projects.
Protobuild supports the following platforms out-of-the-box:
- Android (via Xamarin)
- iOS (via Xamarin)
- Linux
- MacOS
- Ouya (via Xamarin)
- PCL (for Bait-and-Switch PCL only)
- PSMobile
- Windows
- Windows8
- WindowsPhone
- WindowsPhone81
- Web (via JSIL)
You can extend Protobuild to support other platforms by modifying the project generation templates. Refer to :doc:`customizing_protobuild` for more information on how to do this.
Protobuild is made available under an MIT license.
Unfortunately Xamarin Studio (the IDE used to develop Mac OS, Linux, iOS and Android applications) doesn't understand conditionals in C# projects, and likely never will. Since this IDE is used for the majority of cross-platform C# development, it rules out using MSBuild conditionals to solve this problem.
C# is currently the only supported platform type, but support for generating C++ projects is planned.
NuGet was developed primarily with the focus of packaging .NET libraries, and it uses framework versions to distinguish between different .NET binaries. Unfortunately, this abstraction does not work when libraries are dependent on specific operating system or device APIs (particular those that are P/Invoke'd).
Up until October 2014, the only way to include external libraries in Protobuild
was via the submodule mechanism, where you would add a submodule using
git submodule add
, and Protobuild would recursively load all of the
project definitions from the submodules.
This works well from the perspective of being able to debug and correct issues in libraries you are using, but suffers problems when the number of libraries, or the amount of history libraries have is large. This is because when you clone your project, you also need to clone the history of every submodule and all of it's dependencies. In addition, you also need to build all of the libraries you are using, even if you rarely or never change them.
To solve the issues of depending on large, cross-platform libraries, while still maintaining the flexibility of debugging libraries when needed, package management was added to Protobuild. This allows libraries to be referenced in either binary or source form transparently, and allows developers to switch between the two formats as needed. Being developed with cross-platform support in mind, it explicitly supports binaries per-platform, rather than per-framework, which allows libraries dependent on platform-specific functionality to be shipped in a package.
When using Protobuild, you should place the following files in source control:
- Build\Projects\*.definition
- Build\Module.xml
- Protobuild.exe
- Any other source code files
You should not place any of these files in source control, unless they are part of a project not generated by Protobuild:
- Any C# project files
- Any
.sln
solution files
Unlike MSBuild, Protobuild project definitions are purely declarative. That is, you can't declare custom tasks or steps to occur during your build inside a project definition file (but you can do this by overriding the project generation template).
This is done to ensure that two-way synchronisation is possible. If Protobuild used a procedural or task based system for declaring projects, then it would be non-trivial to determine how to synchronise changes in C# projects back into the definition files.
Unless you are migrating an existing library which has users using it in source form, you do not need to set any project GUIDs. Protobuild will automatically generate appropriate project GUIDs for all projects you have defined.
If you are migrating an existing library, and want to retain your project GUIDs when migrating to Protobuild, see :ref:`project-guids-full`.
Please refer to the :doc:`contributing` page.
If you are interested in debugging Protobuild, you should generate projects
for your platform and then open the Protobuild solution in your IDE. Set the
Protobuild.Debug
project as the startup project.
If you are interested in contributing or developing a custom version of
Protobuild, you'll need to run the Build/rebuild.sh
script, which will
build and compress Protobuild to produce the resulting executable.