GN \NODEFAULTLIB[:library] linker option not supported |
||||||
Issue description
Affects: Windows msvc or clang toolchains. (link.exe)
GN configuration does not currently support blocking specific dependencies on Windows. In GYP, things like the following were supported:
'msvs_settings': {
'VCLinkerTool': {
# Set /SUBSYSTEM:WINDOWS.
'SubSystem': '2',
'AdditionalDependencies!': [
'user32.lib',
],
'IgnoreDefaultLibraryNames': [
'user32.lib',
],
In GN, we directly access "ldflags" and "cflags". E.g.:
ldflags = [
"/DELAYLOAD:advapi32.dll",
The linker option "/NODEFAULTLIB" is theoretically the way to remove all (or one, "/NODEFAULTLIB[:library]") default libraries from the list it searches when resolving external references. https://msdn.microsoft.com/en-us/library/3tz4da4a.aspx
This, however, is currently not working as intended in GN.
Details:
"The linker resolves references to external definitions by searching first in libraries that you explicitly specify, then in default libraries specified with the /DEFAULTLIB option, and then in default libraries named in .obj files."
The "default list" is usually defined in a property sheet now (equivilent to "/DEFAULTLIB" option that is no longer exposed in VS UI), and is then set to the "LIB" environment variable to be passed to link.exe.
***In GN, our paths are currently being set using the "/LIBPATH" switch, which actually overrides (is checked before) the "LIB" environment variable (default list).
(/LIBPATH: https://msdn.microsoft.com/en-us/library/1xhzskbe.aspx)
"/LIBPATH - Specifies a path to search before the environmental library path."
Files where where this stuff happens:
- build/toolchain/win/build.gn sets "/LIBPATH" as the switch to use:
https://cs.chromium.org/chromium/src/build/toolchain/win/BUILD.gn?type=cs&sq=package:chromium&l=71
- tools/gn/ninja_binary_target_writer.cc constructs the linker command line with arguments: https://cs.chromium.org/chromium/src/tools/gn/ninja_binary_target_writer.cc?sq=package:chromium&l=849&dr=CSs
So if I add "/NODEFAULTLIB:user32.lib" to a GN file right now, GN will apply that (i.e. remove) "user32.lib" from LIB... but that doesn't affect /LIBPATH.
RESULT: link.exe happily links user32.lib, because it finds it in the /LIBPATH override paths. Really not good for projects like chrome_elf - luckily we have a backup sanity check in automated tests to flag the immediate loading of user32.lib. (Example problem/symptom: https://bugs.chromium.org/p/chromium/issues/detail?id=646414)
SIDE NOTE: None of this has anything to do with the "LIBPATH" environment variable, with is related to compiler settings. (Confusing, I know.)
FOR THE RECORD, order of priority:
----------------------------------
1) libraries specified on the linker command line (i.e. explicitly specified).
a) /LIBPATH: overrides LIB environment variable.
b) /DEFAULTLIB: LIB environment variable (removed by /NODEFAULTLIB)
4) default libraries named in .obj files. (To create an .obj file that does not contain references to default libraries, use /Zl compiler option (Omit Default Library Name).)
So... we could try to use /DEFAULTLIB instead of /LIBPATH to set up our defaults (do it the same way VS goes from property sheet to "LIB"),
or we could manually process /NODEFAULTLIB settings and remove the libs from our /LIBPATH (since LIB env var doesn't get looked at much right now - though I've found it does fall back to LIB occasionally).
Thoughts Brett/Bruce?
,
Sep 15 2016
,
Sep 15 2016
,
Sep 15 2016
I don't understand why it has anything to do with libpath? IgnoreDefaultLibraryNames in gyp is just NODEFAULTLIB. So it seems like it's probably because we're explicitly adding user32.lib somewhere, rather than it having anything to do with the default linking of it. i.e. d:\src\cr3\src>gn desc out/Release //chrome_elf libs --blame advapi32.lib comdlg32.lib dbghelp.lib delayimp.lib dnsapi.lib gdi32.lib kernel32.lib msimg32.lib odbc32.lib odbccp32.lib ole32.lib oleaut32.lib psapi.lib shell32.lib shlwapi.lib user32.lib usp10.lib uuid.lib version.lib wininet.lib winmm.lib winspool.lib ws2_32.lib cfgmgr32.lib powrprof.lib setupapi.lib userenv.lib rpcrt4.lib winhttp.lib (hmm --blame doesn't work for libs apparently, but that looks a lot like config(default_libs)?
,
Sep 15 2016
Put another way, the thing that you're missing in the GN build is "AdditionalDependencies!", right? gn desc out/Release //chrome_elf configs //build/config:feature_flags //build/config/compiler:compiler //build/config/compiler:clang_stackrealign //build/config/compiler:compiler_arm_fpu //build/config/compiler:chromium_code //build/config/compiler:default_include_dirs //build/config/compiler:default_optimization //build/config/compiler:default_stack_frames //build/config/compiler:default_symbols //build/config/compiler:no_rtti //build/config/compiler:runtime_library //build/config/sanitizers:default_sanitizer_flags //build/config/win:lean_and_mean //build/config/win:nominmax //build/config/win:unicode //build/config/win:winver //build/config/win:vs_code_analysis //build/config:release //build/config:default_libs <<------------- //build/config:shared_library_config //build/config/win:default_incremental_linking //build/config/win:windowed //base:base_win_linker_flags //third_party/crashpad/crashpad/util:util_link_config
,
Sep 15 2016
(Side note: yes, we should make --blame work for libs).
,
Sep 22 2016
Clearing the Proj-GN-Migration label since it didn't block the GN migration (I'm trying to figure out what, if any GYP/GN-related tasks might be left).
,
Aug 30
|
||||||
►
Sign in to add a comment |
||||||
Comment 1 by penny...@chromium.org
, Sep 15 2016