[RFC] March Update: Progress report on CMake build system's ability to replace autoconf

There has been a lot of progress since I first sent out an email recapping the status of replacing autoconf, so I thought I’d send an update.

Completed:

  • Bug 15493 - No option to build shared libLLVM-version.so in CMake

  • Bug 12157 - llvmconfig.cmake.in make cmake installations not relocatable

  • Bug 18722 - Option to use CMake with libc++ to compile clang

  • Bug 21560 - Add support to cmake for using installed versions of LLVM and Clang

  • Bug 21569 - Can’t `make install prefix=/tmp/llvm’ with CMake.

  • Bug 21570 - Cannot set default configuration options for CMake

Still Outstanding:

  • Bug 14109 - CMake build for compiler-rt should use just-built clang
  • Looks like there are still some small issues here, but it is further along than expected
  • Bug 18496 - [cmake] .S assembly files not compiled by cmake in libclang_rt.ARCH
  • Unclear if this is still a problem
  • Bug 19462 - Use the INSTALL(EXPORT …) to export CMake definitions
  • Bug 19875 - libraries and executables need different rpaths
  • No Update: Still outstanding, I don’t think this is a blocker.
  • Bug 21561 - Update release scripts to use CMake
  • No Update: Still outstanding and blocking removal of autoconf
  • Bug 21562 - Add a CMake equivalent for make/platform/clang_darwin.mk in compiler_rt
  • No Update: From discussions on llvm-dev and IRC the proper fix for this is a cross-compiling approach for compiler_rt builds, and this is a blocker.
  • Bug 21568 - Cannot add rpath
  • It looks like this is not a blocker because it can be done, but is unwieldy. I think this may be made a lot easier with help from the CMake developers.

Other issues not tracked by bugs:

  • FreeBSD seemed to have problems with CMake identifying itself as amd64 causing x86_64 tests to fail

  • Migrating buildbots

  • We need to make sure libc++ works properly on Darwin

  • Update GettingStarted to prefer CMake

  • Put together a “cheat sheet” document for transitioning
  • If you have an autoconf workflow you’d like to see in the cheat sheet please send your commands my way and I‘ll assemble the cheat sheet.

If there is anything I’m missing please let me know. Thanks,

-Chris

One more outstanding issue:

Bug 22725 - lldb build with cmake fails with "Program error: Invalid parameters entered, -h for help. "

-Chris

Hi Chris,

Thanks for working on this. I haven't been following LLVM for a few
months and in that time it seems support for building a monolithic
shared library has been added which is great! I've been looking over
it and I have a few questions/comments.

* The LLVM_BUILD_LLVM_DYLIB flag isn't document. I've attached a patch for this.

* I'm not very familiar with export lists so sorry if this is a dumb
question. I see that one is generated that only has LLVM's C API in
it.
  It doesn't look like this file gets installed or used by the rest of
the build. Who is the intended consumer for this file?

* I think there's a difference in behaviour between the
autoconf/Makefile build system's ``--enabled-shared``
   and the current implementation. When LLVM is built with
--enable-shared the llvm tools are linked against the shared
   library but with LLVM_BUILD_LLVM_DYLIB the tools are still linked
against the static LLVM libraries. I'm not sure
   if people really care about this (perhaps distribution package
maintainers might?).

* The exported LLVM targets [1] which external projects using CMake can use
   to add LLVM to their project still refers to LLVM's static
libraries rather than the built
   dynamic library. Should this be changed? I'm not sure how easy this would be.

* Placing the files for building the shared library in ``tools/``
feels a bit odd given that its
  not actually a tool. Is there a good reason for doing this?

[1] http://llvm.org/docs/CMake.html#embedding-llvm-in-your-project

Thanks,
Dan.

document_LLVM_BUILD_DYLIB.patch (1.24 KB)

Hi Chris,

Thanks for working on this. I haven’t been following LLVM for a few
months and in that time it seems support for building a monolithic
shared library has been added which is great! I’ve been looking over
it and I have a few questions/comments.

  • The LLVM_BUILD_LLVM_DYLIB flag isn’t document. I’ve attached a patch for this.

Patch LGTM. Later today I will also add this to my patches currently under review: http://reviews.llvm.org/D8046

  • I’m not very familiar with export lists so sorry if this is a dumb
    question. I see that one is generated that only has LLVM’s C API in
    it.
    It doesn’t look like this file gets installed or used by the rest of
    the build. Who is the intended consumer for this file?

It is consumed by the linker. The linker then uses the export list to determine what symbols are exposed in the final binary.

  • I think there’s a difference in behaviour between the
    autoconf/Makefile build system’s --enabled-shared
    and the current implementation. When LLVM is built with
    –enable-shared the llvm tools are linked against the shared
    library but with LLVM_BUILD_LLVM_DYLIB the tools are still linked
    against the static LLVM libraries. I’m not sure
    if people really care about this (perhaps distribution package
    maintainers might?).

You’re the first person to mention this. If it is a problem it can be addressed, although it will need to be controlled by flags. Linking the tools against the dylib would mean exporting the C++ API not just the C API, and validating that the dylib is configured to contain all the libraries required by the tool.

Unlike the Makefile build system the CMake build system’s dylib is highly configurable to fit with the needs of embedded clients.

  • The exported LLVM targets [1] which external projects using CMake can use
    to add LLVM to their project still refers to LLVM’s static
    libraries rather than the built
    dynamic library. Should this be changed? I’m not sure how easy this would be.

The CMake build system’s dylib is highly configurable, so I don’t think this should change.

  • Placing the files for building the shared library in tools/
    feels a bit odd given that its
    not actually a tool. Is there a good reason for doing this?

I actually don’t know the history of this. llvm-shlib has been in tools before the CMake build system had support for it.

-Chris

* I think there's a difference in behaviour between the
autoconf/Makefile build system's ``--enabled-shared``
  and the current implementation. When LLVM is built with
--enable-shared the llvm tools are linked against the shared
  library but with LLVM_BUILD_LLVM_DYLIB the tools are still linked
against the static LLVM libraries. I'm not sure
  if people really care about this (perhaps distribution package
maintainers might?).

You’re the first person to mention this. If it is a problem it can be
addressed, although it will need to be controlled by flags. Linking the
tools against the dylib would mean exporting the C++ API not just the C API,
and validating that the dylib is configured to contain all the libraries
required by the tool.

Unlike the Makefile build system the CMake build system’s dylib is highly
configurable to fit with the needs of embedded clients.

Sure it's not a problem for me but I suspect someone wanting to keep
the their LLVM toolchain binaries as small as possible might want the
binaries to all link against the shared library rather the static
libraries. Maybe when the switch happens someone will chime in but for
now it's probably best to leave this.

Out of curiosity is there a flag that causes all symbols to be
exported (i.e. no version script is passed to the linker)? I couldn't
see one.

* The exported LLVM targets [1] which external projects using CMake can use
  to add LLVM to their project still refers to LLVM's static
libraries rather than the built
  dynamic library. Should this be changed? I'm not sure how easy this would
be.

The CMake build system’s dylib is highly configurable, so I don’t think this
should change.

I'm not quite sure what you mean. Sure the system is configurable but
not to the extent that clients of LLVM have control over what is
returned by ``llvm_map_components_to_libnames()``. AFAICT this will
always give the static libraries which a client of LLVM might not want
(especially if the distribution that ships LLVM removes the static
libraries and only ships the dynamic library). They might want the
dynamic library instead.

This would be a little challenging to implement though because it
might not be so easy to know if an the installed LLVM dynamic library
was built with the components that the caller of
```llvm_map_components_to_libnames()`` asked for.

* Placing the files for building the shared library in ``tools/``
feels a bit odd given that its
not actually a tool. Is there a good reason for doing this?

I actually don’t know the history of this. llvm-shlib has been in tools
before the CMake build system had support for it.

That might be an artifact of the autoconf/Makefile build system to
ensure that all components are built before trying to build the shared
library.

Thanks,
Dan.

* I think there's a difference in behaviour between the
autoconf/Makefile build system's ``--enabled-shared``
and the current implementation. When LLVM is built with
--enable-shared the llvm tools are linked against the shared
library but with LLVM_BUILD_LLVM_DYLIB the tools are still linked
against the static LLVM libraries. I'm not sure
if people really care about this (perhaps distribution package
maintainers might?).

You’re the first person to mention this. If it is a problem it can be
addressed, although it will need to be controlled by flags. Linking the
tools against the dylib would mean exporting the C++ API not just the C API,
and validating that the dylib is configured to contain all the libraries
required by the tool.

Unlike the Makefile build system the CMake build system’s dylib is highly
configurable to fit with the needs of embedded clients.

Sure it's not a problem for me but I suspect someone wanting to keep
the their LLVM toolchain binaries as small as possible might want the
binaries to all link against the shared library rather the static
libraries. Maybe when the switch happens someone will chime in but for
now it's probably best to leave this.

I'm currently not looking at this, but I expect it will be something my team will want next year. I may look into it sooner rather than later.

Out of curiosity is there a flag that causes all symbols to be
exported (i.e. no version script is passed to the linker)? I couldn't
see one.

No, but we will need one if we support linking the tools against the dylib.

* The exported LLVM targets [1] which external projects using CMake can use
to add LLVM to their project still refers to LLVM's static
libraries rather than the built
dynamic library. Should this be changed? I'm not sure how easy this would
be.

The CMake build system’s dylib is highly configurable, so I don’t think this
should change.

I'm not quite sure what you mean. Sure the system is configurable but
not to the extent that clients of LLVM have control over what is
returned by ``llvm_map_components_to_libnames()``. AFAICT this will
always give the static libraries which a client of LLVM might not want
(especially if the distribution that ships LLVM removes the static
libraries and only ships the dynamic library). They might want the
dynamic library instead.

Yes, but I don't think we currently encode which LLVM components the dylib contains in the exported CMake config files, so we don't properly know when you can use the dylib vs when you need to fall back to static libs. One of the side effects of the dylib being configurable is that it isn't a blanket replacement for all the static libs.

This would be a little challenging to implement though because it
might not be so easy to know if an the installed LLVM dynamic library
was built with the components that the caller of
```llvm_map_components_to_libnames()`` asked for.

Exactly. I have some ideas here though.

* Placing the files for building the shared library in ``tools/``
feels a bit odd given that its
not actually a tool. Is there a good reason for doing this?

I actually don’t know the history of this. llvm-shlib has been in tools
before the CMake build system had support for it.

That might be an artifact of the autoconf/Makefile build system to
ensure that all components are built before trying to build the shared
library.

That would make a lot of sense, and there is a similar requirement for the CMake system. I was actually planning to look into whether or not we could make a combined LLVM/Clang dylib for one of our internal clients, which would also make having this be a tool convenient.

-Chris