Tuesday 13 October 2015

Visual Studio 2015, ICU, and error LNK2005

I'll begin by saying that I'm just going to ignore the fact that I haven't written anything in nearly nine months.

So...

While building ICU 56.1 with VS 2015, I was greeted with thousands of errors like this (also described here by someone who came across the same problem):

error LNK2005: "public: static bool const
std::numeric_limits<unsigned short>::is_signed"
(?is_signed@?$numeric_limits@...@std@@2_NB) already defined in
ParagraphLayout.obj

This is defined in <limits>, in a statement like this:

_STCONS(bool, is_signed, false);

Looking at the pre-processor output, we can see its actual definition:

static constexpr bool is_signed = (bool)(false);

If I understood the Standard correctly, this should be OK, and there should be no duplicate symbols during linking. So, I was still missing a logical cause for this.

The usual internet search for «ICU LNK2005» didn't bring anything useful, except for the link above.

Then, as I concentrated my search on LNK2005, I came across this post. The same mysterious behaviour, but now there was a plausible explanation, in a comment by MS's Stephan T. Lavavej, in a quoted post from an MSDN blog:

We recommend against using /Za, which is best thought of as "enable extra conformance and extra compiler bugs", because it activates rarely-used and rarely-tested codepaths. I stopped testing the STL with /Za years ago, when it broke perfectly conformant code like vector<unique_ptr<T>>.  
That compiler bug was later fixed, but I haven't found the time to go re-enable that /Za test coverage. Implementing missing features and fixing bugs affecting all users has been higher priority than supporting this discouraged and rarely-used compiler option.

So, after removing /Za from all projects in ICU's allinone VS Solution (Project Properties -> Configuration Properties -> C/C++ -> Language -> Disable Language Exceptions -> No), I was able to build it with no errors, on all configurations (x86/x64, debug/release).

Apparently, it's one of those rare cases where the error is actually in the compiler, not in the code.

4 comments:

  1. Your fix indeed get me much further except I get 2 errors:
    1. U1077 'rc.exe': return code 0x1. Project: nakedata File: NMAKE Line: 1
    2. MSB3073 The command NMAKE /f makedata.mak ICUMAKE="C:\...\icu\source\data\\" CFG=x64\Release" exited with code 2. Project: makedata File: Microsoft.MakeFile.Targets Line: 38

    ReplyDelete
    Replies
    1. Can you upload your build log and post a link here?

      Delete
    2. I went through the build log and it turns out I'm missing rc.exe. Nothing to do with ICU. Sorry about that.

      Delete
    3. No problem :)

      I ran into that issue when I had a go at building Qt with VS2015. Since I had rc.exe and rcdll.dll from the Windows 8.1 SDK I had installed (mainly for the debuggers), I copied that to \VC\bin, and it worked.

      Hope you get it sorted out.

      Delete