| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "tools/gn/setup.h" | 5 #include "tools/gn/setup.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/files/file_path.h" | 14 #include "base/files/file_path.h" |
| 15 #include "base/files/file_util.h" | 15 #include "base/files/file_util.h" |
| 16 #include "base/process/launch.h" | 16 #include "base/process/launch.h" |
| 17 #include "base/strings/string_split.h" | 17 #include "base/strings/string_split.h" |
| 18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
| 19 #include "base/strings/sys_string_conversions.h" |
| 19 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
| 20 #include "build/build_config.h" | 21 #include "build/build_config.h" |
| 21 #include "tools/gn/commands.h" | 22 #include "tools/gn/commands.h" |
| 22 #include "tools/gn/filesystem_utils.h" | 23 #include "tools/gn/filesystem_utils.h" |
| 23 #include "tools/gn/input_file.h" | 24 #include "tools/gn/input_file.h" |
| 24 #include "tools/gn/parse_tree.h" | 25 #include "tools/gn/parse_tree.h" |
| 25 #include "tools/gn/parser.h" | 26 #include "tools/gn/parser.h" |
| 26 #include "tools/gn/source_dir.h" | 27 #include "tools/gn/source_dir.h" |
| 27 #include "tools/gn/source_file.h" | 28 #include "tools/gn/source_file.h" |
| 28 #include "tools/gn/standard_out.h" | 29 #include "tools/gn/standard_out.h" |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 DCHECK(item); | 143 DCHECK(item); |
| 143 main_loop->PostTask(FROM_HERE, base::Bind(&Builder::ItemDefined, builder, | 144 main_loop->PostTask(FROM_HERE, base::Bind(&Builder::ItemDefined, builder, |
| 144 base::Passed(&item))); | 145 base::Passed(&item))); |
| 145 } | 146 } |
| 146 | 147 |
| 147 void DecrementWorkCount() { | 148 void DecrementWorkCount() { |
| 148 g_scheduler->DecrementWorkCount(); | 149 g_scheduler->DecrementWorkCount(); |
| 149 } | 150 } |
| 150 | 151 |
| 151 #if defined(OS_WIN) | 152 #if defined(OS_WIN) |
| 153 |
| 154 // Given the path to a batch file that runs Python, extracts the name of the |
| 155 // executable actually implementing Python. Generally people write a batch file |
| 156 // to put something named "python" on the path, which then just redirects to |
| 157 // a python.exe somewhere else. This step decodes that setup. On failure, |
| 158 // returns empty path. |
| 159 base::FilePath PythonBatToExe(const base::FilePath& bat_path) { |
| 160 // Note exciting double-quoting to allow spaces. The /c switch seems to check |
| 161 // for quotes around the whole thing and then deletes them. If you want to |
| 162 // quote the first argument in addition (to allow for spaces in the Python |
| 163 // path, you need *another* set of quotes around that, likewise, we need |
| 164 // two quotes at the end. |
| 165 base::string16 command = L"cmd.exe /c \"\""; |
| 166 command.append(bat_path.value()); |
| 167 command.append(L"\" -c \"import sys; print sys.executable\"\""); |
| 168 |
| 169 std::string python_path; |
| 170 if (base::GetAppOutput(command, &python_path)) { |
| 171 base::TrimWhitespaceASCII(python_path, base::TRIM_ALL, &python_path); |
| 172 |
| 173 // Python uses the system multibyte code page for sys.executable. |
| 174 base::FilePath exe_path(base::SysNativeMBToWide(python_path)); |
| 175 |
| 176 // Check for reasonable output, cmd may have output an error message. |
| 177 if (base::PathExists(exe_path)) |
| 178 return exe_path; |
| 179 } |
| 180 return base::FilePath(); |
| 181 } |
| 182 |
| 152 const base::char16 kPythonExeName[] = L"python.exe"; | 183 const base::char16 kPythonExeName[] = L"python.exe"; |
| 184 const base::char16 kPythonBatName[] = L"python.bat"; |
| 153 | 185 |
| 154 base::FilePath FindWindowsPython() { | 186 base::FilePath FindWindowsPython() { |
| 155 base::char16 current_directory[MAX_PATH]; | 187 base::char16 current_directory[MAX_PATH]; |
| 156 ::GetCurrentDirectory(MAX_PATH, current_directory); | 188 ::GetCurrentDirectory(MAX_PATH, current_directory); |
| 157 | 189 |
| 158 // First search for python.exe in the current directory. | 190 // First search for python.exe in the current directory. |
| 159 base::FilePath cur_dir_candidate_exe = | 191 base::FilePath cur_dir_candidate_exe = |
| 160 base::FilePath(current_directory).Append(kPythonExeName); | 192 base::FilePath(current_directory).Append(kPythonExeName); |
| 161 if (base::PathExists(cur_dir_candidate_exe)) | 193 if (base::PathExists(cur_dir_candidate_exe)) |
| 162 return cur_dir_candidate_exe; | 194 return cur_dir_candidate_exe; |
| 163 | 195 |
| 164 // Get the path. | 196 // Get the path. |
| 165 const base::char16 kPathEnvVarName[] = L"Path"; | 197 const base::char16 kPathEnvVarName[] = L"Path"; |
| 166 DWORD path_length = ::GetEnvironmentVariable(kPathEnvVarName, nullptr, 0); | 198 DWORD path_length = ::GetEnvironmentVariable(kPathEnvVarName, nullptr, 0); |
| 167 if (path_length == 0) | 199 if (path_length == 0) |
| 168 return base::FilePath(); | 200 return base::FilePath(); |
| 169 scoped_ptr<base::char16[]> full_path(new base::char16[path_length]); | 201 scoped_ptr<base::char16[]> full_path(new base::char16[path_length]); |
| 170 DWORD actual_path_length = | 202 DWORD actual_path_length = |
| 171 ::GetEnvironmentVariable(kPathEnvVarName, full_path.get(), path_length); | 203 ::GetEnvironmentVariable(kPathEnvVarName, full_path.get(), path_length); |
| 172 CHECK_EQ(path_length, actual_path_length + 1); | 204 CHECK_EQ(path_length, actual_path_length + 1); |
| 173 | 205 |
| 174 // Search for python.exe in the path. | 206 // Search for python.exe in the path. |
| 175 for (const auto& component : base::SplitStringPiece( | 207 for (const auto& component : base::SplitStringPiece( |
| 176 base::StringPiece16(full_path.get(), path_length), L";", | 208 base::StringPiece16(full_path.get(), path_length), L";", |
| 177 base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) { | 209 base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) { |
| 178 base::FilePath candidate_exe = | 210 base::FilePath candidate_exe = |
| 179 base::FilePath(component).Append(kPythonExeName); | 211 base::FilePath(component).Append(kPythonExeName); |
| 180 if (base::PathExists(candidate_exe)) | 212 if (base::PathExists(candidate_exe)) |
| 181 return candidate_exe; | 213 return candidate_exe; |
| 214 |
| 215 // Also allow python.bat, but convert into the .exe. |
| 216 base::FilePath candidate_bat = |
| 217 base::FilePath(component).Append(kPythonBatName); |
| 218 if (base::PathExists(candidate_bat)) { |
| 219 base::FilePath python_exe = PythonBatToExe(candidate_bat); |
| 220 if (!python_exe.empty()) |
| 221 return python_exe; |
| 222 } |
| 182 } | 223 } |
| 183 return base::FilePath(); | 224 return base::FilePath(); |
| 184 } | 225 } |
| 185 #endif | 226 #endif |
| 186 | 227 |
| 187 } // namespace | 228 } // namespace |
| 188 | 229 |
| 189 const char Setup::kBuildArgFileName[] = "args.gn"; | 230 const char Setup::kBuildArgFileName[] = "args.gn"; |
| 190 | 231 |
| 191 Setup::Setup() | 232 Setup::Setup() |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 if (err.has_error()) { | 691 if (err.has_error()) { |
| 651 err.PrintToStdout(); | 692 err.PrintToStdout(); |
| 652 return false; | 693 return false; |
| 653 } | 694 } |
| 654 } | 695 } |
| 655 build_settings_.set_exec_script_whitelist(std::move(whitelist)); | 696 build_settings_.set_exec_script_whitelist(std::move(whitelist)); |
| 656 } | 697 } |
| 657 | 698 |
| 658 return true; | 699 return true; |
| 659 } | 700 } |
| OLD | NEW |