Skip to content

[MSVC] CMake: Prepare for LLVM 5.0#2279

Merged
kinke merged 3 commits intoldc-developers:masterfrom
kinke:cmake2
Aug 19, 2017
Merged

[MSVC] CMake: Prepare for LLVM 5.0#2279
kinke merged 3 commits intoldc-developers:masterfrom
kinke:cmake2

Conversation

@kinke
Copy link
Member

@kinke kinke commented Aug 17, 2017

Some LLVM libs were missing from the linker flags for current LLVM 5.0. It was only during troubleshooting that I noticed the MSVC special case in FindLLVM.cmake. Getting rid of it entirely made the issues disappear. I checked llvm-config.exe, and it's returning appropriate switches for the MS toolchain, no need for special processing.

This apparently also leads to LLVM_CXXFLAGS being used for the first time when building with MSVC. These include /W4, a level further up from CMake's default /W3, so I disabled a few more frequent warnings.

I also had to link in a lib from Microsoft's Debug Info Access SDK manually. As the VS command prompt unfortunately doesn't even include the DIA SDK dir in the LIBPATH environment variable, I even had to specify a full path, relying on the VSINSTALLDIR environment variable.

Some LLVM libs were missing from the linker flags for current LLVM 5.0.
It was only during troubleshooting that I noticed the MSVC special case in
FindLLVM.cmake. Getting rid of it entirely made the issues disappear. I
checked llvm-config.exe, and it's returning appropriate switches for the
MS toolchain, no need for special processing.

This apparently also leads to LLVM_CXXFLAGS being used for the first time
when building with MSVC. These include /W4, a level further up from
CMake's default /W3, so I disabled a few more frequent warnings.

I also had to link in a lib from Microsoft's Debug Info Access SDK
manually. As the VS command prompt unfortunately doesn't even include the
DIA SDK dir in the LIBPATH environment variable, I even had to specify a
full path, relying on the `VSINSTALLDIR` environment variable.
@kinke
Copy link
Member Author

kinke commented Aug 17, 2017

AppVeyor: The command line is too long. ...

One advantage is that the D modules aren't recompiled if only .cpp files
have been modified.

Another advantage is that the 2 separate command lines are shorter than
the single combined one, preventing issues on Windows wrt. max command
line length.
@rainers
Copy link
Contributor

rainers commented Aug 18, 2017

I also had to link in a lib from Microsoft's Debug Info Access SDK manually.

I never had trouble with this when building with LLVM master. I guess that's because I'm not compiling with LLD integration. Does it have debug info support now?

if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-9][\\.0-9A-Za-z]*")
# Versions below 4.0 do not support component debuginfomsf
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "debuginfomsf" index)
endif()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this list is very much appreciated. I had to add the binaryformat library recently, too (probably caused by the selected targets).

@kinke
Copy link
Member Author

kinke commented Aug 18, 2017

Yep binaryformat was missing for me too. I disabled the LLD integration (needs #2148 otherwise to work) but still needed diaguids.lib due to a few class and interface GUIDs.

@kinke
Copy link
Member Author

kinke commented Aug 18, 2017

The remaining AppVeyor issue is unrelated btw, realizing that cost me some hours yesterday - they probably changed something in their image (and once again didn't mention anything in their blog/Twitter feed/...). I built this PR yesterday successfully with both LLVM 5.0 and 4.0.1.

@kinke
Copy link
Member Author

kinke commented Aug 18, 2017

AppVeyor upgraded to the latest VS + WinSDK update and since then master has been red. Upgrading myself right now...

@kinke
Copy link
Member Author

kinke commented Aug 18, 2017

I have the same issue now, even after rebuilding LLVM. LDC segfaults during a GC collection triggered by a druntime module ctor, in gc.impl.conservative.gc.Gcx.mark() called by rt.tlsgc.scan()...

@kinke
Copy link
Member Author

kinke commented Aug 18, 2017

Might have something to do with the .tls section disappearing from ldc2.exe when linking with VS2017 v15.3.1 (but the magic _tls_start/end symbols are still there and bracket a plausibly small range). @rainers: You're the expert for that kind of thing, right? ;)

@rainers
Copy link
Contributor

rainers commented Aug 19, 2017

Might have something to do with the .tls section disappearing from ldc2.exe when linking with VS2017 v15.3.1 (but the magic _tls_start/end symbols are still there and bracket a plausibly small range).

Oh, boy. Sounds like this will break every program linked against/with v15.3.1 ;-(

@rainers: You're the expert for that kind of thing, right? ;)

I'll have a look...

@rainers
Copy link
Contributor

rainers commented Aug 19, 2017

The problem seems to be that .tls is no longer an image section, but only a segment in the .data section. TLS access seems to be ok, but _tls_start and _tls_end are now evaluated relative to the .data section:

int x = 7;

extern(C) extern
{
	int _tls_start;
	int _tls_end;
}

void[] initTLSRanges() nothrow @nogc
{
	auto pbeg = cast(void*)&_tls_start;
	auto pend = cast(void*)&_tls_end;
	return pbeg[0 .. pend - pbeg];
}

void main()
{
	printf("%p: %d\n", &x, x);
	
	auto r = initTLSRanges();
	printf("%p: %d\n", r.ptr, r.length);
}

prints

000001B0638D7470: 7
000001B0638E60E0: 233

i.e. the variable is not in the TLS range (but it's the range that is wrong here). Happens with dmd, too, if using V2017 v15.3.1. This seems to be a linker issue as exchanging the vc library with the one from VS2015 doesn't help.

@kinke
Copy link
Member Author

kinke commented Aug 19, 2017

Thanks for the analysis. So if we were to work around that, the host compiler's druntime would have to be patched first, thanks MS, very much appreciated.
I can't even downgrade to 15.2. Needed to uninstall VS2017 completely and download the 15.0 installer (no installers for the previous updates). I can only upgrade directly to 15.3.1 later on. And I thought the whole reason for the new VS2017 system with less registry keys was to enable different parallel installations...

@rainers
Copy link
Contributor

rainers commented Aug 19, 2017

So if we were to work around that, the host compiler's druntime would have to be patched first

Depends on the workaround. Maybe we can enforce moving the segment back into the .tls section.

I can't even downgrade to 15.2.

I guess my VS2017 is broken now, too. (I mostly use 2013 and 2015, though).

They also changed the vcvars64.bat to always switch to %HOME%\source. That breaks a good deal of my batches, probably also some builds by Visual D.

@kinke kinke merged commit f4038aa into ldc-developers:master Aug 19, 2017
@kinke kinke deleted the cmake2 branch August 19, 2017 19:58
@kinke
Copy link
Member Author

kinke commented Aug 25, 2017

Does it have debug info support now?

From https://llvm.org/docs/CMake.html#llvm-specific-variables:

LLVM_ENABLE_DIA_SDK:BOOL
    Enable building with MSVC DIA SDK for PDB debugging support. Available only with MSVC. Defaults to ON.

Don't know what that means exactly and don't have time to dig into it right now, but I take it as a good sign. ;)

@kinke
Copy link
Member Author

kinke commented Aug 26, 2017

Btw, Microsoft released 15.3.2 4 days later. I don't dare testing that yet though.

They also changed the vcvars64.bat to always switch to %HOME%\source. That breaks a good deal of my batches

Yep, mine too. Additionally, the $(Platform) MSBuild variable apparently isn't defined anymore...

@rainers
Copy link
Contributor

rainers commented Aug 26, 2017

Btw, Microsoft released 15.3.2 4 days later. I don't dare testing that yet though.

I tried it, no improvement for our issues. cv2pdb also doesn't work anymore...

@rainers
Copy link
Contributor

rainers commented Aug 27, 2017

So if we were to work around that, the host compiler's druntime would have to be patched first, thanks MS, very much appreciated.

I have not found any work around, so here is the runtime change: dlang/druntime#1910

@rainers
Copy link
Contributor

rainers commented Sep 1, 2017

I have not found any work around, so here is the runtime change: dlang/druntime#1910

I stumbled over a workaround: there is a hidden linker switch /noopttls that restores the old behaveour. Seems to exist starting with VS2015.

@kinke
Copy link
Member Author

kinke commented Sep 1, 2017

Oh wow, how did you find out about that one? No single Google hit... ;)

@rainers
Copy link
Contributor

rainers commented Sep 1, 2017

Oh wow, how did you find out about that one? No single Google hit... ;)

Staring at strings in link.exe. You can find a quite some more undocumented switches this way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants