-
Allan Sandfeld Jensen authored
Change-Id: Ia4a68eadbe3f37c8d200d6e82dfa8c55479aa55d Reviewed-by:
Alexandru Croitor <alexandru.croitor@qt.io>
a3e8625c
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
// 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.
#include "tools/gn/qmake_link_writer.h"
#include "tools/gn/deps_iterator.h"
#include "tools/gn/ninja_binary_target_writer.h"
#include "tools/gn/output_file.h"
#include "tools/gn/settings.h"
#include "tools/gn/target.h"
#include "tools/gn/config_values_extractors.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
QMakeLinkWriter::QMakeLinkWriter(const NinjaBinaryTargetWriter* writer, const Target* target, std::ostream& out)
: target_(target),
nwriter_(writer),
out_(out),
path_output_(target->settings()->build_settings()->build_dir(),
target->settings()->build_settings()->root_path_utf8(),
ESCAPE_NONE) {
}
QMakeLinkWriter::~QMakeLinkWriter() {
}
// Based on similar function in qt_creator_writer.cc
void CollectDeps(std::set<const Target*> &deps, const Target* target) {
for (const auto& dep : target->GetDeps(Target::DEPS_ALL)) {
const Target* dep_target = dep.ptr;
if (deps.count(dep_target))
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
continue;
deps.insert(dep_target);
CollectDeps(deps, dep_target);
}
}
void PrintSourceFile(std::ostream& out, PathOutput& path_output, const SourceFile& file) {
out << " \\\n \"";
if (file.is_source_absolute()) {
out << "$$PWD/";
path_output.WriteFile(out, file);
} else {
out << file.value();
}
out << "\"";
}
void QMakeLinkWriter::Run() {
CHECK(target_->output_type() == Target::SHARED_LIBRARY)
<< "QMakeLinkWriter only supports SHARED_LIBRARY";
std::vector<SourceFile> object_files;
std::vector<SourceFile> other_files;
std::vector<OutputFile> tool_outputs;
const Settings* settings = target_->settings();
object_files.reserve(target_->sources().size());
for (const auto& source : target_->sources()) {
Toolchain::ToolType tool_type = Toolchain::TYPE_NONE;
if (!target_->GetOutputFilesForSource(source, &tool_type, &tool_outputs)) {
if (GetSourceFileType(source) == SOURCE_DEF)
other_files.push_back(source);
continue; // No output for this source.
}
object_files.push_back(tool_outputs[0].AsSourceFile(settings->build_settings()));
}
UniqueVector<OutputFile> extra_object_files;
UniqueVector<const Target*> linkable_deps;
UniqueVector<const Target*> non_linkable_deps;
nwriter_->GetDeps(&extra_object_files, &linkable_deps, &non_linkable_deps);
std::set<const Target*> deps;
deps.insert(target_);
CollectDeps(deps, target_);
// sources files.
out_ << "NINJA_SOURCES =";
for (const auto& target : deps) {
for (const auto& file : target->sources()) {
PrintSourceFile(out_, path_output_, file);
}
}
out_ << std::endl;
// headers files.
out_ << "NINJA_HEADERS =";
for (const auto& target : deps) {
for (const auto& file : target->public_headers()) {
PrintSourceFile(out_, path_output_, file);
}
}
out_ << std::endl;
std::set<std::string> defines;
for (const auto& target : deps) {
for (ConfigValuesIterator it(target); !it.done(); it.Next()) {
for (std::string define : it.cur().defines()) {
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
defines.insert(define);
}
}
}
out_ << "NINJA_DEFINES =";
for (const auto& define : defines) {
out_ << " \\\n " << define;
}
out_ << std::endl;
// object files.
out_ << "NINJA_OBJECTS =";
for (const auto& file : object_files) {
out_ << " \\\n \"$$PWD/";
path_output_.WriteFile(out_, file);
out_ << "\"";
}
for (const auto& file : extra_object_files) {
out_ << " \\\n \"$$PWD/";
path_output_.WriteFile(out_, file);
out_ << "\"";
}
out_ << std::endl;
// linker flags
out_ << "NINJA_LFLAGS =";
EscapeOptions opts;
opts.mode = ESCAPE_COMMAND;
// First the ldflags from the target and its config.
RecursiveTargetConfigStringsToStream(target_, &ConfigValues::ldflags,
opts, out_);
out_ << std::endl;
// archives
out_ << "NINJA_ARCHIVES =";
std::vector<OutputFile> solibs;
for (const Target* cur : linkable_deps) {
if (cur->dependency_output_file().value() !=
cur->link_output_file().value()) {
solibs.push_back(cur->link_output_file());
} else {
out_ << " \\\n \"$$PWD/";
path_output_.WriteFile(out_, cur->link_output_file());
out_ << "\"";
}
}
out_ << std::endl;
// library dirs
const OrderedSet<SourceDir> all_lib_dirs = target_->all_lib_dirs();
const Tool* tool = target_->toolchain()->GetToolForTargetFinalOutput(target_);
if (!all_lib_dirs.empty()) {
out_ << "NINJA_LIB_DIRS =";
PathOutput lib_path_output(path_output_.current_dir(),
settings->build_settings()->root_path_utf8(),
ESCAPE_COMMAND);
for (size_t i = 0; i < all_lib_dirs.size(); i++) {
out_ << " " << tool->lib_dir_switch();
lib_path_output.WriteDir(out_, all_lib_dirs[i],
PathOutput::DIR_NO_LAST_SLASH);
}
}
out_ << std::endl;
//libs
out_ << "NINJA_LIBS =";
EscapeOptions lib_escape_opts;
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
lib_escape_opts.mode = ESCAPE_COMMAND;
const OrderedSet<LibFile> all_libs = target_->all_libs();
const std::string framework_ending(".framework");
for (size_t i = 0; i < all_libs.size(); i++) {
const LibFile& lib_file = all_libs[i];
const std::string& lib_value = lib_file.value();
if (lib_file.is_source_file()) {
out_ << " ";
PathOutput lib_path_output(settings->build_settings()->build_dir(),
settings->build_settings()->root_path_utf8(),
ESCAPE_COMMAND);
lib_path_output.WriteFile(out_, lib_file.source_file());
} else if (base::EndsWith(lib_value, framework_ending,
base::CompareCase::INSENSITIVE_ASCII)) {
out_ << " -framework ";
EscapeStringToStream(
out_, lib_value.substr(0, lib_value.size() - framework_ending.size()),
lib_escape_opts);
} else {
out_ << " " << tool->lib_switch();
EscapeStringToStream(out_, lib_value, lib_escape_opts);
}
}
out_ << std::endl;
// solibs
if (!solibs.empty()) {
out_ << "NINJA_SOLIBS =";
for (const auto& file : solibs) {
out_ << " \"$$PWD/";
path_output_.WriteFile(out_, file);
out_ << "\"";
}
out_ << std::endl;
}
//targetdeps
out_ << "NINJA_TARGETDEPS = ";
path_output_.WriteFile(out_, OutputFile("\"$$PWD/" + target_->label().name() + ".stamp\""));
out_ << std::endl;
}