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

Fix --no-undefined in Makefile on non-Darwin #2720

Merged
merged 1 commit into from
Nov 14, 2018

Conversation

alyssais
Copy link
Contributor

As far as I can tell, -undefined error was introduced mistakenly to replace --no-undefined, which doesn't work Apple's cctools' ld. The problem is, -undefined error only works on cctools' ld. This is much less noticeable than the original problem, because GCC's ld won't complain, it just won't do the right thing. The Solaris linker, on the other hand, will complain:

ld: fatal: file error: open failed: No such file or directory

This is a misleading error message, but what it is actually telling us is that it can't open a file named "error", which it tries to do because it doesn't recognise "-undefined" as an option that can take an argument.

We can demonstrate that this doesn't have the desired effect in GCC too. Consider this a C source file, main.c, containing the following:

extern void hello(void);

int main(void) {
    hello();
}

If we compile this using the command gcc -fPIC -shared main.c, we will get no indication that the hello function we are trying to call has never been defined. This is for, as the GCC documentation puts it, "historial reasons".

If we don't want this, we can pass --no-undefined to the linker, like this:

gcc -fPIC -shared -Wl,--no-undefined main.c

This is what the Makefile used to do, before being changed. Running this command will produce an error informing us of our mistake:

/tmp/ccGRJkJ8.o: In function `main':
main.c:(.text+0xc): undefined reference to `hello'
collect2: error: ld returned 1 exit status

However, trying to use the cctools' ld's equivalent reveals that GCC's ld definitely does not interpret it the same way. This command will succeed, just the same as the one where we specified no explicit linker options at all. I don't want to speculate on what effect, if any, -undefined error has on GCC's ld, but it definitely isn't the right one.

The fix, then, is to use cctools's ld's -undefined error on Darwin, and GCC's ld's --no-undefined on everything else. Checking operating system isn't bulletproof — it is completely possible to use GCC's ld on Darwin, but it is nevertheless better than the status quo. GCC ld users will get the desired errors, and linking will no longer outright fail on Solaris. I'm not sure what effect this would have on BSD systems, having never used one, but it's conceivable to me that they use a similar linker to Darwin. If this turns out to be the case, the fix is to change the operating system check to use the cctools variant on BSD as well as Darwin.

@alyssais alyssais force-pushed the no-undefined branch 2 times, most recently from d822ddf to 9efe904 Compare September 25, 2018 09:23
@alyssais
Copy link
Contributor Author

Fixed Travis failure on Darwin – I was using UNAME in the Makefile before it had been defined. Should have used OS instead.

AppVeyor looks like it just hung and then timed out. 🤷‍♀️

@glebm
Copy link
Contributor

glebm commented Nov 12, 2018

@alyssais Perhaps we should detect the compiler / linker flavour instead of the operating system? I use clang on Linux and this PR would break it for me, because the clang linker does not support --no-undefined.

Not sure what the best way to detect the compiler toolchain is. Perhaps via the output of $(CC) --version? If it matches 'gcc' use GCC_LDFLAGS, else if matches 'clang' use CLANG_CFLAGS, otherwise use empty CFLAGS.

@xzyfer
Copy link
Contributor

xzyfer commented Nov 12, 2018

Kicked off a new appveyor build. I'm heading to sleep now (Australian time) and will check back in tomorrow.

@mgreter
Copy link
Contributor

mgreter commented Nov 12, 2018

Maybe something like this could be used to detect clang vs gcc (seems to work on windows):

COMPILER=$(if $(filter $(shell $(CC) -v 2>&1),clang),clang,gcc)

In the worst case we could add a small c file using compiler macros to do the detection, which needs to be compiled first and can then be executed to return the used compiler. Although I don't really like to go down this route, since we still have the autotools way ...

#if defined(__clang__)
	/* Clang/LLVM. ---------------------------------------------- */

#elif defined(__ICC) || defined(__INTEL_COMPILER)
	/* Intel ICC/ICPC. ------------------------------------------ */

#elif defined(__GNUC__) || defined(__GNUG__)
	/* GNU GCC/G++. --------------------------------------------- */

#elif defined(__HP_cc) || defined(__HP_aCC)
	/* Hewlett-Packard C/aC++. ---------------------------------- */

#elif defined(__IBMC__) || defined(__IBMCPP__)
	/* IBM XL C/C++. -------------------------------------------- */

#elif defined(_MSC_VER)
	/* Microsoft Visual Studio. --------------------------------- */

#elif defined(__PGI)
	/* Portland Group PGCC/PGCPP. ------------------------------- */

#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
	/* Oracle Solaris Studio. ----------------------------------- */

#endif

@glebm
Copy link
Contributor

glebm commented Nov 12, 2018

I'm not sure if 2 > &1 will work on Windows. I'll try the C program way.

glebm added a commit to glebm/libsass that referenced this pull request Nov 12, 2018
Detects compiler family by compiling and running a tiny C file on every invocation of make (30ms on my machine).

Alternative to sass#2720
@glebm
Copy link
Contributor

glebm commented Nov 12, 2018

Sent #2729

glebm added a commit to glebm/libsass that referenced this pull request Nov 12, 2018
Detects compiler family by compiling and running a tiny C file on every invocation of make (30ms on my machine).

Alternative to sass#2720
glebm added a commit to glebm/libsass that referenced this pull request Nov 12, 2018
Detects compiler family by compiling and running a tiny C file on every invocation of make (30ms on my machine).

Alternative to sass#2720
glebm added a commit to glebm/libsass that referenced this pull request Nov 12, 2018
Detects compiler family by compiling and running a tiny C file on every invocation of make (30ms on my machine).

Alternative to sass#2720
glebm added a commit to glebm/libsass that referenced this pull request Nov 12, 2018
Detects compiler family by compiling and running a tiny C file on every invocation of make (30ms on my machine).

Alternative to sass#2720
@xzyfer
Copy link
Contributor

xzyfer commented Nov 12, 2018

Catching up. Either approach seems reasonable to me. Is there consensus on which we should go with?

@alyssais
Copy link
Contributor Author

I’m confused — there are autotools files in the repo, but the Makefile isn’t generated using autotools? What’s the reason for that — are you trying to move away from it?

Anyway, compiling a small C program is probably (just) more reliable than trying to parse compiler output. Although I wonder if it might be better to take the simpler option of just removing the problematic flags entirely and avoiding the whole problem…

@glebm
Copy link
Contributor

glebm commented Nov 13, 2018

The Makefile is provided so that it can be built without autotools. This is useful when this library is built for a C extension for Python or Ruby, where autotools is not a requirement of the build environment AFAIK.

Anyway, compiling a small C program is probably (just) more reliable than trying to parse compiler output.

It's also fast (30ms compile+run), so I'd prefer we do that instead of attempting to parse the --verbose output.

Although I wonder if it might be better to take the simpler option of just removing the problematic flags entirely and avoiding the whole problem…

Yeah, how useful are these flags?
Anyway, up to @mgreter and @xzyfer now

@xzyfer
Copy link
Contributor

xzyfer commented Nov 13, 2018 via email

@mgreter
Copy link
Contributor

mgreter commented Nov 13, 2018

I'm fine with any solution. Since @glebm already provided a PR for the second approach (thx), I'd say just go with that. It should also be more robust than parsing/matching the version output.

@mgreter
Copy link
Contributor

mgreter commented Nov 13, 2018

@alyssais the Makefile is also used on windows when compiling with mingw-gcc without msys2/cygwin environment. I don't think there is any native windows autotools buildchain.

@glebm
Copy link
Contributor

glebm commented Nov 14, 2018

So the compiler check approach turned out to be wrong, because as @alyssais has pointed out in #2729 (comment), the compiler and the linker can be (and often are) different.

Let's just remove these flags?

@xzyfer
Copy link
Contributor

xzyfer commented Nov 14, 2018

I'm fine with removing these flags.

@alyssais
Copy link
Contributor Author

alyssais commented Nov 14, 2018 via email

@alyssais alyssais force-pushed the no-undefined branch 2 times, most recently from 30cce36 to 2ec222b Compare November 14, 2018 12:11
As far as I can tell, `-undefined error` was introduced mistakenly
to replace `--no-undefined`, which doesn't work Apple's cctools' ld.
The problem is, `-undefined error` _only_ works on cctools' ld.
This is much less noticeable than the original problem, because GCC's ld
won't complain, it just won't do the right thing. The Solaris linker, on
the other hand, _will_ complain:

    ld: fatal: file error: open failed: No such file or directory

This is a misleading error message, but what it is actually telling us
is that it can't open a file named "error", which it tries to do because
it doesn't recognise "-undefined" as an option that can take an
argument.

We can demonstrate that this doesn't have the desired effect in GCC too.
Consider this a C source file, main.c, containing the following:

    extern void hello(void);

    int main(void) {
        hello();
    }

If we compile this using the command `gcc -fPIC -shared main.c`, we
will get no indication that the `hello` function we are trying to call
has never been defined. This is for, as the GCC documentation puts it,
"historial reasons".

If we don't want this, we can pass `--no-undefined` to the linker, like
this:

    gcc -fPIC -shared -Wl,--no-undefined main.c

This is what the Makefile used to do, before being changed. Running this
command will produce an error informing us of our mistake:

    /tmp/ccGRJkJ8.o: In function `main':
    main.c:(.text+0xc): undefined reference to `hello'
    collect2: error: ld returned 1 exit status

However, trying to use the cctools' ld's equivalent reveals that GCC's
ld definitely does not interpret it the same way. This command will
succeed, just the same as the one where we specified no explicit linker
options at all. I don't want to speculate on what effect, if any,
`-undefined error` has on GCC's ld, but it definitely isn't the right
one.

After some discussion, we've decided it's best to just remove these
flags.
@alyssais
Copy link
Contributor Author

Side note: I keep having to rebase this PR so it can be merged, because a new commit has been added to master, even though there aren't any conflicts or anything. Maybe have a think about whether that needs to be a hard "no"? IME it often doesn't, and in this sort of case where the change is very unlikely to conflict with anything else it gets annoying fast.

@xzyfer
Copy link
Contributor

xzyfer commented Nov 14, 2018 via email

@xzyfer xzyfer merged commit a8273fc into sass:master Nov 14, 2018
@xzyfer
Copy link
Contributor

xzyfer commented Nov 14, 2018

Thanks for all your patience

@alyssais
Copy link
Contributor Author

Wonderful, thank you! Do you have any plans for a release?

@xzyfer
Copy link
Contributor

xzyfer commented Nov 15, 2018 via email

glebm added a commit to glebm/sassc-ruby that referenced this pull request Nov 17, 2018
Updates libsass to master to incorporate fixes for:

1. The :not selector. sass#91 sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Building with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also changes the location of libsass.so from ext/ to lib/ (fixes sass#95).
glebm added a commit to glebm/sassc-ruby that referenced this pull request Nov 17, 2018
Updates libsass to master to incorporate fixes for:

1. The :not selector. sass#91 sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Building with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also changes the location of libsass.so from ext/ to lib/ (fixes sass#95).
glebm added a commit to glebm/sassc-ruby that referenced this pull request Nov 17, 2018
Updates libsass to master to incorporate fixes for:

1. The :not selector. sass#91 sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Building with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also:

1. Changes the location of libsass.so from ext/ to lib/. Fixes sass#95
2. No longer tries to run `nmake` on Windows (libsass Makefile is
   compatible with GNU Make only).
glebm added a commit to glebm/sassc-ruby that referenced this pull request Nov 17, 2018
Updates libsass to master ([d225a09a](https://github.com/sass/libsass/tree/d225a09a152050d569c077f97bb944c8dc819d6f)) to incorporate fixes for:

1. The :not selector. Fixes sass#91. sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Now builds with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also:
1. Adds Windows RubyInstaller compilation support via `rake-compiler`. Fixes sass#18.
2. Fixes `load_paths` separator on Windows. Fixes sass#93.
3. Changes the location of `libsass.so` from `ext/` to `lib/`. Fixes sass#95.
glebm added a commit to glebm/sassc-ruby that referenced this pull request Nov 17, 2018
Updates libsass to master ([d225a09a](https://github.com/sass/libsass/tree/d225a09a152050d569c077f97bb944c8dc819d6f)) to incorporate fixes for:

1. The :not selector. Fixes sass#91. sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Now builds with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also:
1. Adds Windows RubyInstaller compilation support via `rake-compiler`. Fixes sass#18.
2. Fixes `load_paths` separator on Windows. Fixes sass#93.
3. Changes the location of `libsass.so` from `ext/` to `lib/`. Fixes sass#95.
@alyssais alyssais deleted the no-undefined branch November 26, 2018 14:33
glebm added a commit to glebm/sassc-ruby that referenced this pull request May 5, 2019
Updates libsass to master to incorporate fixes for:

1. The :not selector. Fixes sass#91. sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Now builds with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also:
1. Adds Windows RubyInstaller compilation support via `rake-compiler`. Fixes sass#18.
2. Fixes `load_paths` separator on Windows. Fixes sass#93.
3. Changes the location of `libsass.so` from `ext/` to `lib/`. Fixes sass#95.
glebm added a commit to glebm/sassc-ruby that referenced this pull request May 5, 2019
Updates libsass to master to incorporate fixes for:

1. The :not selector. Fixes sass#91. sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Now builds with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also:
1. Adds Windows RubyInstaller compilation support via `rake-compiler`. Fixes sass#18.
2. Fixes `load_paths` separator on Windows. Fixes sass#93.
3. Changes the location of `libsass.so` from `ext/` to `lib/`. Fixes sass#95.
glebm added a commit to glebm/sassc-ruby that referenced this pull request May 5, 2019
Updates libsass to master to incorporate fixes for:

1. The :not selector. Fixes sass#91. sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Now builds with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also:
1. Adds Windows RubyInstaller compilation support via `rake-compiler`. Fixes sass#18.
2. Fixes `load_paths` separator on Windows. Fixes sass#93.
3. Changes the location of `libsass.so` from `ext/` to `lib/`. Fixes sass#95.
glebm added a commit to glebm/sassc-ruby that referenced this pull request May 5, 2019
Updates libsass to master to incorporate fixes for:

1. The :not selector. Fixes sass#91. sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Now builds with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also:
1. Adds Windows RubyInstaller compilation support via `rake-compiler`. Fixes sass#18.
2. Fixes `load_paths` separator on Windows. Fixes sass#93.
3. Changes the location of `libsass.so` from `ext/` to `lib/`. Fixes sass#95.
glebm added a commit to glebm/sassc-ruby that referenced this pull request May 5, 2019
Updates libsass to master to incorporate fixes for:

1. The :not selector. Fixes sass#91. sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Now builds with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also:
1. Adds Windows RubyInstaller compilation support via `rake-compiler`. Fixes sass#18.
2. Fixes `load_paths` separator on Windows. Fixes sass#93.
3. Changes the location of `libsass.so` from `ext/` to `lib/`. Fixes sass#95.
glebm added a commit to glebm/sassc-ruby that referenced this pull request May 5, 2019
Updates libsass to master to incorporate fixes for:

1. The :not selector. Fixes sass#91. sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Now builds with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also:
1. Adds Windows RubyInstaller compilation support via `rake-compiler`. Fixes sass#18.
2. Fixes `load_paths` separator on Windows. Fixes sass#93.
3. Changes the location of `libsass.so` from `ext/` to `lib/`. Fixes sass#95.
glebm added a commit to glebm/sassc-ruby that referenced this pull request May 5, 2019
Updates libsass to master to incorporate fixes for:

1. The :not selector. Fixes sass#91. sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Now builds with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also:
1. Adds Windows RubyInstaller compilation support via `rake-compiler`. Fixes sass#18.
2. Fixes `load_paths` separator on Windows. Fixes sass#93.
3. Changes the location of `libsass.so` from `ext/` to `lib/`. Fixes sass#95.
glebm added a commit to glebm/sassc-ruby that referenced this pull request May 8, 2019
Updates libsass to master to incorporate fixes for:

1. The :not selector. Fixes sass#91. sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Now builds with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also:
1. Adds Windows RubyInstaller compilation support via `rake-compiler`. Fixes sass#18.
2. Fixes `load_paths` separator on Windows. Fixes sass#93.
3. Changes the location of `libsass.so` from `ext/` to `lib/`. Fixes sass#95.
glebm added a commit to glebm/sassc-ruby that referenced this pull request May 8, 2019
Updates libsass to master to incorporate fixes for:

1. The :not selector. Fixes sass#91. sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Now builds with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also:
1. Adds Windows RubyInstaller compilation support via `rake-compiler`. Fixes sass#18.
2. Fixes `load_paths` separator on Windows. Fixes sass#93.
3. Changes the location of `libsass.so` from `ext/` to `lib/`. Fixes sass#95.
glebm added a commit to glebm/sassc-ruby that referenced this pull request May 8, 2019
Updates libsass to master to incorporate fixes for:

1. The :not selector. Fixes sass#91. sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Now builds with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also:
1. Adds Windows RubyInstaller compilation support via `rake-compiler`. Fixes sass#18.
2. Fixes `load_paths` separator on Windows. Fixes sass#93.
3. Changes the location of `libsass.so` from `ext/` to `lib/`. Fixes sass#95.
glebm added a commit to glebm/sassc-ruby that referenced this pull request May 8, 2019
Updates libsass to master to incorporate fixes for:

1. The :not selector. Fixes sass#91. sass/libsass#2697
2. Default precision changed to 10. sass/libsass#2716
3. Now builds with `cc` instead of hard-coding `gcc`. sass/libsass#2707
4. Building on Linux and Solaris. sass/libsass#2720

Also:
1. Adds Windows RubyInstaller compilation support via `rake-compiler`. Fixes sass#18.
2. Fixes `load_paths` separator on Windows. Fixes sass#93.
3. Changes the location of `libsass.so` from `ext/` to `lib/`. Fixes sass#95.
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

Successfully merging this pull request may close these issues.

None yet

4 participants