Arch Linux

Please read this before reporting a bug:
https://wiki.archlinux.org/title/Bug_reporting_guidelines

Do NOT report bugs when a package is just outdated, or it is in the AUR. Use the 'flag out of date' link on the package page, or the Mailing List.

REPEAT: Do NOT report bugs for outdated packages!
Tasklist

FS#61445 - Missing headers in clang package

Attached to Project: Arch Linux
Opened by Juan Pablo Garibotti (jp.garibotti) - Thursday, 17 January 2019, 16:25 GMT
Last edited by Evangelos Foutras (foutrelis) - Saturday, 30 March 2019, 13:17 GMT
Task Type Bug Report
Category Packages: Extra
Status Closed
Assigned To Evangelos Foutras (foutrelis)
Architecture All
Severity Low
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 0
Private No

Details

Description:
Attempting to compile a simple program using the LibTooling library provided by clang fails as required headers are missing.

Additional info:
* package version(s)
clang 7.0.1-1

Steps to reproduce:
Create a file main.cpp with the contents:
//
// main.cpp
//
#include "clang/Tooling/CommonOptionsParser.h"

int main() {
return 0;
}
// end of file

Compile with the following command line options:
clang -std=c++14 -c main.cpp -o main.o

Results in the following output:
In file included from src/main.cpp:1:
In file included from /usr/include/clang/Tooling/CommonOptionsParser.h:30:
In file included from /usr/include/clang/Tooling/ArgumentsAdjusters.h:20:
/usr/include/clang/Basic/LLVM.h:22:10: fatal error: 'llvm/Support/Casting.h' file not found
#include "llvm/Support/Casting.h"
^~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.

Expected behavior:
All the headers required to use the library are included in the package, and compilation succeeds.
This task depends upon

Closed by  Evangelos Foutras (foutrelis)
Saturday, 30 March 2019, 13:17 GMT
Reason for closing:  Fixed
Additional comments about closing:  clang 8.0.0-3 adds an optional dependency on llvm so it can more readily be tracked by pacman.
Comment by loqs (loqs) - Thursday, 17 January 2019, 18:47 GMT
pacman -Qo /usr/include/llvm/Support/Casting.h
/usr/include/llvm/Support/Casting.h is owned by llvm 7.0.1-1
Comment by Eli Schwartz (eschwartz) - Thursday, 17 January 2019, 19:16 GMT
But the headers fundamentally come from the llvm package... under no circumstances would it ever ship within the clang package, the only feasible way to implement this would be to make clang have a hard dependency on llvm.

I think it's much more reasonable to say that if you explicitly want to compile projects against llvm, that you install both clang and llvm.
Comment by Juan Pablo Garibotti (jp.garibotti) - Friday, 18 January 2019, 08:02 GMT
I don't want to compile against llvm. I want to use the clang libraries, in particular LibTooling, to create C++ specific tools. I just need clang to parse and provide the AST for code I feed it.

To do this, I would link against the libraries included in the clang package, and for which the headers (in this case, clang/Tooling/CommonOptionsParser.h) are included. The clang headers are the ones that depend on the llvm headers, as you can see from the chain of includes which are all clang specific until it reaches /usr/include/clang/Basic/LLVM.h which includes llvm/Support/Casting.h.

As it is, the clang package is including a broken header, because it depends on something the package didn't include. The more obvious solutions I see would be to either add the dependency on llvm, or to remove the headers and create a separate "clang-devel" package for using the clang libraries to develop new tools, which would depend on llvm.
Comment by Eli Schwartz (eschwartz) - Friday, 18 January 2019, 18:35 GMT
$ for i in /usr/include/clang/*/; do ag '#include "llvm' $i > /dev/null || echo "llvm is not included in $i"; done
llvm is not included in /usr/include/clang/Config/
llvm is not included in /usr/include/clang/FrontendTool/


19 out of 21 use llvm in some way and the remainder are only there for inclusion in other headers. I think this is pretty darn expected: if you want to develop against clang headers, you are using llvm internals as well.

I also think it's purely ridiculous to depend on a 184MB package that conflicts with and cannot be coinstalled with llvm6, for every user than simply wants to use /usr/bin/clang as their $CC implementation.

What would the utility of a split package be, precisely? Either you depend on clang and llvm, or you depend on clang-newtool-headers, but either way you have to install some package other than clang. This issue only ever manifests as a build-time issue, and it's a pretty obvious issue too, with a pretty obvious solution.

In fact, if you use cmake (the only build system for which clang actually provides files like ClangConfig.cmake ClangTargets.cmake) then you'll explicitly find llvm being drawn in as a dependency as well, which is an even clearer sign.

I don't see why a split package is needed for something that is fundamentally part of the low-level nature of linking to clang. It should be automatically expected that if you are developing against libclang and friends, that you need a complete clang/llvm development toolchain.
Comment by Juan Pablo Garibotti (jp.garibotti) - Saturday, 19 January 2019, 14:27 GMT
I see the clang package has two main use cases: as a tool for users, and as a library for developers.

The users don't care about the included headers. They won't use them. For anyone that will use them, however, the package appears broken. It offers a feature, the includes, but using that feature requires unconditionally installing another package.

As I understand it, a package manager fulfills two functions: it installs packages, and it tracks dependencies. If to use one package I have to handle its dependencies manually, installing llvm separately for example, the "dependency tracking" function of the package is broken.

As you say, forcing everyone to install a 184 MB package they don't care about would not be reasonable. But having to install llvm manually is also a bit of a problem, since I could remove the package and pacman won't know that it has to also remove this other hidden dependency. It also runs counter to expectations, as the developer is left wondering why the build is broken. Yes, finding where the missing headers are and fixing the problem is straightforward, but without a warning that the dependencies are missing on purpose, one is left to wonder if something about their installation is broken. Applying a fix without knowing the source of the issue is not good engineering.

From a correctness perspective, I would like the package manager to take care of everything and not have to chase after dependencies.

> It should be automatically expected that if you are developing against libclang and friends, that you need a complete clang/llvm development toolchain.

Yes, which is why the package manager should be handling it. But I realize maintaining a separate package is an additional burden and since no one complained until now, probably not a high priority. At least this answers my underlying question of "why didn't pacman get the llvm headers". And if there's no desire to maintain a second package for the headers, the reasoning is now well documented.
Comment by Fabian Piribauer (piri) - Saturday, 19 January 2019, 23:46 GMT
What about adding llvm to optdepends? Clang's headers partly depend on it, so that would make sense I think?

> since I could remove the package and pacman won't know that it has to also remove this other hidden dependency.

Adding it to optdepends would fix the hidden dependency issue too.
Comment by Eli Schwartz (eschwartz) - Sunday, 20 January 2019, 05:51 GMT
You definitely make a good point about pacman recursing over the dependency tree when uninstalling clang.

Actually, the headers are a not insignificant part of the total package size, so there are potentially arguments that could be made in combination with the other arguments here, in favor of a split package.

I guess one or the other should probably be done, but we'll see what the maintainer thinks.

Comment by Markus (Sekuraz) - Friday, 25 January 2019, 15:10 GMT
Maybe add an optional dependency to llvm (the same way as openmp). Another solution may be a new package called clang-dev which depends on llvm and contains all the headers and maybe also static libraries (I could use them right now :) )

Loading...