From bf984d5f24741a52a70024f3f43432307281f0ae Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 9 May 2012 15:29:25 +0200 Subject: add $$shadowed() function return the build directory corresponding to a given source directory. this is the identity function if not shadow-building. if input lies outside the source directory, return empty value. Change-Id: I2d2a6b1112bd19989fe29cfe19a12d39a0d208c1 Reviewed-by: Marius Storm-Olsen --- qmake/main.cpp | 2 ++ qmake/option.cpp | 25 ++++++++++++++++++++++ qmake/option.h | 3 +++ qmake/project.cpp | 11 +++++++++- .../tools/qmake/testdata/functions/functions.pro | 1 + tests/auto/tools/qmake/tst_qmake.cpp | 3 ++- 6 files changed, 43 insertions(+), 2 deletions(-) diff --git a/qmake/main.cpp b/qmake/main.cpp index 38e09f60fd..45672c67ee 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -163,6 +163,8 @@ int runQMake(int argc, char **argv) fn = fn.right(fn.length() - di - 1); } + Option::prepareProject(fn); + // read project.. if(!project.read(fn)) { fprintf(stderr, "Error processing project file: %s\n", diff --git a/qmake/option.cpp b/qmake/option.cpp index 836cc3f492..a22d184456 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -115,6 +115,8 @@ bool Option::mkfile::do_dep_heuristics = true; bool Option::mkfile::do_preprocess = false; bool Option::mkfile::do_stub_makefile = false; bool Option::mkfile::do_cache = true; +QString Option::mkfile::source_root; +QString Option::mkfile::build_root; QString Option::mkfile::cachefile; QStringList Option::mkfile::project_files; QString Option::mkfile::qmakespec_commandline; @@ -594,6 +596,29 @@ void Option::applyHostMode() } } +void Option::prepareProject(const QString &pfile) +{ + QString srcpath = (pfile != "-") + ? QDir::cleanPath(QFileInfo(pfile).absolutePath()) : qmake_getpwd(); + if (srcpath != output_dir) { + if (!srcpath.endsWith(QLatin1Char('/'))) + srcpath += QLatin1Char('/'); + QString dstpath = output_dir; + if (!dstpath.endsWith(QLatin1Char('/'))) + dstpath += QLatin1Char('/'); + int srcLen = srcpath.length(); + int dstLen = dstpath.length(); + int lastSl = 0; + while (++lastSl, srcpath.at(--srcLen) == dstpath.at(--dstLen)) + if (srcpath.at(srcLen) == QLatin1Char('/')) + lastSl = 1; + mkfile::source_root = srcpath.left(srcLen + lastSl); + mkfile::build_root = dstpath.left(dstLen + lastSl); + } else { + mkfile::source_root.clear(); + } +} + bool Option::postProcessProject(QMakeProject *project) { Option::cpp_ext = project->variables()["QMAKE_EXT_CPP"]; diff --git a/qmake/option.h b/qmake/option.h index f6f5dbbb9d..c58ef4aed0 100644 --- a/qmake/option.h +++ b/qmake/option.h @@ -109,6 +109,7 @@ struct Option //both of these must be called.. static int init(int argc=0, char **argv=0); //parse cmdline static void applyHostMode(); + static void prepareProject(const QString &pfile); static bool postProcessProject(QMakeProject *); enum StringFixFlags { @@ -203,6 +204,8 @@ struct Option static bool do_dep_heuristics; static bool do_preprocess; static bool do_stub_makefile; + static QString source_root; + static QString build_root; static QString cachefile; static int cachefile_depth; static QStringList project_files; diff --git a/qmake/project.cpp b/qmake/project.cpp index 1df4bf0200..de010faeb8 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -81,7 +81,8 @@ enum ExpandFunc { E_MEMBER=1, E_FIRST, E_LAST, E_CAT, E_FROMFILE, E_EVAL, E_LIST E_SPRINTF, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION, E_FIND, E_SYSTEM, E_UNIQUE, E_QUOTE, E_ESCAPE_EXPAND, E_UPPER, E_LOWER, E_FILES, E_PROMPT, E_RE_ESCAPE, E_VAL_ESCAPE, E_REPLACE, - E_SIZE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS }; + E_SIZE, E_SORT_DEPENDS, E_RESOLVE_DEPENDS, E_ENUMERATE_VARS, + E_SHADOWED }; QHash qmake_expandFunctions() { static QHash *qmake_expand_functions = 0; @@ -117,6 +118,7 @@ QHash qmake_expandFunctions() qmake_expand_functions->insert("sort_depends", E_SORT_DEPENDS); qmake_expand_functions->insert("resolve_depends", E_RESOLVE_DEPENDS); qmake_expand_functions->insert("enumerate_vars", E_ENUMERATE_VARS); + qmake_expand_functions->insert("shadowed", E_SHADOWED); } return *qmake_expand_functions; } @@ -2493,6 +2495,13 @@ QMakeProject::doProjectExpand(QString func, QList args_list, case E_ENUMERATE_VARS: ret += place.keys(); break; + case E_SHADOWED: { + QString val = QDir::cleanPath(QFileInfo(args.at(0)).absoluteFilePath()); + if (Option::mkfile::source_root.isEmpty()) + ret += val; + else if (val.startsWith(Option::mkfile::source_root)) + ret += Option::mkfile::build_root + val.mid(Option::mkfile::source_root.length()); + break; } default: { fprintf(stderr, "%s:%d: Unknown replace function: %s\n", parser.file.toLatin1().constData(), parser.line_no, diff --git a/tests/auto/tools/qmake/testdata/functions/functions.pro b/tests/auto/tools/qmake/testdata/functions/functions.pro index 7792859327..0b70b24158 100644 --- a/tests/auto/tools/qmake/testdata/functions/functions.pro +++ b/tests/auto/tools/qmake/testdata/functions/functions.pro @@ -112,3 +112,4 @@ in = easy "less easy" sca$${LITERAL_HASH}ry crazy$$escape_expand(\\t\\r\\n) $$es out = "easy \"less easy\" sca\$\${LITERAL_HASH}ry crazy\$\$escape_expand(\\\\t\\\\r\\\\n) \$\$escape_expand(\\\\t)shit \\\'no\\\"way\\\\here" testReplace($$val_escape(in), $$out, "val_escape") +testReplace($$shadowed($$PWD/something), $$OUT_PWD/something, "shadowed") diff --git a/tests/auto/tools/qmake/tst_qmake.cpp b/tests/auto/tools/qmake/tst_qmake.cpp index 88ff10a764..1cdf0d7c7e 100644 --- a/tests/auto/tools/qmake/tst_qmake.cpp +++ b/tests/auto/tools/qmake/tst_qmake.cpp @@ -250,7 +250,8 @@ void tst_qmake::subdir_via_pro_file_extra_target() void tst_qmake::functions() { QString workDir = base_path + "/testdata/functions"; - QVERIFY( test_compiler.qmake( workDir, "functions" )); + QString buildDir = base_path + "/testdata/functions_build"; + QVERIFY( test_compiler.qmake( workDir, "functions", buildDir )); } void tst_qmake::operators() -- cgit v1.2.3