-
Notifications
You must be signed in to change notification settings - Fork 44
Building
This page explains how to build WinDirStat from its source code.
[TOC]
In any case it's assumed that if you want to contribute code, you have a minimal understanding of the tools a developer normally uses and have worked with Visual Studio.
Note: I cannot provide installation support for the prerequisites or support if you fail in one of these steps. Feel free to file a ticket on the issue tracker if you have done your "homework" and feel this may be caused by faulty project settings or so.
Also note that I am not including more than a few screenshots and brief descriptions here. If you need more guidance concerning Mercurial, refer to hginit.com an excellent tutorial on the matter. For more details I refer you to the book Mercurial: A Definitive Guide which can also be downloaded and read here.
- Visual Studio
- It has to be the Pro edition or better
- Tested versions are Visual C++ 2005, 2010, 2012, 2013, 2015 and 2017 (all Pro editions)
- Note that these versions were tested at different times, so it's possible some defects have crept into the code base that will affect only a particular version of Visual Studio.
- Attention: in case of Visual C++ 2005 use a fully patched installation (article with detailed explanations and screenshots) with Windows 7.1 SDK embedded.
- A Mercurial client, I prefer TortoiseHg
This description uses Visual Studio 2013 for the screenshots and explanations, so use common sense whenever something is different on your Visual Studio version.
Note: you'll most likely need at least the Pro edition of Visual Studio, but I don't want to waste the time on verifying the Express edition works nor do I have the MSDN subscription level to test higher editions.
Agree to the license agreement, then hit Next
:
Select the components you want to install. You will have to install the Microsoft Foundation Classes for C++, also known as MFC.
Wait for the installation to finish:
And dismiss the final setup page, if successful:
For this description we'll install TortoiseHg, but in general any Mercurial client will do. And if you feel happy using some foreign tool to get the code and commit, that's fine too. Just keep in mind that for example the Git/Hg tools rely on a local repository of the native type you cloned from. I found that this local repository must be kept archived, because any new clone will be "unrelated" and therefore the mappings between the two version control systems will break.
Simply start the setup process by double-clicking the .msi
you downloaded from the TortoiseHg website:
then make your choices and follow the wizard step by step until you finally reach:
After that log off and back on or reboot so that the context menu will work. I found that with an alternative file manager I can skip this step safely.
Right click an empty folder you created and then pick from the context menu TortoiseHg
followed by Clone
. You'll see the following dialog:
after entering the details as shown (or adjusted depending on your needs and appropriate settings), hit the Clone
button and enjoy the progress:
The dialog will close automatically if the cloning succeeds. Should it fail (e.g. connection issue), simply retry the steps - but make sure to empty out the previously directory before attempting to clone again.
https://github.com/windirstat/windirstat.git
-
[email protected]:windirstat/windirstat.git
(requires a GitHub account)
Of course you may also instead fork to your own repository and then use its URLs instead.
WinDirStat currently employs windirstat/windirstat/premake-4.x-stable
, a fork of premake/premake-4.x
, for consistent generation of the projects from a template (premake4.lua
in the root of the working copy). A script eases the steps required by simply creating all possible projects.
Follow these steps:
- Open a command prompt. E.g. by pressing
Win
+R
and then enteringcmd
and hittingEnter
. - Then change into the directory into which you cloned the source code in the previous step, e.g.
cd /d %USERPROFILE%\Documents\windirstat
. - Enter the following command
common\produce_vsprojects.cmd --dev
and hitEnter
.
Below is how this might look in screenshots:
Please note that for this to work the working copy has to be in a location that is writable and executable at the time of issuing the command. This will execute common\\premake4.exe
. That binary is code-signed by me (Oliver), but you can also build your own if you don't trust code built by others ;)
Voila! You now have a set of solutions and projects suitable to build the source code. Well, hopefully. If not, file an Issue.
Side-note: the Visual C++ 2005 development solution and projects in the repository are created by using common\produce_vsprojects.cmd --sdk71 2005
.
Note: This requires the Windows 7 SP1 SDK to be installed and registered for the VS2005 and 2008 projects. For VS2005 this article will be of help.
Follow these steps:
- Open a command prompt. E.g. by pressing
Win
+R
and then enteringcmd
and hittingEnter
. - Then change into the directory into which you cloned the source code in the previous step, e.g.
cd /d %USERPROFILE%\Documents\windirstat
. - Enter the following command
common\produce_vsprojects.cmd --full
and hitEnter
.
This complements the --sdk71 --resources
option when you use premake4.exe
directly.
Note: This will simply #define HAVE_WIN7_SDK=0
(checked in stdafx.h
) and thereby disable parts of the WinDirStat functionality. It's not vital for its functioning, but it's desirable. This only affects these older VS versions, though.
Follow these steps:
- Open a command prompt. E.g. by pressing
Win
+R
and then enteringcmd
and hittingEnter
. - Then change into the directory into which you cloned the source code in the previous step, e.g.
cd /d %USERPROFILE%\Documents\windirstat
. - Enter the following command
common\produce_vsprojects.cmd --resources
and hitEnter
.
This complements the --resources
option when you use premake4.exe
directly.
If you have Visual Studio 2005, you have to fulfill the following requirements:
- Install Visual Studio 2005 Pro with at least C++ compilers (including x64 ones, if desired)
- Install the Service Pack 1 for Visual Studio 2005 Pro (KB929697), which is apparently no longer offered for download from Microsoft
- Install this patch (KB929470) to run Visual Studio 2005 on Windows Vista, 7, 2008 Server and 2008 R2 Server.
- Install this patch (KB949009) to get rid of a certain error condition concerning debug symbols
- Fetch the latest updates via Windows Update and apply any other patches that may apply in your case.
- Microsoft® Windows® Software Development Kit for Windows 7 and .NET Framework 4 (from now on called Windows 7 SP1 SDK in this document).
As far as I know (see Issue #31) Visual Studio 2008 Pro causes the same symptoms without the Windows 7 SP1 SDK (check a bit below).
You encounter an error like this:
#!text
Compiling resources...
fatal error RC1106: invalid option: -ologo
Project : error PRJ0002 : Error result 1 returned from 'C:\Program Files (x86)\Microsoft Visual Studio 8\VC\bin\rc.exe'.
Whoopsie daisy. It's not the only one you may encounter with that version of the resource compiler, but it will be the first you get to see.
The error indicates that the version of rc.exe
you're using is too old. However, simply getting rid of /nologo
on the command line won't cut it. The problem also affects other parts. Let's see what happens if we remove it:
#!text
Compiling resources...
.\windirstat.rc(32) : error RC2176 : old DIB in ..\common\WinDirStat.ico; pass it through SDKPAINT
Well, baste my steaming puddings! Turns out the version is also too old to handle the new WinDirStat icon either. What to do?
The only solution I have found so far is to overwrite the rcdll.dll
and rc.exe
that come with Visual Studio 2005 with the ones from the Windows 7 SP1 SDK (check a bit below). Theoretically also the Vista SDK might work, but since you'll need the Windows 7 SP1 SDK anyway to build a feature-complete WinDirStat, why not use those files from there?
- Start Windows Explorer elevated (e.g. right-click and "Run as Administrator")
- Pick the files
rc.exe
andrcdll.dll
fromC:\Program Files\Microsoft SDKs\Windows\v7.1\Bin
(adjust to your specific installation of Windows, i.e.%ProgramFiles%\Microsoft SDKs\Windows\v7.1\Bin
) and- copy the two files to
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\bin
(or%ProgramFiles(x86)%\Microsoft Visual Studio 8\VC\bin
or%ProgramFiles%\Microsoft Visual Studio 8\VC\bin
if the former doesn't exist)
- copy the two files to
Try whether that fixed the compilation issue. If not, file a ticket.
#!text
WDS_Lua_C.obj : error LNK2019: unresolved external symbol _IsDebuggerPresent referenced in function _win_traceA
../build/wds32.exe : fatal error LNK1120: 1 unresolved externals
That one can be resolved by integrating the Windows 7 SP1 SDK into VS2005 and 2008.
Normally you'll encounter an error if you forgot to install the Windows 7 SP1 SDK but generated the project with the settings that assume availability of that SDK. Typically you will see one or multiple of these errors (line numbers may vary):
#!text
mainframe.h(212) : error C2065: 'ITaskbarList3' : undeclared identifier
mainframe.h(213) : error C2146: syntax error : missing ';' before identifier 'm_TaskbarButtonState'
mainframe.cpp(441) : error C2065: 'TBPF_INDETERMINATE' : undeclared identifier
So if you see those, make sure to install the Windows 7 SP1 SDK (see next section below).
On a Windows x64 (i.e. 64-bit) use the ISO GRMSDKX_EN_DVD.iso
and on 32-bit Windows use GRMSDK_EN_DVD.iso
or the web installer. You can use the download links below:
- Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)
- Microsoft Windows SDK for Windows 7 and .NET Framework 4
Just read the information and use Next
:
In the following step agree to the license terms and click Next
again:
Choose a location or use the given defaults and click Next
again:
Pick the components to install. I picked only the bare minimum necessary for our use case, but feel free to simply skip the selection and clicking Next
immediately:
The next wizard page informs you that you may bail out before installation commences. Click Next
to continue the installation:
The installation progress page is so beautiful you'll want to sit through it and sip on your coffee/tea/getRandomBeverage()
. On my Windows 7 SP1 x64 VM it took less than two minutes.
On the last page hit Finish
if the installation succeeded and otherwise copy the error message to investigate what went wrong.
From the start menu under "Programs" go via "Microsoft Windows SDK v7.1", "Visual Studio Registration" to "Windows SDK Configuration Tool" and you'll see this:
pick the appropriate SDK version (7.1 is the one we want) and click Make current
:
upon success you should see this:
After completing those steps, WinDirStat should build just fine with Visual Studio 2005 and 2008.
If those steps fail, proceed to the next section for a known issue and how to troubleshoot it.
The registration fails with "Your system does not have Visual Studio 2005 or Visual Studio 2008 installed."
Turns out that the tool included even in the Windows 7 SP1 SDK is flaky at times. If it fails when the system locale isn't English. It depends, I think, mostly on the decimal separator.
The fix is rather easy:
- set the locale to English
- log off and back on
- finish the registration
- set it back to your locale
- log off and back on
Related issues:
- https://blogs.msdn.com/b/windowssdk/archive/2008/10/06/how-to-get-the-winsdk-configuration-tool-to-work.aspx
- https://blogs.msdn.com/b/windowssdk/archive/2009/08/07/using-the-win-7-sdk-build-environment-with-vs-2008.aspx
If you encounter a LNK2019: unresolved external symbol "public: int __cdecl CListCtrl::GetColumnOrderArray(int *,__int64)"
This is a very very annoying bug. And it's inside the MFC that comes with VS2005. I'll see whether and when I can check other versions (such as specifically VS2008). VS2010 doesn't appear to have the issue.
So we get LNK2019: unresolved external symbol "public: int __cdecl CListCtrl::GetColumnOrderArray(int *,__int64)"
with a decorated name of ?GetColumnOrderArray@CListCtrl@@QEAAHPEAH_J@Z
. If we have a quick look into the .def
files for amd64
in VS2005 we find no such function.
Here are all the closest matches I get to see:
#!text
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\amd64\mfc80.def
2325 ?GetColumnOrderArray@CListCtrl@@QEAAHPEAHH@Z @ 2566 NONAME
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\amd64\mfc80d.def
3304 ?GetColumnOrderArray@CListCtrl@@QEAAHPEAHH@Z @ 3545 NONAME
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\amd64\mfc80u.def
2316 ?GetColumnOrderArray@CListCtrl@@QEAAHPEAHH@Z @ 2557 NONAME
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\amd64\mfc80ud.def
3293 ?GetColumnOrderArray@CListCtrl@@QEAAHPEAHH@Z @ 3534 NONAME
Microsoft provides a tool named undname
that can be used o undecorate the names. Let's compare ?GetColumnOrderArray@CListCtrl@@QEAAHPEAHH@Z
with ?GetColumnOrderArray@CListCtrl@@QEAAHPEAH_J@Z
then:
#!text
C:\>undname ?GetColumnOrderArray@CListCtrl@@QEAAHPEAHH@Z
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :- "?GetColumnOrderArray@CListCtrl@@QEAAHPEAHH@Z"
is :- "public: int __cdecl CListCtrl::GetColumnOrderArray(int * __ptr64,int) __ptr64"
C:\>undname ?GetColumnOrderArray@CListCtrl@@QEAAHPEAH_J@Z
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :- "?GetColumnOrderArray@CListCtrl@@QEAAHPEAH_J@Z"
is :- "public: int __cdecl CListCtrl::GetColumnOrderArray(int * __ptr64,__int64) __ptr64"
Oh brilliant. So the issue is the second parameter. Let's dig further.
Looking for GetColumnOrderArray
in the atlmfc
subfolder underneath the VS2005 installation we find:
#!text
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\atlmfc\include\afxcmn.h
396 BOOL GetColumnOrderArray(LPINT piArray, int iCount = -1);
C:\Program Files (x86)\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\winctrl6.cpp
192 BOOL CListCtrl::GetColumnOrderArray(LPINT piArray, int iCount /* = -1 */)
See the problem already? Hint as can be seen on this Microsoft documentation page of "Windows Data Types" INT_PTR
is equivalent to __int64
on 64bit Windows.
#!c++
#if defined(_WIN64)
typedef __int64 INT_PTR;
#else
typedef int INT_PTR;
#endif
Now, that was probably introduced with the Windows 7 SP1 SDK and I found no other way than to actually fix the declaration in afxcmn.h
to match the definition from which the libs were built.
That means we change the occurrence at line 396 in afxcmn.h
to read:
#!text
BOOL GetColumnOrderArray(LPINT piArray, int iCount = -1);
And that's that.