cmake & vc++: clang vs. libclang woes

For a few days now I've been plagued by output target conflicts between
the clang and libclang projects in Visual Studio. The errors I'm getting
look like this:

------ Build started: Project: clang, Configuration: Debug Win32 ------
  LINK : C:\boost\consulting\git\llvm\bin\Debug\clang.exe not found or
not built by the last incremental link; performing full link
     Creating library C:/boost/consulting/git/llvm/lib/Debug/clang.lib
and object C:/boost/consulting/git/llvm/lib/Debug/clang.exp
cc1as_main.obj : warning LNK4204:
'c:\boost\consulting\git\llvm\bin\debug\clang.pdb' is missing debugging
information for referencing module; linking object as if no debug info
cc1_main.obj : warning LNK4204:
'c:\boost\consulting\git\llvm\bin\debug\clang.pdb' is missing debugging
information for referencing module; linking object as if no debug info
driver.obj : warning LNK4204:
'c:\boost\consulting\git\llvm\bin\debug\clang.pdb' is missing debugging
information for referencing module; linking object as if no debug info
  clang.vcxproj -> C:\boost\consulting\git\llvm\bin\Debug\clang.exe
------ Build started: Project: c-index-test, Configuration: Debug Win32

For a few days now I've been plagued by output target conflicts between
the clang and libclang projects in Visual Studio. The errors I'm getting
look like this:

<snip>

At the very least, there is a bug in the CMake files because both these
projects try to build bin/[config]/clang.pdb. There seems to be other
conflicts too, leading to the above linker errors, but I can't track it
down. (Maybe clang.exp or clang.obj or clang.lib?)

Yep, both projects use lib/[config]/clang.exp as their export library.
This causes havoc. I've worked around the problem by manually changing
the generated clang.vcproj to use "expclang" as the name of the import
library, which makes it generate lib/[clang]/expclang.exp and
lib/[config]/expclang.lib. This doesn't break anything because nobody
uses the exports from clang.exe. I'm not even sure why we're generating
an import library for clang.exe.

I've also turned off incremental linking for both clang.vcproj and
libclang.vcproj because they both try to use bin/[config]/clang.ilk as
their incremental link file.

If I knew more CMake, I would suggest a patch, but I'll leave that for
someone else.

Eric Niebler <eric@boostpro.com> writes:

For a few days now I've been plagued by output target conflicts between
the clang and libclang projects in Visual Studio. The errors I'm getting
look like this:

<snip>

At the very least, there is a bug in the CMake files because both these
projects try to build bin/[config]/clang.pdb. There seems to be other
conflicts too, leading to the above linker errors, but I can't track it
down. (Maybe clang.exp or clang.obj or clang.lib?)

Suggestion: Why not make libclang generate libclang.[dll|lib] instead of
clang.[lib|dll]? I think that would avoid these problems.

The proper name of the library is "clang", not "libclang". Changing it
to libclang only for VS would be arbitrary and would break the build for
multi-platform clients.

Yep, both projects use lib/[config]/clang.exp as their export library.
This causes havoc. I've worked around the problem by manually changing
the generated clang.vcproj to use "expclang" as the name of the import
library, which makes it generate lib/[clang]/expclang.exp and
lib/[config]/expclang.lib. This doesn't break anything because nobody
uses the exports from clang.exe. I'm not even sure why we're generating
an import library for clang.exe.

I've also turned off incremental linking for both clang.vcproj and
libclang.vcproj because they both try to use bin/[config]/clang.ilk as
their incremental link file.

If I knew more CMake, I would suggest a patch, but I'll leave that for
someone else.

Thanks for investigating, the information you provided is valuable. Next
time please open a bug report, though.

The real fix would be to not create an exports file for clang.exe, as
you suggest. It seems that the exports file is created when the
executable exports symbols (a Windows executable can act as a dll too.)
So now the question is locating where those symbols are exported. The
only place that uses dllexport is on include/clang-c/Index.h when
_CINDEX_LIB_ is true. But that macro is not defined when clang.exe is
created.

Inspecting clang.exe with depends.exe shows this two exported functions:

std::_Mutex::_Mutex(enum std::_Uninitialized)
class std::_Init_locks & std::_Init_locks::operator=(class std::_Init_locks const &)

No idea why they are there. Actually, it seems that most (all?)
executables created by the build exports those symbols and the lib
directory is plagued with .exp and .lib files corresponding to the LLVM
executables.

I have no time right now for running a build on my Windows VM (which
takes a while) but will look at the problem before the weekend, unless
someone beats me to it.

Óscar Fuentes <ofv@wanadoo.es> writes:

[snip]

The real fix would be to not create an exports file for clang.exe, as
you suggest. It seems that the exports file is created when the
executable exports symbols (a Windows executable can act as a dll too.)

[snip]

Inspecting clang.exe with depends.exe shows this two exported functions:

std::_Mutex::_Mutex(enum std::_Uninitialized)
class std::_Init_locks & std::_Init_locks::operator=(class std::_Init_locks const &)

No idea why they are there. Actually, it seems that most (all?)
executables created by the build exports those symbols and the lib
directory is plagued with .exp and .lib files corresponding to the LLVM
executables.

It is a bug on VS, reported as fixed on the upcoming VS 11 (which
doesn't help us):

http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/4692205a-0296-4f41-adbb-fa8339597f5c/

Defining _STATIC_CPPLIB is mentioned as a workaround, but I don't know
all the implications.

[snip]

Hi, I have MSVS with the Service Pack 1 (released a few weeks ago) and
I don't get this problem.
Is VS 11 == SP1 because I really doubt there will ever be a MSVS 2011.

Francois Pichet <pichet2000@gmail.com> writes:

It is a bug on VS, reported as fixed on the upcoming VS 11 (which
doesn't help us):

http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/4692205a-0296-4f41-adbb-fa8339597f5c/

Defining _STATIC_CPPLIB is mentioned as a workaround, but I don't know
all the implications.

Hi, I have MSVS with the Service Pack 1 (released a few weeks ago) and
I don't get this problem.

Thanks for the info. So a solution for VS 10 users is to install SP1.
But it hits VS 9 too.

Is VS 11 == SP1 because I really doubt there will ever be a MSVS 2011.

VS 11 does not imply 2011. For example, the product "Visual Studio 2008"
is labeled as "Version 9", and so on. VS 11 is mentioned on the MSDN
discussion I linked.

That might solve the conflict on clang.[exp|lib] (I haven't tested), but
not for clang.ilk (incremental linking) or clang.pdb (debug symbols)
that I originally reported.

Eric Niebler <eric@boostpro.com> writes:

Thanks for the info. So a solution for VS 10 users is to install SP1.

That might solve the conflict on clang.[exp|lib] (I haven't tested), but
not for clang.ilk (incremental linking) or clang.pdb (debug symbols)
that I originally reported.

Right. I asked on the cmake ml but my hopes are low. Renaming clang.dll
is tricky due to the reasons mentioned on a previous post.

Eric Niebler <eric@boostpro.com> writes:

Hi Oscar,

I know this is well-intended, but this really isn't wonderful for those of us not developing on Windows. From a user standpoint, this looks like a bug, as the Makefile-based produces a different output than the CMake-based build.

Ted

Hello Ted,

Ted Kremenek <kremenek@apple.com> writes:

I've renamed libclang's output name to libclang. This way we create
libclang.dll on Windows and liblibclang.a elsewhere.

Hi Oscar,

I know this is well-intended, but this really isn't wonderful for
those of us not developing on Windows. From a user standpoint, this
looks like a bug, as the Makefile-based produces a different output
than the CMake-based build.

I'm not happy with it either, that's the reason it took several days
from the bug report to the change. But what else could we do? VS
generates a series of files for each executable (.exe or .dll) using the
executable's basename as a default. There are options for changing the
name of the .pdb, but AFAIK there is no option for chaning the name of
the .ilk (incremental linker info file), and there are others such as
the .lib and .exp files which are created for EXEs too due to a bug on
VS. It's a minefield. Considering that the VS build was broken and cmake
is the only method for building LLVM with VS, I was forced to make that
change.

If anyone knows a better solution, I'll be happy to hear it.

Hi Oscar,

I unfortunately don't have a better solution; I'm not an expert on CMake, and I understand this solution was not taken lightly.

That said, is this mainly an inherent limitation in the CMake build system? If so, should we file a bug against CMake so that we can do the "right thing" later?

Ted

Ted Kremenek <kremenek@apple.com> writes:

I unfortunately don't have a better solution; I'm not an expert on
CMake, and I understand this solution was not taken lightly.

That said, is this mainly an inherent limitation in the CMake build
system? If so, should we file a bug against CMake so that we can do
the "right thing" later?

It is a limitation in VS (both by design and by a bug.) It seems that
building a library and a executable with the same basename is not a good
idea when working with VS.

Shall we implement "build on other directory and copy" scheme for ms toolchain?

I don't prefer "libclang.lib" and "libclang.dll", nor "liblibclang.a".

...Takumi

NAKAMURA Takumi <geek4civic@gmail.com> writes:

It is a limitation in VS (both by design and by a bug.) It seems that
building a library and a executable with the same basename is not a good
idea when working with VS.

Shall we implement "build on other directory and copy" scheme for ms toolchain?

That solution is tricky. We must deal with potential side-effects on the
installation process, for instance. We must copy the .pdb file
too.

I don't prefer "libclang.lib" and "libclang.dll", nor "liblibclang.a".

The library name is not terribly bad, IMHO. What is undesirable is the
divergence with the configure&make build, as Ted notes. However, I'm
presupposing that the people who use cmake on Unix for building LLVM
also uses cmake for their projects, and currently I don't know of anyone
using cmake for distributing a LLVM-based project or LLVM itself to the
public. So there is little room for a mismatch on the user's part.