Set Clang config file directory relative to Clang executable

Hi there!

I’m working on making a Clang/LLVM distribution that works with a bunch of ARM Cortex-M micros from Microchip/Atmel. As part of this effort, I generate a bunch of configuration files using the info from the Clang docs here that have things like device-specifc macros, directories, and the --target option for that device. There is one file per microcontroller device, so there are probably over 100 of them. I’d like to allow a user to easily specify their microcontroller by supplying something like --config pic32cz8110ca80208.cfg without having to also specify the absolute path to it. Basically, a user shouldn’t have to care where the toolchain is installed when specifying this info.

I originally tried having default config files “clang.cfg” and “clang++.cfg” that would specify a search directory with --config-system-dir=<CFGDIR>/../cortex-m/config, but it turns out that Clang determines all of the search directories before reading any of the files. So that doesn’t work.

I did see there is a build option called CLANG_CONFIG_FILE_SYSTEM_DIR, but I wasn’t sure if that would be relative to the Clang executable (what I want) or relative to one’s current working directory (which I don’t want).

So, short of just dumping all 100 of the config files into the same directory as the Clang executable, is there a way to accomplish what I’m looking for?

Oh, I do also have a multilib.yaml file that Clang is able to find. Could I use the option matching stuff in there to make something work?

Thanks!

llvm::sys::path::append(configFileDir, CLANG_CONFIG_FILE_SYSTEM_DIR); where configFileDir is Dir which is std::string(llvm::sys::path::parent_path(ClangExecutable)) so I think you would be relative to the folder where the clang binary is.

For multilib, @vhscampos might be able to help.

Perhaps it would be useful to post the content of one of these config files, so they can tell what the multilib system could and could not provide for you.

1 Like

Oh! It looks like I need to pull the latest version of the Clang/LLVM sources and rebuild. I currently have LLVM 19.1.5. The code you show looks like it’ll do exactly what I want, so I’m all good!

I mentioned the multilib support just because it appears to be able to transform options. I wasn’t sure if I’d need to muck with that, but now I’m pretty sure I wont. The multilib stuff as-is works well. I’ve considered whether I’d want to be able to somehow select “size” vs “speed” library builds for an embedded environment, but I’m not too worried about that for now.

Thanks for the help!

For reference, here’s what I saw in the 19.1.5 version of Driver.cpp. It wasn’t clear to me how the assignment SystemConfigDir = CLANG_CONFIG_FILE_SYSTEM_DIR; would be interpreted. The code you show is much clearer.

  Name = std::string(llvm::sys::path::filename(ClangExecutable));
  Dir = std::string(llvm::sys::path::parent_path(ClangExecutable));

  if ((!SysRoot.empty()) && llvm::sys::path::is_relative(SysRoot)) {
    // Prepend InstalledDir if SysRoot is relative
    SmallString<128> P(Dir);
    llvm::sys::path::append(P, SysRoot);
    SysRoot = std::string(P);
  }

#if defined(CLANG_CONFIG_FILE_SYSTEM_DIR)
  SystemConfigDir = CLANG_CONFIG_FILE_SYSTEM_DIR;
#endif

The commit ([Clang][Driver] Support relative paths for CLANG_CONFIG_FILE_SYSTEM_D… · llvm/llvm-project@1682c99 · GitHub) that changed it did so for the same use case you have.

And yes, this is so recent it’s only on main, but it will be in 20.x when that releases.