Cross-platform code sharing with Visual C++
With Visual Studio 2015, Visual C++ supports three new platforms: Universal Windows Platform (just announced), Android and iOS (more info). This is in addition to its continued support for Desktop, Windows Store and Windows Phone. During the bring-up of these new platforms, a key requirement for our team was to make sure that Visual C++ provides an easy way to reuse code across all these platforms.
This post goes through the improvements we made in Visual Studio 2015 to streamline the reuse and code sharing throughout the edit-build-debug cycle for C++ developers.
Today we’re also making available through VS Gallery a new C++ project template that serves as a starting point for showcasing Visual C++’s code sharing capabilities – it creates a fully functional cross-platform OpenGLES 2 application that targets Android, iOS and Windows 10. Download the project template and give it a try today!
[Update 11/3] With Visual Studio 2015 Update 1, the OpenGLES 2 application template is now directly available as part of the Visual C++ Mobile Development package in the New Project dialog under C++ > Cross-Platform node.
Visual C++ is your IDE for C++ cross-platform development
If you’re already building cross-platform applications, it is likely that you already have a codebase that is, to a large degree, common across the different platforms. Or if you’re just getting started with a new cross-platform project or plan to expand one to a new platform, chances are one of the main reasons you’ve chosen C++ is to leverage its high degree of portability.
With Visual C++, our goal is to provide you with a unified C++ development experience for all the platforms you’re targeting from the same IDE, the same solution, the same codebase. You are able to:
- Easily acquire all platform-specific development tools
- Target multiple platforms from a single solution
- Get state-of-the-art unified IntelliSense for the files that are common across the different platforms
- Discover all aspects of your cross-platform code using familiar browsing and navigation controls
- Improve code quality using our latest refactoring facilities
- Use a common build system and build binaries for all platforms at once – no need to leave the IDE or resort to other platform-specific build systems
- Debug your code on all platforms using a familiar experience either on physical devices or the preconfigured emulators and simulators
Quick start with an example: OpenGLES 2 project template
If you want to quickly see Visual C++ cross-platform code sharing capabilities in action, download the Visual C++ OpenGLES 2 project template from Visual Studio Gallery today. As long as you make sure that you have the optional VS Tools for Windows 10, Visual C++ Android and Visual C++ iOS components installed, the template will create a solution that contains Windows Universal, Android and iOS applications that have all their OpenGLES 2 source code shared among them. The Windows version of this app uses the ANGLE library that was just recently released as a convenient NuGET package.
Share source code across multiple C++ projects
Note: Some of you may be already familiar to the way Visual Studio 2013 enables code sharing between Windows Store and Windows Phone projects. With Visual Studio 2015, we expanded this support to all the platforms targeted by Visual C++ and we enabled more flexibility in the way code sharing can be achieved.
The main building block to share code across multiple projects is the “Shared Items Project” C++ project template. These “shared items” projects don’t participate in build but they can contain any number of C++ headers and sources. When you add such a project as a reference to a regular C++ project, the files in the referenced “shared items” project will simply be treated as if they were part of the referencing project and will be built under the configuration & architecture-specific settings specified by the referencing project.
Figure 1. Select “Shared Projects” tab in “Add Reference” dialog to add shared item projects as references
Build your code for all platforms at once
By referencing a “shared items” project from multiple projects targeting different platforms, you enable your cross-platform source code to be built multiple times in the same build, once for each of the platforms you’re targeting, each time using the appropriate platform-specific toolchain and settings. As a result, any changes you make to your shared code will be validated for all platforms at each build. This enables you to promptly discover any potential compile-time incompatibilities between platforms early during development.
Figure 2. When you change a file (SimpleRenderer.cpp in this case), it will be built by all C++ projects that reference its parent “shared items” project
Note: You can use Shared Items Projects even if you don’t do cross-platform development. You can think of “shared items” projects as another way of organizing your files in case you have many projects building the same source file (e.g. in case you build multiple applications that share the same source and you’re not already using static libraries for this purpose).
Code editing and IntelliSense for cross-platform code
Having to build your cross-platform source code using different compiler toolchains and/or different compiler switches (including different header includes and different preprocessor macros) is usually a guaranteed recipe for unexpected build failures. Visual C++ assists by going a step further and providing an unrivaled IntelliSense experience that is aware of the full set of platforms you are currently targeting and warn you before starting a build about any impending compile-time problems.
If you want to focus on a specific platform, as you make code changes, you can select the active project context you would like Visual C++ to provide IntelliSense for. The project context dropdown lists all projects the shared file is currently part of. Once you switch, Visual C++ provides Semantic colorization, Quick Info, Parameter Help and Member List results that are specific to that selected project’s platform. E.g. if you select the Android project from the list, you will see Android-specific IntelliSense. If you select a Windows or iOS project, similarly, you will only see the libraries and APIs that are available on Windows specifically or iOS respectively.
Figure 3. IntelliSense for Windows
Figure 4. Switch project context
Figure 5. IntelliSense for Android
In case you make any errors, of course, IntelliSense will show you familiar red squiggles for all the platform-specific errors. With the assistance of platform-specific Member List and Parameter Help though, it’s less likely that you’ll make any coding errors, right? At this point you’re probably more worried about not introducing errors in the other platforms. Rather than making you switch between project contexts every other minute to see if any new errors have appeared, Visual C++ will periodically reevaluate for you in the background the other project contexts too. Any errors that are identified in the inactive project contexts and are not present in the active project context are shown using purple squiggles in the editor and their tooltip will clearly specify the project context it originated in.
Figure 6. Error originating from another project context
Alternatively, you can keep an eye on the full list of IntelliSense errors listed in Error List. Error List now allows advanced filtering by project, file, tool as well as an integrated search.
Figure 7. Filtered view of the Error List window
Browsing and Refactoring C++ cross-platform code
Code understanding functionality like Go to/Peek definition/declaration, Find all References, Call Hierarchy and Class View are at your disposal to discover and navigate any code whether it targets Windows, Android or iOS or all of the above. You will be able to easily navigate deep in the platform-specific included headers and then back to your shared source code.
You can leverage all refactoring features supported in Visual C++ announced previously on this blog for any source code whether it’s cross-platform or platform-specific: e.g. rename symbol, extract method, move function definition and more that will be coming soon (Stay tuned).
Debugging code on each platform
If your motto is not “If it builds, it ships”, Visual C++ is the tool for you. Visual C++ supports debugging your code on all the supported platforms: Windows, Android and iOS.
In this release the Debug Target toolbar was also improved to streamline the debug launching process:
- Solution platform dropdown is now always visible to allow you to select the architecture you want to target
- The new “Startup projects” dropdown presents a filtered list of all applications in your solution for quick selection
- The Debug target dropdown button automatically refreshes based on your selection from the previous buttons allowing only valid platform and architecture selections (e.g. if you select a Windows app to be built for ARM, you’ll be able to debug it either on a device or a remote machine. Options like debugging the ARM Windows binary on a x86 Android emulator or x86 Windows emulator are filtered)
Figure 8. Different instances of the Debug Target toolbar
Set your breakpoints once and start cycling through the different possible start-up projects to validate your code on each platform. You can choose any of the Windows 10 emulators as a target if you’re not already on a Windows 10 machine or one of the preconfigured VS Android emulators if you prefer it instead of the Android device and so on.
Show us your apps and share your feedback
The new OpenGLES 2 template should be a good starting point to evaluate Visual C++ cross-platform development experience. After taking a look at it, if you end up doing a better job than spinning a cube in your app, don’t hesitate to write us. We’d love to hear from you about the cross-platform apps you built using Visual C++ and the experience you had doing it.
So, what are your thoughts? We’re constantly looking for new ways of improving the C++ cross-platform experience and your feedback and suggestions are important whether you’re already using VS today or not; What do you find useful, what should we change, what should we leave unchanged?