I wonder what the "modern" (read: property-based) way is to set _WIN32_WINNT and WINVER for a CMake project.
The problem I want to solve is how to set the version to the highest value that is required by any of the libraries or subcomponents of my project. For example, if my project code by itself needs WINVER to be at least 0x0601 (Windows 7), but it uses library A that needs at least 0x0603 (Windows 8.1) and library B that needs at least 0x0A00 (Windows 10), it is clear that my overall product needs the highest of those.
If I just define appropriate settings as target_compile_definitions, I may end up having the same macro definition on the command line several times, with the last taking precedence, which may be the wrong one.
How do I arrange for the highest version to be taken automatically?
I have tried to find other answers to this question, but they seem to be fairly old, and hence don't seem to reflect modern practice.
Related
For reasons related to customers with different applications versions i need to maintain in my laptop several versions of Delphi (7, XE 7, XE 8, XE 10.1 Berlin and XE 10.2 Tokyo). My main concern is about PATH variable and problems during compilation and linking time. There'll be any problems ? Do i need to change what ? Any suggestion is most welcome.
I have all versions of Delphi from 7 thru XE8 installed in a single VM and versions 1 thru 6 in another (my Delphi "museum" :)).
The Delphi "museum" is a Windows XP VM to avoid the problems that those older versions of Delphi have with more recent Windows versions. The Delphi 7+ VM started life as Windows 7 VM but has since been upgraded to Windows 8.x and then Windows 10 without any problem.
The two sets of VM's are kept separate in this way to avoid OS complications with those older versions and because I use 1-6 only very, very rarely and version 7+ more often. The precise version at which the "cut-off" was made was determined by the fact that dotted unit names were also only supported from version 7 onward so a lot of the code I ever wrote for 7+ is simply not even usable with 1-6 so there's no point having them alongside each other.
In both cases the IDE/compilers (any version) have no intrinsic problems running alongside other versions.
The only real difficulty is installing Delphi 2006 on Windows Vista (or later). Should you ever need to, this is the only one that presents any real difficulty due to a dependency on .NET which is not handled very well by the installer. But it is do-able and not especially difficult as long as you follow the steps described in detail by Dr. Bob.
Install Locations: Minimising PATH Length/Manageability
With a large number of Delphi versions installed the overall length of the PATH variable can become a problem, but in my experience this is a problem only of manageability. To simplify things on that score and to avoid problems with earlier versions of Delphi on more recent versions of Windows, I installed all my IDE's in a sub-folder directly off the root:
c:\delphi\<version>
Where version is each Delphi version number (e.g. 7.0, 2007, 2009, XE, XE2 etc etc). I then have a number of other folders for shared components:
c:\delphi\bde
c:\delphi\database desktop
c:\delphi\shared files
When I setup the VM I installed each Delphi version in order and changed the installation locations for these components to these locations. In this way there is one common installation of these shared components which is updated by each more recent version as required.
I also have a c:\delphi\common\ folder where I keep things such as pre-compiled FastMM_FullDebugMode.dll etc to be shared across all Delphi versions.
I did all this primarily for my own benefit however, to keep things organised and consistent rather than to solve any particular problem (apart from the previously mentioned issues affecting older versions if installed under Program Files).
e.g. if you simply install into default locations then you will end up with versions "scattered" across Borland, CodeGear and Embarcadero folders. All my IDE versions are in one place.
With or without these considerations, the IDE should be perfectly happy to run all the different versions you mention without any particular configuration required, but you may need to pay attention to configuration/assumptions made by some 3rd party packages/libraries.
3rd Party Packages
Most 3rd party libraries/packages are usually fine, but there may be the occasional one that needs a bit of help. I myself have never come across anything that couldn't be resolved but have to say that I also don't use 3rd party libraries particularly extensively so simply may not have come across any "trouble makers".
In any event, it's unfortunately difficult to give general advice on this point since it obviously depends very much on the 3rd party libraries and the particular "problems" that any particular one might have.
I have all Delphi versions from 6 to 10.2 installed on a computer running Windows 8.1 64 bit. It's not easy to setup, especially for the older versions. The first rule would be: Do not install to "c:\program files", use a separate directory (I use "c:\delphi" with a numerical subdirectory for each version.)
That has two effects:
Older versions, that still write to the installation directory, will work.
The path entries will not be as long (even though, they will be too long after the 5th or 6th Delphi install, see the comments to your question for possible solutions)
Why did I not use multiple VMs? I maintain GExperts for the versions mentioned above and it is too much hassle to maintain the VMs. As long as it works, I will keep all Delphi versions on my computer. If it stops working, I will probably drop GExperts suppport for some Delphi versions.
There are multiple articles on getting older Delphi versions to work on Windows 8.1. They might be useful if you try it.
They are all in the category Windows 8.1:
https://blog.dummzeuch.de/category/windows/windows-8-1/
I was recently fixing some IAT on MoleBox packed executable and saw that it links with kernel32 functions: '_lopen', '_lwrite' and '_lread'. This site states that those API's are provided for compatibility with 16-bit versions of Windows. I undesrtand that 'Win16' applications can't be executed in long mode (yes - I'm running Win8.1 x64) - so what is the purpose those to be still included in 'kernel32.dll'?
By the way those functions aren't even included in the 'msdn' library.
EDIT: It also seems that those function aren't actually 16-bit! They're taking 32-bit parameters on the stack.
It's not that the functions can be called by 16 bit applications. Clearly they cannot because they live in 32 bit and 64 bit modules. The point is (was) to make it easier for developers to compile old programs without having to re-write them.
Now, in 2015 there's no real need to cater for developers that have 16 bit programs that they wish to re-compile. That is probably not happening any more to any significant level. But if you roll back the clock 20 years then this was a real concern. And hence MS included these compat crutches. And once they had been included, then MS probably decided to leave them there so as not to break binary compatibility. MS does go to great lengths to avoid breaking old programs. Were these functions to be removed, any programs that rely on them would break.
Microsoft doesn't remove functions "just because" they're old. They will remove these functions as soon as they would require a reimplementation, but for now it takes less work to keep them.
Are there any free, GCC-compatible suites for Windows that generate standalone executables without external dependencies?
Here are a few that do not fit the bill, ordered by undesirability, least to most:
MinGW (MSVCRT.DLL)
Cygwin (Cygwin runtime DLLs)
DJGPP (NTVDM.EXE; not present on x64 platforms)
Right now I'm leaning towards (and using, albeit tentatively,) MinGW, as it does seem to be the "cleanest" approach. I still am not thrilled with the MSVCRT.DLL dependency, especially as I can and do have to deal with customers running pre-Win2K. (Windows 2000 was the first edition to ship with MSVCRT.DLL) Distributing MSVCRT with the application is not an option.
P.S.: I am aware that there is an attempt to create an MSVCRT replacement for MinGW, but it is still unstable/beta, and has limited functionality; not something I'd feel comfortable using for production applications.
P.P.S.: Answers to the effect of "MSCVRT is usually there anyway," or "Just package the redist" are not constructive answers. The question specifically asks how to AVOID dependencies, not ensure their presence.
To avoid MSVCRT with MinGW, use the following flags for the linker:
-nostdlib -Wl,--exclude-libs,msvcrt.a -Wl,-eWinMain
Notice that you have to declare a function named WinMain (you can also choose another name for it) which will be your main. You also can't use any of the standard functions like strlen, printf and friends. Instead, you must use the WinAPI equivalents like lstrcmp, wsprintf, etc.
You can see an example of this using SCons at:
https://sourceforge.net/p/nsis/code/6160/tree/NSIS/trunk/SCons/Config/gnu
I've used this for my project that also requires Windows 9x compatibility. This also has the nice side effect of having smaller executables. From your comments above, it seems you're looking for that too. If that's the case, there are even more tricks you can use in the file I linked above.
Microsoft has a table matching CRT functions to WinAPI at the following KB99456:
Win32 Equivalents for C Run-Time Functions (Web Archive)
More information on getting rid of CRT (although for VC, it can still help) at:
http://www.catch22.net/tuts/win32/reducing-executable-size
I have an application which has many services and one UI module. All these are developed in VC++ 6.0. The total KLOC would be 560 KLOC.
It uses Mutltithreading,MFC and all datatypes like word,int, long.
Now we need to support 64bit OS. What would be the changes we would need to make to the product.
By support i mean both like running the application on a 64bit OS and also making use of the 64bit memory.
Edit: I am ruling out migration to VS2005 or anything higher than VC6.0 due to time constraints.
So what changes need to be done.
64bit Windows includes 32bit via WOW. Any 32bit application should just continue to work.
(It is only drivers that have to match the bitness of the OS.)
[Note to commenters: plugins—of whatever type—are not separate applications but dlls used by other applications which do need to match the host. In that case you also get the same problem where 64bit extensions are incompatible with 32bit hosts.]
As Richard says, the 32-bit version should continue to work unless you've got a driver or a shell extension or something.
However if you do need to upgrade the code you're going to have to upgrade the compiler too: I don't think MFC got good 64-bit support until VS2005 or later. I'd suggest you get the 32-bit code building in VS2010 - this will not be trivial - and then start thinking about converting it to 64-bit. You can of course leave the production 32-bit builds in VC6 but then you add maintainership burden.
You'll probably get most of the way converting by flipping the compiler to 64-bit and turning on full warnings - particularly given the size of your code it may be impractical to review it all. One thing to watch out for is storing pointers in ints, dwords, etc. which may now be too short to hold the pointer - you need DWORD_PTR etc. now - but I think the warnings do catch that.
Or if this is in many components then you might get away with only migrating a few components to 64-bit. Then, unfortunately, you've got data length issues for communication between the two versions.
You must convert to a newer compiler. Time constraints are pretty much irrelevant. The VC6 compiler simply cannot generate 64 bits code. Every pointer it generates is 32 bits, for starters. If you need to access "64 bit memory", i.e. memory above 0x00000000FFFFFFFF, then 32 bits is simply not enough.
If you're ruling out changing your IDE to one that intrinsically supports 64-bit compiling and debugging, you're making your job unnecessarily more complex. Are you sure it's not worth the hit?
Just for running on a 64bit OS, you won't need to make any changes. That's what WOW64 is for.
If, however, you want to run 64bit natively (i.e., access the 64bit memory space) you will have to compile as 64bit. That means using an IDE that supports 64bit. There is no way around this.
Most programs should have no problem converting to 64bit if they are written with decent coding standards (mainly, no assumptions about the size of a pointer, like int-pointer conversions). You'll get a lot of warnings about things like std::size_t conversions, but they will be fairly meaningless.
Is anyone aware of any performance implications from changing the _win32_winnt from 0x400 to 0x0501?
I am compiling C++ on VS2005.
My Application is very communications oriented, doing quite a lot of Winsock work.
A value of 0x0400 targets _WIN32_WINNT_NT4, which is a smaller subset of the windows SDk that targets Windows 2000. That means you are excluding, ignoring and throwing away a lot of code that would have been compiled into your executable. So yes it will execute faster.
So when you define 0x0501 you are saying, yes give me all that rich extra goodness that the header files for Windows XP. However your application most likely will not run on windows 2000 due to failed imports. Since you are bringing in all that extra fatness, your compile times will be slower, and your code will be bigger, your executable will be bigger, and most likely it will be slower.
You can find more information here on these topics:
http://blogs.msdn.com/b/oldnewthing/archive/2007/04/11/2079137.aspx
http://msdn.microsoft.com/en-us/library/aa383745.aspx
I'm unaware of any particular performance-related issues, but if you could provide more specific details about how your performance is suffering, someone might be able to help.
For example, is your network throughput lower than you think it used to be?