Troubleshooting building wxWidgets using Microsoft VC

From WxWiki
Jump to: navigation, search

Ensure Correct Linking

wxWidgets can be built with either Multi-threaded (/MT) or Multi-threaded DLL (/MD) setting (these can be set from project properties). Ensure that your whole project uses the same settings. The default project file uses /MD, so you have to recompile with /MT if your project uses the latter.

If you get a missing _timezone symbol problem, see http://sourceforge.net/tracker/index.php?func=detail&aid=1904863&group_id=9863&atid=109863 .

Replace

#elif defined(__WXWINCE__) && defined(__VISUALC8__)

with

#elif defined(__VISUALC8__)

on line #172 of datetime.cpp to fix this.

Problems when using wxALL, SVN or Daily Snapshot Source

Visual C++ will probably complain about "corrupted project files". This is because your project files have Unix line endings (LF) instead of DOS ones (CR LF). You must transform your project files to the DOS format using a program such as Microsoft WordPad or Notepad++. A google search of convert unix dos files should point you in the right direction if you do not already know how to process these files.

If, when building wxWidgets, you get an error like this:

------ Build started: Project: wxregex, Configuration: Debug Win32 ------
Creating ..\..\lib\vc_lib\mswd\wx\setup.h
The system cannot find the file specified.
Project : error PRJ0019: A tool returned an error code from "Creating ..\..\lib\vc_lib\mswd\wx\setup.h"
Build log was saved at "file://c:\wxWidgets\build\msw\vc_mswd\wxregex\BuildLog.htm"
wxregex - 1 error(s), 0 warning(s)

Then you will need to copy include\wx\msw\setup0.h to include\wx\msw\setup.h

Memory Leak Detection Doesn't Show File Names and Line Numbers

wxWidgets has the ability to include memory leak detection in MSVC for debug builds, but by default it doesn't show the filenames or lines as it was intended to be used. In include\wx\defs.h there's a note saying it's disabled because it causes issues with the iostream header. See lines 772 through 778 of \include\wx\defs.h. wxUSE_DEBUG_NEW_ALWAYS is defined there to 0. That setting is checked at line 663 of \include\wx\object.h and it blocks the invocation of the #include "wx/msw/msvcrt.h" line at line 669.

If that memory leak is bothering you and you could care less about bugs in iostream, you can add the following lines to your files. Put them after all other header includes and avoid using them unless there's actually a memory leak.

#ifdef _MSC_VER
   #include <wx/msw/msvcrt.h>
#endif

Unresolved External Symbol Linker Errors

If you receive unresolved external symbol linker errors such as LNK2001 and LN2019, find a sample wxWidgets application which uses the same functions that are not correctly linked in your application. Load that project into Visual Studio and set the Configuration Properties > Linker > General property page Show Progress attribute to Display All Progress Messages (/VERBOSE). Compile and link the sample application.

When completed, examine the BuildLog.htm produced. Search for the item not linked in your application. The log will show in which library the reference was found. Verify that the cited library is being searched in the build of your application.

Unresolved Externals for Windows API Functions

If you get unresolved externals to Windows API functions when linking your project, then you may be missing the required Win32 libraries in your project settings. These errors most commonly show for Visual C++ 2005 (8.0) Express users since wxWidgets has relied on the default project configuration to specify the Windows API libraries for linking, and starting with VC8 Express, Microsoft has dropped these libraries from the default configuration since the PSDK containing the libraries is not included in the Express edition.

If you are using Visual C++ 2005 Express Edition and haven't installed the Platform SDK yet, you will need to do so now. First, download the Windows Platform SDK. Next the PSDK's Bin, Lib and Include directories need to be added to your Visual Studio options, or you may get an error message about files such as windows.h not being found. See this Microsoft article for setup instructions.

There are two solutions to this problem. The first is to add the libraries to your global default project configuration where Visual C++ will pick up the settings and apply them to all projects you open that are configured to inherit the settings (this is the default setting for new projects, and all wxWidgets projects do the same). You should try this first if you are using VC8 Express along with the Windows Server 2003 PSDK. The second solution is to manually add the libraries to all projects that need them.

First Solution: Global Library Import Settings

If you are using any other version of Visual C++ other than 2005 (8.0) Express, this should already be setup for you. You can double check your settings though by finding the "CoreWin.vsprops" (found in the "VC\VCProjectDefaults" folder of your Visual C++ installation location) and ensuring that at least the following libraries are listed in your "AdditionalDependencies" setting:

kernel32.lib user32.lib gdi32.lib comdlg32.lib comctl32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib rpcrt4.lib

VC8 Express users need to do this with the "corewin_express.vsprops" file. Slightly more detailed instructions for doing this with the latest PSDK can be found on the Visual C++ Express site.

Second Solution: Manual Import of Libraries

For any project missing these settings, open your Project Properties, select the Linker, under that, select Input settings, find the Additional Dependencies setting and make sure the following are listed:

user32.lib
gdi32.lib
comdlg32.lib
comctl32.lib
advapi32.lib
shell32.lib
ole32.lib
oleaut32.lib
rpcrt4.lib

MSVC 7.0 (2002) Release Build Problems

There is a bug in VC++ 7.0 (VC.NET 2002) optimisation which causes release builds to work incorrectly. To resolve this, after you have converted the wxWidgets VC6 project file to VC.NET, change the Optimization setting from Maximise Speed (/O2) to Custom. Then change Inline Function Expansion to Disabled. If Disabled is not an option you can add "/Ob0" (without quotes) to the Additional Options of the Command Line. It is thought that this only needs to be done for the wxWidgets library, or other code that implements wxModules. Note that this bug been fixed in VC7.1 (VC.NET 2003).

MSVC 8.0 (2005) DLL Linker Issues

If you're getting linker errors when trying to build a DLL version of a program, make sure the preprocessor has the WXUSINGDLL symbol defined. If the application crashes immediately after starting or cannot be initialised properly, open the file $(WXWIN)\src\msw\main.cpp and search for and remove the function 'DllMain' then recompile wxWidgets DLLs.

You can also get linker errors when there is mismatch between /Zc:wchar_t setting when the wxWidgets library files were built and the /Zc:wchar_t setting in your project. To change this setting in the Visual Studio development environment:

  1. Open the project's Property Pages dialog box.
  2. Click the C/C++ folder.
  3. Click the Language property page.
  4. Modify the Treat wchar_t as Built-in Type property.

More information about the wchar_t setting can be found in the MSDN documentation: [1]

MSVC 8.0 (2005) Deprecated Function Warnings

MS has created a bunch of new 'safe' CRT (C RunTime, MS's name for the C Standard Library) and C++ Standard Library routines (with new names). The old 'unsafe' functions have been marked with a DEPRECATED keyword so they will generate a level 1 warnings (the highest level) unless _CRT_SECURE_NO_DEPRECATE (for the C library) and _SCL_SECURE_NO_DEPRECATE (for the C++ Standard Library) are defined or all deprecation warnings are turned off with "#pragma warning(disable : 4996)". Since the new MS functions are not cross platform (and probably never will be) future versions of wx will probably define _CRT_SECURE_NO_DEPRECATE.

In addition, MS has deprecated some of the POSIX-compliant function names in favor of C Standard Library names. Define _CRT_NONSTDC_NO_DEPRECATE to suppress those warnings.

Another solution (to make the warnings go away) for 2.6.0 is to add the following code to your setup.h:

#if (_MSC_VER >= 1400)       // VC8+
  #pragma warning(disable : 4996)    // Either disable all deprecation warnings,
  // Or just turn off warnings about the newly deprecated CRT functions.
  // #ifndef _CRT_SECURE_NO_DEPRECATE
  // #define _CRT_SECURE_NO_DEPRECATE
  // #endif
  // #ifndef _CRT_NONSTDC_NO_DEPRECATE
  // #define _CRT_NONSTDC_NO_DEPRECATE
  // #endif
#endif   // VC8+

Adding this to your setup file will solve the problem for the wxWidgets libraries and for your own projects. More information on these changes may be found here and here.

If you want to completely disable the warning in Visual Studio itself, edit the corewin.vsprops file (or the corewin_express.vsprops if you are using Visual Studio Express) in the "C:\Program Files\Microsoft Visual Studio 8\VC\VCProjectDefaults" directory. Add the following tag before the final close tag of the file:

<Tool Name="VCCLCompilerTool" PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"/>

Note that on some versions (well, Express downloaded in June 2006, anyway) the tool name is "VCCompilerTool". If you use C++ Standard Library classes you may also want to add "_SCL_SECURE_NO_DEPRECATE" to the list.

Also

The deprecations flags can also been defined at the project level by adding them in “Project Property Page \ Configuration Properties \ C/C++ \ Preprocessor \ Preprocessor Definitions”.

Note

Defining the deprecations flags at the project level or globally in corewin.vsprops file will not work if the project has been upgraded from a previous version to VC8 (as described above). During the upgrade Visual Studio adds $(NoInherit) to each file level setting, so they do not inherit the project level settings, hence adding the definition on the project level will have no effect. The easiest way to fix this, is to open each project file (.vcproj) in a text editor (Notepad) then do a search and replace on the string ;(NoInherit) and replace it with nothing.

MSVC 8.0 (2005) Windows XP Manifest Build Problems

MSVC 8.0 has changed the way manifests are embedded in your executable. Your project will not build if you include wx.manifest in your resource file (tested with 2.6.0).

To solve this, exclude the manifest from your resources. In your resource file:

// #define wxUSE_NO_MANIFEST 0	// comment this line out
#define wxUSE_NO_MANIFEST 1	// and add this one

Then add these lines to your one of your source or header files to enable XP-Style common controls:

#if defined(__WXMSW__) && !defined(__WXWINCE__)
#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df'\"")
#endif

Name Conflicts

If you are using VC++ and MFC in combination with the wxWidgets, the new (in wxWidgets 2.3.3) wxTopLevelWindowMSW class has a CreateDialog member function. This is a macro in the depths of Windows headers (WINUSER.H) and creates a conflict. Since the product hasn't been released yet, I thought it might be good to mention so there's a chance to fix it.

  • This is still a problem in wxWidgets 2.4, when using any program that includes <windows.h> -- not just with MFC or VC++. It appears to manifest as errors like "syntax error before numeric constant" in wxWidgets headers. The solution is to always include all wxWidgets headers before <windows.h> (if you have many include files in your project, consider creating a single header which includes all the wx headers and then the windows headers, rather than doing it separately in every file).

Code optimization issues

If you have installed VC++ 6 ServicePack 5 + Processor Pack, you must know its code optimizer is quite buggy, at least when you set optimizations to "maximize speed". You have two options: turn off optimizations, OR not installing processor pack... until Microsoft fixes it.