Migrate Win32 C/C++ Applications to Linux
An anonymous reader writes "This series of articles helps you migrate your Win32 C/C++ applications to Linux on POWER. Win32 C/C++ Apps to Linux Part-1 of this series covers the Win32 APIs mapping to Linux on POWER regarding the initialization and termination, process, thread, and shared memory services. Win32 C/C++ Apps to Linux Part-2 illustrates how to map Win32 to Linux with respect to mutex application program interfaces (APIs)."
...that sometimes during the process the stragglers fall prey to hunters.
Nope. It relates to porting Mac applications to run under Solaris. They just called it "Win32C/C++ Applications to Linux" to see if you'd ask a stupid question.
Worked brilliantly, too!
To fight the war on terror, stop being afraid.
I was thinking about this today. everyone complains that there isnt *Insert Random Program HERE* available for Linux, isnt part of the problem that most code being written isnt portable? eg its too dependant on specific libraries.
.
I cant write code myself, so obviously there is a lot that i dont know. But is it really that hard to write code that is portable?
Thoughts , Ideas?
Comments and/or Flames should be posted below this line
---------------------
The hardest part of porting to LINUX will be refactoring all of the GUI stuff.
No. No it wouldn't.
OS-X has the market share of Linux with the cost of Windows. If you want a Server, Linux is a better option. If you want a desktop, Windows generally wins out. Why the hell would it be smarter to "move apps to OS X"?
Just moved J2EE webapp from windows to linux. Really nothing to it ;)
Apoptosis
Yeah, but aren't most computers running Linux backend servers? In terms of desktop users that need program X, I'd imagine there are more Mac users than Linux users.
I'm taking a C++ class at the local college that's being taught by the Unix guru. The class is using Visual Studio .NET as the IDE (which the instructor is not familar with and is threatening to go to Linux instead).
;) I would like to learn how to program basic C++ fluently on both platforms.
No offense, but anyone who can't figure out how to use and become familar enough with the visual studio IDE to use it in a teaching environment shouldn't be called a guru of anything. It's extremely simple to use until you want to start doing very complex things. And that's when you start pining for makefiles. I can't imagine you're writing anything that complex for (what your post would indicate is) an introductory c++ class.
Tried using Visual C++ Express edition but it seems more trouble to use (e.g., there's no automatic prompt to prevent the DOS box from disappearing).
Actually, there is. Where it is buried in the settings? Couldn't tell you off the top of my head, but here is something for you to try: Navigate to the directory where the exe is being dumped and run the thing from the command line yourself.
Anyway, I tried compling the sample programs under gcc and g++ on my Linux file server, and I get a lot of errors. I thought C++ (or at least, C) was supposed to portable.
Not familiar with the book, but unless it is doing something windows specific (and it may be) you should not have any trouble compiling simple programs under gcc and the MS c++ compiler.
Migrating a Win32 app the way they suggest is going to be painful and time consuming. In addition, there are numerous things that they don't mention, like associated performance costs: is creating a thread going to be more expensive or cheaper on Linux vs. Win32? Don't look to the article for the answer. It doesn't even mention the biggest parts like the graphics/windowing library.
Secondly, it is making a wild assumption that your win32 app is written in a that is conducive to a Unix/Linux process model. Namely that you spawn processes and use environment variables as opposed to having a message loop and handlers (the way most windows apps are written).
Third, if it was so straight forward to port a Win32 app, why not just write a library that maps the windows calls onto the equivalent Linux calls instead of manually changing all your source?
Finally, why not look at a binary solution like Wine first and not touch your source at all?
This is the worst way migrate app. The source works and manually mucking with it like this is a good way to break it and introduce all sorts of bugs. Look for a binary solution like Wine. Then look to see if somebody implemented a Win32 on Linux library next to recompile (like Cygwin in reverse). Then, the last choice is to factor out your platform specific portions of your code and replace them with OS neutral calls. But beware of the performance of your app, it will probably take a hit. But, hacking apart your app like this makes me cringe.
Facts are meaningless. You could use facts to prove anything that's even remotely true! -Homer Simpson
I don't get it. IBM seems to have some massive aversion to Wine. It seems to me the easiest thing they could do would be to port Wine to the Power architecture. It would consume a little time, but surely nothing as suggesting every application developer rewrite massive parts of their Win32 app. These articles basically suggest an app needs to be rewritten from scratch, which will immediately make any ISV laugh at Linux on Power. (Why would you bother porting a Win32 app to Power? Why not just keep using a cheap Intel box running Linux?)
Winelib was specifically designed to help with porting and you can do it tiny controlled steps:
1. Port from MSVC++ to the MinGW compiler and develop things like a Makefile.
2. Test the app.
3. Port the code from Windows to Linux (not as trivial as you'd think - there are problems with case sensitivity, etc.)
4. Test compiling.
5. Finish compiling using the custom Wine tools, such as winegcc (a wrapper around gcc that makes it behave like MinGW).
6. Test your Winelib app.
7. Begin ripping out chunks of Win32 specific code and replace them with native equivalents - Wine dialogs for KDE/GNOME ones.
8. Test
That's a valid and controlled migration path. Asking developers to basically rewrite massive chunks of code involving threading, memory management, and other such exciting things is a nightmare. Oh, and after rewriting you get to debug it all. Would you trust an enterprise app that just had it's whole threading model replaced?
The part I find amazing though, is just how much they haven't addressed. What do you do when your app relies on COM? What about Windows common controls? What about networking?
Anyway, it looks like IBM missed the ball - a few engineers porting Wine to Power could have solved many of their migration issues. It certainly would have solved every single one mentioned in these articles. Instead they want the software developers of the world to take on the task of rewriting their apps.
----- obSig
I'm taking a C++ class at the local college that's being taught by the Unix guru. The class is using Visual Studio .NET as the IDE (which the instructor is not familar with and is threatening to go to Linux instead). At home, I'm using Visual C++ 6.0 Learning Edition that was provided by the Deitel and Deitel book. Tried using Visual C++ Express edition but it seems more trouble to use (e.g., there's no automatic prompt to prevent the DOS box from disappearing).
That's because you're running it under the debugger, and the assumption is that if you want it to stick around, you most likely have a breakpoint set somewhere.
Run it outside of the debugger - namely, by hitting CTRL+F5, or the "!" icon - and it'll run and when it terminates it'll ask you to press a key before finishing.
There you go. Learn your tools, and you'll find it much easier to use them.
Coming soon - pyrogyra
I take it back when I said "C++ is not supposed to be portable." It really depends. Straight C++ with no OS specific calls should work just fine on any platform. (You'll have to recompile it of course)
If you are having problems, make sure that there aren't any OS specific calls being used.
IMHO, the ease or difficulty in porting an application really begins at the design stage. If you design for a standard(GUI apps excepted) like POSIX then porting is much easier. Granted that many things on Windows become more difficult but usually not impossible. I have written many apps over the years for diverse platforms and usualy only have to rewrite one module that contains the platform specific code. For example, calling SYS$ & LIB$ functions on OpenVMS. However, whe it comes to the GUI then things get a lot more indeterminate which it where the auhor is coming from. There are some tradeoffs to be done here. Either:- 1) Design for performance 2) Design for portability If you take the former and for example, design the GUI using Visual Studio tools then you will get something that will work and perform well on Windows but moving to other platforms is nigh on impossible. So, where do we go in the future? Well Microsoft would want you to go down the .NET route but they ave singularly failed to release it for other platforms. Mono is there but it does not have the cachet of Mictosoft support which is needed in many companies.
Java is pretty portable and there are lots of skill out there to continue development.
There are other niche languages & environments that are portable but these have their roots in OSS and sometimes trying to itroduce something like Python into a totally Microsoft shop is like trying to make the Red Sea part. {I know as I tried this and was regarded as a subversive influence.}
The overall situation is cloudy but there are breaks of sunlight where Portability is a prime consideration and the company can reap the benefits in a MultiPlatform world.
I'd rather be riding my '63 Triumph T120.
Comment removed based on user account deletion
If you're programming a simple program in Visual Studio and it won't compile when you try doing it with gcc/g++, it's probably a very simple problem.
Your main in Visual Studio is probably "void main(void)" and returns nothing. To compile it in gcc, declare "int main()" and make the last line of main "return 0;" and it will probably compile.
And what the hell is POWER and pSeries? I'm pretty much going to ignore this article. I've been writing win32 software for quite some time and am seriously fed up with that platform. Rather than tweaking my software so that it works with Wine I'm much more interested in rewriting the GUI from scratch using wxWidgets. With a wx based application, you can then compile it into native Linux (GTK+), native win32, or even Mac OS X apps. To me that seems like the most promising route. I've used some wx based applications like Audacity and they're just amazing, really look like they belong on each target platform.
I am not that familiar with WINE, but isn't there a package to install on Windows that integrates nicely with VisualStudio where you can simply check to see if your application will also work on Linux under WINE? That way, it would make developers conscious of whether they were using libraries that would make it incompatible with WINE. Is this already possible?
That's because most programs for Linux are written with portability in mind, including the libraries. That's why the Linux code compile fine on other platforms, including Win32, and not always the other way around.
The author might have meant: "Porting Windows programmers to POSIX" :-)
SIOUX basically just creates a simple MacOS 9 app with a window that acts as a console. Just add that, and standard I/O will behave almost exactly like it does on a *nix machine.
English is easier said than done.
The second article "Migrate Win32 C/C++ application to Linux on POWER, Part 2: Mutexes" worth nothing, since you can't use semaphore (SysV semaphore) instead of mutex. It seems that the author do not know/understand the very basic difference between binary semaphore and mutex - and the difference is that there is no owner for semaphore and there is always owner for mutex. This means that once mutex taken/locked, only the thread/process which holds the lock able to release the lock, and this is not true for binary semaphore ... since it has no owner and any process/thread can unlock it.. I can even say that the example demonstrated in second article is dangerous.. Since it leads to misunderstanding and production of wrong/problematic code. At the moment there is no standard way to map Wind0ze inter-process mutex to Linux, this could probably be done using FUTEX API, but it is still changing, not standard and not well documented.
Regards,
Mike
Third, if it was so straight forward to port a Win32 app, why not just write a library that maps the windows calls onto the equivalent Linux calls instead of manually changing all your source?
What do you think WINE is? It's exactly that library, plus a loader and relinker and other related tools. You certainly can compile win32 programs against it for porting purposes.
WINE is a binary solution only in the worst case -- if the port is being done by someone with the source, they can recompile against winelib and so be portable to non-x86 targets.
Well, considering that most of the apps i've written under MSVC utilize either MFC ( yea i know its 'orrible but gets the job done ), ATL and COM, with very little direct code interfacing to Win32 layer, this doesnt help much.
For similar app under linux its easier to start from a scratch and just lift the parts of the code that are separate classes/libs with no or little platform-specific dependencies.
http://validator.w3.org/check?uri=http%3A%2F%2Fwww.slashdot.org Errors found while checking this document as HTML5!
One notibly important difference between Win32 and Linux is that the internal Unicode encoding is UTF-8 as opposed to UTF-16LE. This takes some getting used as it requires special consideration when working with text (e.g. when iterating over individual characters). I have prepared a document and a text.h header file [1] that could assist people with porting Win32 applications to Linux. Or at the very least it explains how to maintain I18N support as you migrate code.
[1] The header is part of a library but you can easily remove the library specific #defines.
Writing perfectly portable code is possible, but as they say "there ain't no such thing as a free meal." Let's take your DirectX vs OpenGL example, just as a random example, to illustrate the problems.
1. It costs extra time and money.
And it costs time and money to also _test_ it on the new platform. Otherwise you won't even know what functions don't exactly work the same. Or you won't even know that the widget sizes are different on the other platform, and the whole GUI is a disfunctional piece of junk with truncated texts and buttons falling completely out of the dialog box.
(Writing the code is not the alpha and the omega, as you undoubtedly already know. Testing and debugging can easily account for 10 times more time.)
The promised DirectX-vs-OpenGL example: Now _Direct3D_ is pretty much an equivalent of OpenGL. No, not the same function calls, but you can get the same results.
But DirectX offers a lot more than that. Direct3D is just a part of it. You also get networking, sound, etc. If you wanted to stay portable and _only_ use OpenGL, you'd have to write all those extra bits yourself. Which costs time and money.
2. Performance problems, here we come.
Of course, you could just use a wrapper that encapsulates, abstracts and emulates everything. Proper software engineering, right? The problem is: it costs performance.
DirectX-vs-OpenGL fits nicely here too: as fate would have it, Matrox already tried handling that via a wrapper. Back in the days of the G100 and G200, Matrox thought the're smart. No use writing two different 3D libraries that do the same, right? So they actually wrote their OpenGL implementation as a wrapper around DirectX.
The problem? Performance was abysmal. No, not just bad. It _killed_ 3D gaming. With Doom 2 and such being the "killer apps" of video gaming back then, Matrox lost gamer market share (and game developper mind share) with both hands. And who rose like a star? NVidia, who to this day still has the fastest OpenGL implementation.
Just in case you wonder why no games are written using one of those wrapper libraries, now you know why. Because noone wants to make a game that looks like classic ass (low polygon count) or gets single digit FPS. Or both.
3. Those pesky users.
There's one thing that all these emulation and one-lib-to-rule-them-all apologists just don't get: reusing existing skills is good.
When Joe Average gets a Windows app.. actually, screw Joe: when even _I_ get a Windows app, I expect it to look and behave exactly like every other Windows app. No, I don't want it to look like Swing, I don't want it to look like QT, and I sure don't want Mozilla's skinned idiocy, and I'm gonna puke if I have to use another idiotic GTK file dialog in _Windows_, etc. I want it to look and _act_ exactly like one thing: the Win32 widgets. Nothing else.
And if I were on a Mac, I'd expect it to look and feel like on a Mac. I would _not_ want an app that looks and acts like Windows (e.g., wants me to right-click) in the middle of an Aqua desktop.
It's possible to get it right, yes. See for example IBM's SWT widget set for Java. But it's also quite the norm to get it awfully wrong: witness Sun's Swing.
A polar bear is a cartesian bear after a coordinate transform.
And source code delivery has nothing to do with it being commercial or free, in either the "beer" or "speech" sense. When the software is important enough, having the source code is an absolute necessity which every system administrator will insist upon. There's a disturbing meme going through the industry that "COTS" (commercial, off-the-shelf) software can be sold without source code. That's bullshit. When your company's business is totally dependent on a system, you must have access to the source code, no matter what the licence is.
Of course it could _help_ in migration even with the source. You could partly port the application and partly extend wine until it ran the application
http://michaelsmith.id.au
In gcc declaring an array of 0 length does not allocate space for the pointer! It's basically an inline memory pointer. Given:
// inline ptr
struct {
int a;
int b[0];
} test;
Assuming a 4 byte int and the object is at address 0. (yes, yes, NULL pointer and all that rot)
sizeof(test) = 4
&test.a = 0x0
&test.b[0] = 0x4
&test.b[1] = 0x8
One use is to allocate the memory yourself and then use the struct to map that memory. The sizeof() would give you the header size. Then (sizeof(header) + allocated data storage) is the total size to alloc.
See: Zero Length (gcc)
IMO, it is a very bad habit to use "type name[0]" when you mean "type* name".
Doing what you claim (sorry, you're AC) is the "Microsoft way" will cause memory corruption in GCC.
There are two kinds of people: 1) those that need closure
A serious point, if IBM is really serious about people to port their Windows apps to "Linux on POWER" (which does have a nice ring to it) then why are all IBM's POWER based systems so expensive?!
;-)
Now Apple can make a PowerPC based system for £339 (BYODKM as Steve might say) why can't IBM create something similar? Preload it Linux and we'd all be happy little "porters". Now if they really wanted us to do this then a laptop would be really great. But presently IBM will only sell expensive POWER systems.
Now after you've ported your "killer app" to LoP, how the heck do you deploy it? On what? Some mega-expensive POWER Server? Doesn't IBM realise that Windows apps are usually run on the desktop or laptop? I mean they're not suggesting we're using Windows as a server OS are they?
PS. Anyone from IBM reading this - yes I would buy an IBM LoP box if it was sub £500 BYODKM.
The same can be applied to GUIs, though for Windows you'll have to write a WinMain wrapper.
I cant write code myself, so obviously there is a lot that i dont know. But is it really that hard to write code that is portable?
Part of the problem is that unless a developer tests their code on another platform, you don't know if it is truely portable (unless you are writing a pretty basic application that is compiled with -ansi -pedantic). As you can imagine, a lot of developers will not take the time to do this testing, maynot want to support other platforms, or maynot own other platforms on which to test their code.
-- Mike
I thought that was the best part of it!
... mmmm, spammer!*
*imagines a crocodile picking off Mr. Iwritespam Formoney while he's trying to port "New Smileys For Your Computer!" to Linux
While what you say is true to an extent, I think you're ignoring a valid point. Sure, Microsoft plays fast and loose with its own apps, particularly the menu, toolbar and open/save dialogs. Others tailor the interface somewhat as well. But the vast majority of the conventions -- the things an average user will just assume to work -- are the same in pretty much all native Windows apps. A right-click brings up a context menu. You save your work by going to File->Save, and you'll find the Open, Print and Exit commands in the same place. The max/min/restore buttons are at the top-right of the window if applicable. And so it goes.
Some variations on the theme work very well. I was impressed with the simple but effective variation Firefox has adopted for its "find" feature, for example. Others suck: after my first experience using the GIMP on Windows, when it insisted on trying to use completely unfamiliar UI conventions, I gave up.
But the bottom line is that most native Windows apps do have a high level of UI consistency, and if you're going to vary the theme, it should be for a clear reason (such as the Firefox feature I mentioned) and not just because you're developing an app with an inadequate toolkit that can't handle native widgets properly.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
And if I were on a Mac, I'd expect it to look and feel like on a Mac. I would _not_ want an app that looks and acts like Windows (e.g., wants me to right-click) in the middle of an Aqua desktop.
You are 100% right --- ported apps should have "native look and feel" on each platform! A good cross-platform API that has been designed with this goal in mind since the start is wxWidgets.
Unfortunately it doesn't cover the really fun part -- mapping windows Event into pthread's Conditional Variable.
I passed the Turing test.
No offense, but you seem to make two of them yourself.
1. Basically "if we don't have 100% consistency, we should go for 0% instead". Or, if you will, "bah, you already had a change of look-and-feel some 5 years ago, so suck it up and accept one daily, for each program."
Sorry, no. The real world isn't that clear-cut black-and-white. Sometimes you have to settle for "good enough" instead of "perfect".
2. More importantly, the underlying fallacy is "looks are all that matters." Seein' as what you came up with is flat buttons or different icons.
And that's not just a fallacy, it's also _the_ number one _failure_ of GUIs designed by programmers, graphics artists, marketting, etc. (Though each of them for very different reasons.) Generally anyone else who really has _zero_ clue about usability, and just thinks anything graphical will do.
What I'm more concerned with isn't "waaah, but they changed the 'new folder' icon in XP!" I'm more concerned with how things work. Which is why my point explicitly said "reusing skills" not "reusing graphics."
Take the Windows file open dialog for example. Sure, some apps might add a preview field next to it, or a couple of extra fields, but by and large it stayed the same since Windows '95. You can still do the same things (e.g., creating or renaming a folder right in the list), in the same way, in all apps that use it.
The important thing is: Once you've learned to use it once, you can do it mechanically, without even thinking about it. Even if you just bought/downloaded/compiled/whatever a brand new app, you already know how its file dialog works. That's one less thing to go through a learning curve about.
Now kindly open a GTK dialog box in Windows. E.g., open a file in Gimp. Ugh. WTF is that box? What was wrong with the "normal" box, that needed replacing? Or try it with a Swing app. Ugh. Why does everything look and act differently?
Try to answer those questions _without_ going into technical details about widget sets and libraries. Pretend I'm Joe Average, who doesn't even know what GTK is. And more importantly, who doesn't _care_ about such details. I just want to use the program, with a minimum of learning curve or thinking.
What was wrong, from a _functionality_ point of view, with the old dialog? What end-user functionality absolutely wasn't available through it, so that it needed a completely different dialog?
A polar bear is a cartesian bear after a coordinate transform.
I'm not sure if this should be a reply to someone else's comment, so I'll start anew.
I'm the guy who helped port the gaim-encryption plugin FROM Linux over TO Win32. (The opposite of the article and this topic, I know). But, after I sent the patches back up to the maintainer, he was able to easily carry it in his source tree.
I used Cygwin and MingW to handle the compilation with his original autoconf, etc. build environment. Of course, there was the requisite GTK+ libraries, etc. that went along with it too. But the magic was MingW and Cygwin.
Perhaps this could give the various developers some insight that "it really can be done".
--
3. Don't forget to enjoy!
$ cp /mnt/samba/xyzzy/programs/windows_app.exe . ./windows_app
$ objcopy -O elf32-i386 windows_app.exe windows_app
$
I wrote an application that worked on Windows, Unix, Linux, and mainframe. I wrote the GUI separately calling the library function then a simple command line version for Unix.
What I should have done is totally separate the GUI and the application entirely. I could rewrite the GUI in in a portable framework on linux faster than any port of the Windows software. I could then install the framework on all the windows desktops and have them work the same. Not port but total rewrite in a portable framework.
Problem with a lot of GUI code is that the business logic becomes intertwined with the GUI logic. It is incredibly easy to do especially with the Rapid Application Development (RAD) tools and this cause nightmares in porting if your RAD tool is not cross platform.