diff --git a/config/BUILDCONFIG.gn b/config/BUILDCONFIG.gn index bd4dac8a3..d3a0683ea 100644 --- a/config/BUILDCONFIG.gn +++ b/config/BUILDCONFIG.gn @@ -43,6 +43,15 @@ declare_args() { # TODO(brettw) this should be moved out of the main build config file. use_ozone = false + # Forces a 64-bit build on Windows. Does nothing on other platforms. Normally + # we build 32-bit on Windows regardless of the current host OS bit depth. + # Setting this flag will override this logic and generate 64-bit toolchains. + # + # Normally this would get set automatically when you specify a target using + # the 64-bit toolchain. You can also set this on the command line to convert + # the default toolchain to 64-bit. + force_win64 = false + # Set to true on the command line when invoked by GYP. Build files can key # off of this to make any GYP-output-specific changes to the build. is_gyp = false @@ -138,10 +147,13 @@ if (os == "win") { # ============================================================================= if (is_win) { - # Always use 32-bit on Windows, even when compiling on a 64-bit host OS. - # TODO(brettw) when we support 64-bit cross-compiles, we probably need to - # set a build arg in the toolchain to disable this override. - cpu_arch = "ia32" + # Always use 32-bit on Windows, even when compiling on a 64-bit host OS, + # unless the override flag is specified. + if (force_win64) { + cpu_arch = "ia64" + } else { + cpu_arch = "ia32" + } } # ============================================================================= @@ -371,7 +383,11 @@ set_defaults("source_set") { # default toolchain. if (is_win) { - host_toolchain = "//build/toolchain/win:32" + if (cpu_arch == "ia64") { + host_toolchain = "//build/toolchain/win:64" + } else if (cpu_arch == "ia32") { + host_toolchain = "//build/toolchain/win:32" + } set_default_toolchain(host_toolchain) } else if (is_linux) { host_toolchain = "//build/toolchain/linux:host" diff --git a/config/win/BUILD.gn b/config/win/BUILD.gn index e101c2b8e..72147e01f 100644 --- a/config/win/BUILD.gn +++ b/config/win/BUILD.gn @@ -44,10 +44,7 @@ config("sdk") { # Linker flags for Windows SDK setup, this is applied only to EXEs and DLLs. config("sdk_link") { - # TODO(brettw) 64-bit. - is_64bit = false - - if (is_64bit) { + if (cpu_arch == "ia64") { ldflags = [ "/MACHINE:X64" ] lib_dirs = [ "$windows_sdk_path\Lib\win8\um\x64", diff --git a/toolchain/win/BUILD.gn b/toolchain/win/BUILD.gn index 95cd9472a..68194ab16 100644 --- a/toolchain/win/BUILD.gn +++ b/toolchain/win/BUILD.gn @@ -23,6 +23,9 @@ gyp_win_tool_source = rebase_path("//tools/gyp/pylib/gyp/win_tool.py", ".", root_build_dir) exec_script("setup_toolchain.py", [ gyp_win_tool_source ], "value") +stamp_command = "$python_path gyp-win-tool stamp \$out" +copy_command = "$python_path gyp-win-tool recursive-mirror \$in \$out" + # 32-bit toolchain ------------------------------------------------------------- toolchain("32") { @@ -30,108 +33,35 @@ toolchain("32") { lib_prefix = "" lib_dir_prefix="/LIBPATH:" + cc_command = "ninja -t msvc -e environment.x86 -- cl.exe /nologo /showIncludes /FC @\$out.rsp /c \$in /Fo\$out /Fd\$pdbname" tool("cc") { - command = "ninja -t msvc -e environment.x86 -- cl.exe /nologo /showIncludes /FC @\$out.rsp /c \$in /Fo\$out /Fd\$pdbname" + command = cc_command description = "CC \$out" rspfile = "\$out.rsp" rspfile_content = "\$defines \$includes \$cflags \$cflags_c" deps = "msvc" } tool("cxx") { - command = "ninja -t msvc -e environment.x86 -- cl.exe /nologo /showIncludes /FC @\$out.rsp /c \$in /Fo\$out /Fd\$pdbname" + command = cc_command # Same as above description = "CXX \$out" rspfile = "\$out.rsp" rspfile_content = "\$defines \$includes \$cflags \$cflags_cc" deps = "msvc" } - #tool("idl") { - # command = $python_path gyp-win-tool midl-wrapper environment.x86 \$outdir \$tlb \$h \$dlldata \$iid \$ - # \$proxy \$in \$idlflags - # description = IDL \$in - #} tool("rc") { command = "$python_path gyp-win-tool rc-wrapper environment.x86 rc.exe \$defines \$includes \$rcflags /fo\$out \$in" description = "RC \$in" } - #tool("asm") { - # command = $python_path gyp-win-tool asm-wrapper environment.x86 ml.exe \$defines \$includes /c /Fo \$ - # \$out \$in - # description = ASM \$in - #} + tool("asm") { + command = "$python_path gyp-win-tool asm-wrapper environment.x86 ml.exe \$defines \$includes /c /Fo \$out \$in" + description = "ASM \$in" + } tool("alink") { command = "$python_path gyp-win-tool link-wrapper environment.x86 lib.exe /nologo /ignore:4221 /OUT:\$out @\$out.rsp" description = "LIB \$out" rspfile = "\$out.rsp" rspfile_content = "\$in_newline \$libflags" } - #tool("solink_embed_inc") { - # command = cmd /c $python_path gyp-win-tool link-wrapper environment.x86 link.exe /nologo \$implibflag \$ - # /DLL /OUT:\$dll /PDB:\$dll.pdb @\$dll.rsp && $python_path gyp-win-tool \$ - # manifest-wrapper environment.x86 cmd /c if exist \$dll.manifest del \$dll.manifest && \$ - # $python_path gyp-win-tool manifest-wrapper environment.x86 mt.exe -nologo -manifest \$manifests \$ - # -out:\$dll.manifest && $python_path gyp-win-tool manifest-to-rc environment.x86 \$dll.manifest \$ - # \$dll.manifest.rc 2 && $python_path gyp-win-tool rc-wrapper environment.x86 rc.exe \$ - # \$dll.manifest.rc && $python_path gyp-win-tool link-wrapper environment.x86 link.exe /nologo \$ - # \$implibflag /DLL /OUT:\$dll /PDB:\$dll.pdb @\$dll.rsp \$dll.manifest.res - # description = LINK_EMBED_INC(DLL) \$dll - # restat = 1 - # rspfile = \$dll.rsp - # rspfile_content = \$libs \$in_newline \$ldflags - #} - #tool("solink_module_embed_inc") { - # command = cmd /c $python_path gyp-win-tool link-wrapper environment.x86 link.exe /nologo \$implibflag \$ - # /DLL /OUT:\$dll /PDB:\$dll.pdb @\$dll.rsp && $python_path gyp-win-tool \$ - # manifest-wrapper environment.x86 cmd /c if exist \$dll.manifest del \$dll.manifest && \$ - # $python_path gyp-win-tool manifest-wrapper environment.x86 mt.exe -nologo -manifest \$manifests \$ - # -out:\$dll.manifest && $python_path gyp-win-tool manifest-to-rc environment.x86 \$dll.manifest \$ - # \$dll.manifest.rc 2 && $python_path gyp-win-tool rc-wrapper environment.x86 rc.exe \$ - # \$dll.manifest.rc && $python_path gyp-win-tool link-wrapper environment.x86 link.exe /nologo \$ - # \$implibflag /DLL /OUT:\$dll /PDB:\$dll.pdb @\$dll.rsp \$dll.manifest.res - # description = LINK_EMBED_INC(DLL) \$dll - # restat = 1 - # rspfile = \$dll.rsp - # rspfile_content = \$libs \$in_newline \$ldflags - #} - #rule link_embed_inc - # command = cmd /c $python_path gyp-win-tool link-wrapper environment.x86 link.exe /nologo /OUT:\$out \$ - # /PDB:\$out.pdb @\$out.rsp && $python_path gyp-win-tool manifest-wrapper environment.x86 cmd /c \$ - # if exist \$out.manifest del \$out.manifest && $python_path gyp-win-tool \$ - # manifest-wrapper environment.x86 mt.exe -nologo -manifest \$manifests -out:\$out.manifest && \$ - # $python_path gyp-win-tool manifest-to-rc environment.x86 \$out.manifest \$out.manifest.rc 1 && \$ - # $python_path gyp-win-tool rc-wrapper environment.x86 rc.exe \$out.manifest.rc && \$ - # $python_path gyp-win-tool link-wrapper environment.x86 link.exe /nologo /OUT:\$out /PDB:\$out.pdb \$ - # @\$out.rsp \$out.manifest.res - # description = LINK_EMBED_INC \$out - # rspfile = \$out.rsp - # rspfile_content = \$in_newline \$libs \$ldflags - #rule solink_embed - # command = cmd /c $python_path gyp-win-tool link-wrapper environment.x86 link.exe /nologo \$implibflag \$ - # /DLL /OUT:\$dll /PDB:\$dll.pdb @\$dll.rsp && $python_path gyp-win-tool \$ - # manifest-wrapper environment.x86 cmd /c if exist \$dll.manifest del \$dll.manifest && \$ - # $python_path gyp-win-tool manifest-wrapper environment.x86 mt.exe -nologo -manifest \$manifests \$ - # -outputresource:\$dll;2 - # description = LINK_EMBED(DLL) \$dll - # restat = 1 - # rspfile = \$dll.rsp - # rspfile_content = \$libs \$in_newline \$ldflags - #rule solink_module_embed - # command = cmd /c $python_path gyp-win-tool link-wrapper environment.x86 link.exe /nologo \$implibflag \$ - # /DLL /OUT:\$dll /PDB:\$dll.pdb @\$dll.rsp && $python_path gyp-win-tool \$ - # manifest-wrapper environment.x86 cmd /c if exist \$dll.manifest del \$dll.manifest && \$ - # $python_path gyp-win-tool manifest-wrapper environment.x86 mt.exe -nologo -manifest \$manifests \$ - # -outputresource:\$dll;2 - # description = LINK_EMBED(DLL) \$dll - # restat = 1 - # rspfile = \$dll.rsp - # rspfile_content = \$libs \$in_newline \$ldflags - #rule link_embed - # command = cmd /c $python_path gyp-win-tool link-wrapper environment.x86 link.exe /nologo /OUT:\$out \$ - # /PDB:\$out.pdb @\$out.rsp && $python_path gyp-win-tool manifest-wrapper environment.x86 cmd /c \$ - # if exist \$out.manifest del \$out.manifest && $python_path gyp-win-tool \$ - # manifest-wrapper environment.x86 mt.exe -nologo -manifest \$manifests -outputresource:\$out;1 - # description = LINK_EMBED \$out - # rspfile = \$out.rsp - # rspfile_content = \$in_newline \$libs \$ldflags tool("solink") { command = "cmd /c $python_path gyp-win-tool link-wrapper environment.x86 link.exe /nologo \$implibflag /DLL /OUT:\$dll /PDB:\$dll.pdb @\$dll.rsp && $python_path gyp-win-tool manifest-wrapper environment.x86 cmd /c if exist \$dll.manifest del \$dll.manifest && $python_path gyp-win-tool manifest-wrapper environment.x86 mt.exe -nologo -manifest \$manifests -out:\$dll.manifest" description = "LINK(DLL) \$dll" @@ -146,11 +76,11 @@ toolchain("32") { rspfile_content = "\$in_newline \$libs \$ldflags" } tool("stamp") { - command = "$python_path gyp-win-tool stamp \$out" + command = stamp_command description = "STAMP \$out" } tool("copy") { - command = "$python_path gyp-win-tool recursive-mirror \$in \$out" + command = copy_command description = "COPY \$in \$out" } } @@ -158,4 +88,67 @@ toolchain("32") { # 64-bit toolchain ------------------------------------------------------------- toolchain("64") { + # Make these apply to all tools below. + lib_prefix = "" + lib_dir_prefix="/LIBPATH:" + + cc_command = "ninja -t msvc -e environment.x64 -- cl.exe /nologo /showIncludes /FC @\$out.rsp /c \$in /Fo\$out /Fd\$pdbname" + tool("cc") { + command = cc_command + description = "CC \$out" + rspfile = "\$out.rsp" + rspfile_content = "\$defines \$includes \$cflags \$cflags_c" + deps = "msvc" + } + tool("cxx") { + command = cc_command # Same as above + description = "CXX \$out" + rspfile = "\$out.rsp" + rspfile_content = "\$defines \$includes \$cflags \$cflags_cc" + deps = "msvc" + } + tool("rc") { + command = "$python_path gyp-win-tool rc-wrapper environment.x64 rc.exe \$defines \$includes \$rcflags /fo\$out \$in" + description = "RC \$in" + } + tool("asm") { + command = "$python_path gyp-win-tool asm-wrapper environment.x64 ml.exe \$defines \$includes /c /Fo \$out \$in" + description = "ASM \$in" + } + tool("alink") { + command = "$python_path gyp-win-tool link-wrapper environment.x64 lib.exe /nologo /ignore:4221 /OUT:\$out @\$out.rsp" + description = "LIB \$out" + rspfile = "\$out.rsp" + rspfile_content = "\$in_newline \$libflags" + } + tool("solink") { + command = "cmd /c $python_path gyp-win-tool link-wrapper environment.x64 link.exe /nologo \$implibflag /DLL /OUT:\$dll /PDB:\$dll.pdb @\$dll.rsp && $python_path gyp-win-tool manifest-wrapper environment.x64 cmd /c if exist \$dll.manifest del \$dll.manifest && $python_path gyp-win-tool manifest-wrapper environment.x64 mt.exe -nologo -manifest \$manifests -out:\$dll.manifest" + description = "LINK(DLL) \$dll" + restat = "1" + rspfile = "\$dll.rsp" + rspfile_content = "\$libs \$in_newline \$ldflags" + } + tool("link") { + command = "cmd /c $python_path gyp-win-tool link-wrapper environment.x64 link.exe /nologo /OUT:\$out /PDB:\$out.pdb @\$out.rsp && $python_path gyp-win-tool manifest-wrapper environment.x64 cmd /c if exist \$out.manifest del \$out.manifest && $python_path gyp-win-tool manifest-wrapper environment.x64 mt.exe -nologo -manifest \$manifests -out:\$out.manifest" + description = "LINK \$out" + rspfile = "\$out.rsp" + rspfile_content = "\$in_newline \$libs \$ldflags" + } + tool("stamp") { + command = stamp_command + description = "STAMP \$out" + } + tool("copy") { + command = copy_command + description = "COPY \$in \$out" + } + + # When invoking this toolchain not as the default one, these args will be + # passed to the build. They are ignored when this is the default toolchain. + toolchain_args() { + cpu_arch = "ia64" + # Normally the build config resets the CPU architecture to 32-bits. Setting + # this flag overrides that behavior. + force_win64 = true + } } diff --git a/toolchain/win/setup_toolchain.py b/toolchain/win/setup_toolchain.py index bba18dfc5..162c2e16c 100644 --- a/toolchain/win/setup_toolchain.py +++ b/toolchain/win/setup_toolchain.py @@ -35,6 +35,49 @@ def ExtractImportantEnvironment(): 'required to be set to valid path' % required) return result + +# VC setup will add a path like this in 32-bit mode: +# c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN +# And this in 64-bit mode: +# c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\BIN\amd64 +# Note that in 64-bit it's duplicated but the 64-bit one comes first. +# +# What we get as the path when running this will depend on which VS setup +# script you've run. The following two functions try to do this. + +# For 32-bit compiles remove anything that ends in "\VC\WIN\amd64". +def FixupPath32(path): + find_64 = re.compile("VC\\\\BIN\\\\amd64\\\\*$", flags=re.IGNORECASE) + + for i in range(len(path)): + if find_64.search(path[i]): + # Found 32-bit path, insert the 64-bit one immediately before it. + dir_64 = path[i].rstrip("\\") + dir_64 = dir_64[:len(dir_64) - 6] # Trim off "\amd64". + path[i] = dir_64 + break + return path + +# For 64-bit compiles, append anything ending in "\VC\BIN" with "\amd64" as +# long as that thing isn't already in the list, and append it immediately +# before the non-amd64-one. +def FixupPath64(path): + find_32 = re.compile("VC\\\\BIN\\\\*$", flags=re.IGNORECASE) + + for i in range(len(path)): + if find_32.search(path[i]): + # Found 32-bit path, insert the 64-bit one immediately before it. + dir_32 = path[i] + if dir_32[len(dir_32) - 1] == '\\': + dir_64 = dir_32 + "amd64" + else: + dir_64 = dir_32 + "\\amd64" + path.insert(i, dir_64) + break + + return path + + def FormatAsEnvironmentBlock(envvar_dict): """Format as an 'environment block' directly suitable for CreateProcess. Briefly this is a list of key=value\0, terminated by an additional \0. See @@ -59,14 +102,22 @@ def CopyTool(source_path): '# Generated by setup_toolchain.py do not edit.\n'] + tool_source[1:])) + # Find the tool source, it's the first argument, and copy it. if len(sys.argv) != 2: print "Need one argument (win_tool source path)." sys.exit(1) CopyTool(sys.argv[1]) -# Write the environment file to the current directory. -environ = FormatAsEnvironmentBlock(ExtractImportantEnvironment()) +important_env_vars = ExtractImportantEnvironment() +path = important_env_vars["PATH"].split(";") + +important_env_vars["PATH"] = ";".join(FixupPath32(path)) +environ = FormatAsEnvironmentBlock(important_env_vars) with open('environment.x86', 'wb') as env_file: env_file.write(environ) +important_env_vars["PATH"] = ";".join(FixupPath64(path)) +environ = FormatAsEnvironmentBlock(important_env_vars) +with open('environment.x64', 'wb') as env_file: + env_file.write(environ)