|
| 1 | +# Configuring LDC to use compiler-rt libraries |
| 2 | + |
| 3 | +LDC provides some functionalities like PGO, sanitizers and fuzzing, which require the presence of some libraries that are part of the compiler-rt LLVM sub-project. |
| 4 | +This document aims to describe how to tell LDC the locations of these libraries, based on your installation method. |
| 5 | +It is meant mostly for people using LDC through a Linux package manager or manually building it, which includes package maintainers. |
| 6 | + |
| 7 | +## Using the prebuilt packages or [dlang.org/install.sh](https://dlang.org/install.sh) |
| 8 | + |
| 9 | +The tarballs at https://github.com/ldc-developers/ldc/releases come with the compiler-rt libraries and you don't need to do any configuration. |
| 10 | +The dlang.org install.sh script also uses these tarballs so the same things applies to it. |
| 11 | + |
| 12 | +## Using a Linux distribution's package manager |
| 13 | + |
| 14 | +Given a survey of the available options at the time of writing, |
| 15 | +most distributions don't add a dependency on compiler-rt nor do they configure LDC to find them when installed manually, |
| 16 | +therefore, it is needed to do both of these steps manually. |
| 17 | + |
| 18 | +### Installing compiler-rt |
| 19 | + |
| 20 | +The name of the actual package varies quite a lot across distributions but you can usually find it be searching for `compiler-rt` or `libclang`. |
| 21 | +Below you will find a list of popular Linux distributions and the name of the `compiler-rt` package: |
| 22 | + |
| 23 | +- Debian/Ubuntu: `libclang-rt-dev` |
| 24 | +- Fedora: `compiler-rt` |
| 25 | +- Arch: `compiler-rt` |
| 26 | +- Gentoo: `compiler-rt-sanitizers` |
| 27 | + |
| 28 | +### Adding the compiler-rt path to ldc2.conf |
| 29 | + |
| 30 | +After you've installed the packages chances are that the libraries still won't be found because the path differs from what LDC expects. |
| 31 | +To solve this you need to first determine the path of the libraries. |
| 32 | +Again, this path depends on distribution but it is easy to find if you use your package manager to list the contents of the `compiler-rt` package installed in the previous step. |
| 33 | + |
| 34 | +Usually the path has the form: `<some_directory>/lib/clang/<major_version>/lib/linux/`. |
| 35 | +Where `<major_version>` is a number like 18, 17, etc. |
| 36 | +`linux` may be, instead, a target triple like `x86_64-redhat-linux-gnu`. |
| 37 | +If the directory you found contains a bunch of `libclang_rt.*` files then you've found the right path, if not, try again. |
| 38 | + |
| 39 | +For simplicity, below you can find the paths of some Linux distributions. |
| 40 | +Remember to adapt them to the appropriate version of the package you have installed. |
| 41 | + |
| 42 | +- Debian/Ubuntu: `/usr/lib/llvm-<major_version>/lib/clang/<major_version>/lib/linux/` |
| 43 | +- Fedora: `/usr/lib/clang/<major_version>/lib/x86_64-redhat-linux-gnu/` |
| 44 | +- Arch: `/usr/lib/clang/<major_version>/lib/linux/` |
| 45 | +- Gentoo: `/usr/lib/clang/<major_version>/lib/linux/` |
| 46 | + |
| 47 | +You now need to edit the ldc2 configuration file. |
| 48 | +Since you're installing ldc2 through your package manager the config file is probably in `/etc/ldc2.conf`. |
| 49 | +If it's not there it should be in `../etc/ldc2.conf` relative to the directory of the ldc2 executable. |
| 50 | + |
| 51 | +Use your favorite text editor to edit the file and jump to the `lib-dirs = ` snippet. |
| 52 | + |
| 53 | +On recent versions you should see: |
| 54 | +``` |
| 55 | + lib-dirs = [ |
| 56 | + "/usr/lib", |
| 57 | + "/usr/lib/clang/17/lib/linux", // compiler-rt directory |
| 58 | + ]; |
| 59 | +``` |
| 60 | +You should edit the line with the `compiler-rt directory` comment and put the path you determined above in there. |
| 61 | + |
| 62 | +On older versions you wouldn't have the second entry so you would only see: |
| 63 | +``` |
| 64 | + lib-dirs = [ |
| 65 | + "/usr/lib", |
| 66 | + ]; |
| 67 | +``` |
| 68 | + |
| 69 | +In that case just add another line with the path surrounded by `"`. |
| 70 | + |
| 71 | +In the end, you should have: |
| 72 | +``` |
| 73 | + lib-dirs = [ |
| 74 | + "/usr/lib", |
| 75 | + "YOUR_PATH_HERE", // compiler-rt directory |
| 76 | + ]; |
| 77 | +``` |
| 78 | +With or without the `compiler-rt` comment. |
| 79 | + |
| 80 | +## Building from source |
| 81 | + |
| 82 | +When building from source you can pass a number of options to cmake related to compiler-rt libraries. |
| 83 | + |
| 84 | +### `COMPILER_RT_BASE_DIR` |
| 85 | + |
| 86 | +This option tells cmake a path that will be transformed, assuming standard layout, in the final compiler-rt directory. |
| 87 | +If you are using a distribution tarball for llvm then the default value for this option, `<LLVM_LIB_DIR>/clang`, should be the correct one. |
| 88 | + |
| 89 | +If on Linux and using the llvm provided through your package manager set this option to something like `/usr/lib/clang`. |
| 90 | +How to find the correct path is described above, in the Linux section. |
| 91 | + |
| 92 | +### `COMPILER_RT_LIBDIR_OS` |
| 93 | + |
| 94 | +This option only applies to non-Mac Unixes and refers to the final directory name in the full path to the compiler-rt libraries. |
| 95 | + |
| 96 | +If the path is `[...]/clang/<version>/lib/linux` then this value should be `linux`. |
| 97 | +If it is `[...]/clang/<version>/lib/x86_64-redhat-linux-gnu` then this value should be `x86_64-redhat-linux-gnu`. |
| 98 | + |
| 99 | +### `LDC_INSTALL_LLVM_RUNTIME_LIBS_ARCH` |
| 100 | + |
| 101 | +The option only applied to non-Mac Unixes and refers to the architecture component in the filename of the libraries. |
| 102 | +It only makes sense specifying this if `LDC_INSTALL_LLVM_RUNTIME_LIBS` is set to `ON`, see below. |
| 103 | + |
| 104 | +If the filename of the libraries is `libclang_rt.asan-x86_64.a` then this value should be `x86_64`. |
| 105 | +If the filename of the libraries is `libclang_rt.asan.a` then this value should be `""` (empty). |
| 106 | + |
| 107 | +### `LDC_INSTALL_LLVM_RUNTIME_LIBS` |
| 108 | + |
| 109 | +This option tells cmake to copy the library files from the compiler-rt directory specified above to the library directory of ldc2. |
| 110 | +If you enable this you don't need to configure anything else, the libraries will be found when you run ldc2. |
| 111 | + |
| 112 | +### `COMPILER_RT_LIBDIR_CONFIG` |
| 113 | + |
| 114 | +The final path that is stored in the configuration file in regards to compiler-rt is `${COMPILER_RT_BASE_DIR}/${LLVM_MAJOR_VERSION}/lib/${COMPILER_RT_LIBDIR_OS}`. |
| 115 | +If this setting doesn't match your layout, as a last resort, you can specify your custom path with `-DCOMPILER_RT_LIBDIR_CONFIG` and that unaltered path will be stored in the config. |
| 116 | + |
| 117 | +## Checking that everything works |
| 118 | + |
| 119 | +Try to compile the empty program below with `ldc2 -fprofile-generate -vv sample.d` |
| 120 | +```d |
| 121 | +void main () {} |
| 122 | +``` |
| 123 | + |
| 124 | +And check the end of the output: |
| 125 | +``` |
| 126 | +[...] |
| 127 | +*** Linking executable *** |
| 128 | +Searching profile runtime: /usr/lib/libldc_rt.profile.a |
| 129 | +Searching profile runtime: /usr/lib/llvm-17/lib/clang/17/lib/linux/libldc_rt.profile.a |
| 130 | +Searching profile runtime: /usr/lib/libldc_rt.profile.a |
| 131 | +Searching profile runtime: /usr/lib/llvm-17/lib/libldc_rt.profile.a |
| 132 | +Searching profile runtime: /usr/lib/libclang_rt.profile-x86_64.a |
| 133 | +Searching profile runtime: /usr/lib/llvm-17/lib/clang/17/lib/linux/libclang_rt.profile-x86_64.a |
| 134 | +Found, linking with /usr/lib/llvm-17/lib/clang/17/lib/linux/libclang_rt.profile-x86_64.a |
| 135 | +Linking with: |
| 136 | +[...] |
| 137 | +``` |
| 138 | +The import line is `Found, linking with ...`. |
| 139 | +If you see this it means that you configured LDC correctly and the library was found. |
| 140 | + |
| 141 | +If you're missing that line, like in: |
| 142 | +``` |
| 143 | +*** Linking executable *** |
| 144 | +Searching profile runtime: /usr/lib/libldc_rt.profile.a |
| 145 | +Searching profile runtime: /usr/lib/libldc_rt.profile.a |
| 146 | +Searching profile runtime: /usr/lib/llvm-17/lib/libldc_rt.profile.a |
| 147 | +Searching profile runtime: /usr/lib/libclang_rt.profile-x86_64.a |
| 148 | +Searching profile runtime: /usr/lib/libclang_rt.profile-x86_64.a |
| 149 | +Searching profile runtime: /usr/lib/llvm-17/lib/libclang_rt.profile-x86_64.a |
| 150 | +Searching profile runtime: /usr/lib/clang/17.0.6/lib/linux/libclang_rt.profile-x86_64.a |
| 151 | +Searching profile runtime: /usr/lib/clang/17.0.6/lib/linux/libclang_rt.profile-x86_64.a |
| 152 | +Searching profile runtime: /usr/lib/llvm-17/lib/clang/17.0.6/lib/linux/libclang_rt.profile-x86_64.a |
| 153 | +Linking with: |
| 154 | +``` |
| 155 | +You should recheck the paths and make the necessary adjustments in the config file until `ldc2` can find it. |
0 commit comments