With all the fuss about opensource projects, how come there is still not a strong standard that enables you to make portable code (I mean in C/C++ not Java or C#)
Everyone is kind of making it's own soup.
There are even some third party libs like Apache Portable Runtime.
Yes, there is no standard but libraries like Qt and boost can make your life much easier when you do cross-platform development.
wxwidgets is a great abstraction layer on the native GUI widgets of most window managers.
I think the main reason there isn't any single library anyone agrees on is that everyone's requirements are different. When you want to wrap system libraries you'll often need to make some assumptions about what the use cases will be, unless you want to make the wrapper huge and impossible to work with. I think that might be the main reason there's no single, common cross platform runtime.
For GUI, the reason would be that each platform has its own UI conventions, you can't code one GUI that fits all, you'll simply get one that fits just one or even none at all.
There are many libraries that make cross-platform development easier on their own, but making a complete wrapper for all platforms ends up being either small and highly customized, or massive and completely ridiculous.
Carried to it's logical conclusion, a complete wrapper for all aspects of an operating system becomes an entire virtual runtime. You might as well make your own programming language.
The ADAPTIVE Communication Environment (ACE) is an excellent object oriented framework that provides cross-platform support for all of the low level OS functionality like threading, sockets, mutexes, etc. It runs with a crazy number of compilers and operating systems.
C and C++ as languages are standards languages. If you closely follow their rules when coding (That means not using vendor-specific extensions) you're code should be portable and you should be able to compile it with any modern compiler on any OS.
However C and C++ don't have a GUI library, like Java or C#, however there exist some free or commercial GUI libraries that will allow you to write portable GUI applications.
I think the most populars are Qt (Commercial) and wxWidgets (FOSS). According to wikipedia there is a lot more.
There is also boost, while not a GUI library boost is a really great complement to C++'s STL. In fact some of the boost libraires will be added in the next C++ standard.
If you make sure it compiles cleanly with both GCC and MS VC++, it will be little extra effort to port to somewhere else.
Related
I'm a die-hard .NET developer with limited experience in C++. I'm really familiar with how happily interpreted languages (and scripting languages) work cross-platform, but what about C++?
I realize that GCC/GPP and some other compilers sorta work multi-platform with the right compiler flags, and I understand that the STL is normalized between compilers, but what else am I missing? I'll need to do audio in/out, high accuracy timers, and I'll need to do multithreading. I don't think any of these things are supported in the STL, so I'll be needing a cross-platform library of some type, right? Which one should I use?
I'm aiming to support the latest Mac and Windows platforms. This is a shared framework/sdk and won't have a UI. I plan on writing the UI in a native language such as Objective-C/Cocoa and .NET/WPF (both which have excellent native UI support).
So what should my tool chain look like? Should I be using GCC/GPP or MinGW? What other 'libraries' should I integrate that will function cross platform? I'd like to setup my build environment to 'just work' such that I can build a Mac compatible binary and a windows compatible binary (32 bit and 64 bit). How can I do that?
At this point, I'll be writing code for each platform so that I can interop with this my C++ multiplatform framework sdk/api thingy. In windows, I think this will look like a managed DLL, is that right? Any thoughts on how I'll do this on a Mac?
Any suggestions or recommendations?
Thanks for the suggestions,
Brett
1) Your real goal here should be to write portable C++ -- you get portability by keeping your language use clean, not by using a particular compiler.
2) Some of what you want, like audio i/o, is fairly inherently platform dependent. You can, however, cleanly isolate the platform dependencies inside particular modules and conditionally compile a set of platform support files on each platform.
3) Stuff like multithreading can be done in a platform independent manner using standard libraries.
Getting into subjective territory but for a developer used to working with large, do-it-all kind of frameworks like those we find in .NET, QT would probably be your best cross-platform C++ analogy (though I am not a huge fan of it). There you have your threads, XML I/O, localization, sockets, high accuracy timers, GUI building blocks, etc.
[...] and I'll need to do multithreading. I don't think any of these things
are supported in the STL [...]
Just a small thing, but the STL is limited to describing the aggregate containers and generic algorithms of the C++ Standard Library. It is not synonymous, but C++11 has specifications in the standard library for concurrency support. However, popular compilers are still slow to support it fully. You also have boost if you need threads for the time being: http://www.boost.org which is an extremely cross-platform library.
As for building an API that can happily plug in to various environments (.NET, Cocoa, etc), your best, most cross-platform option is actually to expose a C API (you're free to implement it using C++). It'll cause the least headaches this way (no issues with name mangling, trying to interop with complex, user-defined C++ types, etc.).
I recommend you get some practice with building DLLs/shared libraries in C++ as a way to extend .NET and Cocoa applications (ex: C++ module used in objective-C) before you start trying to develop a grand library.
For timing the standard library has <chrono>, which has nanosecond resolution on Mac. Unfortunately it's only got millisecond resolution on Windows as of the VS11 Beta. I'm hoping they fix it without too much delay.
In C++, if I write a simple game like pong using Linux, can that same code be compiled on Windows and OSX? Where can I tell it won't be able to be compiled?
You have three major portability hurdles.
The first, and simplest, is writing C++ code that all the target compilers understand. Note: this is different from writing to the C++ standard. The problem with "writing to the standard" starts with: which standard? You have C++98, C++03, C++TR1 or C++11 or C++14 or C++17? These are all revisions to C++ and the newer one you use the less compliant compilers are likely to be. C++ is very large, and realistically the best you can hope for is C++98 with some C++03 features.
Compilers all add their own extensions, and it's all too easy to unknowingly use them. You would be wise to write to the standard and not to the compiler documentation. Some compilers have a "strict" mode where they will turn off all extensions. You would be wise to do primary development in the compiler which has the most strictures and the best standard compliance. gcc has the -Wstrict family of flags to turn on strict warnings. -ansi will remove extensions which conflict with the standard. -std=c++98 will tell the compiler to work against the C++98 standard and remove GNU C++ extensions.
With that in mind, to remain sane you must restrict yourself to a handful of compilers and only their recent versions. Even writing a relatively simple C library for multiple compilers is difficult. Fortunately, both Linux and OS X use gcc. Windows has Visual C++, but different versions are more like a squabbling family than a single compiler when it comes to compatibility (with the standard or each other), so you'll have to pick a version or two to support. Alternatively, you can use one of the gcc derived compiler environments such as MinGW. Check the [list of C++ compilers](less compliant compilers are likely to be) for compatibility information, but keep in mind this is only for the latest version.
Next is your graphics and sound library. It has to not just be cross platform, it has to look good and be fast on all platforms. These days there's a lot of possibilities, Simple DirectMedia Layer is one. You'll have to choose at what level you want to code. Do you want detailed control? Or do you want an engine to take care of things? There's an existing answer for this so I won't go into details. Be sure to choose one that is dedicated to being cross platform, not just happens to work. Compatibility bugs in your graphics library can sink your project fast.
Finally, there's the simple incompatibilities which exist between the operating systems. POSIX compliance has come a long way, and you're lucky that both Linux and OS X are Unix under the hood, but Windows will always be the odd man out. Things which are likely to bite you mostly have to do with the filesystem. Here's a handful:
Filesystem layout
File path syntax (ie. C:\foo\bar vs /foo/bar)
Mandatory Windows file locking
Differing file permissions systems
Differing models of interprocess communication (ie. fork, shared memory, etc...)
Differing threading models (your graphics library should smooth this out)
There you have it. What a mess, huh? Cross-platform programming is as much a state of mind and statement of purpose as it is a technique. It requires some dedication and extra time. There are some things you can do to make the process less grueling...
Turn on all strictures and warnings and fix them
Turn off all language extensions
Periodically compile and test in Windows, not just at the end
Get programmer who likes Windows on the project
Restrict yourself to as few compilers as you can
Choose a well maintained, well supported graphics library
Isolate platform specific code (for example, in a subclass)
Treat Windows as a first class citizen
The most important thing is to do this all from the start. Portability is not something you bolt on at the end. Not just your code, but your whole design can become unportable if you're not vigilant.
C++ is ultra portable and has compilers available on more platforms than you can shake a stick at. Languages like Java are typically touted as being massively cross platform, ironically they are in fact usually implemented in C++, or C.
That covers "portability". If you actually mean, how cross platform is C++, then not so much: The C++ standard only defines an IO library suitable for console IO - i.e. text based, so as soon as you want develop some kind of GUI, you are going to need to use a GUI framework - and GUI frameworks are historically very platform specific. Windows has multiple "native" GUI frameworks now - the C++ framework made available from Microsoft is still MFC - which wraps the native Win32 API which is a C API. (WPF and WinForms are available to CLR C++).
The Apple Mac's GUI framework is called Cocoa, and is an objective-C library, but its easy to access Objective C from C++ in that development environment.
On Linux there is the GTK+ and Qt frameworks that are both actually ported to Windows and Apple, so one of these C++ frameworks can solve your "how to write a GUI application in C++ once that builds and runs on windows, apple mac and linux".
Of course, its difficult to regard Qt as strictly C++ anymore - Qt defines a special markup for signals and slots that requires a pre-compile compile step.
You can read the standard - if a program respects the standard, it should be compilable on all platforms that have a C++ standard-compliant compiler.
As for 3rd party libraries you might be using, the platform availability is usually specified in the documentation.
When GUI comes to question, there are cross-platform options (such as QT), but you should probably ask yourself - do I really want portability when it comes to UI? Sometimes, it's better to have the GUI part platform-specific.
If you are thinking of porting from Linux to Windows, using OPENGL for the graphical part gives you freedom to run your program on both operating systems as long as you don't use any system specific functionality.
Compared to C, C++ portability is extremely limited, if not completely unexisting. For one you can't disable exceptions (well you can), for the standard specifically says that's undefined behaviour. Many devices don't even support exceptions. So as for that, C++ is ZERO portable. Plus seeing the UB, it's obvioulsy a no-go for zero-fail high-performance real time systems in which exceptions are taboo - undefined behaviour has no place in zero-fail environment. Then there's the name mangling which most, if not every, compiler does completely different. For good portability and inter-compatibility extern "C" would have to be used to export symbols, yet this renders any and all namespace information completely void, resulting in duplicate symbols. One can ofcourse choose to not use namespaces and use unique symbol names. Yet another C++ feature rendered void. Then there's the complexity of the language, which results in implementation difficulties in the various compilers for various architectures. Due to these difficulties, true portability becomes a problem. One can solve this by having a large chain of compiler directives/#ifdefs/macros. Templates? Not even supported by most compilers.
What portability? You mean the semi-portability between a couple of main-stream build targets like MSVC for Windows and GCC for Linux? Even there, in that MAIN-STREAM segment, all the above problems and limitations exist. It's retarded to even think C++ is portable.
What are the best practices on writing a cross platform library in C++?
My development environment is Eclipse CDT on Linux, but my library should have the possibility to compile natively on Windows either (from Visual C++ for example).
Thanks.
To some extent, this is going to depend on exactly what your library is meant to accomplish.
If you were developing a GUI application, for instance, you would want to focus on using a well-tested cross-platform framework such as wxWidgets.
If your library depends primarily on File IO, you would want to make sure you use an existing well-tested cross-platform filesystem abstraction library such as Boost Filesystem.
If your library is none of the above (i.e. there are no existing well-tested cross-platform frameworks for you to use), your best bet is to make sure you adhere to standard C++ as much as possible (this means don't #include <linux.h> or <windows.h>, for instance). When that isn't possible (i.e. your library reads raw sound data from a microphone), you'll want to make sure the implementation details for a given platform are sufficiently abstracted away so that you minimize the work involved in porting your library to another platform.
To my knowledge, there are a few things you can do:
You can divide the platform specific code into different namespaces.
You can use the PIMPL idiom to hide platform specific code.
You can use macros do know what code to compile (in this case the code will be platform specific). Check this link for more information.
Test your library in multiple environments.
Depending on what you are doing it might be good to use libraries such as Boost because it is not specific to a platform. The downside (or possibly the good side) is that you will force the use of the libraries you included.
Couple of suggestions from my practical experience:
1) Make sure of regular compilation of sources in your targeted platforms. Don't wait till the end. This'd help point to errors early. Use a continuous build system -- it makes life a lot easier.
2) Never use platform specific headers. Not even for writing native code -- for all you know some stuff in a windows header might expect some string which was ABC in XP but got changed to ABC.12 in Win7.
3) Use ideas from STL and BOOST and then build on top of them. Never consider these to be a panacea for problems though -- STL is easy to ship with your code but BOOST is not.
4) Do not use compiler specific constructs like __STDCALL. This is asking for hell.
5) The same code when compiled with similar compiler options in g++ and cl might result in different behavior. Please have a copy of your compiler manual very handy.
Anytime I work on something like this I try and build it in the different environments that I want to be supported. Similarly if you were making a web page and you wanted to make sure it worked in IE, Firefox, and Chrome you'd test it in all three of those browsers. Test it in the different environments you want to support, and you'll know what systems you can safely say it works for.
question as stated is bit abstract.but you can give QT a consideration
It's really just as simple as "don't using anything platform specific". The wealth of freely available tools availalble these days makes writing cross-platform code in C++ a snap. For those rare but occasional cases where you really do need to use platform specific APIs, just be sure to separate them out via #defines or, better in my opinion, distinct .cpp files for each platform.
There are many alternatives for cross platform libraries but my personal preferences are:
GUI: Qt
OS abstraction (though Qt does a great job of this all by itself): Boost
Cross-platform Makefiles: CMake
The last one, CMake, has been a tremendous help for me over the last few years for keeping my build environment sane while doing dual-development on Windows & Linux. It has a rather steep learning curve but once it's up and running, it works exceptionally well.
You mean besides continuous integration and testing on target platforms? Or besides using design to abstract away the implementation details?
No, can't think of anything.
I need to develop a Windows/Linux command line utility. The utility will talk to middleware that has a standard API on both platforms. I have done some cross-platform development before, on FreeBSD/Linux, which was considerably easier - and I had people in the group with experience that I could talk to.
At this point there is no one in my group who has tackled a Windows/Linux development project. I am looking for advice on how to best set it up. I'm kind of a newbie to C++ too, I have mostly developed C#/.Net GUI applications and Linux device driver level "stuff". Kind of a weird mix.
I was thinking that it would be best to define my own data types and not use either the Linux or the Windows defined types - keep the OS specific code in separate folders and include conditionally. That's kind of what we did for the Linux/BSD work. So it seemed like a good start.
One of the developers here is a big fan of Boost... another thought the TCLAP command line parser library was easier to use... Obviously everything has to be compatible with the licensing.
The code will be open sourced, but it is production code - so I don't want to be sloppy. What else should I be doing or looking for? Are there any best practices out there?
Boost is good, as is ACE. Between the 2 of those they cover pretty much anything you would want to do in a cross-platform manner. I have also gone the route of getting posix libraries for windows and using gcc on cygwin, but I don't recommend it.
Use a portable runtime that is supported on both platforms. I have had good luck with the Apache Portable Runtime.
Use standard C or C++ for most of the project. Only use platform specific functions when necessary. If possible, put those in a wrapper in isolated files so that the build (makefile) can substitute in the correct version for the appropriate platform.
Refrain from using #ifdef LINUX or #ifdef WINDOWS or similar conditional compilation. Those get really hard to debug and there are error prone when the keyword is not supplied to the compiler.
Use Boost. Among other things, you'll get a portable implementation of a subset of TR1, which is worth it if only for <cstdint> and the types within - int32_t etc. As well, shared_ptr is essential for many moderately complicated data structures.
Boost also has a slew of helper types which are extremely convenient in day-to-day C++ tasks. Two specific ones that come to mind right away are optional, and ptr_... polymorphic container types come to mind right away. String algorithm library is also very handy, considering the lack of very commonly needed string functions, such as case conversion or trimming, in the standard library.
Speaking of more heavyweight components, Boost.Filesystem is a very decent cross-platform abstraction for filesystem navigation, also a relatively common task in command-line tools. Then there's Boost.MultiIndex is a swiss army knife of containers - rarely truly needed, but when it is, it's indispensable.
I did a gig this summer in .NET and just ported to Mono. Worked great.
Although there are some good cross platform libraries out there (like Boost), remember that they are probably not there by default. This is especially problematic if you are shipping binaries only. The target platform is unlikely to have the library (or correct version of the library) that you need.
First prize is to stick with standard C++ (even if you need to implement simple stuff yourself). This avoid library dependence altogether.
If you must use a library, try statically linking against it (although this may create big binaries). This will allow you to avoid runtime failure due to lack of binaries.
If you must ship DLLs (or .so on some unixes) make sure that the correct version is shipped with your product and some way to avoid conflicts with the wrong version.
If you are shipping code, include the library with the code and build the library as well as your utility.
Also beware of GPL and possibly LGPL code. If you release a library with a GPL dependency (or modify an LGPL library) you will need to supply the code and allow redistribution as per the GPL.
TCLAP is the only header-only CLI parsing option that I'm aware of. As such, it strikes me as the most portable and is probably your best bet (it's currently what I use and recommend for exactly those reasons). It also helps that the API for TCLAP is very developer friendly and automatically generates decently formatted help messages for you.
Boost program_options has a shard library component to it, which is irritating to maintain ABI with. It also gets around nuisance parsing incompatibilities and behaviors from the getopt family of arguments.
I have used libparamset, that is cross platform (Windows, OS X, Linux) CLI parser. It provides flexible and powerful CLI parser and various UI building features (input error handling, wildcards, typo detection, task resolving, help formatting ...) to build a good command-line tool. It is suitable for both C and C++ projects.
I am writing a small C++ program for fun and for extending my C++ skill. Since its scope is relatively small, I also planning to try out cross-platform development by making this program support both Windows and Linux.
I reckon my C++ proficiency is sitting somewhere between casual and intermediate level: OO, a bit of templates and design patterns, used STL before and trying to look into it more in details, ... However, while coding this little program, I find that the deeper I dig into C++, the more pain I feel, especially when I come to understanding and dealing with differences between different platform's/vendor's implementation.
The use of cross-platform frameworks like Qt, ACE, Boost seems help to speed up development a lot thus make life easier, but I worry if this will beat my purpose. Can somebody give some advice if there is any "best practice" for doing C++ cross-platform development? Thanks.
Can somebody give some advice if there is any "best practice" for doing C++ cross-platform development?
There are three things:
Write your own code so that it's portable
Wrap platform-specific APIs behind an abstraction/insulation/utility layer
Choose cross-platform libraries
You can choose option #2 and/or #3.
Advantages of #3 over #2 tend to be things like, "It's already written, debugged, and supported"; and the disadvantages are like, "I have to learn it, I might have to pay for it, I can't necessarily support it myself, and it may not do exactly what I want."
Developers will often prefer option #3 instead of #2, especially if it's free open source (which all three of the libraries that you cited are).
http://blog.backblaze.com/2008/12/15/10-rules-for-how-to-write-cross-platform-code/
Should provide more detail to the answers already given.
Also I suggest using existing libraries that abstract endianness, data type sizes and differences. The following should be considered before starting your cross-platform project.
GUI
Qt
XVT
wxWidgets
General Libraries/frameworks
STL (Incorporated in most platform libraries already)
Boost
Game Development
SDL
Cocos2d-x
Use gcc. It's available on both Windows and Linux and the libraries and language syntax is identical on both platforms.
For cross platform GUI applications, Qt is a good idea. There is no getting away from having a dependency on a GUI framework if you are trying to achieve platform independence.
Unless you are doing GUI stuff cross platform isn't a big problem.
There are some small issues to do with filesystems ( different / \ separators, allowed characters in filenames etc) but these are at the application level rather than the c++.
Doing major applications gets more complex, you need to handle help, file locations an possibly security and user info in a cross platform way. For simple algorithm type programming there isn't a problem.
Qt is mainly a GUI library, although it has extra cross platform filesystems stuff. STL, Boost, ACE are cross platform but that isn't there main point.
Use them! Seriously. The only reason you may not want to use them is if you plan on working in an environment where they're not available. But, given their cross-platform nature, that's not likely.
You will find that the benefit you get from using them is immense, even if they weren't cross-platform. The "best practice" you speak of is to be able to deliver your "product" as quicly and easily as possible.
I once answered a question from someone who stated he didn't want to use GUI libraries at a level above Xlib. If he'd actually ever used Xlib, he'd know the pain we'd all felt when forced to code at such a low level of abstraction. This makes about as much sense as wanting to code in assembler because C/C++?Python/Perl/everthting-else is simply a higher-level abstarction.
this answers are really good and you can make a list for find where is the beginning. but i think you should read some articles about "porting application".not relevant with cross-platform development but this can give you very large perspective about cross platform development. In cross-platform developing, one of more importing thing is memory issues like "endian" (byte order- byte order can show differences for tehnologies or platforms)
use boost. they take care of cross-platform stuff for you.
boost::filesystem is a great example
i think you can learn a lot from using ACE or equivalent libraries. they will boost your understanding of c++ and design patterns. i think this is the best thing you can do to improve your coding skills.
If your are really interested in making your code as cross-platform as possible, use as many compilers as possible. If you are using Windows and Linux, use VC and gcc, at the minimum. This will ensure that you don't use complier specific features, and that you don't rely on system specific behavior. Use more compilers (Intel, IBM, etc) and OSs (OS X, Solaris) if you have access to them.
You can try using U++ > http://www.ultimatepp.org/index.html