Commit 4441041b authored by brettw@chromium.org's avatar brettw@chromium.org

Add support for data deps.

Data deps are non-linked dependencies of a target. They are built in parallel (they are not input dependencies). I redefined "data" to mean data file dependencies, and added a new "datadeps" contept for non-linked target dependencies.

Fix a bug to make it not crash if there's nothing to generate.

Add variable documentation for some vars.

Removed support for some builtin vars "root output dir name" and related. These had changed definition from when I originally wrote them, and I don't think there's any use for these values. We can add them back if we need.

I moved the variable name constant declarations from scope_per_file_provider to the new variables file which includes documentation.

I added support for getting the name of the current toolchain via a builtin variable.

I removed support for solink_module which is not necessary. This was a way to express a .dll target that isn't linked to its dependees, but that's no longer necessary for datadeps.

BUG=
R=scottmg@chromium.org

Review URL: https://codereview.chromium.org/22290010

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@215976 0039d316-1c4b-4281-b951-d872f2087c98
parent ddf48eac
......@@ -107,6 +107,8 @@ static_library("gn_lib") {
"value.h",
"value_extractors.cc",
"value_extractors.h",
"variables.cc",
"variables.h",
]
deps = [
"//base",
......
......@@ -35,6 +35,10 @@ void RecursiveCollectDeps(const Target* target, std::set<Label>* result) {
const std::vector<const Target*>& deps = target->deps();
for (size_t i = 0; i < deps.size(); i++)
RecursiveCollectDeps(deps[i], result);
const std::vector<const Target*>& datadeps = target->datadeps();
for (size_t i = 0; i < datadeps.size(); i++)
RecursiveCollectDeps(datadeps[i], result);
}
// Prints dependencies of the given target (not the target itself).
......@@ -42,6 +46,9 @@ void RecursivePrintDeps(const Target* target,
const Label& default_toolchain,
int indent_level) {
std::vector<const Target*> sorted_deps = target->deps();
const std::vector<const Target*> datadeps = target->datadeps();
for (size_t i = 0; i < datadeps.size(); i++)
sorted_deps.push_back(datadeps[i]);
std::sort(sorted_deps.begin(), sorted_deps.end(), CompareTargetLabel());
std::string indent(indent_level * 2, ' ');
......@@ -53,10 +60,11 @@ void RecursivePrintDeps(const Target* target,
}
void PrintDeps(const Target* target, bool display_header) {
const CommandLine* cmdline = CommandLine::ForCurrentProcess();
Label toolchain_label = target->label().GetToolchainLabel();
// Tree mode is separate.
if (CommandLine::ForCurrentProcess()->HasSwitch("tree")) {
if (cmdline->HasSwitch("tree")) {
if (display_header)
OutputString("\nDependency tree:\n");
RecursivePrintDeps(target, toolchain_label, 1);
......@@ -65,7 +73,7 @@ void PrintDeps(const Target* target, bool display_header) {
// Collect the deps to display.
std::vector<Label> deps;
if (CommandLine::ForCurrentProcess()->HasSwitch("all")) {
if (cmdline->HasSwitch("all")) {
if (display_header)
OutputString("\nAll recursive dependencies:\n");
......@@ -83,6 +91,10 @@ void PrintDeps(const Target* target, bool display_header) {
const std::vector<const Target*>& target_deps = target->deps();
for (size_t i = 0; i < target_deps.size(); i++)
deps.push_back(target_deps[i]->label());
const std::vector<const Target*>& target_datadeps = target->datadeps();
for (size_t i = 0; i < target_datadeps.size(); i++)
deps.push_back(target_datadeps[i]->label());
}
std::sort(deps.begin(), deps.end());
......@@ -227,6 +239,7 @@ const char kDesc_Help[] =
" Show immediate (or, when \"--all\" or \"--tree\" is specified,\n"
" recursive) dependencies of the given target. \"--tree\" shows them\n"
" in a tree format. Otherwise, they will be sorted alphabetically.\n"
" Both \"deps\" and \"datadeps\" will be included.\n"
"\n"
" defines [--blame]\n"
" includes [--blame]\n"
......
......@@ -58,11 +58,8 @@ int RunGen(const std::vector<std::string>& args) {
return 1;
// Write the root ninja files.
if (!NinjaWriter::RunAndWriteFiles(&setup->build_settings())) {
Err(Location(),
"Couldn't open root buildfile(s) for writing").PrintToStdout();
if (!NinjaWriter::RunAndWriteFiles(&setup->build_settings()))
return 1;
}
base::TimeTicks end_time = base::TimeTicks::Now();
......
......@@ -11,6 +11,7 @@
#include "tools/gn/input_conversion.h"
#include "tools/gn/setup.h"
#include "tools/gn/standard_out.h"
#include "tools/gn/variables.h"
namespace commands {
......@@ -30,8 +31,7 @@ void PrintShortHelp(const std::string& line) {
}
void PrintToplevelHelp() {
std::cout <<
"Commands (type \"gn help <command>\" for more details):\n";
OutputString("Commands (type \"gn help <command>\" for more details):\n");
const commands::CommandInfoMap& command_map = commands::GetCommands();
for (commands::CommandInfoMap::const_iterator i = command_map.begin();
......@@ -46,10 +46,11 @@ void PrintToplevelHelp() {
" -q: Quiet mode, don't print anything on success.\n"
" --root: Specifies source root (overrides .gn file).\n"
" --secondary: Specifies secondary source root (overrides .gn file).\n"
" -v: Verbose mode, print lots of logging.\n"
"\n"
"Buildfile functions (type \"gn help <function>\" for more details):\n");
" -v: Verbose mode, print lots of logging.\n");
// Functions.
OutputString("\nBuildfile functions (type \"gn help <function>\" for more "
"details):\n");
const functions::FunctionInfoMap& function_map = functions::GetFunctions();
std::vector<std::string> sorted_functions;
for (functions::FunctionInfoMap::const_iterator i = function_map.begin();
......@@ -59,6 +60,24 @@ void PrintToplevelHelp() {
for (size_t i = 0; i < sorted_functions.size(); i++)
OutputString(" " + sorted_functions[i] + "\n", DECORATION_YELLOW);
// Built-in variables.
OutputString("\nBuilt-in predefined variables (type \"gn help <variable>\" "
"for more details):\n");
const variables::VariableInfoMap& builtin_vars =
variables::GetBuiltinVariables();
for (variables::VariableInfoMap::const_iterator i = builtin_vars.begin();
i != builtin_vars.end(); ++i)
PrintShortHelp(i->second.help_short);
// Target variables.
OutputString("\nVariables you set in targets (type \"gn help <variable>\" "
"for more details):\n");
const variables::VariableInfoMap& target_vars =
variables::GetTargetVariables();
for (variables::VariableInfoMap::const_iterator i = target_vars.begin();
i != target_vars.end(); ++i)
PrintShortHelp(i->second.help_short);
OutputString("\nOther help topics:\n");
PrintShortHelp("dotfile: Info about the toplevel .gn file.");
PrintShortHelp(
......@@ -99,6 +118,26 @@ int RunHelp(const std::vector<std::string>& args) {
return 0;
}
// Builtin variables.
const variables::VariableInfoMap& builtin_vars =
variables::GetBuiltinVariables();
variables::VariableInfoMap::const_iterator found_builtin_var =
builtin_vars.find(args[0]);
if (found_builtin_var != builtin_vars.end()) {
OutputString(found_builtin_var->second.help);
return 0;
}
// Target variables.
const variables::VariableInfoMap& target_vars =
variables::GetTargetVariables();
variables::VariableInfoMap::const_iterator found_target_var =
target_vars.find(args[0]);
if (found_target_var != target_vars.end()) {
OutputString(found_target_var->second.help);
return 0;
}
// Random other topics.
if (args[0] == "input_conversion") {
OutputString(kInputConversion_Help);
......
......@@ -117,6 +117,8 @@
'value.h',
'value_extractors.cc',
'value_extractors.h',
'variables.cc',
'variables.h',
],
},
{
......
......@@ -116,12 +116,12 @@ OutputFile NinjaHelper::GetTargetOutputFile(const Target* target) const {
// This is prepended to the output file name.
const char* prefix;
if (target->settings()->IsWin() ||
target->output_type() == Target::EXECUTABLE) {
prefix = "";
} else {
if (!target->settings()->IsWin() &&
(target->output_type() == Target::SHARED_LIBRARY ||
target->output_type() == Target::STATIC_LIBRARY))
prefix = "lib";
}
else
prefix = "";
const char* extension;
if (target->output_type() == Target::NONE ||
......
......@@ -229,6 +229,15 @@ void NinjaTargetWriter::WriteCustomRules() {
// Precompute the common dependencies for each step. This includes the
// script itself (changing the script should force a rebuild) and any data
// files.
//
// TODO(brettW) this needs to be re-thought. "data" is supposed to be runtime
// data (i.e. for tests and such) rather than compile-time dependencies for
// each target. If we really need this, we need to have a different way to
// express it.
//
// One idea: add an "inputs" variable to specify this kind of thing. We
// should probably make it an error to specify data but no inputs for a
// script as a way to catch people doing the wrong way.
std::ostringstream common_deps_stream;
path_output_.WriteFile(common_deps_stream, target_->script());
const Target::FileList& datas = target_->data();
......@@ -457,9 +466,40 @@ void NinjaTargetWriter::WriteLinkerStuff(
internal_output_file = external_output_file;
}
// TODO(brettw) should we append data files to this?
// In Python see "self.ninja.build(output, command, input,"
WriteLinkCommand(external_output_file, internal_output_file, object_files);
if (target_->output_type() == Target::SHARED_LIBRARY) {
out_ << " soname = ";
path_output_.WriteFile(out_, internal_output_file);
out_ << std::endl;
out_ << " lib = ";
path_output_.WriteFile(out_, internal_output_file);
out_ << std::endl;
out_ << " dll = ";
path_output_.WriteFile(out_, internal_output_file);
out_ << std::endl;
if (settings_->IsWin()) {
out_ << " implibflag = /IMPLIB:";
path_output_.WriteFile(out_, external_output_file);
out_ << std::endl;
}
// TODO(brettw) postbuild steps.
if (settings_->IsMac())
out_ << " postbuilds = $ && (export BUILT_PRODUCTS_DIR=/Users/brettw/prj/src/out/gn; export CONFIGURATION=Debug; export DYLIB_INSTALL_NAME_BASE=@rpath; export EXECUTABLE_NAME=libbase.dylib; export EXECUTABLE_PATH=libbase.dylib; export FULL_PRODUCT_NAME=libbase.dylib; export LD_DYLIB_INSTALL_NAME=@rpath/libbase.dylib; export MACH_O_TYPE=mh_dylib; export PRODUCT_NAME=base; export PRODUCT_TYPE=com.apple.product-type.library.dynamic; export SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk; export SRCROOT=/Users/brettw/prj/src/out/gn/../../base; export SOURCE_ROOT=\"$${SRCROOT}\"; export TARGET_BUILD_DIR=/Users/brettw/prj/src/out/gn; export TEMP_DIR=\"$${TMPDIR}\"; (cd ../../base && ../build/mac/strip_from_xcode); G=$$?; ((exit $$G) || rm -rf libbase.dylib) && exit $$G)";
}
out_ << std::endl;
}
void NinjaTargetWriter::WriteLinkCommand(
const OutputFile& external_output_file,
const OutputFile& internal_output_file,
const std::vector<OutputFile>& object_files) {
out_ << "build ";
path_output_.WriteFile(out_, internal_output_file);
if (external_output_file != internal_output_file) {
......@@ -467,58 +507,69 @@ void NinjaTargetWriter::WriteLinkerStuff(
path_output_.WriteFile(out_, external_output_file);
}
out_ << ": " << GetCommandForTargetType();
// Object files.
for (size_t i = 0; i < object_files.size(); i++) {
out_ << " ";
path_output_.WriteFile(out_, object_files[i]);
}
if (target_->output_type() == Target::EXECUTABLE ||
target_->output_type() == Target::SHARED_LIBRARY ||
target_->output_type() == Target::LOADABLE_MODULE) {
// Library inputs (deps and inherited static libraries).
//
// Static libraries since they're just a collection of the object files so
// don't need libraries linked with them, but we still need to go through
// the list and find non-linkable data deps in the "deps" section. We'll
// collect all non-linkable deps and put it in the order-only deps below.
std::vector<const Target*> extra_data_deps;
const std::vector<const Target*>& deps = target_->deps();
const std::set<const Target*>& inherited = target_->inherited_libraries();
// Now append linkable libraries to the linker command.
for (size_t i = 0; i < deps.size(); i++) {
if (deps[i]->IsLinkable() &&
inherited.find(deps[i]) == inherited.end()) {
if (inherited.find(deps[i]) != inherited.end())
continue;
if (target_->output_type() != Target::STATIC_LIBRARY &&
deps[i]->IsLinkable()) {
out_ << " ";
path_output_.WriteFile(out_,
helper_.GetTargetOutputFile(target_->deps()[i]));
path_output_.WriteFile(out_, helper_.GetTargetOutputFile(deps[i]));
} else {
extra_data_deps.push_back(deps[i]);
}
}
for (std::set<const Target*>::const_iterator i = inherited.begin();
i != inherited.end(); ++i) {
if (target_->output_type() == Target::STATIC_LIBRARY) {
extra_data_deps.push_back(*i);
} else {
out_ << " ";
path_output_.WriteFile(out_, helper_.GetTargetOutputFile(*i));
}
}
out_ << std::endl;
if (target_->output_type() == Target::SHARED_LIBRARY) {
out_ << " soname = ";
path_output_.WriteFile(out_, internal_output_file);
out_ << std::endl;
out_ << " lib = ";
path_output_.WriteFile(out_, internal_output_file);
out_ << std::endl;
// Append data dependencies as order-only dependencies.
const std::vector<const Target*>& datadeps = target_->datadeps();
const std::vector<SourceFile>& data = target_->data();
if (!extra_data_deps.empty() || !datadeps.empty() || !data.empty()) {
out_ << " ||";
out_ << " dll = ";
path_output_.WriteFile(out_, internal_output_file);
out_ << std::endl;
if (settings_->IsWin()) {
out_ << " implibflag = /IMPLIB:";
path_output_.WriteFile(out_, external_output_file);
out_ << std::endl;
// Non-linkable deps in the deps section above.
for (size_t i = 0; i < extra_data_deps.size(); i++) {
out_ << " ";
path_output_.WriteFile(out_,
helper_.GetTargetOutputFile(extra_data_deps[i]));
}
// TODO(brettw) postbuild steps.
if (settings_->IsMac())
out_ << " postbuilds = $ && (export BUILT_PRODUCTS_DIR=/Users/brettw/prj/src/out/gn; export CONFIGURATION=Debug; export DYLIB_INSTALL_NAME_BASE=@rpath; export EXECUTABLE_NAME=libbase.dylib; export EXECUTABLE_PATH=libbase.dylib; export FULL_PRODUCT_NAME=libbase.dylib; export LD_DYLIB_INSTALL_NAME=@rpath/libbase.dylib; export MACH_O_TYPE=mh_dylib; export PRODUCT_NAME=base; export PRODUCT_TYPE=com.apple.product-type.library.dynamic; export SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk; export SRCROOT=/Users/brettw/prj/src/out/gn/../../base; export SOURCE_ROOT=\"$${SRCROOT}\"; export TARGET_BUILD_DIR=/Users/brettw/prj/src/out/gn; export TEMP_DIR=\"$${TMPDIR}\"; (cd ../../base && ../build/mac/strip_from_xcode); G=$$?; ((exit $$G) || rm -rf libbase.dylib) && exit $$G)";
// Data deps.
for (size_t i = 0; i < datadeps.size(); i++) {
out_ << " ";
path_output_.WriteFile(out_, helper_.GetTargetOutputFile(datadeps[i]));
}
// Data files.
const std::vector<SourceFile>& data = target_->data();
for (size_t i = 0; i < data.size(); i++) {
out_ << " ";
path_output_.WriteFile(out_, data[i]);
}
}
out_ << std::endl;
}
......
......@@ -49,6 +49,11 @@ class NinjaTargetWriter {
void WriteSources(std::vector<OutputFile>* object_files);
void WriteLinkerStuff(const std::vector<OutputFile>& object_files);
// Writes the build line for linking the target. Includes newline.
void WriteLinkCommand(const OutputFile& external_output_file,
const OutputFile& internal_output_file,
const std::vector<OutputFile>& object_files);
// Returns NULL if the source type should not be compiled on this target.
const char* GetCommandForSourceType(SourceFileType type) const;
......
......@@ -29,6 +29,12 @@ bool NinjaWriter::WriteRootBuildfiles() {
std::vector<const Target*> all_targets;
build_settings_->target_manager().GetAllTargets(&all_targets);
if (all_targets.empty()) {
Err(Location(), "No targets.",
"I could not find any targets to write, so I'm doing nothing.")
.PrintToStdout();
return false;
}
for (size_t i = 0; i < all_targets.size(); i++) {
categorized[all_targets[i]->label().GetToolchainLabel()].push_back(
all_targets[i]);
......@@ -54,11 +60,19 @@ bool NinjaWriter::WriteRootBuildfiles() {
if (i->first == default_label)
default_targets = &i->second;
all_settings.push_back(settings);
if (!NinjaToolchainWriter::RunAndWriteFile(settings, i->second))
if (!NinjaToolchainWriter::RunAndWriteFile(settings, i->second)) {
Err(Location(),
"Couldn't open toolchain buildfile(s) for writing").PrintToStdout();
return false;
}
}
// Write the root buildfile.
return NinjaBuildWriter::RunAndWriteFile(build_settings_, all_settings,
*default_targets);
if (!NinjaBuildWriter::RunAndWriteFile(build_settings_, all_settings,
*default_targets)) {
Err(Location(),
"Couldn't open toolchain buildfile(s) for writing").PrintToStdout();
return false;
}
return true;
}
......@@ -11,6 +11,7 @@ class BuildSettings;
class NinjaWriter {
public:
// On failure will print an error and will return false.
static bool RunAndWriteFiles(const BuildSettings* build_settings);
private:
......
......@@ -9,29 +9,7 @@
#include "tools/gn/source_file.h"
#include "tools/gn/toolchain_manager.h"
#include "tools/gn/value.h"
const char* ScopePerFileProvider::kDefaultToolchain =
"default_toolchain";
const char* ScopePerFileProvider::kPythonPath =
"python_path";
const char* ScopePerFileProvider::kToolchain =
"toolchain";
const char* ScopePerFileProvider::kRootOutputDirName =
"root_output_dir";
const char* ScopePerFileProvider::kRootGenDirName =
"root_gen_dir";
const char* ScopePerFileProvider::kTargetOutputDirName =
"target_output_dir";
const char* ScopePerFileProvider::kTargetGenDirName =
"target_gen_dir";
const char* ScopePerFileProvider::kRelativeRootOutputDirName =
"relative_root_output_dir";
const char* ScopePerFileProvider::kRelativeRootGenDirName =
"relative_root_gen_dir";
const char* ScopePerFileProvider::kRelativeTargetOutputDirName =
"relative_target_output_dir";
const char* ScopePerFileProvider::kRelativeTargetGenDirName =
"relative_target_gen_dir";
#include "tools/gn/variables.h"
ScopePerFileProvider::ScopePerFileProvider(Scope* scope,
const SourceFile& source_file)
......@@ -44,35 +22,30 @@ ScopePerFileProvider::~ScopePerFileProvider() {
const Value* ScopePerFileProvider::GetProgrammaticValue(
const base::StringPiece& ident) {
if (ident == kDefaultToolchain)
if (ident == variables::kCurrentToolchain)
return GetCurrentToolchain();
if (ident == variables::kDefaultToolchain)
return GetDefaultToolchain();
if (ident == kPythonPath)
if (ident == variables::kPythonPath)
return GetPythonPath();
if (ident == kTargetOutputDirName)
return GetTargetOutputDir();
if (ident == kTargetGenDirName)
return GetTargetGenDir();
if (ident == kRelativeRootOutputDirName)
if (ident == variables::kRelativeRootOutputDir)
return GetRelativeRootOutputDir();
if (ident == kRelativeRootGenDirName)
if (ident == variables::kRelativeRootGenDir)
return GetRelativeRootGenDir();
if (ident == kRelativeTargetOutputDirName)
if (ident == variables::kRelativeTargetOutputDir)
return GetRelativeTargetOutputDir();
if (ident == kRelativeTargetGenDirName)
if (ident == variables::kRelativeTargetGenDir)
return GetRelativeTargetGenDir();
return NULL;
}
// static
Value ScopePerFileProvider::GetRootOutputDir(const Settings* settings) {
return Value(NULL, GetRootOutputDirWithNoLastSlash(settings));
}
// static
Value ScopePerFileProvider::GetRootGenDir(const Settings* settings) {
return Value(NULL, GetRootGenDirWithNoLastSlash(settings));
const Value* ScopePerFileProvider::GetCurrentToolchain() {
if (!current_toolchain_) {
current_toolchain_.reset(new Value(NULL,
scope_->settings()->toolchain()->label().GetUserVisibleName(false)));
}
return current_toolchain_.get();
}
const Value* ScopePerFileProvider::GetDefaultToolchain() {
......@@ -94,32 +67,6 @@ const Value* ScopePerFileProvider::GetPythonPath() {
return python_path_.get();
}
const Value* ScopePerFileProvider::GetToolchain() {
if (!toolchain_) {
toolchain_.reset(new Value(NULL,
scope_->settings()->toolchain()->label().GetUserVisibleName(false)));
}
return toolchain_.get();
}
const Value* ScopePerFileProvider::GetTargetOutputDir() {
if (!target_output_dir_) {
target_output_dir_.reset(new Value(NULL,
GetRootOutputDirWithNoLastSlash(scope_->settings()) +
GetFileDirWithNoLastSlash()));
}
return target_output_dir_.get();
}
const Value* ScopePerFileProvider::GetTargetGenDir() {
if (!target_output_dir_) {
target_gen_dir_.reset(new Value(NULL,
GetRootGenDirWithNoLastSlash(scope_->settings()) +
GetFileDirWithNoLastSlash()));
}
return target_gen_dir_.get();
}
const Value* ScopePerFileProvider::GetRelativeRootOutputDir() {
if (!relative_root_output_dir_) {
relative_root_output_dir_.reset(new Value(NULL,
......@@ -164,7 +111,7 @@ std::string ScopePerFileProvider::GetRootOutputDirWithNoLastSlash(
const std::string& output_dir =
settings->build_settings()->build_dir().value();
CHECK(!output_dir.empty());
return output_dir.substr(0, output_dir.size() - 1);
return output_dir.substr(1, output_dir.size() - 1);
}
// static
......
......@@ -21,34 +21,10 @@ class ScopePerFileProvider : public Scope::ProgrammaticProvider {
virtual const Value* GetProgrammaticValue(
const base::StringPiece& ident) OVERRIDE;
// Returns the value to expose to script for the given thing. These values
// are acually set globally, but are put here so we can keep all logic
// for converting paths to built-in values in this one file.
static Value GetRootOutputDir(const Settings* settings);
static Value GetRootGenDir(const Settings* settings);
// Variable names. These two should be set globally independent of the file
// being processed.
static const char* kRootOutputDirName;
static const char* kRootGenDirName;
// Variable names. These are provided by this class as needed.
static const char* kDefaultToolchain;
static const char* kPythonPath;
static const char* kToolchain;
static const char* kTargetOutputDirName;
static const char* kTargetGenDirName;
static const char* kRelativeRootOutputDirName;
static const char* kRelativeRootGenDirName;
static const char* kRelativeTargetOutputDirName;
static const char* kRelativeTargetGenDirName;
private:
const Value* GetCurrentToolchain();
const Value* GetDefaultToolchain();
const Value* GetPythonPath();
const Value* GetToolchain();
const Value* GetTargetOutputDir();
const Value* GetTargetGenDir();
const Value* GetRelativeRootOutputDir();
const Value* GetRelativeRootGenDir();
const Value* GetRelativeTargetOutputDir();
......@@ -63,11 +39,9 @@ class ScopePerFileProvider : public Scope::ProgrammaticProvider {
SourceFile source_file_;
// All values are lazily created.
scoped_ptr<Value> current_toolchain_;
scoped_ptr<Value> default_toolchain_;
scoped_ptr<Value> python_path_;
scoped_ptr<Value> toolchain_;
scoped_ptr<Value> target_output_dir_;
scoped_ptr<Value> target_gen_dir_;
scoped_ptr<Value> relative_root_output_dir_;
scoped_ptr<Value> relative_root_gen_dir_;
scoped_ptr<Value> relative_target_output_dir_;
......
......@@ -382,12 +382,16 @@ component("base") {
"posix/unix_domain_socket_linux.h",
"power_monitor/power_monitor.cc",
"power_monitor/power_monitor.h",
"power_monitor/power_monitor_android.cc",
"power_monitor/power_monitor_android.h",
"power_monitor/power_monitor_ios.mm",
"power_monitor/power_monitor_mac.mm",
"power_monitor/power_monitor_posix.cc",
"power_monitor/power_monitor_win.cc",
"power_monitor/power_monitor_device_source.cc",
"power_monitor/power_monitor_device_source.h",
"power_monitor/power_monitor_device_source_android.cc",
"power_monitor/power_monitor_device_source_android.h",
"power_monitor/power_monitor_device_source_ios.mm",
"power_monitor/power_monitor_device_source_mac.mm",
"power_monitor/power_monitor_device_source_posix.cc",
"power_monitor/power_monitor_device_source_win.cc",
"power_monitor/power_monitor_source.cc",
"power_monitor/power_monitor_source.h",
"power_monitor/power_observer.h",
"process/internal_linux.cc",
"process/internal_linux.h",
......
......@@ -40,23 +40,17 @@ toolchain("clang") {
deps = "gcc"
}
tool("alink") {
command = "rm -f \$out && ./gyp-mac-tool filter-libtool libtool \$libtool_flags -static -o \$out \$in\$postbuilds"
command = "rm -f \$out && ./gyp-mac-tool filter-libtool libtool \$libtool_flags -static -o \$out \$in \$postbuilds"
description = "LIBTOOL-STATIC \$out, POSTBUILDS"
}
tool("solink") {
command = "if [ ! -e \$lib -o ! -e \${lib}.TOC ] || otool -l \$lib | grep -q LC_REEXPORT_DYLIB ; then $ld -shared \$ldflags -o \$lib \$in \$solibs \$libs\$postbuilds && { otool -l \$lib | grep LC_ID_DYLIB -A 5; nm -gP \$lib | cut -f1-2 -d' ' | grep -v U\$\$; true; } > \${lib}.TOC; else $ld -shared \$ldflags -o \$lib \$in \$solibs \$libs\$postbuilds && { otool -l \$lib | grep LC_ID_DYLIB -A 5; nm -gP \$lib | cut -f1-2 -d' ' | grep -v U\$\$; true; } > \${lib}.tmp && if ! cmp -s \${lib}.tmp \${lib}.TOC; then mv \${lib}.tmp \${lib}.TOC ; fi; fi"
command = "if [ ! -e \$lib -o ! -e \${lib}.TOC ] || otool -l \$lib | grep -q LC_REEXPORT_DYLIB ; then $ld -shared \$ldflags -o \$lib \$in \$solibs \$libs \$postbuilds && { otool -l \$lib | grep LC_ID_DYLIB -A 5; nm -gP \$lib | cut -f1-2 -d' ' | grep -v U\$\$; true; } > \${lib}.TOC; else $ld -shared \$ldflags -o \$lib \$in \$solibs \$libs \$postbuilds && { otool -l \$lib | grep LC_ID_DYLIB -A 5; nm -gP \$lib | cut -f1-2 -d' ' | grep -v U\$\$; true; } > \${lib}.tmp && if ! cmp -s \${lib}.tmp \${lib}.TOC; then mv \${lib}.tmp \${lib}.TOC ; fi; fi"
description = "SOLINK \$lib, POSTBUILDS"
#pool = "link_pool"
restat = "1"
}
tool("solink_module") {
command = "if [ ! -e \$lib -o ! -e \${lib}.TOC ] || otool -l \$lib | grep -q LC_REEXPORT_DYLIB ; then $ld -shared \$ldflags -o \$lib \$in \$solibs \$libs\$postbuilds && { otool -l \$lib | grep LC_ID_DYLIB -A 5; nm -gP \$lib | cut -f1-2 -d' ' | grep -v U\$\$; true; } > \${lib}.TOC; else $ld -shared \$ldflags -o \$lib \$in \$solibs \$libs\$postbuilds && { otool -l \$lib | grep LC_ID_DYLIB -A 5; nm -gP \$lib | cut -f1-2 -d' ' | grep -v U\$\$; true; } > \${lib}.tmp && if ! cmp -s \${lib}.tmp \${lib}.TOC; then mv \${lib}.tmp \${lib}.TOC ; fi; fi"
description = "SOLINK(module) \$lib, POSTBUILDS"
#pool = "link_pool"
restat = "1"
}
tool("link") {
command = "$ld \$ldflags -o \$out \$in \$solibs \$libs\$postbuilds"
command = "$ld \$ldflags -o \$out \$in \$solibs \$libs \$postbuilds"
description = "LINK \$out, POSTBUILDS"
#pool = "link_pool"
}
......@@ -69,7 +63,7 @@ toolchain("clang") {
# description = "MACTOOL \$mactool_cmd \$in"
#}
#tool("package_framework") {
# command = "./gyp-mac-tool package-framework \$out \$version\$postbuilds && touch \$out"
# command = "./gyp-mac-tool package-framework \$out \$version \$postbuilds && touch \$out"
# description = "PACKAGE FRAMEWORK \$out, POSTBUILDS"
#}
tool("stamp") {
......
......@@ -64,9 +64,14 @@ class Target : public Item {
const FileList& data() const { return data_; }
void swap_in_data(FileList* d) { data_.swap(*d); }
// Linked dependencies.
const std::vector<const Target*>& deps() const { return deps_; }
void swap_in_deps(std::vector<const Target*>* d) { deps_.swap(*d); }
// Non-linked dependencies.
const std::vector<const Target*>& datadeps() const { return datadeps_; }
void swap_in_datadeps(std::vector<const Target*>* d) { datadeps_.swap(*d); }
// List of configs that this class inherits settings from.
const std::vector<const Config*>& configs() const { return configs_; }
void swap_in_configs(std::vector<const Config*>* c) { configs_.swap(*c); }
......@@ -118,6 +123,7 @@ class Target : public Item {
FileList sources_;
FileList data_;
std::vector<const Target*> deps_;
std::vector<const Target*> datadeps_;
std::vector<const Config*> configs_;
std::vector<const Config*> all_dependent_configs_;
std::vector<const Config*> direct_dependent_configs_;
......
......@@ -22,6 +22,7 @@
#include "tools/gn/token.h"
#include "tools/gn/value.h"
#include "tools/gn/value_extractors.h"
#include "tools/gn/variables.h"
namespace {
......@@ -98,6 +99,7 @@ void TargetGenerator::Run() {
if (TypeHasOutputs(output_type))
FillOutputs();
FillDependencies(); // All types have dependencies.
FillDataDependencies(); // All types have dependencies.
if (TypeHasConfigValues(output_type)) {
ConfigValuesGenerator gen(&target_->config_values(), scope_,
......@@ -208,22 +210,46 @@ void TargetGenerator::FillGenericConfigs(
(target_->*setter)(&dest_configs);
}
void TargetGenerator::FillGenericDeps(
const char* var_name,
void (Target::*setter)(std::vector<const Target*>*)) {
const Value* value = scope_->GetValue(var_name, true);
if (!value)
return;
std::vector<Label> labels;
if (!ExtractListOfLabels(*value, input_directory_,
ToolchainLabelForScope(scope_), &labels, err_))
return;
std::vector<const Target*> dest_deps;
dest_deps.resize(labels.size());
for (size_t i = 0; i < labels.size(); i++) {
dest_deps[i] = GetBuildSettings()->target_manager().GetTarget(
labels[i], value->list_value()[i].origin()->GetRange(), target_, err_);
if (err_->has_error())
return;
}
(target_->*setter)(&dest_deps);
}
void TargetGenerator::FillConfigs() {
FillGenericConfigs("configs", &Target::swap_in_configs);
FillGenericConfigs(variables::kConfigs, &Target::swap_in_configs);
}
void TargetGenerator::FillAllDependentConfigs() {
FillGenericConfigs("all_dependent_configs",
FillGenericConfigs(variables::kAllDependentConfigs,
&Target::swap_in_all_dependent_configs);
}
void TargetGenerator::FillDirectDependentConfigs() {
FillGenericConfigs("direct_dependent_configs",
FillGenericConfigs(variables::kDirectDependentConfigs,
&Target::swap_in_direct_dependent_configs);
}
void TargetGenerator::FillSources() {
const Value* value = scope_->GetValue("sources", true);
const Value* value = scope_->GetValue(variables::kSources, true);
if (!value)
return;
......@@ -235,6 +261,8 @@ void TargetGenerator::FillSources() {
}
void TargetGenerator::FillData() {
// TODO(brettW) hook this up to the constant when we have cleaned up
// how data files are used.
const Value* value = scope_->GetValue("data", true);
if (!value)
return;
......@@ -247,25 +275,11 @@ void TargetGenerator::FillData() {
}
void TargetGenerator::FillDependencies() {
const Value* value = scope_->GetValue("deps", true);
if (!value)
return;
std::vector<Label> labels;
if (!ExtractListOfLabels(*value, input_directory_,
ToolchainLabelForScope(scope_), &labels, err_))
return;
std::vector<const Target*> dest_deps;
dest_deps.resize(labels.size());
for (size_t i = 0; i < labels.size(); i++) {
dest_deps[i] = GetBuildSettings()->target_manager().GetTarget(
labels[i], value->list_value()[i].origin()->GetRange(), target_, err_);
if (err_->has_error())
return;
}
FillGenericDeps(variables::kDeps, &Target::swap_in_deps);
}
target_->swap_in_deps(&dest_deps);
void TargetGenerator::FillDataDependencies() {
FillGenericDeps(variables::kDatadeps, &Target::swap_in_datadeps);
}
void TargetGenerator::FillDestDir() {
......
......@@ -46,10 +46,12 @@ class TargetGenerator {
// Sets err_ on failure.
Target::OutputType GetOutputType() const;
// Reads configs from the given var name, and uses the given setting on the
// target to save them
// Reads configs/deps from the given var name, and uses the given setting on
// the target to save them.
void FillGenericConfigs(const char* var_name,
void (Target::*setter)(std::vector<const Config*>*));
void FillGenericDeps(const char* var_name,
void (Target::*setter)(std::vector<const Target*>*));
void FillConfigs();
void FillAllDependentConfigs();
......@@ -57,6 +59,7 @@ class TargetGenerator {
void FillSources();
void FillData();
void FillDependencies();
void FillDataDependencies();
void FillDestDir();
void FillScript();
void FillScriptArgs();
......
......@@ -13,7 +13,6 @@ const char* Toolchain::kToolObjCxx = "objcxx";
const char* Toolchain::kToolAsm = "asm";
const char* Toolchain::kToolAlink = "alink";
const char* Toolchain::kToolSolink = "solink";
const char* Toolchain::kToolSolinkModule = "solink_module";
const char* Toolchain::kToolLink = "link";
const char* Toolchain::kToolStamp = "stamp";
const char* Toolchain::kToolCopy = "copy";
......@@ -47,7 +46,6 @@ Toolchain::ToolType Toolchain::ToolNameToType(const base::StringPiece& str) {
if (str == kToolAsm) return TYPE_ASM;
if (str == kToolAlink) return TYPE_ALINK;
if (str == kToolSolink) return TYPE_SOLINK;
if (str == kToolSolinkModule) return TYPE_SOLINK_MODULE;
if (str == kToolLink) return TYPE_LINK;
if (str == kToolStamp) return TYPE_STAMP;
if (str == kToolCopy) return TYPE_COPY;
......@@ -64,7 +62,6 @@ std::string Toolchain::ToolTypeToName(ToolType type) {
case TYPE_ASM: return kToolAsm;
case TYPE_ALINK: return kToolAlink;
case TYPE_SOLINK: return kToolSolink;
case TYPE_SOLINK_MODULE: return kToolSolinkModule;
case TYPE_LINK: return kToolLink;
case TYPE_STAMP: return kToolStamp;
case TYPE_COPY: return kToolCopy;
......
......@@ -32,7 +32,6 @@ class Toolchain : public Item {
TYPE_ASM,
TYPE_ALINK,
TYPE_SOLINK,
TYPE_SOLINK_MODULE,
TYPE_LINK,
TYPE_STAMP,
TYPE_COPY,
......@@ -47,7 +46,6 @@ class Toolchain : public Item {
static const char* kToolAsm;
static const char* kToolAlink;
static const char* kToolSolink;
static const char* kToolSolinkModule;
static const char* kToolLink;
static const char* kToolStamp;
static const char* kToolCopy;
......
......@@ -43,15 +43,6 @@ void SetSystemVars(const Settings& settings, Scope* scope) {
#else
scope->SetValue("is_linux", Value(NULL, 0), NULL);
#endif
// Set this value without the terminating slash because the code expects
// $root_output_dir/foo to work.
scope->SetValue(ScopePerFileProvider::kRootOutputDirName,
ScopePerFileProvider::GetRootOutputDir(&settings),
NULL);
scope->SetValue(ScopePerFileProvider::kRootGenDirName,
ScopePerFileProvider::GetRootGenDir(&settings),
NULL);
}
} // namespace
......
This diff is collapsed.
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef TOOLS_GN_VARIABLES_H_
#define TOOLS_GN_VARIABLES_H_
#include <map>
#include "base/strings/string_piece.h"
namespace variables {
// Builtin vars ----------------------------------------------------------------
extern const char kCurrentToolchain[];
extern const char kCurrentToolchain_HelpShort[];
extern const char kCurrentToolchain_Help[];
extern const char kDefaultToolchain[];
extern const char kDefaultToolchain_HelpShort[];
extern const char kDefaultToolchain_Help[];
extern const char kPythonPath[];
extern const char kPythonPath_HelpShort[];
extern const char kPythonPath_Help[];
extern const char kRelativeRootGenDir[];
extern const char kRelativeRootGenDir_HelpShort[];
extern const char kRelativeRootGenDir_Help[];
extern const char kRelativeRootOutputDir[];
extern const char kRelativeRootOutputDir_HelpShort[];
extern const char kRelativeRootOutputDir_Help[];
extern const char kRelativeTargetGenDir[];
extern const char kRelativeTargetGenDir_HelpShort[];
extern const char kRelativeTargetGenDir_Help[];
extern const char kRelativeTargetOutputDir[];
extern const char kRelativeTargetOutputDir_HelpShort[];
extern const char kRelativeTargetOutputDir_Help[];
// Target vars -----------------------------------------------------------------
extern const char kAllDependentConfigs[];
extern const char kAllDependentConfigs_HelpShort[];
extern const char kAllDependentConfigs_Help[];
extern const char kCflags[];
extern const char kCflags_HelpShort[];
extern const char* kCflags_Help;
extern const char kCflagsC[];
extern const char kCflagsC_HelpShort[];
extern const char* kCflagsC_Help;
extern const char kCflagsCC[];
extern const char kCflagsCC_HelpShort[];
extern const char* kCflagsCC_Help;
extern const char kCflagsObjC[];
extern const char kCflagsObjC_HelpShort[];
extern const char* kCflagsObjC_Help;
extern const char kCflagsObjCC[];
extern const char kCflagsObjCC_HelpShort[];
extern const char* kCflagsObjCC_Help;
extern const char kConfigs[];
extern const char kConfigs_HelpShort[];
extern const char kConfigs_Help[];
extern const char kDatadeps[];
extern const char kDatadeps_HelpShort[];
extern const char kDatadeps_Help[];
extern const char kDefines[];
extern const char kDefines_HelpShort[];
extern const char kDefines_Help[];
extern const char kDeps[];
extern const char kDeps_HelpShort[];
extern const char kDeps_Help[];
extern const char kDirectDependentConfigs[];
extern const char kDirectDependentConfigs_HelpShort[];
extern const char kDirectDependentConfigs_Help[];
extern const char kLdflags[];
extern const char kLdflags_HelpShort[];
extern const char kLdflags_Help[];
extern const char kSources[];
extern const char kSources_HelpShort[];
extern const char kSources_Help[];
// -----------------------------------------------------------------------------
struct VariableInfo {
VariableInfo();
VariableInfo(const char* in_help_short,
const char* in_help);
const char* help_short;
const char* help;
};
typedef std::map<base::StringPiece, VariableInfo> VariableInfoMap;
// Returns the built-in readonly variables.
// Note: this is used only for help so this getter is not threadsafe.
const VariableInfoMap& GetBuiltinVariables();
// Returns the variables used by target generators.
// Note: this is used only for help so this getter is not threadsafe.
const VariableInfoMap& GetTargetVariables();
} // namespace variables
#endif // TOOLS_GN_VARIABLES_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment