Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

-march=armv7-a will cause ccls not to work #107

Closed
kvinwang opened this issue Oct 28, 2018 · 8 comments
Closed

-march=armv7-a will cause ccls not to work #107

kvinwang opened this issue Oct 28, 2018 · 8 comments
Labels
question Further information is requested

Comments

@kvinwang
Copy link

kvinwang commented Oct 28, 2018

I am trying to use ccls with a cross-compiled project with compile_commands.json. There is a flags -march=armv7-a that cause ccls always to show 'xxx is being indexed'.

@kvinwang kvinwang changed the title error: unknown argument -march=armv7-a will cause ccls not to work Oct 28, 2018
@bstaletic
Copy link
Contributor

This happens because libclang doesn't support -march=armv7-a and using that flag leads to an AST deserialization error.

@kvinwang
Copy link
Author

cquery works fine with the same compile_commands.json. is ccls possible to handle this issue?

@Riatre
Copy link
Contributor

Riatre commented Oct 29, 2018

Could you please try to also put --target=arm-none-linux-gnueabi (or whatever target triplet your project cross-compiled to) in the compile flags? You may also need to point clang to your cross GCC toolchain with --gcc-toolchain or --sysroot or adding -isystems so it can find your system header files.

Without setting target triplet Clang assumes your target is same as the host (i.e. not cross compiling), so it barks at -march=armv7-a because there are no such arch for your host architecture (likely x86_64).

It looks like cquery blacklists -march= args, so when using cquery, your project is actually treated by Clang as a non cross-compiled one without -march= being in compile commands. Combined with their automatic system header path detection it may be good enough for your project, but I don't think this is the right thing to do.

@MaskRay
Copy link
Owner

MaskRay commented Oct 29, 2018

-march=armv7-a is not supported in clang. You may change it to -target armv7a-linux-gnueabi.

clang -target armv7a-linux-gnueabi -E -dM -xc /dev/null

ln -s your_clang armv7a-linux-gnueabi-clang
./armv7a-linux-gnueabi -E -dM -xc /dev/null

A compile_commands.json entry looks like:

    {
        "arguments": [ "armv7a-linux-gnueabi-clang++", "-c", "-o", "a.o", "a.cc" ], 
        "directory": "/tmp/d", 
        "file": "a.cc"
    }

For GCC options that are unknown to clang, you can exclude them with the initialization option clang.extraArgs:

"clang": { "extraArgs": ["-mno-thumb-interwork", "-fconserve-stack", "-fno-var-tracking-assignments"]}

@kvinwang
Copy link
Author

Thank you guys for the patient explanation. It works now (with some random crash, rarely).

I was expecting ccls to works out-of-box.
In the future, can it be distributed with a default config which with a cquery-like blacklist or extraArgs ?

@Riatre
Copy link
Contributor

Riatre commented Oct 29, 2018

I would also want to make ccls work out-of-box in this case, but (IMO) there are simply no good way to do it while keeping the correct behavior. You have to at least point Clang to your cross toolchain's system headers, so it sounds like it must involve some arg mangle.


Sidenote: With correct --target, -march= is supported.

$ clang++-7 --target=arm-linux-gnueabi -march=armv7-a -v -x c++ -
clang version 7.0.0-6 (tags/RELEASE_700/final)
Target: arm-linux-gnueabi
Thread model: posix
InstalledDir: /usr/bin
 "/usr/lib/llvm-7/bin/clang" -cc1 -triple armv7-linux-gnueabi -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name - -mrelocation-model static <...snipped...>

See how the triplet passed to cc1 is actually armv7-linux-gnueabi, so clangDriver did the work.

Edit: Typo in target triplet.

@MaskRay
Copy link
Owner

MaskRay commented Oct 30, 2018

@LoongW May I ask you to contribute a wiki page (cross compilation) for posterity since you've figured it out?

As @Riatre, it would be nice to work out-of-box but driver code is hard to write and maintain on the Clang API user side. As a quick example:

% strace -fe file -o >(grep /opt/rh/devtoolset) ~/llvm/Release/bin/clang++ -c a.cc
66559 stat("/opt/rh/devtoolset-7/root/usr", 0x7ffde47316c8) = -1 ENOENT (No such file or directory)
66559 stat("/opt/rh/devtoolset-6/root/usr", 0x7ffde47316c8) = -1 ENOENT (No such file or directory)
66559 stat("/opt/rh/devtoolset-4/root/usr", 0x7ffde47316c8) = -1 ENOENT (No such file or directory)
66559 stat("/opt/rh/devtoolset-3/root/usr", 0x7ffde47316c8) = -1 ENOENT (No such file or directory)
66559 stat("/opt/rh/devtoolset-2/root/usr", 0x7ffde47316c8) = -1 ENOENT (No such file or directory)

Extra fun in https://github.com/llvm-mirror/clang/tree/master/include/clang/Driver/Distro.h https://github.com/llvm-mirror/clang/tree/master/lib/Driver/ToolChains/Linux.cpp
When you specify an ARM triple, the detected toolchain path will change a bit.

Studying this piece of code strengthened my idea that user should just tweak compile_commands.json command line options by themselves. There is also nuance between the clang driver and clang tools (ccls, c-index-test, cquery, ...). The latter use CompilerInvocation APIs in a way similar to clang -cc1 but lacks some handling.

Users mostly use GCC as the cross compiler. clang provides excellent emulation but sometimes you still need to tweak a bit to make it work: "clang": { "extraArgs": ["-mno-thumb-interwork", "-fconserve-stack", "-fno-var-tracking-assignments"]} in your case.

On the other hand, cross compiling users have gone through the relatively complex toolchain usage process it is reasonable to expect them to handle this configuration twiddling. A wiki page is very welcomed to help others :)

@Riatre ah yes, -march is done after triple selection.

@MaskRay MaskRay closed this as completed Oct 30, 2018
@MaskRay MaskRay added the question Further information is requested label Dec 15, 2018
@MaskRay
Copy link
Owner

MaskRay commented Dec 22, 2018

This PR #171 may help.

% cat .ccls
%compile_commands.json
--target=armv7a-linux-gnueabi

--target does not need to be placed before -march=armv7-a: clang++ -march=armv7-a -x c++ /dev/null -E --target=arm-linux-gnueabi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants