Folks,
You are probably familiar with the Winelib page: http://www.dssd.ca/wine/Winelib-Apps.html where I describe what one needs to do to compile a Win32 application under Winelib.
My original motivation for doing the work was to better understand what inconveniences one has to go through to do the port, and what we can do to eliminate them.
Here are my thoughts on the subject, in the build order:
Compilation This step require the addition of some flags, and the potential removal of others. Simple to do, and if there is a configure script, quite doable.
However, these tweaks are really annoying in the initial stages of the port, and would be so nice if we had a nice compiler wrapper (call it wcc) that would do that behind the scenes, so that the only modification to the makefile would be:
-CC=gcc +CC=wcc
Q: Alexandre, would you accept such a utility in the tree?
Resources These ones are nasty. Programs typically use the windres compiler that compiles a .rc file into a .o file directly, which is later simply linked into the application. We go a different route, by sticking the resources in the .spec.c files, and this entails non-trivial modifications to the makefiles. The ideal option would be to provide a windres compatible command line mode for wrc, so that we can do:
-RC=windres +RC=wrc
This would mean moving the resources out of the .spec.c file, and exporting the resources variable so we can link it into the .spec.c file.
Q: Alexandre, is this acceptable? Does it warrant discussion?
Linking Another tricky step, with multiple problems 1. We are missing import libraries. As a result, we can not link with -lwinspool, we need to link with -lwinspool.drv Small change, but it can present nasty problems if you want to submit the patch upstream, to the application maintainers. I understand this one is already on Alexandre's TODO, so we should have a solution to it not before too long.
2. Our linking process is quite different from the "standard" one which uses gcc/ld to do the linking. We generate intermediate files (.spec.c files), and use different flags. Again, the solution for this (to at least help initial porting efforts) would be a wrapper script that does this, that can be used instead of ld. And so the question comes back again, to haunt us: is this needed/wanted/acceptable?
Running This is a new step in the process that we introduce. Currently we produce a shared library that requires a wrapper script to start it up. Many considers this (and I might say rightfully so) ugly/bloat/etc. The ideal situation would be to generate regular executables, like all well behaved libraries.
Here are a few solutions: 1. An interim step is to improve the wineapploader script so that it can be used by all apps. This is a simple thing to do at the moment, but does not solve the root cause, it just ease the pain a bit. This way you don't need to fight the application maintainers to get such script included in their tree, and having to answer the eternal questions: "WTF is this? I thought that compiling under Winelib would yield an executable that did not need wine. What's the difference as compared to running the Win32 binary directly?"
2. Fix the build process so that we can actually generate regular executables. Thing is, I don't know what's involved in doing so, and I'm afraid only Alexandre knows the answer (hint, hint :)). So a discussion on this topic is needed, just to figure where we want to go from here.
Now, this message is meant to elicit discussion on these topics, so that at the end of the day I can gather the conclusions, and track them on TODO page. So do not hesitate to send in your comments. :)))
Thanks for your attention, and sorry for the long message.
Am Don, 2002-11-28 um 07.35 schrieb Dimitrie O. Paun:
-CC=gcc +CC=wcc
-RC=windres +RC=wrc
I can't follow you here. You seem to have been porting Applications using Unix-Style Makefiles. I'd guess the vast majority of Applications comes with Windows VC++ "project files" (.dsp) and "workspaces" (.dsw).
In any case, IMO this is what's winemaker is all about. Your idea of introducing compatibility tools is nice but somewhat limited in scope. What we really need is a much more intelligent winemaker.
Martin
Martin Wilck wrote:
Am Don, 2002-11-28 um 07.35 schrieb Dimitrie O. Paun:
-CC=gcc +CC=wcc
-RC=windres +RC=wrc
I can't follow you here. You seem to have been porting Applications using Unix-Style Makefiles. I'd guess the vast majority of Applications comes with Windows VC++ "project files" (.dsp) and "workspaces" (.dsw).
This is probably true, although a lot of the already-portable open source applications like Mozilla that Dimi's thinking of can use Unix-Style Makefiles as well.
In any case, IMO this is what's winemaker is all about. Your idea of introducing compatibility tools is nice but somewhat limited in scope. What we really need is a much more intelligent winemaker.
What would be really nice is if the new intelligent winemaker produced a Makefile, rather than doing the actual build. That way it would be less opaque to debug any problems as you could see exactly what the make was doing, and alter it if necessary. It also means people won't have to keep on using VC++. Or does winemaker do this already?
David
Am Don, 2002-11-28 um 11.37 schrieb David Fraser:
means people won't have to keep on using VC++. Or does winemaker do this already?
Yes. Actually, it produces "configure" and "Makefile.in". Martin
On November 28, 2002 04:23 am, Martin Wilck wrote:
I've addressed both of these on the web page :)
I can't follow you here. You seem to have been porting Applications using Unix-Style Makefiles. I'd guess the vast majority of Applications comes with Windows VC++ "project files" (.dsp) and "workspaces" (.dsw).
From the page:
"Fortunately, most OSS applications have a build system based around the MinGW tool chain. Sometimes they have alternative build systems for the Borland and/or Microsoft tools, but more often than not they have to support the MinGW tools out of necessity. I will cover this class of applications for the rest of this section."
I should have been more clear: this message address this class of apps. The closed source ones have a VC++ build system, as you say, and are covered by winemaker. Not the focus of my efforts, though.
In any case, IMO this is what's winemaker is all about. Your idea of introducing compatibility tools is nice but somewhat limited in scope. What we really need is a much more intelligent winemaker.
From the page:
"Before I begin, I think I need to explain why we have to treat these applications any differently. Why don't we just run winemaker, and get it over with? The reason is quite simple: people are attached to their build process, and for good reason. If we are to have our modifications included in their tree, we can not simply submit a new build system. Such a patch would never be accepted. Needless to say, having these modifications included in their build process is important."
If we are to just generate a parallel build system, we'd be wasting out time. We have to make it simple so we have a chance of the app maintainers doing the porting themselves. There are thousand of apps, all we can do is port a few. But if we want them to recognize Wine as a platform, and port to it, we can not expect them to simply accept a parallel set of makefiles which are just a bit different from what they have.
"Dimitrie O. Paun" dpaun@rogers.com writes:
However, these tweaks are really annoying in the initial stages of the port, and would be so nice if we had a nice compiler wrapper (call it wcc) that would do that behind the scenes, so that the only modification to the makefile would be:
-CC=gcc +CC=wcc
Q: Alexandre, would you accept such a utility in the tree?
I don't know, I don't think you can write a one-size-fits-all script, different apps will require different options, and then it will get even more confusing IMO if you have two different ways of doing it depending on your options. Maybe we should simply have a script example in the documentation that people can adapt and ship with their app if the makefile really makes it hard to set options.
-RC=windres +RC=wrc
This would mean moving the resources out of the .spec.c file, and exporting the resources variable so we can link it into the .spec.c file.
Q: Alexandre, is this acceptable? Does it warrant discussion?
I don't think that's necessary. Using .o files has a number of problems, and it's really cleaner to use .res IMO. It's also more along the lines of how Windows does it, and allows you to keep using windres if you want, instead of being forced to switch to wrc.
- Our linking process is quite different from the "standard" one which uses gcc/ld to do the linking. We generate intermediate files (.spec.c files), and use different flags. Again, the solution for this (to at least help initial porting efforts) would be a wrapper script that does this, that can be used instead of ld. And so the question comes back again, to haunt us: is this needed/wanted/acceptable?
Yes, I think we want a wrapper like dllwrap to do all that. I'm not sure a script would be enough, we may want a full-fledged C program. The idea would be that you do something like:
winewrap *.o *.res -o foo -lwhatever
and it builds the .spec.c, compiles it, links everything into foo.exe.so, and builds a foo executable (which may be a wrapper script or a real ELF binary). This also (mostly) solves the "Running" issues: you still have a .exe.so file, but you don't really need to worry about it. You simply run "foo" and everything works.
On November 28, 2002 01:35 pm, Alexandre Julliard wrote:
-CC=gcc +CC=wcc
Q: Alexandre, would you accept such a utility in the tree?
I don't know, I don't think you can write a one-size-fits-all script, different apps will require different options, and then it will get even more confusing IMO if you have two different ways of doing it depending on your options. Maybe we should simply have a script example in the documentation that people can adapt and ship with their app if the makefile really makes it hard to set options.
Sorry, maybe I was unclear. This wrapper will probably be a small C program that understands gcc's options. It needs to do the following: -- add the include dirs first -- add -fshort-wchar -- add -D__int8=char -D__int16=short -D__int32=int "-D__int64=long long" -- remove cygwin options not recognized by the Linux gcc
If you think about them, it kindda makes sense, as under a Windowish environment these options are _implied_ in the invocation of gcc, just like -I /usr/include is implied when you invoke gcc under Linux.
So to be honest, I don't see why it would be confusing, and second, why we can not have a one-size-fits-all wrapper.
As I said, this is more a porting tool, to help you with the initial port. If the app has a configure script, you would want to instrument it to generate the correct flags for the compiler, and use gcc directly. But this is time consuming, and you have to worry about so many things at the beginning, I find it so much easier to have something working, and tweak only one thing at a time.
"Dimitrie O. Paun" dpaun@rogers.com writes:
As I said, this is more a porting tool, to help you with the initial port. If the app has a configure script, you would want to instrument it to generate the correct flags for the compiler, and use gcc directly. But this is time consuming, and you have to worry about so many things at the beginning, I find it so much easier to have something working, and tweak only one thing at a time.
OK, as a specialized hack to be mingw compatible I can understand it. It sounded more like a general Winelib compiler that would be used in all cases, which I don't think is a realistic option. But sure, a small mingw tool is fine, just name it something like mingw-wrapper to make it clear it's not a general purpose thing.
On Thursday 28 November 2002 08:00 pm, Dimitrie O. Paun wrote:
On November 28, 2002 01:35 pm, Alexandre Julliard wrote:
-CC=gcc +CC=wcc
Q: Alexandre, would you accept such a utility in the tree?
I don't know, I don't think you can write a one-size-fits-all script, different apps will require different options, and then it will get even more confusing IMO if you have two different ways of doing it depending on your options. Maybe we should simply have a script example in the documentation that people can adapt and ship with their app if the makefile really makes it hard to set options.
Sorry, maybe I was unclear. This wrapper will probably be a small C program that understands gcc's options. It needs to do the following: -- add the include dirs first -- add -fshort-wchar -- add -D__int8=char -D__int16=short -D__int32=int "-D__int64=long long" -- remove cygwin options not recognized by the Linux gcc
If you think about them, it kindda makes sense, as under a Windowish environment these options are _implied_ in the invocation of gcc, just like -I /usr/include is implied when you invoke gcc under Linux.
So to be honest, I don't see why it would be confusing, and second, why we can not have a one-size-fits-all wrapper.
As I said, this is more a porting tool, to help you with the initial port. If the app has a configure script, you would want to instrument it to generate the correct flags for the compiler, and use gcc directly. But this is time consuming, and you have to worry about so many things at the beginning, I find it so much easier to have something working, and tweak only one thing at a time.
Some small ide from uClibc.
On November 28, 2002 01:35 pm, Alexandre Julliard wrote:
I don't think that's necessary. Using .o files has a number of problems, and it's really cleaner to use .res IMO. It's also more along the lines of how Windows does it, and allows you to keep using windres if you want, instead of being forced to switch to wrc.
I did not mean to say that we should chance the way wrc works. Just enhance it to support a "direct to .o" compilation mode.
As for "more along the lines of how Windows does it" is an academic issue: all OSS projects coding for Win32 use windres, and they compile directly to .o. Keep in mind that windres can be used just like wrc (.rc -> .res), but nobody uses it like that.
The problem with that of course is that the makefiles have the resource.o file in all sorts of variables, etc. You can go and get rid of it from there manually for the initial porting effort, but it's actually not trivial to come up with solution that's acceptable to the app maintainer. Keep in mind that due to these thing working only on Windows, most of the apps don't have (and don't need) a configure script.
Tweaking build processes is nasty, nasty business. Even the nice and clean ones are hard to understand, let alone the fact that most are ... weak. :) For a big project, you're in for a lot of pain. Most people will no go through with it if they know they don't have a chance of integrating their changes upstream. Or maybe that's just me...
"Dimitrie O. Paun" dpaun@rogers.com writes:
As for "more along the lines of how Windows does it" is an academic issue: all OSS projects coding for Win32 use windres, and they compile directly to .o. Keep in mind that windres can be used just like wrc (.rc -> .res), but nobody uses it like that.
That was my point. If you replace the .rc.o rule by .rc.res and .res.o then windres happily builds the .res for you, and it still works on Windows too. Yes you need to change the link command-line but I don't think it's that bad.
Generating .o files in the proper format for linking directly is fairly hard to do cleanly in ELF; wrc actually supports generating C files, and we used to do it that way, but you need all kinds of tricks to make them integrate properly in the PE header.
On November 28, 2002 02:26 pm, Alexandre Julliard wrote:
That was my point. If you replace the .rc.o rule by .rc.res and .res.o then windres happily builds the .res for you, and it still works on Windows too.
This is simple, I agree. Adding a .rc -> .res is simple, and portable.
Yes you need to change the link command-line but I don't think it's that bad.
What about having to deal with the .o file that is present all over the place? That is the problem. And without a configure script, it becomes nasty.
Generating .o files in the proper format for linking directly is fairly hard to do cleanly in ELF; wrc actually supports generating C files, and we used to do it that way, but you need all kinds of tricks to make them integrate properly in the PE header.
In fact, I had something a lot simpler in mind. Currently, we define a variable called resources in the .spec.c file, which is later used in the nt_header structure. The idea was to simply generate the resources tree in a separate .c file, rename it to something like __wine_<spec file name>_resources, and make it non-static. Later, we can use it in the nt_header structure, just like we do right now. We still need to transfer the size of the resources...
"Dimitrie O. Paun" dpaun@rogers.com writes:
In fact, I had something a lot simpler in mind. Currently, we define a variable called resources in the .spec.c file, which is later used in the nt_header structure. The idea was to simply generate the resources tree in a separate .c file, rename it to something like __wine_<spec file name>_resources, and make it non-static. Later, we can use it in the nt_header structure, just like we do right now. We still need to transfer the size of the resources...
The biggest problem is if you want to support multiple resource files. But as long as you don't break the current .res support that wouldn't matter too much I guess.
On November 28, 2002 04:19 pm, Alexandre Julliard wrote:
The biggest problem is if you want to support multiple resource files. But as long as you don't break the current .res support that wouldn't matter too much I guess.
Yeah, but it's very limitted. I forgot about the multi-file part. Hmmm... Me don't like this. What else can we do?
What about this: -- currently, makefiles have such a rule:
%.o: %.rc $(WINDRES) $< $@
-- it's easy enough to split it like so:
%.res: %.rc $(WINDRES) $< $@
%.o: %.res $(RC) $@ $<
And the WINDRES and RC variables will be defined as such:
in MingW: WINDRES = windres RC = windres
in Winelib: WINDRES = wrc RC = utility_that_creates_dummy_empty_object_file
Which leaves just the linking a bit different...
Even better, we can just remember the .res file in the dummy object file, and have the link wrapper recover it from there, so we just have to redefine LD, instead of modifying the link target.
This way you should be able to compile a Win32 app under Winelib with a few changed definitions in the Makefile: CC, WINDRES, RC, LD and split the .rc.o rule into .rc.res, and .res.o.
Now that's easy. How about it?
On November 28, 2002 01:35 pm, Alexandre Julliard wrote:
Yes, I think we want a wrapper like dllwrap to do all that. I'm not sure a script would be enough, we may want a full-fledged C program. The idea would be that you do something like:
winewrap *.o *.res -o foo -lwhatever
Excellent, exactly what I had in mind too. And you are right, it will take care of the running business as well. I'll add to the pages.