summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaximilian Blochberger <[email protected]>2025-06-26 17:37:27 +0200
committerMaximilian Blochberger <[email protected]>2025-07-04 15:02:22 +0200
commitd65a45d2bcca25adb4f0d3ea29092f274f0c2a6d (patch)
tree7767b317a7eeb842cd9090125429fcf0a9d909b9
parentaa52e34173409e8bb23d7968a4ae0f2a9e166e15 (diff)
Fail builds on Apple platforms with invalid Info.plist
Information property lists (Info.plist) files are part of application bundles on Apple platforms and contain basic information about the application, such as the name of the application's executable. The Info.plist file can have multiple formats, such as binary or XML. Makefiles generated by qmake convert Info.plist files to XML by default, so that variables in the Info.plist can be substituted with values defined by qmake, such as the name of the application's executable. This is important if users use external tools such as Xcode for modifying the Info.plist file, which may save it in binary format. To convert the formats, the plutil tool shipped with macOS (or the Xcode command-line tools) is used. The Unix tool sed is then used to actually substitute variables. If the Info.plist file is invalid, e.g., due to an invalid tag name, the plutil invocation fails. However, the converted plist is piped into sed for variable substitution. The plutil command will simply write an error message to standard out and return with a non-zero exit code. Due to the pipe chain, make will not fail and the error message will end up in the Info.plist in the built application bundle. The application bundle is then invalid as well, as vital information such as the name of the executable of the application is missing. The change ensures that the pipe chain fails, if plutil exits with a non-zero exit code. The issue was introduced with my solution for QTBUG-45357. Beforehand, Info.plists and mistakes therein were simply copied into the application bundle. [ChangeLog][qmake] Fail builds on Apple platforms if the Info.plist is invalid instead of generating corrupt application bundles. Pick-to: 6.5 6.9 6.10 Change-Id: Ibdb2a18e9bbf35a654af8534aa61188f8389c55a Reviewed-by: Joerg Bornemann <[email protected]> Reviewed-by: Tor Arne Vestbø <[email protected]>
-rw-r--r--qmake/generators/unix/unixmake2.cpp4
-rw-r--r--tests/auto/tools/qmake/testdata/invalid-info-plist/Info.plist1
-rw-r--r--tests/auto/tools/qmake/testdata/invalid-info-plist/invalid-info-plist.pro2
-rw-r--r--tests/auto/tools/qmake/testdata/invalid-info-plist/main.cpp4
-rw-r--r--tests/auto/tools/qmake/tst_qmake.cpp18
5 files changed, 27 insertions, 2 deletions
diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp
index 96036eba701..9c29b26fb82 100644
--- a/qmake/generators/unix/unixmake2.cpp
+++ b/qmake/generators/unix/unixmake2.cpp
@@ -804,7 +804,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
QString icon = fileFixify(var("ICON"));
t << "@$(DEL_FILE) " << info_plist_out << "\n\t"
- << "@plutil -convert xml1 -o - " << info_plist << " | "
+ << "@set -o pipefail && plutil -convert xml1 -o - " << info_plist << " | "
<< "sed ";
for (const ProString &arg : std::as_const(commonSedArgs))
t << arg;
@@ -837,7 +837,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
if (!isShallowBundle)
symlinks[bundle_dir + "Resources"] = "Versions/Current/Resources";
t << "@$(DEL_FILE) " << info_plist_out << "\n\t"
- << "@plutil -convert xml1 -o - " << info_plist << " | "
+ << "@set -o pipefail && plutil -convert xml1 -o - " << info_plist << " | "
<< "sed ";
for (const ProString &arg : std::as_const(commonSedArgs))
t << arg;
diff --git a/tests/auto/tools/qmake/testdata/invalid-info-plist/Info.plist b/tests/auto/tools/qmake/testdata/invalid-info-plist/Info.plist
new file mode 100644
index 00000000000..5468597e2b4
--- /dev/null
+++ b/tests/auto/tools/qmake/testdata/invalid-info-plist/Info.plist
@@ -0,0 +1 @@
+<invalid>
diff --git a/tests/auto/tools/qmake/testdata/invalid-info-plist/invalid-info-plist.pro b/tests/auto/tools/qmake/testdata/invalid-info-plist/invalid-info-plist.pro
new file mode 100644
index 00000000000..0230f9c6736
--- /dev/null
+++ b/tests/auto/tools/qmake/testdata/invalid-info-plist/invalid-info-plist.pro
@@ -0,0 +1,2 @@
+SOURCES += main.cpp
+QMAKE_INFO_PLIST = Info.plist
diff --git a/tests/auto/tools/qmake/testdata/invalid-info-plist/main.cpp b/tests/auto/tools/qmake/testdata/invalid-info-plist/main.cpp
new file mode 100644
index 00000000000..905869dfa38
--- /dev/null
+++ b/tests/auto/tools/qmake/testdata/invalid-info-plist/main.cpp
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/tests/auto/tools/qmake/tst_qmake.cpp b/tests/auto/tools/qmake/tst_qmake.cpp
index 278cf4ad232..080f0abbdaa 100644
--- a/tests/auto/tools/qmake/tst_qmake.cpp
+++ b/tests/auto/tools/qmake/tst_qmake.cpp
@@ -47,6 +47,7 @@ private slots:
void rawString();
#if defined(Q_OS_DARWIN)
void bundle_spaces();
+ void invalid_info_plist();
#elif defined(Q_OS_WIN)
void windowsResources();
#endif
@@ -534,6 +535,23 @@ void tst_qmake::bundle_spaces()
QVERIFY( test_compiler.removeMakefile(workDir) );
}
+void tst_qmake::invalid_info_plist()
+{
+ QString workDir = base_path + "/testdata/invalid-info-plist";
+
+ // We set up alternate arguments here, to make sure we're testing Mac
+ // Bundles. We need to actually run make to check whether the failing
+ // plutil invocation breaks the build.
+
+ test_compiler.setArguments(QStringList(),
+ QStringList() << "-spec" << "macx-clang");
+
+ QVERIFY( test_compiler.qmake(workDir, "invalid-info-plist") );
+
+ // Make fails: plutil fails to parse the Info.plist file
+ QVERIFY( test_compiler.make(workDir, QString(), true) );
+}
+
#elif defined(Q_OS_WIN) // defined(Q_OS_DARWIN)
void tst_qmake::windowsResources()