Cross-Platform C++ development with VisualStudio - c++

I want to start a cross-platform C++ project with VisualStudio 2019.
After some research I found two possible ways:
CMake
Tutorial: Create C++ cross-platform projects in Visual Studio
Create and configure a Linux CMake project
CMake is pretty common for cross-platform projects, but I haven't done much with it and it feels like you need to put in much effort to make it run as you want to. But you have a huge amount of possibilities to configure it. This SO questions also recommends CMake, but says that there are other ways.
VS Shared Project
Shared Project : An Impressive Feature of Visual Studio 2015
Cross-platform code sharing with Visual C++
If you use cross-platform code sharing in VS you have several projects in your solution (one for each platform) and at least one shared project, which includes your source + header files. The platform specific projects include all the configuration settings and the program entry point. The shared code can be used from each project as if it is in the project.
All the configuration is possible in VS. It looks less complex but with limited possibilities.
Question
Both ways look like they would fit my needs, but I haven't found a comparison between them. I already coded running examples for both of them, but those small code bases haven't given me the insight I need.
What are the pro's and con's of those two ways? Considering attributes like build-speed, flexibility, time to learn/master/market, VS feature support, unit testing, continuous integration, ...

Take a look at Premake. You can generate Makefiles and VS project from simple lua configurations. Not a lot of projects use premake but my experience so far has been positive.

Related

Use VS Code for Cross-Platform Scalable C++ Project

This tutorial provided by the VS Code team explains how to setup C++ in VS Code with MinGW (https://code.visualstudio.com/docs/cpp/config-mingw), however it seems to only target small-scale projects as it is configured to rebuilds all files each time, and isn't setup to allow for easy configuration of a project (global defines, adding link libraries etc.) (or am I missing something?).
I am looking into using CMake as my build tool inside VS Code, however am really turned off by the idea of having to update the CMakeLists.txt file to change my project's configurations, e.g. every time I add files to my project or link a new library, as I have grown up using IDEs who do this process for me, which I find magnitudes easier as it allows me to purely to focus on writing code.
My question is, is there a known method to setup VS Code that will allow me to use a tool such as CMake without having to tinker with it too often?
This tutorial seems like a good starting point to setup CMake, but its method requires CMake knowledge https://pspdfkit.com/blog/2019/visual-studio-code-for-cpp/
I ideally would like the setup to cater for both small-scale and large-scale projects, both of which should allow for cross-platform building.
Thanks
As Visual Studio Code is not a heavy weight IDE, you will need to put some effort to get it run the way you want it to have, either:
Write a CMake InputFile generator, e.g. :
list(APPEND EXECUTABLE_LIST executable_1 executable_2)
list(APPEND LIBRARY_LIST library_2 library_2 library_3)
foreach(lib IN LISTS LIBRARY_LIST)
add_library(${lib} STATIC ${lib}.cpp)
endforeach()
foreach(exe IN LISTS EXECUTABLE_LIST)
add_executable(${exe} ${exe}.cpp)
target_include_directories(${exe} PUBLIC ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(${exe} ${LIBRARY_LIST})
endforeach()
or you could also use Visual Studio Code CMake Tool extention
For sure, you couldn't expect the highly functionality like Visual Studio in VS Code as they serve different purpose (highly specialised, deep system couple but slow and big vs small, fast, highly configurable).

How to write truly cross-platform C++ libraries for distribution

The problem:
I'm writing an SDK that is primarily C++. The source code will be licensed to developers who pay for it, and the output libraries and include headers will be free for public usage. The SDK will target a plethora of platforms including Windows, Xbox, Playstation, Android, iOS, Mac OS X, and Linux. I'm a kind of guy who mostly likes Visual Studio and usually develops software using Windows machines. In the last few years, Visual Studio has made this quite a lot easier than it used to, where I have a mostly clear path to target all the previously mentioned platforms using a Visual Studio set of project files as the source of truth that brings all my source code files together... except for Mac OS X, unfortunately. Visual Studio is able to build executable code for iOS and Linux by remotely interfacing with a Mac or Linux box respectively for compilation and debugging, which is really quite cool, but for some reason Mac OS X as a target is left out here. Additionally I'm well aware that there are plenty of other professional developers out there that don't write code on Windows machines, nor do they have any interest in buying a commercial license for Visual Studio.
The question:
Since C++ still does not yet have a build system standard, and may not ever, how do I maintain a single source of truth that maintains the build configurations for all my source files targeting so many different platforms while simultaneously minimizing the barrier to entry of supporting software developer clients who need to build, run, and debug my source code?
Possible answers I'm aware of:
A) Visual Studio projects remain the source of truth from which any other C++ project types (such as Android Studio, XCode, and .make files) are derived. I'm aware of tools that can convert VS to .make and the like, but haven't actually tried them yet (my source code base is starting to get somewhat large already). Or I could just bite the bullet and write them by hand and try to keep them all in sync.
B) CMake. Sigh. So frustrating that it's very popular, and seems to exactly solve my issues, but it has its own set of problems that seem to be deal-breakers. For starters, once you go in on CMake, you pretty much can't come back. Using Visual Studio and property sheets, I've been able to tweak my build configurations with properties that are mostly inherited and rarely duplicated across projects and configurations. As far as I can see, CMake doesn't care about respecting such things, and for common properties, it just duplicates them on all vcxproj files. To make matters worse, all file paths it generates in the output projects are absolute, not relative, and to top it all off, it forces anyone else who builds your code to use CMake, disallowing distribution of the project build files it creates without it. Also, does this even work for game consoles? Last I checked I couldn't find a reasonable way of supporting them without hacking the source code.
C) Roll my own script that's similar to CMake, but allows redistribution of its output projects, and supports all the platforms I need. It goes without saying that this would consume a lot of dev time.
Any other options I'm missing here? Your input is greatly appreciated.
I agree with the comments from #Scheff and #arrowd. Use CMake. I have built and deployed software to multiple platforms and CMake is the best, though not perfect, solution I have found for building C++ code.
I have not had to hack the cmake code to get it to work on various platforms.
Do not worry about properties being duplicated in vcxproj files. With CMake the build language is in the CMakeLists.txt file(s). The vcxproj files are generated code. As long as you are do not have redundant cmake logic, you should not care about replicated properties in the generated vcxproj files. Similarly, you should not care that the generated vcxproj files have absolute paths; you do not reuse the vcxproj files you reuse the CMakeLists.txt files and regenerate vcxproj files for each new platform or build.
Use the top-level CMakeLists.txt to define the properties that are common to all targets. Then in individual target(s) CMakeLists.txt files use target properties to tweak builds of specific targets. In my experience the replication of properties in the generated files helps because they make the builds more consistent; I am able to minimize replication in the source CMake logic.
Various IDEs (VS 2017, CLion, QtCreator) can use cmake based projects directly.
There is nothing cmake specific about the generated artifacts. The headers, libraries (and dlls), and executables of our SDK are standalone artifacts. Yes, cmake can make it easier for your SDK users but using CMake in your SDK will not force your customers to use CMake.
Have you tried CMake and not been able to use it? Or are you looking for something better? There are certainly multiple C++ build systems, but despite its shortcomings I believe CMake is the best one available right now.

How to develop a cross-platform C++ project?

I'm a C++ beginner and I'm starting to develop my first cross-platform C++ project. I need to use platform-specific calls (Win32 and POSIX) so I need to compile frequently both in Windows and Linux.
Whit single-platform projects I'm using, until now, KDevelop in Linux and Visual Studio 2012 in Windows.
How can I use two different IDEs in two different Operating Systems with the same project?
Should I use a single, cross-platform, IDE?
Should I learn CMake (or similar) and configure it to work with both IDEs?
Could/Should I host my code in the web and sync automatically with offline projects?
Alternatives?
Thanks in advance to everyone.
EDIT:
Just for clarification, the project will be a simple server for a scholastic protocol. There will be a client asking for upload/retrieve some files to/from the server.
With scholastic I mean that, for example, I have to use pthreads/win32 threads instead of an higher level C++ threads library.
Maybe - really depends on what you feel most comfortable with. As the project is non-graphical, all the IDE gives you is editing of files and compilation. So you can build the project on one machine with the IDE there, and then move the sources to another machine for compiling there.
I personally would just have two makefiles, one for Linux and one for Widnows. Makes life fairly simple [you could have a "outer" makefile that picks the right one based on some clever method].
Yes, you should find a version control system that works for both Windows and Linux (git, mercurial, subversion, bazaar and several others). That way, not only do you have a central repository [you can use either of your machines as "server" for any of these], but it also allows you to keep track of your changes. Definitely worthwile doing!
There are hundreds of different alternatives. But the simpler you keep it, and the less complicated your tools are, the more time you get to spend on actually programming your project, rather than, for example, figure out why CMake isn't building the way you want it to.
Also, make sure that you separate out all your system-specific code to one file per architecture. That way, it's easy to port to another architecture later, and it makes MOST of your code compile on both systems.
Typically, it's easy to adjust the IDE-specific project/build files to added/moved/deleted source files. Therefore, using a cross-platform IDE isn't that important.
You can do that, I think that CMake can also create project files for some IDEs that can then be used to build the project.
Ahem, if you want to host it online or not is your choice. What you should definitely do is to use some kind of version control. A bug-tracking system is also helpful. If you want to open-source the code anyway, using one of the existing hosting facilities is a clear yes.
Not really.
One comment though: You will have much more trouble making the C++ code portable. Building on top of a toolkit like Qt is a tremendous help. If you want to stay closer to standard C++, at least consider using Boost for stuff like threads, smart pointers, filesystem access. Good luck!
My recent experience suggest to take a look at Qt. The IDE (QtCreator) it's very good, and available on all major platforms.
I've used for a fairly simple project, that uses fairly complex components, like OpenCV and ZBar. I develop on Linux, copy the source to Windows, and recompile.
I had some trouble to setup OpenCV on both platforms, so I can't say it's super easy, but it's working. Since you already know KDevelop, you should already know Qt.
I also put much value in recent trend that see Qt5 as the platform for Ubuntu on smartphones. I really hope to see this developing.
HTH
How can I use two different IDEs in two different Operating Systems with the same project?
Should I use a single, cross-platform, IDE?
No. I think this is a case of asking the wrong question. To make a cross-platform project, what matters is your build scripts and the system-neutral nature of your code. Sometimes it might help to have project files for your preferred IDE, but maintaining multiple project files for multiple IDEs will only make things more difficult and complex for you. Instead, you should focus on finding a build system that minimizes the amount of time you spend on project maintenance.
For that, CMake and PreMake seem to be two of the best tools to make that happen.
There are dozens of alternatives (like SCons, Cook, kbuild, Jam and Boost Jam, and many others), but since CMake and PreMake both generate project files and build scripts, they might be the best solutions.
Your mileage will vary.
Could/Should I host my code in the web and sync automatically with offline projects?
You should have robust source control that works everywhere you do. Git and Mercurial seem to work best if you use some kind of "cloud" hosting like Github or BitBucket, but they by no means require it. Depending on your work environment and team size, you may prefer Subversion or PerForce or something else, but that's up to you and your team.
it will help, you will quite likely need to debug on many platforms... Qt Creator, Netbeans and Eclipse come to mind.
Yes. cmake, or qmake for Qt maybe
Not technical question. Just use version control! github and gitorious are easy choices for open source project though.
Qt is a no-brainer choice for cross-platform C++ GUI app, and also decent choice for network app with no GUI.

Getting started with a cross platform C++ project

I am starting a c++ project which I would like to compile equally well in Eclipse (Linux) and vs2010 from the same repository and could use some help getting started. While many of the aspects can individually be Google'd, I was hoping for advice on how to approach the problem on a whole.
For example, where to keep the library sources, how to structure the make file, and how to integrate googletest (finding a novice tutorial on googletest alone is hard). A link to a tutorial that addresses these aspects would be great, or a series of tutorials that together could help.
My background is in C# and I'm trying to maintain the "cleanness" and organization of my VS projects.
I have done cross platform projects that used the "native" build systems on both platforms (vsproj files on windows and makefiles on linux), but it was definitely a pain to maintain both project files. So, yes, I would agree with the other suggestions that you should try to start with a solid cross platform build utility. CMake or possibly Boost build seem like decent options - likely there are many others.
When it comes to 3rd party libraries, you'll want to stick to stuff that is solidly tested cross platform. Boost is the best general purpose library for c++ (yes, you see it mentioned here in just about every c++ thread...but that's because it really is a nice collection of useful stuff). As for XML, HTTP, image libs, UI - there are all good cross platform options - just look around or ask here if you have specific requirements. Whatever you do, don't use some library from CodeProject or other MS oriented site that has only been tested with Visual Studio 6 - that will just lead to misery. Most of the GNU libs build on windows these days, so you should be reasonably safe with that stuff.
Although it will be tempting, try to minimize the platform#ifdefs in your code - prefer instead to abstract any platform specific stuff in a library wherever possible.
Good luck!
You'll want to look at cmake.
One thing that I could suggest if you're going strongly cross-platform and you want everything to be as "clean" as possible: Centralize your build system with a modern cross-platform build tool like Scons. It's written in Python, it's quite concise and powerful, and it works everywhere.
Or, if you're a fan of Eclipse, just install Eclipse on both Windows and GNU/Linux. As I mentioned above, it's cross-platform, and you can get it working for compilers on all sorts of different systems.

Using Makefile instead of Solution/Project files under Visual Studio (2005)

Does anyone have experience using makefiles for Visual Studio C++ builds (under VS 2005) as opposed to using the project/solution setup. For us, the way that the project/solutions work is not intuitive and leads to configuruation explosion when you are trying to tweak builds with specific compile time flags.
Under Unix, it's pretty easy to set up a makefile that has its default options overridden by user settings (or other configuration setting). But doing these types of things seems difficult in Visual Studio.
By way of example, we have a project that needs to get build for 3 different platforms. Each platform might have several configurations (for example debug, release, and several others). One of my goals on a newly formed project is to have a solution that can have all platform build living together, which makes building and testing code changes easier since you aren't having to open 3 different solutions just to test your code. But visual studio will require 3 * (number of base configurations) configurations. i.e. PC Debug, X360 Debug, PS3 Debug, etc.
It seems like a makefile solution is much better here. Wrapped with some basic batchfiles or scripts, it would be easy to keep the configuration explotion to a minimum and only maintain a small set of files for all of the different builds that we have to do.
However, I have no experience with makefiles under visual studio and would like to know if others have experiences or issues that they can share.
Thanks.
(post edited to mention that these are C++ builds)
I've found some benefits to makefiles with large projects, mainly related to unifying the location of the project settings. It's somewhat easier to manage the list of source files, include paths, preprocessor defines and so on, if they're all in a makefile or other build config file. With multiple configurations, adding an include path means you need to make sure you update every config manually through Visual Studio's fiddly project properties, which can get pretty tedious as a project grows in size.
Projects which use a lot of custom build tools can be easier to manage too, such as if you need to compile pixel / vertex shaders, or code in other languages without native VS support.
You'll still need to have various different project configurations however, since you'll need to differentiate the invocation of the build tool for each config (e.g. passing in different command line options to make).
Immediate downsides that spring to mind:
Slower builds: VS isn't particularly quick at invoking external tools, or even working out whether it needs to build a project in the first place.
Awkward inter-project dependencies: It's fiddly to set up so that a dependee causes the base project to build, and fiddlier to make sure that they get built in the right order. I've had some success getting SCons to do this, but it's always a challenge to get working well.
Loss of some useful IDE features: Edit & Continue being the main one!
In short, you'll spend less time managing your project configurations, but more time coaxing Visual Studio to work properly with it.
Visual studio is being built on top of the MSBuild configurations files. You can consider *proj and *sln files as makefiles. They allow you to fully customize build process.
While it's technically possible, it's not a very friendly solution within Visual Studio. It will be fighting you the entire time.
I recommend you take a look at NAnt. It's a very robust build system where you can do basically anything you need to.
Our NAnt script does this on every build:
Migrate the database to the latest version
Generate C# entities off of the database
Compile every project in our "master" solution
Run all unit tests
Run all integration tests
Additionally, our build server leverages this and adds 1 more task, which is generating Sandcastle documentation.
If you don't like XML, you might also take a look at Rake (ruby), Bake/BooBuildSystem (Boo), or Psake (PowerShell)
You can use nant to build the projects individually thus replacing the solution and have 1 coding solution and no build solutions.
1 thing to keep in mind, is that the solution and csproj files from vs 2005 and up are msbuild scripts. So if you get acquainted with msbuild you might be able to wield the existing files, to make vs easier, and to make your deployment easier.
We have a similar set up as the one you are describing. We support at least 3 different platforms, so the we found that using CMake to mange the different Visual Studio solutions. Set up can be a bit painful, but it pretty much boils down to reading the docs and a couple of tutorials. You should be able to do virtually everything you can do by going to the properties of the projects and the solution.
Not sure if you can have all three platforms builds living together in the same solution, but you can use CruiseControl to take care of your builds, and running your testing scripts as often as needed.