premake / premake-core

Premake
https://premake.github.io/
BSD 3-Clause "New" or "Revised" License
3.22k stars 620 forks source link

can I remove '-Wl,-x' from ALL_LDFLAGS when leaving off the "Symbols" flag? #133

Open JohannesMP opened 9 years ago

JohannesMP commented 9 years ago

I'm using Premake5 (stable and nightly) for gmake on mac 10.9.5 (clang 5.1).

Basing my premake file off the 'first scriI noticed that with a super simple c++ hello world file, I was able to run the make file for debug, but not for release. In release I would get a linker error:

ld: internal error: atom not found in symbolIndex(__ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc) for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

The only difference between the debug and release configuration in my premake5.lua file is that debug has flags { "Symbols" } while release does not. It seems that when this flag is left off for a given configuration, it has -Wl,-x appended to the ALL_LDFLAGS variable in the resulting make file.

-Wl,-x is what is causing this linker error. It seems to be a known issue for clang on mac 10.9, but has yet to be fixed. In the meantime, I would like to know if there is a way for me to prevent premake from adding this flag.

For reference, here are my premake5.lua file and the resulting project makefile, after running premake5 gmake.

TL;DR

How can I prevent -Wl,-x from being added to the ALL_LDFLAGS makefile variable? I don't think always adding the Symbols flag is an acceptable workaround, since I may not want to use the -g compiler flag in a release build.


_EDIT_: I'm not sure, but this issue on the old forums seems to be similar: http://industriousone.com/topic/how-remove-flags-ldflags, although the end of the thread seems to indicate that the issue was fixed in revision 23d8ffcc9144.

starkos commented 9 years ago

Did you set toolset "clang"?

fzwoch commented 9 years ago

This is the old issue with Apple's linker described here: https://bitbucket.org/premake/premake-dev/issue/263/os-x-gcc-clang-and-the-infamous-wl-x

As mentioned there the only workaround at this time is to remove "-x" (this is exclusive to system == macosx, right?) altogether but instead issue a "strip -x" on the final binary.

I wanted to write a patch for it but couldn't figure out how to handle it in the code :/

For the record - I issued a bug report to Apple on this issue back in March 2015. It did not get any attention up to this date. So I guess it is safe to assume it is not getting fixed unless accidentally or upstream by LLVM if it is their bug at all.

starkos commented 9 years ago

Looking at the code, it appears we've already removed that flag for Clang though? We don't emit a strip -x yet, and we should (so let's keep this ticket open) but you shouldn't be getting a -Wl,-x if you've set the toolset to Clang. And if you are it would be good to know how that's happening so we can fix it!

fzwoch commented 9 years ago

Confirmed that 'toolset "clang"' is working fine - ignoring the fact it does not strip. I didn't come across the "toolset" option before. I assumed that "--cc=clang" on the command line would do this for me.

starkos commented 9 years ago

I assumed that "--cc=clang" on the command line would do this for me.

Yes, that should have been equivalent, you're right. Would be good to know what went wrong there? I haven't looked at that bit of code in quite a while.

fzwoch commented 9 years ago

I was not confident enough to actually create a pull request for this.. I think this might remedy the issue that --cc=clang was not set correctly picked up for the gmake target.

This was merely copied from the codelite module. Not sure if this is okay or should be fixed differently. This not being handled globally could mean every other module could easily fail here as well.

diff --git a/src/actions/make/make_cpp.lua b/src/actions/make/make_cpp.lua
index 9b746c8..573b199 100644
--- a/src/actions/make/make_cpp.lua
+++ b/src/actions/make/make_cpp.lua
@@ -81,9 +81,9 @@
                        -- identify the toolset used by this configurations (would be nicer if
                        -- this were computed and stored with the configuration up front)

-                       local toolset = premake.tools[cfg.toolset or "gcc"]
+                       local toolset = premake.tools[_OPTIONS.cc or cfg.toolset or "gcc"]
                        if not toolset then
-                               error("Invalid toolset '" + cfg.toolset + "'")
+                               error("Invalid toolset '" + (_OPTIONS.cc or cfg.toolset) + "'")
                        end

                        _x('ifeq ($(config),%s)', cfg.shortname)
starkos commented 9 years ago

It would be better if we could handle this in one place, and give the exporters a function they can call to get the correct value. Thinking off the top of my head:

---
-- Return the correct toolset adapter for the given configuration.
--
-- @param cfg
--    The configuration to be tested.
-- @param default
--    An optional toolset identifier (i.e. "gcc") to select if no value is
--    provided by the configuration.
-- @param language
--    An optional language identifier (i.e. "C++") to override the language
--    that has been set in the configuration.
-- @return
--    A toolset adapter or nil
---
function config.toolset(cfg, default, language)
   -- get the tool ID (i.e. "cc" or "cxx") for the given language
   -- TODO: write this function; maps "C"->"cc", "C++"->"cxx", etc.
   local tool = p.tools.identifyTool(language or cfg.language)

   -- get the toolset ID (i.e. "gcc" or "clang") 
   local toolset = _OPTIONS[tool] or cfg.toolset or default

   if toolset then
      return p.tools[toolset]
   end
end