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

Tool does not follow symlinks #408

Open
chrisburnor opened this issue Jun 1, 2019 · 11 comments
Open

Tool does not follow symlinks #408

chrisburnor opened this issue Jun 1, 2019 · 11 comments

Comments

@chrisburnor
Copy link

with_features in Tool uses the name of the path to determine compiler family in https://github.com/alexcrichton/cc-rs/blob/master/src/lib.rs#L2113

It appears that for modern Macs running Mojave (10.14+), c++ is symlinked to clang++ but cc doesn't follow the symlink and treats it as a gnu compiler.

Current workaround is to manually set CXX=$(which clang++) but the right solution should look at the output of 'c++ -v` instead of the path name.

@torkleyy
Copy link

torkleyy commented Jun 2, 2019

What does c++ -v output? On Fedora I get this:

Using built-in specs.
COLLECT_GCC=c++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,objc,obj-c++,ada,go,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl --enable-libmpx --enable-offload-targets=nvptx-none --without-cuda-driver --enable-gnu-indirect-function --enable-cet --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 8.3.1 20190223 (Red Hat 8.3.1-2) (GCC)

I'm not sure if it's a good idea to try to parse this.

@alexcrichton
Copy link
Member

This is sort of happening on #407, and it might be good to fix both at the same time!

@spl
Copy link
Contributor

spl commented Jun 3, 2019

I was actually thinking of doing something to follow symlinks, too, after working on #407. But I'd really be fine with just following symlinks instead of #407. I think it's a more general solution that handles more than just fixing the default for macOS.

@alexcrichton If you agree with that, I'll finish my work on cleaning up the tests first and then do the symlink following.

Is there an existing solution for following symlinks, or should I use std::fs::read_link in a loop?

@alexcrichton
Copy link
Member

I think that canonicalize might do the trick as well, but if that doesn't work using read_link also seems reasonable!

@spl
Copy link
Contributor

spl commented Jun 4, 2019

Just to open up the discussion a bit more to alternatives for compiler detection, we could instead use a small C program with #ifdefs to identify the compiler. Here's a simple one that works for the currently identified compilers:

int main() {
#if defined(__clang__)
  return 1;
#elif defined(__GNUC__)
  return 2;
#elif defined(_MSC_VER)
  return 3;
#else
  return 0;
#endif
}

Another option is to use something like the existing boost/predef.h that supports a very large number of compilers.

@spl
Copy link
Contributor

spl commented Jun 4, 2019

But, as I just realized, my suggestion in #408 (comment) won't work for cross-compiling. So it looks like the current executable-name-based mechanism with symlink resolution is good enough.

@alexcrichton
Copy link
Member

While you're right that the executable strategy doesn't work for cross compilation it would work for using the preprocessor to learn what the compiler is, but I think relying on symlink reading for now is good enough

@spl
Copy link
Contributor

spl commented Jun 4, 2019

While you're right that the executable strategy doesn't work for cross compilation it would work for using the preprocessor to learn what the compiler is

It wouldn't work if the compiler is a cross-compiler to a target that is incompatible with the host because you couldn't run the above program (without an emulator).

But I believe you're suggesting a way to use the preprocessor alone – without building an executable – to determine the compiler? That would require knowing which flag to pass to the compiler to invoke the preprocessor. But, as long as you're only interested in a few compilers, you don't need to worry about trying all possible flags. GCC and Clang both use -E, and MSVC uses /P.

I think relying on symlink reading for now is good enough

Fine with me. It's always good to discuss the options.

@spl
Copy link
Contributor

spl commented Jun 5, 2019

But I believe you're suggesting a way to use the preprocessor alone – without building an executable – to determine the compiler?

Ah, I see this is already implemented in try_expand()/expand(). So it would be easy enough.

@spl
Copy link
Contributor

spl commented Jul 3, 2019

Just to provide an update, I'm actively working on a solution to this. I should hopefully have something to show within the next few days. The hard part is done. I'm working my way through dealing with unit tests now.

I decided to use the C preprocessor (similar to #408 (comment)), since I think it is the most reliable method and can easily scale to support other C/C++ compilers.

@grovesNL
Copy link
Contributor

grovesNL commented Nov 8, 2019

@spl Is there a branch somewhere that contains your changes so far?

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

No branches or pull requests

5 participants