[llvm-dev] Correctly linking against libLLVM (single shared library build)

1,581 views
Skip to first unread message

Michal Srb via llvm-dev

unread,
Oct 23, 2017, 10:19:14 AM10/23/17
to llvm-dev, Jiri Slaby
Hi,

In SUSE we have recently switched from building LLVM as multiple shared
libraries (using BUILD_SHARED_LIBS) to building it as a single shared library
(using LLVM_BUILD_LLVM_DYLIB).

The multiple shared libraries build was causing issues and apparently it is
only meant for LLVM developers. Our guidelines prohibit linking against static
libraries unless there is no other option.

After this change, some external tools failed building because they try to
link against libraries given by the cmake function
`llvm_map_components_to_libnames`. This function returns library names as if
each component was in its own library. (LLVMSupport, LLVMCore, ...)
Usage of this function comes from documentation:
https://llvm.org/docs/CMake.html#embedding-llvm-in-your-project

1) Is `llvm_map_components_to_libnames` working as expected? Shouldn't it
return just "LLVM" if LLVM_BUILD_LLVM_DYLIB was used?

2) I saw that there is a `add_llvm_library` function that chooses between
using `llvm_map_components_to_libnames` or just using "LLVM" directly based on
LLVM_BUILD_LLVM_DYLIB. Is this function suitable for use by external projects?
It doesn't seem to be documented. Is there also equivalent for executables?

Thank you,
Michal Srb
_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

Chris Bieneman via llvm-dev

unread,
Nov 13, 2017, 7:26:11 PM11/13/17
to Michal Srb, llvm-dev, Jiri Slaby
Sorry for the delayed response. I've been out of town a lot lately.

The documentation you referenced is unfortunately out of date (you might notice it still references autoconf). I'll see if I can find time to update it, but the guidance should be to use the `llvm_config` CMake function instead. The proper usage of that in the example there would be to replace the call to `llvm_map_components_to_libnames` with `llvm_config(simple-tool support core irreader)`.

`llvm_config` should properly handle the LLVM shared library.

Thanks,
-Chris

Michal Srb via llvm-dev

unread,
Nov 16, 2017, 2:45:12 AM11/16/17
to Jiri Slaby, llvm-dev
On Thursday, 16 November 2017 08:34:50 CET Jiri Slaby wrote:
> Actually it does not work at all. It behaves exactly the same as
> map_components with this CMakeLists.txt:

> llvm_config(bubak support core irreader)

I think the llvm_config needs USE_SHARED parameter, something like:
llvm_config(bubak USE_SHARED support core irreader)

Otherwise it assumes you want to link with the static libraries.

In our case we do not package the static libraries, so it would make sense if
llvm_config defaulted to USE_SHARED - we could patch it to behave that way in
our package.

Jiri Slaby via llvm-dev

unread,
Nov 16, 2017, 2:50:56 AM11/16/17
to Chris Bieneman, Michal Srb, llvm-dev
On 11/14/2017, 01:26 AM, Chris Bieneman wrote:
> Sorry for the delayed response. I've been out of town a lot lately.
>
> The documentation you referenced is unfortunately out of date (you might notice it still references autoconf). I'll see if I can find time to update it, but the guidance should be to use the `llvm_config` CMake function instead. The proper usage of that in the example there would be to replace the call to `llvm_map_components_to_libnames` with `llvm_config(simple-tool support core irreader)`.
>
> `llvm_config` should properly handle the LLVM shared library.

Actually it does not work at all. It behaves exactly the same as
map_components with this CMakeLists.txt:
cmake_minimum_required(VERSION 3.4.3)
project(SimpleProject)

find_package(LLVM REQUIRED CONFIG)

message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")

llvm_map_components_to_libnames(llvm_libs support core irreader)
message(STATUS "Components mapped to libnames: ${llvm_libs}")

add_executable(bubak a.c)

llvm_config(bubak support core irreader)
get_target_property(LL bubak LINK_LIBRARIES)
message(STATUS "Components mapped by llvm_config: ${LL}")


It results in:
-- Found LLVM 4.0.1
-- Using LLVMConfig.cmake in: /usr/lib64/cmake/llvm
-- Components mapped to libnames: LLVMSupport;LLVMCore;LLVMIRReader
-- Components mapped by llvm_config: LLVMSupport;LLVMCore;LLVMIRReader

And in turn we get linking errors:
[ 50%] Linking C executable bubak
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld:
cannot find -lLLVMSupport
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld:
cannot find -lLLVMCore
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld:
cannot find -lLLVMIRReader

So this does not work either :/.

thanks,
--
js
suse labs

Jiri Slaby via llvm-dev

unread,
Nov 21, 2017, 3:13:04 AM11/21/17
to Michal Srb, llvm-dev
On 11/16/2017, 08:45 AM, Michal Srb wrote:
> On Thursday, 16 November 2017 08:34:50 CET Jiri Slaby wrote:
>> Actually it does not work at all. It behaves exactly the same as
>> map_components with this CMakeLists.txt:
>
>> llvm_config(bubak support core irreader)
>
> I think the llvm_config needs USE_SHARED parameter, something like:
> llvm_config(bubak USE_SHARED support core irreader)
>
> Otherwise it assumes you want to link with the static libraries.
>
> In our case we do not package the static libraries, so it would make sense if
> llvm_config defaulted to USE_SHARED - we could patch it to behave that way in
> our package.

That neither works for me, unfortunately:


-- Components mapped by llvm_config: LLVMSupport;LLVMCore;LLVMIRReader

So it's huge defunct mess :(. This all should be indeed handled by the
internals of llvm cmake files. And I believe this is exactly the reason
why klee by default invokes llvm-config *program* and not the
llvm-config (or other) cmake macro (one has to explicitly set
USE_CMAKE_FIND_PACKAGE_LLVM=ON to use the latter).

On the top of all that, trying to map the "native" component errors the
cmake process with:
CMake Error at /usr/lib64/cmake/llvm/LLVM-Config.cmake:126 (message):
Target X86 is not in the set of libraries.
Call Stack (most recent call first):
/usr/lib64/cmake/llvm/LLVM-Config.cmake:66
(llvm_map_components_to_libnames)
/usr/lib64/cmake/llvm/LLVM-Config.cmake:59 (explicit_llvm_config)
CMakeLists.txt:19 (llvm_config)

With or without USE_SHARED, with llvm_map_components_to_libnames or
llvm_config.

This works, of course:
$ llvm-config --libnames native
libLLVM.so

thanks,
--
js
suse labs

Reply all
Reply to author
Forward
0 new messages