[OS X]: building lldb with cmake

Hi,

I've been working on a MacPorts port for lldb (MacPorts already provides ports for llvm and clang; cf. #45251 (request for lldb) – MacPorts). Using the Xcode project isn't really an option here, so I've based my approach on the instructions for building using CMake on *n*x.

In short:

- unpack llvm sources
- unpack lldb sources in the expected location in the llvm tree
- call cmake from an out-of-tree build directory pointing it to the toplevel CMakeLists.txt (i.e. the one in llvm-src)
- call make in the lldb subdir under the build directory (build/tools/lldb).

The nice thing with CMake's Makefiles generator is that it is usually able to figure out what needs to be built from upstreams when make is called in a project subdirectory, and this works with lldb.

Yet I've been asked to look into the possibility of building *just* lldb, using whatever dependencies it requires from the already installed llvm+clang directory.

I'm presuming that there might be a benefit to that approach on other Unices too. Has anyone tried whether this is the case, assuming that it's actually possible?

NB: MacPorts' port:lldb will depend on port:llvm and port:clang, so prebuilt dependencies will be available, as long as nothing is required that is omitted from a standard install.

Thanks,
René

Hi Rene,

building lldb on osx with cmake should work fine when you're doing it
as a part of llvm (our buildbot is doing it
<http://lab.llvm.org:8011/builders/lldb-x86_64-darwin-13.4&gt;\).

What you are asking for is called a "standalone" build of LLDB. I
don't think anyone has tried it on a mac, but other people are using
it, with varying levels of success. You should look at
lldb/cmake/modules/LLDBStandalone.cmake for how to set it up. As far
as I know, the main trick is pointing your build to the llvm-config
binary installed by the llvm package (you should just check out the
lldb repo, without llvm and clang sources).

good luck,
pl

Hi Pavel

Thanks for pointing me to

Hi Rene,

lldb/cmake/modules/LLDBStandalone.cmake for how to set it up. As far
as I know, the main trick is pointing your build to the llvm-config
binary installed by the llvm package

So, adding

-DLLVM_CONFIG=/opt/local/libexec/llvm-3.9/bin/llvm-config -DLLVM_DIR=/opt/local/libexec/llvm-3.9/lib/cmake/llvm

almost allows cmake to succeed when pointed to ../llvm-3.9.0.src/tools/lldb, except for 1 pesky error:

-- Found LLVM_CONFIG as /opt/local/libexec/llvm-3.9/bin/llvm-config
-- Building with -fPIC
CMake Error at cmake/modules/LLDBStandalone.cmake:89 (include):
  include could not find load file:

    CheckAtomic
Call Stack (most recent call first):
  CMakeLists.txt:3 (include)

and with reason: the path to that file is llvm-3.9.0.src/cmake/modules/CheckAtomic.cmake

(you should just check out the
lldb repo, without llvm and clang sources).

Yeah, one would hope for that, eh? :slight_smile:

Thanks,
René

The biggest issue with trying to use cmake on macOS is that there is no support for building frameworks, please correct me if I am wrong. The xcode build will build a "LLDB.framework" that contains all headers and the shared library, and the "lldb" command line tool that links against that. We really want the LLDB.framework since it gives us a bundle like directory that contains everything we need. Current the LLDB.framework contains:
- LLDB headers
- clang headers needed for expression compilation where the compiler parses modules
- associated binaries needed for debugging (lldb-server, lldb-argdumper, debugserver, darwin-debug
- Python module and packages
- XPC services for debugging as root

I believe the normal cmake build just will build a lldb.dylib or lldb.so instead of a LLDB.framework. Then you would need to find a place for all of the remaining stuff just like you have to do on linux.

With MacPorts, do all projects tend to not build frameworks, or do some build frameworks?

Greg Clayton

It’s possible they weren’t supported in the past, but creating Frameworks is definitely supported now.

https://cmake.org/cmake/help/v3.6/manual/cmake-buildsystem.7.html#apple-frameworks
https://cmake.org/cmake/help/v3.6/prop_tgt/FRAMEWORK.html#prop_tgt:FRAMEWORK

Here’s a more detailed example.

https://gitlab.kitware.com/cmake/cmake/blob/v3.6.2/Tests/Framework/CMakeLists.txt

Hi,

The biggest issue with trying to use cmake on macOS is that there is no support for building frameworks, please correct me if I am wrong. The xcode build will build a "LLDB.framework" that contains all headers and the shared library, and the "lldb" command line tool that links against that. We really want the LLDB.framework since it gives us a bundle like directory that contains everything we need.

That may not be supported by the current cmake system, but cmake definitely supports the possibility as pointed out by Zachary.
However, it's not an issue for MacPorts. In fact,

Current the LLDB.framework contains:
- LLDB headers
- clang headers needed for expression compilation where the compiler parses modules
- associated binaries needed for debugging (lldb-server, lldb-argdumper, debugserver, darwin-debug
- Python module and packages

This is may be an issue with MacPorts. I haven't looked at that.

Since you mention it: the other parts of LLVM and Clang aren't built as frameworks, correct? If Xcode were to include an llvm-config utility, would it point dependents to the correct locations inside the framework(s)?

- XPC services for debugging as root

I believe the normal cmake build just will build a lldb.dylib or lldb.so instead of a LLDB.framework. Then you would need to find a place for all of the remaining stuff just like you have to do on linux.

Indeed. And that just works without any problem at all; the stuff all gets installed into ${prefix}/libexec/llvm-${branch}.

With MacPorts, do all projects tend to not build frameworks, or do some build frameworks?

Some build frameworks, but as a general rule of thumb one can say that cross-platform software is built and installed as it would on any other Unix system. That's the best guarantee that the largest selection of dependent software will also build.

Example: Qt builds frameworks even under MacPorts, just to be sure we install .dylib symlinks to the framework binaries (which AFAIK are redundant nowadays). But all of KDE builds regular shared libraries that link to the Qt frameworks without a glitch. To make things even more "perverse": Qt installs a range of plugins, which go into standard XDG-compliant locations.

R.

Hi,

I wanted to see how far I could get with a standalone build, so I copied the missing CheckAtomic.cmake file into the installed cmake/llvm directory, and tried to build lldb.
It aborted at 93% because it tried to include a headerfile from the llvm source:

{{{
In file included from /opt/local/var/macports/build/_opt_local_site-ports_lang_llvm-3.9/lldb-3.9/work/llvm-3.9.0.src/tools/lldb/tools/lldb-mi/MICmdCmdData.cpp:45:
/opt/local/var/macports/build/_opt_local_site-ports_lang_llvm-3.9/lldb-3.9/work/llvm-3.9.0.src/tools/lldb/tools/lldb-mi/MIUtilParse.h:13:10: fatal error:
      '../lib/Support/regex_impl.h' file not found
#include "../lib/Support/regex_impl.h"
         ^
1 error generated.
}}}

To be honest, I'm not sure how this could have worked with my approach of calling make in build/tools/lldb, but that looks like a clear bug if standalone builds are to be possible.

R.

Yes, this is a bug in LLDB. You’re welcome to try to fix it by changing it to include “llvm/Support/Regex.h” instead of this private header. Not sure if you will run into any issues, but in theory I see no reason why it shouldn’t work.

To be completely honest with you I don’t even know why this class exists. All it needs to do is use llvm’s regex class. The entire MIUtilParse.h / .cpp files can be deleted as far as I’m concerned.

That clearly needs a bit more work, it provides a class that's used. It also needs access to the private header; the public Regex.h header lacks the definition for a private type.
I'll leave this to someone else to figure out. I was trying a standalone build with the lldb source tree at its usual location so I could simply correct the include statement (#include "../../../lib/Support/regex_impl.h").

I must say that there is a significant advantage to doing a standalone build if you already have all dependencies in place. The resulting build directory is over twice smaller than it is when you do an official/full configure and then invoke make in the tools/lldb subdirectory. The build time must be proportionally shorter.

R.

There's another issue with the standalone build.

I call cmake with -DDCMAKE_INSTALL_PREFIX=/opt/local/libexec/llvm-3.9, so that lldb gets installed with the rest of llvm 3.9, into /opt/local/libexec/llvm-3.9 . It looks like liblldb.${version} is generated with the wrong install path recorded:

%> otool -L /opt/local/libexec/llvm-3.9/lib/liblldb.dylib
/opt/local/libexec/llvm-3.9/lib/liblldb.dylib:
        /opt/local/lib/liblldb.3.9.0.dylib (compatibility version 0.0.0, current version 3.9.0)
        /opt/local/lib/libedit.0.dylib (compatibility version 1.0.0, current version 1.51.0)
        /opt/local/lib/libncurses.6.dylib (compatibility version 6.0.0, current version 6.0.0)
        /opt/local/lib/libform.6.dylib (compatibility version 6.0.0, current version 6.0.0)
        /opt/local/lib/libpanel.6.dylib (compatibility version 6.0.0, current version 6.0.0)
        /opt/local/Library/Frameworks/Python.framework/Versions/2.7/Python (compatibility version 2.7.0, current version 2.7.0)
        /opt/local/lib/libxml2.2.dylib (compatibility version 12.0.0, current version 12.2.0)
        /System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 157.0.0)
        /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1056.17.0)
        /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 855.17.0)
        /System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices (compatibility version 1.0.0, current version 59.0.0)
        /System/Library/Frameworks/Security.framework/Versions/A/Security (compatibility version 1.0.0, current version 55471.14.40)
        /System/Library/PrivateFrameworks/DebugSymbols.framework/Versions/A/DebugSymbols (compatibility version 1.0.0, current version 106.0.0)
        /opt/local/lib/libffi.6.dylib (compatibility version 7.0.0, current version 7.4.0)
        /opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
        /opt/local/libexec/llvm-3.9/lib/libLLVM.dylib (compatibility version 1.0.0, current version 3.9.0)
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
        /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)

and thus

%> otool -L /opt/local/libexec/llvm-3.9/bin/lldb
/opt/local/libexec/llvm-3.9/bin/lldb:
        /opt/local/lib/liblldb.3.9.0.dylib (compatibility version 0.0.0, current version 3.9.0)
        /opt/local/lib/libncurses.6.dylib (compatibility version 6.0.0, current version 6.0.0)
        /opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
        /opt/local/libexec/llvm-3.9/lib/libLLVM.dylib (compatibility version 1.0.0, current version 3.9.0)
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)

so

%> /opt/local/libexec/llvm-3.9/bin/lldb
dyld: Library not loaded: /opt/local/lib/liblldb.3.9.0.dylib
  Referenced from: /opt/local/libexec/llvm-3.9/bin/lldb
  Reason: image not found
Trace/BPT trap

I also seems that the actual path to liblldb is not added to lldb's rpath.

R.

Agree that a standalone build would be great to have working, it just requires someone willing and able to come along and fix it :slight_smile:

This class should no longer be used anywhere (unless someone re-added
uses of it in the last few days). https://reviews.llvm.org/D23883
removes it completely.

I have it on my TODO but honestly speaking, LLDB is a bit of a mess
right now and I'm not even sure where to start. So far I'm focusing
on the other LLVM components but I should be able to get to LLDB soon.
Though I can't promise much since my time is quite limited.

Re: MIUtilParse: I'm building the 3.9.0 release so no worries that the class has been added back supposing it was removed *after* the release.

Agree that a standalone build would be great to have working, it just
requires someone willing and able to come along and fix it :slight_smile:

I have it on my TODO but honestly speaking, LLDB is a bit of a mess
right now and I'm not even sure where to start. So far I'm focusing
on the other LLVM components but I should be able to get to LLDB soon.
Though I can't promise much since my time is quite limited.

There really isn't much to be done to get it to work, esp. if the abovementioned class is already removed:

- fix finding CheckAtomic.cmake (or just install it with LLVM)
- fix the install location as recorded in liblldb and make sure that location gets added to the rpath in lldb, lldb-mi and other dependents.

There's also an issue finding the proper Python library, at least when building MacPorts. It finds the correct framework binary when doing a complete build using the toplevel CMake file, but apparently goes for the latest version if you use the standalone build.

R.

There is already available framework with standalone build of LLDB for
Darwin -- pkgsrc. So far it ships with local patches, but they are being
eliminated.

http://pkgsrc.se/devel/lldb

Re: MIUtilParse: I'm building the 3.9.0 release so no worries that the class has been added back supposing it was removed *after* the release.

Agree that a standalone build would be great to have working, it just
requires someone willing and able to come along and fix it :slight_smile:

I have it on my TODO but honestly speaking, LLDB is a bit of a mess
right now and I'm not even sure where to start. So far I'm focusing
on the other LLVM components but I should be able to get to LLDB soon.
Though I can't promise much since my time is quite limited.

There really isn't much to be done to get it to work, esp. if the abovementioned class is already removed:

- fix finding CheckAtomic.cmake (or just install it with LLVM)

CheckAtomic is installed with LLVM on trunk, and will be this way in future releases.

Good, thanks for confirming that the tentative solution I adopted in my 3.9.0 packaging was the right one.

R.