I am a software engineer and i work in VC++, C++ in WIndows OS.
Are there any major differences when it comes to coding in C++ in Linux environment.
Or is it just some adjustments that we have to make when we need to code in C++ in Linux.
It would depend on the types of projects you've worked on and what native windows APIs you made use of. For example if you used the native Windows API for everything, you're going to have a pretty big task ahead of you, it'd be worth making your project(s) work nicely with Wine instead.
In the Linux environment you have the man pages, quite detailed documentation of almost everything :). As mentioned above, look at POSIX, and while I recommend Qt - it provides a LOT of abstractions for things you might want to learn to do the Linux way (eg sockets, filesystem...)
Use the POSIX API instead of the Win32 API.
Use gtkmm, Qt, or wxWidgets instead of MFC.
Linux programming world is very different from you are familiar with in Windows world. You have to understand it and get used to it. Once you understand you will not want to come back.
You have many small/good tools that works with each other rather then all-in-one MSVC solution. For example:
In Linux you have a compiler as stand-alone tool (Gnu compiler collection), you have build system as stand-alone tool (autotools, CMake). You have GNU Debugger as stand alone tool and you have very good editors as stand alone tool (like hard core vim/emacs).
There are integrated development environments like Eclipse, Netbeans, KDevelop, Anjuta
but still you have to understand how stuff works.
You should understand that each separate tool is very powerful and integrates with others.
OS Level API is designed for simplicity. You'll rarely will find calls like CreateProcessEx with bizzilion parameters rather you have simple fork()+exec(). man is you real friend in all connected to system API and standard C library.
GUI - You have two big GUI libraries Qt/GTK. Qt is great C++ library that makes GUI development enjoyable work (unlike MFC). GTK has both C and C++ APIs GTK and GTKmm (no experience with them).
i18n/l10n/unicode - this is where Linux programming makes life easier. Almost everything is UTF-8. No wide API crap, no issues with opening Chinese file names with simple fopen or ifstream, no 3rd part library that can't open file with Unicode name. Great built in tools available like gettext, and good translation toolkits like KBabel.
Libraries - this is where Linux programming makes you hate Windows. Almost every single free library is already installed or available with simple apt-get or yum install. no debug/release incompatibility crap, no DLL_EXPORT-ing, simple robust, making shared objects is as simple as working with static libraries (and most do not use static libraries at all).
My $0.02
(I'm Linux programmer that have deal a lot with windows development)...
It depends on how many windows-specific things you've been using. The standard part of C++ is the same, but using that will not get you much further than command-line applications.
There's also the whole makefile-instead-of-letting-VS-build-for-you thing. Depending on what tool (or IDE) you decide to use in Linux, that could be a big difference.
I have worked quite a bit on both platforms and like them both, but in general I found most developers to like one and hate the other.
I would describe *nix environment as "geek friendly": many excellent and very flexible tools on your disposal. Some of them introduce hard learning curve, and some are simply broken but still popular for some reason (make) but if you are willing to invest some time in properly learning them, the reward is high. In fact, I use many *nix tools even when working on Windows: vim, grep, perl, etc...
On the other hand, Windows platform offers Win32 API which has way more functionality than POSIX, is very well documented and supported by very good tools. Debuggers on Windows (especially windbg) are generally more powerful that any *nix debugger I have tried, although gdb is generally good enough for most tasks. Deployment of executables is also easier than in Linux world - in fact the only truly reliable way to deploy software on Linux is to ship source code and build it on clients' machines via config/make.
I would suggest to use a Buildsystem like SCons which works very well on both Linux and Win32.
Take a look at the source to some open-source project that runs on both Linux and Windows. Typically, over 80% of the code is identical, and the bigger the project the less the system-specific part tends to be. Unfortunately, there can be hard parts (threading, non-blocking network IO, GUI details) in the system-specific code.
There are some major differences that I can think of:
Tools. Good and bad points. If you are used to Visual Studio, there is nothing quite like that available. Each Linux IDE has some issues. On the other hand, especially debugging tools are very good. But all in all, you are supposed to create your own working environment from what's available.
API's. Documentation varies wildly. Some components are well documented, but often you end up reading the source code to figure out how something is supposed to work. On the other hand, you have source code so eventually you have all the tools possible to figure out why something doesn't work.
The Linux programming community is usually very good as long as you remember to behave and you find the right places. SO isn't half bad in some issues, but sometimes you need to find other places.
Things are not quite as automatic as you might have learned in the Windows world. Yes, some tools allow you to create projects without Makefile knowledge, but really, you should learn how to use them. In Windows it's much more common that you never edit the project files (e.g. Makefiles) by hand.
If you want to work in kernel space (drivers etc) C is a better bet than C++ since the kernel is written with that.
And I agree with people suggesting Qt. Very nice widget set. Beats at least Swing (yes, I know, it's Java) hands down. And Qt Creator isn't half bad.
Don't underestimate the power of shell scripting! Something very few Windows programmers have figured out, but you can do a hell of a lot with them to help your work.
A typical windows programmer who is used to Visual C++ might find the following aspects of Linux C++ programming novel, or difficult:
Linux programming isn't linux programming, it's Unix programming. Unix programming's roots go back a lot further than the MS-DOS roots of Windows, and it shows in a lot of places.
Windows programmers tend to think about the environment, they tend to think about the IDE tools (your GUI editor, compiler, debugger) first. Unix programmers tend to be arranged in various tribes, many core Unix (linux) C++ programmers are very comfortable working from the command line without an IDE, and some, I'm sure, use visual-studio style IDEs on Linux, of which there are many.
I personally found I had to learn how to read (and maybe write) a makefile, build a bunch of standard Linux/Unix applications from source (and understand how to type my way through steps like 'autoconfiguration' and the various "--command-line-options" one might select there), before I get the feel, and the flavour of the environment.
Until you are a seasoned Linux system administrator you might want to stick with the newbie-friendly Linux distributions (like Ubuntu).
Related
Background: I'm working on porting a large project that was developed in C++ exclusively for unix systems, to be compatible with windows to make way for an eventual windows distribution. I don't have very much experience in Windows development, but I'd like to get whatever I can do, done right, before senior developers move in and take over.
Question: So for a while, I've been looking up Windows versions for all the unix/posix calls that are used in the software, most coming from dirent.h, unistd.h, and some ones under sys, like sys/stat.h or sys/types.h. And although it'll take a lot of work to modify the programs to adopt the new Win32 API calling conventions and return types (and sometimes all new functions), it'll probably work, eventually.
But I've been seeing this come up frequently, the fact that MinGW, I guess, includes many native unix calls and functionalities as part of the GCC environment, and can translate them into windows-compatible calls so you can compile on Windows, and use said compiled program on Windows easily. In fact, one of the similar questions I read in the sidebar talks about just that. What I don't understand, and seem to have trouble understanding, is exactly the extent of this built-in translation functionality, and where I can find a list of system stuff that'll work with this.
Sorry this post is a little unstructured and that I'm so green with this, but I only have 2 weeks to try to accomplish something with this before I get swapped with a senior developer.
No. MinGW does not attempt to implement UNIX functions on Windows. It cannot replicate most system calls with no effort.
However, Cygwin does do that.
Are there any platforms to build GUI platform without resorting to QT or .NET using native C++ ?
QT is cool, but take a lot of time to learn, in addition it has a lot of things I don't really need and really dislike QT IDE, compared to Visual Studio (I know you can use QT within Visual Studio)
.NET suffers same problem (I am actually learning C# and WPF right now, though it looks like WPF is somewhat easier to program and you can call native C++ code from WPF)
I am looking for something that is: relatively easy learn, does not have to have advanced features, works with C++11, support C++11 multi-threading, works with Visual Studio. Planning to build some applications for Numerical analysis.
There are lots of alternatives with varying levels of support in VS.
MFC has quite a bit of direct support in Visual Studio in the form of code generators, Wizards, etc. Unfortunately, the basic design is very old and hasn't aged very gracefully at all. Quite a few programmers not only would but do cite it as a prime example of a library that's better avoided if humanly possible.
WTL is Microsoft's other class library for producing Windows applications. It's a much newer design than MFC and generally considered much cleaner and nicer. As implied by the name, it's heavily template based, which helps it produce applications that are generally considerably smaller and faster than MFC ever attempted. For better or worse, Microsoft placed it under a fairly permissive open-source license some time ago, and updates since then have been quite minimal. Despite both being from Microsoft, Visual Studio has never done much to support WTL development.
wxWidgets started as more or less a clone of Microsoft's MFC, but has continued active development while MFC has mostly stagnated. It now has quite a few features (e.g., XML-based UI design, layout managers) far beyond anything MFC ever even considered including.
Ultimate++ is a fairly unusual toolkit that has mapped its own route (so to speak) that's quite a bit different from most others. They have their own IDE (TheIDE). Code can be quite simple and short, but is enough different from most typical C++ that many people find it difficult to grasp at first (and some experienced C++ programmers don't particularly like how some thing work).
GTK+/gtkmm is less of a Windows framework than a Linux framework that's portable enough to also work under Windows. It's probably not your best choice if you're developing exclusively (or even primarily) for Windows. These are also much more purely GUI frameworks than most others (i.e., they don't include things like collections, networking, cryptography, etc., that many others do include).
FLTK is another cross-platform toolkit. Its fairly small and fast, but somewhat like GTK+, it seems (at least to me) less like a Windows toolkit, than a Linux toolkit that happens to be portable enough that it can also work on Windows (but the results don't look or feel much like most Windows applications).
Juce was originally used to develop some music software (Traktion) so it includes a lot of music-oriented functionality. It also have some fairly unusual widgets that most others don't include (especially widgets that imitate controls you'd see on all sorts of audio equipment). Nonetheless, it has a solid core of basic GUI functionality, as well as the usual "extras" like network, crypto, XML and JSON, etc. Although I haven't tried to do anything like a full review of the code, it appears to be rather better written than most.
That's not a complete list by any means, but I think it hits most of the more popular/widely used GUI toolkits (other than Qt, of course).
Some time ago I asked myself exactly that same question.
I wrote my program using C++/CLI, which was not bad (my C++ code was very well isolated from the GUI/CLI part), but sharing the executable with others was a problem: it was the typical - it runs in my PC(...only). So, I needed a light alternative to the user unfriendly command line programs in scientific calculations, which I could easily share.
I am now happy to use Nana. Please join the group of users and / or developers of Nana and... have fun!
GUI with Nana C++ Library
Nana C++ Library takes aim at easy-to-use and portable library. It
provides a GUI framework and threads for easy programming with modern
C++ methods, such as traits, metaprogramming and other template
technologies.
Since you plan to develop exclusively for Windows, I think you should stay with MS provided GUI toolkits. While third party toolkits may provide the cross platform advantage you already said don't need, they add complication and dependencies.
Complication by for example when a new Visual Studio is released, then you have to wait for the toolkit to get that new VS supported, and dependencies, which means more dlls to be installed on the target system.
Plus some toolkits do not use the native look of the operating system, like many java programs for example.
I'm not sure the way I'm organising my library is the most elegant way to organise it. I'm mainly concerned about making all the code that I type compile/run for all systems that I'm targeting (keeping it portable), and also keeping it up-to-date for every system.
For example:
I'm not sure using __declspec(dllexport/dllimport) would be used for Mac or Linux. I assume that it's not, but I don't know what the equivalent is for Mac/Linux is. Or another example might be calling specific Operating System functions, which I try to avoid. However, things such as: measuring how long something takes to happen*, in a precise manner, does require me to call OS specific functions.
*as in getting the user's time precisely (down to micro/milli-seconds).
The systems that I am currently (perhaps more in the future) aiming for is Mac, Windows and Linux. But testing that the code compiles (and runs correctly) for every system just seems like a waste of time. As currently, the way I'm proposing to do it, requires me to make a separate project for every system. i.e. I create a Visual Studio Project for Windows, an Xcode project for Mac, and use the command line for Linux or use some other IDE.
Okay, so my main problems with the way I organise things are:
1. Time Consumption, as in creating the projects for all systems and keeping each indiviual project, for each system up-to-date.
2. Knowledge on all IDE's/Compilers that I require to use
Please note, I've never really used* Linux before, I'm thinking about switching. The only problem that I'm concerned about is finding the right tools for me to use with it, and finding the right Distro that would suit me, for what I need. I would really appreciate if someone that is experienced with Linux could guide me, or give me some advice whether to switch or not.
I really like Visual Studio, and it's been my main IDE for quite a while now. I'm just not sure if I want to ditch Visual Studio or not, for Linux; as I don't know if the tools that are available for Linux can do what Visual Studio can or not. What I mean is, it being as user friendly as Visual Studio is. I'm afraid to learn how to use Linux's tools, I'm just not sure if it's worth doing so. Time isn't a major factor on this library, I have plenty of time, I'm fairly young and determined to program as my career in the future.
*I have used it before, but I've never replaced it for Windows.
I am currently hosting all my source code for my project on BitBucket, but at the moment, I only have the RAW code on my repo. There is no project files or any other tool to compile it with, just the code and a readme file. I was thinking of using Makefiles, since they seem popular. But I've never made a Makefile before, don't get me wrong, I am willing to learn. I'm just not really sure where to start. I've heard that people use CMake to create portable libraries, such as SFML and Ogre3D. I've built a couple of libraries with CMake, but I have no clue on how to actually make my own library with it to make my project/make files. Should I learn and incorporate CMake with my library, or is there a better option available?
EDIT:
I'm not aiming to write a library for actual Software that uses a GUI. I'm mainly aimed to write games.
1 - Boost. Boost will help your portability more than you can imagine. Its only real sticking point is, believe it or not, OS X.
2 - Use CMake. It integrates with Visual Studio project files as the build tool, and you can put most of your different-platform compilation voodoo in there.
3 - If you're seriously writing a portable library, consider writing it in C/writing a C wrapper, or making it header-only, or providing the source-code. Making it a shared or statically linkable library does not mean that it will play nice. Name mangling leads to inconsistencies that will blow your mind.
4 - Always be explicit about the number of bits in each variable.
5 - use git. It'll allow you to setup a crappy local server for a repository very easy and get very fast transfers of the kind of huge changes MSVC will make annoyingly
There are a lot more best-practices that can be discussed about cross-platform development. All of that advice isn't applicable in every case; I have a very code-heavy Linux/Windows library that I code almost exclusively in MSVC2k10 and mostly build/test for in Linux, and it is nowhere close to header-only.
EDIT in response to comments:
git was suggested because I find it very easy to use and manage locally. I've use svn before and liked it, I won't really endorse any others, but there are probably plenty of fine ones.
To expound on point 3,
A C wrapper would make it so that anyone anywhere could use your library - FORTRAN developers, Ruby, even Java.
Otherwise you generally have to have similar compiler versions to link properly and it will only link to other C++ code, outside the case of DLLs, and there are still versioning issues. It's one of the stupidest problems in C++ left over, check "name mangling" on Wikipedia. There is a reason widely-used libraries are written in C or have C wrappers, such as libz, openssl etc.
There are other advantages to it. Exception propagation across dynamic libraries is non-existent; with static libraries it can be inconsistent or non-existent.
You'll find that the most widely-used C++ libraries are mostly header-only, like Boost. A header-only library solves many problems by putting all the code directly into a project in a relatively intuitive way, and modern compilers can still optimize away much (but certainly not all) of the extra compile time associated with it.
With all this said, it is certainly possible to do without a C wrapper or header-only, it is just annoying and very troublesome. DLL hell and its Linux equivalents still exist.
You also asked about Boost. That depends. If you're distributing the sourcecode then you certainly must distribute Boost with your code/have people install it. Having people install libraries in order to compile other libraries or use programs is common practice. Think of how specific versions of DirectX come with games for an example.
However if you are distributing binary versions of your library, statically linking against Boost will eliminate any need to include it as long as you are careful to keep Boost headers out of the outward-facing parts of your library. This is where you start seeing things like void * pointers inside C++ headers; an unfortunate side-effect of some of the shortcomings of C++ compilation and library distribution unfortunately.
CMake is a good choice. You can learn to use it. Read a tutorial:
http://www.cmake.org/cmake/help/cmake_tutorial.html
But, if your targets are Linux and Windows only. It is probably OK, in your case (small/average first multi-platform project), to maintain 2 separate build systems.
On Linux, Use Make. It is standard and has a very good reference manual:
http://www.gnu.org/software/make/manual/make.html
On Windows. Use your IDE project file, be it Visual, DevC++ or other. That is the simplest way to go.
Most important, make it easy to test your library/software on different platforms. Install a virtual machine on your desktop. Or at least compile your library into Cygwin.
Once you are here come back on stackoverflow and we will help !
Personally I'd leverage a framework like Qt, because it is quite portable, it does abstract a lot of OS functionality (files, timing, threads, networking), and you get a decent, free IDE (Qt Creator) that is also portable and runs on Windows, OS X and any Unix flavor that runs Qt. It'd give you the lowest barrier to entry. Qt Creator can leverage the Visual Studio compiler and the CDB debugger if they are available.
You do not need to use OpenGL to use Qt, in fact you're not bound to any particular graphics subsystem. Qt only "uses" OpenGL in Qt 5 for the Qt Quick 2 graphics backend. It's not needed for Qt 4, nor for Qt Quick 1 (even in Qt 5!).
You can use any 2D or 3D framework you fancy to push images and other content to the screen. What Qt is good at is creating the kind of 2D imagery that is often needed in games - menus, configuration screens, HUDs, etc. There's a lot of controls and drawing primitives that Qt makes easy to leverage for your purposes.
Qt also lets you use a reasonably powerful model-view and networking frameworks, thus you'd be able to reasonably easily generate server or client lists that update in real time.
There'd need to be a small amount of shim code between Qt and DirectX, of course. On the output side, you typically end up with a QImage in Qt, and then use DirectX, SDL, OpenGL, etc. to push it to the screen. On the input side, you need to call qApp->processEvents() within your main game loop, and you will need to post user input events from DirectX etc. to Qt's event queue using qApp->postEvent(...). This would be only needed if, say, DirectX main loop consumes all Windows messages and won't let standard winapi/win32 code (Qt's windows event dispatcher) see them. I haven't deal with DirectX much, so others feel free to chime in with details, of course.
I have read a few articles in the cross-platform tag. However, as I'm starting a fresh application (mostly a terminal/console app), I'm wondering about the easiest way to make it cross-platform (i.e. working for Linux, Mac OS X, and Windows). I have thought about the following:
adding various macro/tags in my code to build different binary executables for each operating system
use Qt platform to develop a cross-functional app (although the GUI and platform component would add more development time as I'm not familiar with Qt)
Your thoughts? Thanks in advance for your contribution!
Edit: Sounds like there are a lot of popular responses on Java and Qt. What are the tradeoffs between these two while we're at it?
Do not go the first way. You'll encounter a lot of problems that are already solved for you by numerous tools.
Qt is an excellent choice if you definitely want C++. In fact, it will speed up development even if you aren't familiar with it, as it has excellent documentation and is easy to use. The good part about it is that it isn't just a GUI framework, but also networking, XML, I/O and lots of other stuff you'll probably need.
If not necessary C++, I'd go with Java. C++ is far too low level language for most applications. Debugging memory management and corrupt stacks can be a nightmare.
To your edited question:
The obvious one: Java has garbage collection, C++ doesn't. It means no memory leaks in Java (unless you count possible bugs in JVM), no need to worry about dangling pointers and such.
Another obvious one: it is extremely easy to use platform-dependent code in C++ using #ifdefs. In Java it is a real pain. There is JNI but it isn't easy to use at all.
Java has very extensive support of exceptions. While C++ has exceptions too, Qt doesn't use them, and some things that generate exceptions in Java will leave you with corrupt memory and crashes in C++ (think buffer overflows).
"Write once, run everywhere." Recompiling C++ program for many platforms can be daunting. Java programs don't need to be recompiled.
It is open to debate, but I think Java has more extensive and well-defined library. The abstraction level is generally higher, the interfaces are cleaner. And it supports more useful things, like XML schemas and such. I can't think of a feature that is present in Qt, but absent in Java. Maybe multimedia or something, I'm not sure.
Both languages are very fast nowadays, so performance is usually not an issue, but Java can be a real memory hog. Not extremely important on modern hardware too, but still.
The least obvious one: C++ can be more portable than Java. One example is FreeBSD OS which had very poor support for Java some time ago (don't know if it is still the case). C++/Qt works perfectly there. If you plan on supporting a wide range of Unix systems, C++ may be a better choice.
Use Java. As much bashing as it gets/used to get, it's the best thing to get stuff working across any platform. Sure, you will still need to handle external OS related functions you may be using, but it's much better than using anything else.
Apart from Java, there are a few things you can run on the JVM - JRuby, Jython, Scala come to mind.
You could also write with the scripting languages directly( Ruby, Python, etc ).
C/C++ is best left for applications that demand complete memory control and high controllability.
I'd go with the QT (or some other framework) option. If you went with the first you'd find it considerably harder. After all, you have to know what to put into the various conditionally compiled sections for all the platforms you're targeting.
I would suggest using a technology designed for cross-platform application development. Here are two technologies I know of that -- as long as you read the documentation and use the features properly -- you can build the application to run on all 3 platforms:
Java
XULRunner (Mozilla's Development Platform)
Of course, there is always the web. I mostly use web applications not just for their portability, but also because they run on my Windows PC, my Ubuntu computer, and my Mac.
We mainly build web applications because the web is the future. Local applications are viewed in my organization as mostly outdated, unless there is of course some feature or technology the web doesn't yet support that holds that application back from being fully web-based.
I would also suggest Github's electron which allows to build cross platform desktop applications using NodeJs and the Google's Chromium. The only drawback for this method is that an electron application run much slower than a native C++ application due to the abstraction layers between Javascript and native C++.
If you're making a console app, you should be able to use the same source for all three platforms if you stick to the functions defined in the POSIX libraries. Setting up your build environment is the most complicated part, especially if you want to be able to build for multiple platforms out of the same source tree.
I'd say if you really want to use C++, QT is the easiest way for cross-platform application, I found myself using QT when I need an UI even though QT has a large set of library which makes pretty much everything easier in C++.
If you don't want to use QT then you need a good design and a lot of abstraction to make cross-platfform application.
However I'm using more and more Python bindinq to QT for medium size application.
If you are working on a console application and you know a bit of python, you might find Python scripting much more comfortable than C++. It keeps the time comsuming stuff away to be able to focus on your application.
I am trying to save some money and develop a desktop application that would work on both Windows and a Mac OS. Is this possible? Can we do it in C++ and then, with a few fixes and tweaks, still reuse the same app on both OS?
Yes this is possible. Some code may differ as there are differences in the operating systems.
You should use a common library for GUI such as Qt: http://qt.nokia.com/
It is worth noting that Qt brings much more cross-platform features to the table, so familiarize yourself with it.
There will be some differences to handle such as
File paths (C: doesn't exist on Mac, \ and / are path separators, etc)
File endings differ (CrLf in Windows, Lf in Mac)
You need to compile to two different target CPU's. Most C++ compilers can do this.
The same code can be used for both, you just define regions to be (or not be) included depending on what OS the compiler is targeting.
Just Google a cross-os development guide, looooots of people has done this before. :)
It may not be relevant, but still worth noting (because you said "save money"), that both Java and the Mono Project (.Net, Qt) allows you to write cross platform applications with limited skills about the underlying platform. They are higher level language which in general are considered a time saver (but that is a separate discussion.)
Expanding on my comment:
Don't.
Write your library code in portable C++; putting as much as possible of the functionality in the library, making sure you study the platform-specific APIs (probably Cocoa and .NET) as you go, so the interfaces to the library are at least moderately suitable for either.
Then wrap your library in native binaries; ensuring that you pay attention to how applications are supposed to look on each platform, as well as the feel of them.
Building an application that looks like an X11 application and does everything in a manner somewhere between a Gnome application, a KDE application, an OS X application and a Windows application will really hurt user experience.
Badly.
WxWidgets
This question gets asked a lot, see also:
this question, this one and this one amongst others.
Coming in late to the party here!
I'm in the last stages of finishing a cross-platform, commercial application (OS/X and Windows for right now, conceivably Linux or iOS later).
We're using an open-source, cross-platform C++ development library called Juce, and I can't speak highly enough of it. It's extremely full-featured, the code is solid and high-quality, and you can apparently build for Windows, OS/X, Linux, iOS and Android from the same codebase (we've only tried the first two, but other developers are apparently reporting success for the other platforms).
What's particularly nice is that lead developer is very active on his bulletin boards and extremely responsive to trouble reports.
Also, you can license the library under GPL, and they also have a very reasonably priced commercial license.
Juce is very popular amongst people doing digital audio applications - indeed, to my best knowledge many or perhaps most of the top commercial digital audio apps use this system - but it's very full-featured and extremely fast and should be considered a top candidate for any cross-platform development application.