New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 647315 link

Starred by 2 users

Issue metadata

Status: Closed
Owner:
Last visit > 30 days ago
Closed: Aug 30
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Windows
Pri: 2
Type: Bug

Blocking:
issue 627924
issue 631771



Sign in to add a comment

GN \NODEFAULTLIB[:library] linker option not supported

Project Member Reported by penny...@chromium.org, Sep 15 2016

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?



 
Cc: robertshield@chromium.org
FYI +robertshield
Blocking: 627924
Blocking: 631771
Cc: scottmg@chromium.org
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)?


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
(Side note: yes, we should make --blame work for libs).
Labels: -Build-Tools-GN -Proj-GN-Migration
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).
Status: Closed (was: Assigned)

Sign in to add a comment