Can't build against LLVM-3.5 with CMake: CMakeExports.cmake broken?

Hi all,

I can't seem to get the simplest CMakeLists.txt file working from http://llvm.org/docs/CMake.html#embedding-llvm-in-your-project. Do any of the LLVM projects use `find_package(LLVM REQUIRED CONFIG)`? Should I just be using `llvm-config` directly?

http://llvm.org/bugs/show_bug.cgi?id=20884

David

This should work. Are you building LLVM with CMake or Autoconf/Makefile build system?

If you build with CMake you can build your application using the LLVM build or install directory. If you built LLVM with Autoconf/Makefiles then you can only build your application using the LLVM install directory.

Should I just be using llvm-config directly?

No. If you are using CMake this is the right way to do it.

When I’m at a real computer rather than my phone I’ll take a proper look.

Hi,

I can't reproduce your issue on the LLVM 3.5 release branch or trunk
it. Looking at your bug report I think your install is messed up


CMake Error at /usr/local/Cellar/llvm/HEAD/share/llvm/cmake/LLVMExports.cmake:6
(set_property):
  set_property could not find TARGET LLVMSupport.  Perhaps it has not yet
  been created.
Call Stack (most recent call first):
  /usr/local/share/llvm/cmake/LLVMConfig.cmake:50 (include)
  CMakeLists.txt:4 (find_package)

/usr/local/share/llvm/cmake/LLVMConfig.cmake seems to calling
/usr/local/Cellar/llvm/HEAD/share/llvm/cmake/LLVMExports.cmake which
doesn't make sense. I would try cleaning up your install and start
again. If you intend to working with different versions of LLVM I
don't think it's a good idea to install it anyway. You can just build
your project against the LLVM build directory and add the LLVM tools
to your PATH when you need to.

I have a simple example project that uses ``find_package(LLVM)``.

Here are the steps I followed to build (I build against the LLVM build
directory and don't bother installing it)

$ mkdir tutorial/

# Build LLVM
$ mkdir llvm/
$ cd llvm/
$ svn co http://llvm.org/svn/llvm-project/llvm/branches/release_35 src
$ mkdir build
$ cd build
$ cmake -G Ninja ../src
$ ninja
# This is just for convenience when setting LLVM_DIR later on.
$ LLVM_BUILD_ROOT="$(pwd)"

# Build simple tutorial project
$ cd ../
$ mkdir srg-llvm-pass-tutorial
$ git clone https://github.com/delcypher/srg-llvm-pass-tutorial.git src
$ mkdir build
$ cd build/
# I'm assuming your shell will example ${LLVM_BUILD_ROOT} before invoking cmake
$ cmake -DLLVM_DIR:PATH=${LLVM_BUILD_ROOT}/share/llvm/cmake/ -G Ninja ../src
$ ninja

Hope that helps

Dan.

Hi David,

CC'ing Brad King and Eric Christopher as they'll probably be interested.

I've just managed to reproduce your issue David. I figured this out
because my Linux distribution just upgraded to LLVM/Clang 3.5 and I
noticed that trying use find_package(LLVM ...) was broken :frowning: . They
use the Autoconf/Makefile build system (specifically because the CMake
build system doesn't support generating a single versioned shared
library) and use --enable-shared flag to configure.

What is happening is that none of the libraries are being added into
LLVMExports.cmake file when it is generated by
``cmake/modules/Makefile``. So when a CMake project tries to use
``find_package()`` it complains about the missing targets.

This is happening because the ``LLVMConfigLibs`` makefile variable is
empty when used in ``cmake/modules/Makefile``. It is normally set in
Makefile.rules . However if you build with --enable-shared this
variable doesn't get set and so LLVMExports.cmake isn't generated
correctly.

@David: Were you also compiling this way?

One way to "fix" this is make sure LLVMConfigLibs is also set when
using --enable-shared as the attached patch does. I'm not convinced
this is the right way to do it though. Perhaps
``cmake/modules/Makefile`` should invoke llvm-config itself?

This is rather annoying. I didn't catch this before because when I was
testing I never used --enable-shared.

Thoughts?

Thanks,
Dan.

llvm_fix_broken_cmake_package_under_autoconf_enableshared.patch (1.1 KB)

because my Linux distribution just upgraded to LLVM/Clang 3.5 and I
noticed that trying use find_package(LLVM ...) was broken :frowning:

AFAIK, that never worked in any version of LLVM not built by CMake before.
That's why we taught cmake/modules/Makefile to generate LLVMConfig.cmake
and LLVMExports.cmake.

What is happening is that none of the libraries are being added into
LLVMExports.cmake file when it is generated by ``cmake/modules/Makefile``.

[snip]

One way to "fix" this is make sure LLVMConfigLibs is also set when
using --enable-shared as the attached patch does.

The patch works for me and is likely sufficient at least for a fixup
during distro packaging and perhaps also in the 3.5 release branch.

Making the shared library itself available as an imported target is
a separate problem for another day (like when the CMake build system
is taught an equivalent to --enable-shared).

Perhaps ``cmake/modules/Makefile`` should invoke llvm-config itself?

It looks like LLVMConfigLibs was created in r112714 for local use in
Makefile.rules. The only use outside Makefile.rules is now in
cmake/modules/Makefile. Teaching cmake/modules/Makefile to do
a direct invocation would be fine with me.

Thanks,
-Brad

because my Linux distribution just upgraded to LLVM/Clang 3.5 and I
noticed that trying use find_package(LLVM ...) was broken :frowning:

AFAIK, that never worked in any version of LLVM not built by CMake before.
That's why we taught cmake/modules/Makefile to generate LLVMConfig.cmake
and LLVMExports.cmake.

They tried back porting the patches you made between the 3.4 and 3.5
releases. It didn't actually work properly though.

What is happening is that none of the libraries are being added into
LLVMExports.cmake file when it is generated by ``cmake/modules/Makefile``.

[snip]

One way to "fix" this is make sure LLVMConfigLibs is also set when
using --enable-shared as the attached patch does.

The patch works for me and is likely sufficient at least for a fixup
during distro packaging and perhaps also in the 3.5 release branch.

Okay. I'm not sure what the policy is on applying changes to the
release branch after LLVM has been released.

@Bill What is the policy for applying changes to a release branch
after that version of LLVM has been released?

Making the shared library itself available as an imported target is
a separate problem for another day (like when the CMake build system
is taught an equivalent to --enable-shared).

Agreed. My Linux distro actually usually removes all static libraries
but they make an exception for LLVM so this should work in my case.

Perhaps ``cmake/modules/Makefile`` should invoke llvm-config itself?

It looks like LLVMConfigLibs was created in r112714 for local use in
Makefile.rules. The only use outside Makefile.rules is now in
cmake/modules/Makefile. Teaching cmake/modules/Makefile to do
a direct invocation would be fine with me.

Okay. Attached is a patch that does this. Does this work okay for you?

Thanks,
Dan.

cleaner_fix_llvm_broken_cmake_export.patch (1.53 KB)

Yes.

Thanks,
-Brad

Okay. Attached is a patch that does this. Does this work okay for you?

Yes.

Great.

@Eric Is this okay to commit to trunk?

I think I’ll hold of applying to the release_35 branch until I know if I’m allowed to.

> > Okay. Attached is a patch that does this. Does this work okay for you?
>
> Yes.

Great.

@Eric Is this okay to commit to trunk?

Yep. Thanks!

I think I'll hold of applying to the release_35 branch until I know if I'm
allowed to.

I think Tom was our point release guy IIRC.

-eric

The last time, yes. I built with OS X Homebrew (http://brew.sh) and it looks like their formulas use --enable-shared by default, although there is an option to turn it off (https://github.com/Homebrew/homebrew/blob/master/Library/Formula/llvm.rb). I was trying to work on a patch to update to 3.5.0 when I ran into the problem.

I'll try --disable-shared with the Homebrew formula and see if that unblocks me on 3.5.0. Homebrew also has an option to pull build from trunk as well, IIRC.

Perhaps we should advise the project to build with cmake if possible?

It looks like this has been pretty much solved, sorry for the delay. I forgot that I had llvm-dev going to a dedicated mail folder.

David

@Eric Is this okay to commit to trunk?

Yep. Thanks!

Thanks. Committed in r217484.

I think I'll hold of applying to the release_35 branch until I know if I'm
allowed to.

I think Tom was our point release guy IIRC.

Okay I'll start a separate thread about this.

@David: Were you also compiling this way?

The last time, yes. I built with OS X Homebrew (http://brew.sh) and it looks like their formulas use --enable-shared by default, although there is an option to turn it off (https://github.com/Homebrew/homebrew/blob/master/Library/Formula/llvm.rb). I was trying to work on a patch to update to 3.5.0 when I ran into the problem.

I'll try --disable-shared with the Homebrew formula and see if that unblocks me on 3.5.0. Homebrew also has an option to pull build from trunk as well, IIRC.

Perhaps we should advise the project to build with cmake if possible?

That would be nice but unfortunately there is not equivalent of
--enable-shared in the CMake build right now. You can build shared
libraries with CMake but it will build separate shared libraries (e.g.
libLLVMSuport.so, libLLVMJIT.so, ...) instead of a single monolithic
shared library (i.e. libLLVM.so) .

It looks like this has been pretty much solved, sorry for the delay. I forgot that I had llvm-dev going to a dedicated mail folder.

I've committed the fix to trunk in r217484. Could you try trunk? If it
works for you then I'll close PR20884

Thanks,
Dan.

Urgh.. Looks like I broke ``make clean``. r217490 should fix that.

Thanks,
Dan.