Wizards: Support using #pragma once instead of include guards

Allow users to choose #pragma once instead of #ifndef include guards in
generated header files.

Fixes: QTCREATORBUG-12166
Change-Id: I3ba41c7570beb9c5958e174b5581fcc25855050f
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Filip Bucek <fbucek@atlas.cz>
This commit is contained in:
Filip Bucek
2019-01-03 10:56:36 +01:00
parent 2781c2a900
commit aaa8beab88
31 changed files with 235 additions and 52 deletions

View File

@@ -1,5 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef @COLLECTION_INCLUDE_GUARD@
#define @COLLECTION_INCLUDE_GUARD@
@endif
#include <QtDesigner>
#include <qplugin.h>
@@ -19,4 +23,6 @@ private:
QList<QDesignerCustomWidgetInterface*> m_widgets;
};
#endif
@if ! '%{Cpp:PragmaOnce}'
#endif // @COLLECTION_INCLUDE_GUARD@
@endif

View File

@@ -1,5 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef @SINGLE_INCLUDE_GUARD@
#define @SINGLE_INCLUDE_GUARD@
@endif
#include <QDesignerCustomWidgetInterface>
@@ -28,4 +32,6 @@ private:
bool m_initialized;
};
#endif
@if ! '%{Cpp:PragmaOnce}'
#endif // @SINGLE_INCLUDE_GUARD@
@endif

View File

@@ -1,5 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef @WIDGET_INCLUDE_GUARD@
#define @WIDGET_INCLUDE_GUARD@
@endif
#include <@WIDGET_BASE_CLASS@>
@@ -11,4 +15,6 @@ public:
@WIDGET_CLASS@(QWidget *parent = 0);
};
#endif
@if ! '%{Cpp:PragmaOnce}'
#endif // @WIDGET_INCLUDE_GUARD@
@endif

View File

@@ -1,5 +1,10 @@
%{Cpp:LicenseTemplate}\
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %{GUARD}
#define %{GUARD}
@endif
#include <gtest/gtest.h>
#include <gmock/gmock-matchers.h>
@@ -11,3 +16,7 @@ TEST(%{TestCaseName}, %{TestSetName})
EXPECT_EQ(1, 1);
ASSERT_THAT(0, Eq(0));
}
@if ! '%{Cpp:PragmaOnce}'
#endif // %{GUARD}
@endif

View File

@@ -36,6 +36,10 @@
"key": "TestCaseFileWithHeaderSuffix",
"value": "%{JS: 'tst_%{TestCaseName}.'.toLowerCase() + Util.preferredSuffix('text/x-c++hdr') }"
},
{
"key": "GUARD",
"value": "%{JS: '%{TestCaseFileWithHeaderSuffix}'.toUpperCase().replace('.', '_') }"
},
{
"key": "TestCaseFileWithCppSuffix",
"value": "%{JS: 'tst_%{TestCaseName}.'.toLowerCase() + Util.preferredSuffix('text/x-c++src') }"

View File

@@ -1,6 +1,10 @@
%{Cpp:LicenseTemplate}\
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %{GUARD}
#define %{GUARD}
@endif
%{JS: QtSupport.qtIncludes([ ( '%{IncludeQObject}' ) ? 'QtCore/%{IncludeQObject}' : '',
( '%{IncludeQWidget}' ) ? 'QtGui/%{IncludeQWidget}' : '',
@@ -53,4 +57,6 @@ private:
@endif
};
%{JS: Cpp.closeNamespaces('%{Class}')}
#endif // %{GUARD}\
@if ! '%{Cpp:PragmaOnce}'
#endif // %{GUARD}
@endif

View File

@@ -1,6 +1,10 @@
%{Cpp:LicenseTemplate}\
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %{GUARD}
#define %{GUARD}
@endif
%{JS: QtSupport.qtIncludes([ 'QtCore/%{Base}' ], [ 'QtCore/%{Base}' ])}\
%{JS: Cpp.openNamespaces('%{Class}')}\
@@ -62,4 +66,6 @@ public:
private:
};
%{JS: Cpp.closeNamespaces('%{Class}')}
#endif // %{GUARD}\
@if ! '%{Cpp:PragmaOnce}'
#endif // %{GUARD}
@endif

View File

@@ -1,6 +1,10 @@
%{Cpp:LicenseTemplate}\
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %{GUARD}
#define %{GUARD}
@endif
%{JS: QtSupport.qtIncludes([ 'QtCore/%{Base}' ], [ 'QtCore/%{Base}' ])}\
%{JS: Cpp.openNamespaces('%{Class}')}\
@@ -47,4 +51,6 @@ public:
private:
};
%{JS: Cpp.closeNamespaces('%{Class}')}
#endif // %{GUARD}\
@if ! '%{Cpp:PragmaOnce}'
#endif // %{GUARD}
@endif

View File

@@ -1,6 +1,10 @@
%{Cpp:LicenseTemplate}\
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %{GUARD}
#define %{GUARD}
@endif
%{JS: QtSupport.qtIncludes([ 'QtCore/%{Base}' ], [ 'QtCore/%{Base}' ])}\
%{JS: Cpp.openNamespaces('%{Class}')}\
@@ -50,4 +54,6 @@ public:
private:
};
%{JS: Cpp.closeNamespaces('%{Class}')}
#endif // %{GUARD}\
@if ! '%{Cpp:PragmaOnce}'
#endif // %{GUARD}
@endif

View File

@@ -1,5 +1,9 @@
%{Cpp:LicenseTemplate}\
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %{JS: Cpp.headerGuard('%{FileName}')}
#define %{JS: Cpp.headerGuard('%{FileName}')}
#endif // %{JS: Cpp.headerGuard('%{FileName}')}
@endif

View File

@@ -1,4 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %ProjectName:h%_H
#define %ProjectName:h%_H
@endif
#include "%PluginName:l%_global.%CppHeaderSuffix%"
@@ -26,3 +31,7 @@ private:
} // namespace Internal
} // namespace %PluginName%
@if ! '%{Cpp:PragmaOnce}'
#endif // %ProjectName:h%_H
@endif

View File

@@ -1,4 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %ProjectName:h%_GLOBAL_H
#define %ProjectName:h%_GLOBAL_H
@endif
#include <QtGlobal>
@@ -7,3 +12,7 @@
#else
# define %PluginName:u%SHARED_EXPORT Q_DECL_IMPORT
#endif
@if ! '%{Cpp:PragmaOnce}'
#endif // %ProjectName:h%_GLOBAL_H
@endif

View File

@@ -1,4 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %ProjectName:h%_CONSTANTS_H
#define %ProjectName:h%_CONSTANTS_H
@endif
namespace %PluginName% {
namespace Constants {
@@ -8,3 +13,7 @@ const char MENU_ID[] = "%PluginName%.Menu";
} // namespace %PluginName%
} // namespace Constants
@if ! '%{Cpp:PragmaOnce}'
#endif // %ProjectName:h%_CONSTANTS_H
@endif

View File

@@ -1,5 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %ObjectName:u%_H
#define %ObjectName:u%_H
@endif
#include <QQuickItem>
@@ -13,4 +17,6 @@ public:
~%ObjectName%();
};
@if ! '%{Cpp:PragmaOnce}'
#endif // %ObjectName:u%_H
@endif

View File

@@ -1,4 +1,9 @@
@if '%{Cpp:PragmaOnce}'
#pragma once
@else
#ifndef %ProjectName:h%_PLUGIN_H
#define %ProjectName:h%_PLUGIN_H
@endif
#include <QQmlExtensionPlugin>
@@ -10,3 +15,7 @@ class %ProjectName:s%Plugin : public QQmlExtensionPlugin
public:
void registerTypes(const char *uri) override;
};
@if ! '%{Cpp:PragmaOnce}'
#endif // %ProjectName:h%_PLUGIN_H
@endif

View File

@@ -27,6 +27,7 @@
#include "cppfilesettingspage.h"
#include "cppmodelmanager.h"
#include "cpptools/cpptoolsplugin.h"
#include <utils/fileutils.h>
#include <utils/macroexpander.h>
@@ -68,5 +69,10 @@ QString AbstractEditorSupport::licenseTemplate(const QString &file, const QStrin
return Utils::TemplateEngine::processText(&expander, license, nullptr);
}
bool AbstractEditorSupport::usePragmaOnce()
{
return Internal::CppToolsPlugin::instance()->usePragmaOnce();
}
} // namespace CppTools

View File

@@ -49,6 +49,7 @@ public:
unsigned revision() const { return m_revision; }
static QString licenseTemplate(const QString &file = QString(), const QString &className = QString());
static bool usePragmaOnce();
private:
CppModelManager *m_modelmanager;

View File

@@ -55,6 +55,7 @@ static const char headerSuffixKeyC[] = "HeaderSuffix";
static const char sourceSuffixKeyC[] = "SourceSuffix";
static const char headerSearchPathsKeyC[] = "HeaderSearchPaths";
static const char sourceSearchPathsKeyC[] = "SourceSearchPaths";
static const char headerPragmaOnceC[] = "HeaderPragmaOnce";
static const char licenseTemplatePathKeyC[] = "LicenseTemplate";
const char *licenseTemplateTemplate = QT_TRANSLATE_NOOP("CppTools::Internal::CppFileSettingsWidget",
@@ -68,11 +69,6 @@ const char *licenseTemplateTemplate = QT_TRANSLATE_NOOP("CppTools::Internal::Cpp
namespace CppTools {
namespace Internal {
CppFileSettings::CppFileSettings() :
lowerCaseFiles(false)
{
}
void CppFileSettings::toSettings(QSettings *s) const
{
s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
@@ -83,6 +79,7 @@ void CppFileSettings::toSettings(QSettings *s) const
s->setValue(QLatin1String(headerSearchPathsKeyC), headerSearchPaths);
s->setValue(QLatin1String(sourceSearchPathsKeyC), sourceSearchPaths);
s->setValue(QLatin1String(Constants::LOWERCASE_CPPFILES_KEY), lowerCaseFiles);
s->setValue(QLatin1String(headerPragmaOnceC), headerPragmaOnce);
s->setValue(QLatin1String(licenseTemplatePathKeyC), licenseTemplatePath);
s->endGroup();
}
@@ -106,6 +103,7 @@ void CppFileSettings::fromSettings(QSettings *s)
.toStringList();
const bool lowerCaseDefault = Constants::lowerCaseFilesDefault;
lowerCaseFiles = s->value(QLatin1String(Constants::LOWERCASE_CPPFILES_KEY), QVariant(lowerCaseDefault)).toBool();
headerPragmaOnce = s->value(headerPragmaOnceC, headerPragmaOnce).toBool();
licenseTemplatePath = s->value(QLatin1String(licenseTemplatePathKeyC), QString()).toString();
s->endGroup();
}
@@ -127,6 +125,7 @@ bool CppFileSettings::applySuffixesToMimeDB()
bool CppFileSettings::equals(const CppFileSettings &rhs) const
{
return lowerCaseFiles == rhs.lowerCaseFiles
&& headerPragmaOnce == rhs.headerPragmaOnce
&& headerPrefixes == rhs.headerPrefixes
&& sourcePrefixes == rhs.sourcePrefixes
&& headerSuffix == rhs.headerSuffix
@@ -303,6 +302,7 @@ CppFileSettings CppFileSettingsWidget::settings() const
{
CppFileSettings rc;
rc.lowerCaseFiles = m_ui->lowerCaseFileNamesCheckBox->isChecked();
rc.headerPragmaOnce = m_ui->headerPragmaOnceCheckBox->isChecked();
rc.headerPrefixes = trimmedPaths(m_ui->headerPrefixesEdit->text());
rc.sourcePrefixes = trimmedPaths(m_ui->sourcePrefixesEdit->text());
rc.headerSuffix = m_ui->headerSuffixComboBox->currentText();
@@ -323,6 +323,7 @@ void CppFileSettingsWidget::setSettings(const CppFileSettings &s)
{
const QChar comma = QLatin1Char(',');
m_ui->lowerCaseFileNamesCheckBox->setChecked(s.lowerCaseFiles);
m_ui->headerPragmaOnceCheckBox->setChecked(s.headerPragmaOnce);
m_ui->headerPrefixesEdit->setText(s.headerPrefixes.join(comma));
m_ui->sourcePrefixesEdit->setText(s.sourcePrefixes.join(comma));
setComboText(m_ui->headerSuffixComboBox, s.headerSuffix);

View File

@@ -42,16 +42,15 @@ namespace Ui { class CppFileSettingsPage; }
struct CppFileSettings
{
CppFileSettings();
QStringList headerPrefixes;
QString headerSuffix;
QStringList headerSearchPaths;
QStringList sourcePrefixes;
QString sourceSuffix;
QStringList sourceSearchPaths;
bool lowerCaseFiles;
QString licenseTemplatePath;
bool headerPragmaOnce = false;
bool lowerCaseFiles = false;
void toSettings(QSettings *) const;
void fromSettings(QSettings *);

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>547</width>
<height>363</height>
<height>406</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
@@ -67,7 +67,7 @@ These paths are used in addition to current directory on Switch Header/Source.</
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLabel" name="headerPrefixesLabel">
<property name="text">
<string>&amp;Prefixes:</string>
@@ -77,7 +77,7 @@ These paths are used in addition to current directory on Switch Header/Source.</
</property>
</widget>
</item>
<item row="4" column="1">
<item row="5" column="1">
<widget class="QLineEdit" name="headerPrefixesEdit">
<property name="toolTip">
<string>Comma-separated list of header prefixes.
@@ -86,6 +86,26 @@ These prefixes are used in addition to current file name on Switch Header/Source
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="headerPragmaOnceLabel">
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Include guards</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="headerPragmaOnceCheckBox">
<property name="toolTip">
<string>Uses #pragma once instead of #ifndef include guards.</string>
</property>
<property name="text">
<string>Use '#pragma once' instead of '#ifndef' guards</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@@ -140,6 +140,11 @@ QString CppToolsPlugin::licenseTemplate()
return m_instance->m_fileSettings->licenseTemplate();
}
bool CppToolsPlugin::usePragmaOnce()
{
return m_instance->m_fileSettings->headerPragmaOnce;
}
const QStringList &CppToolsPlugin::headerSearchPaths()
{
return m_instance->m_fileSettings->headerSearchPaths;
@@ -204,6 +209,11 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
tr("The configured path to the license template"),
[]() { return CppToolsPlugin::licenseTemplatePath().toString(); });
expander->registerVariable(
"Cpp:PragmaOnce",
tr("Insert #pragma once instead of #ifndef include guards into header file"),
[] { return usePragmaOnce() ? QString("true") : QString(); });
return true;
}

View File

@@ -65,6 +65,7 @@ public:
static void clearHeaderSourceCache();
static Utils::FileName licenseTemplatePath();
static QString licenseTemplate();
static bool usePragmaOnce();
bool initialize(const QStringList &arguments, QString *errorMessage) final;
void extensionsInitialized() final;

View File

@@ -26,6 +26,7 @@
#include "formclasswizarddialog.h"
#include "formclasswizardpage.h"
#include "formclasswizardparameters.h"
#include <cpptools/abstracteditorsupport.h>
#include <designer/formtemplatewizardpage.h>
#include <qtsupport/codegenerator.h>
@@ -88,6 +89,7 @@ FormClassWizardParameters FormClassWizardDialog::parameters() const
m_classPage->getParameters(&rc);
// Name the ui class in the Ui namespace after the class specified
rc.uiTemplate = QtSupport::CodeGenerator::changeUiClassName(m_rawFormTemplate, rc.className);
rc.usePragmaOnce = CppTools::AbstractEditorSupport::usePragmaOnce();
return rc;
}

View File

@@ -43,6 +43,7 @@ public:
QString sourceFile;
QString headerFile;
QString uiFile;
bool usePragmaOnce = false;
};
} // namespace Designer

View File

@@ -104,8 +104,12 @@ bool QtDesignerFormClassCodeGenerator::generateCpp(const FormClassWizardParamete
// 1) Header file
QTextStream headerStr(header);
headerStr << headerLicense << "#ifndef " << guard
<< "\n#define " << guard << '\n' << '\n';
headerStr << headerLicense;
if (parameters.usePragmaOnce)
headerStr << "#pragma once\n\n";
else
headerStr << "#ifndef " << guard << "\n#define " << guard << "\n\n";
// Include 'ui_'
if (generationParameters.embedding != QtSupport::CodeGenSettings::PointerAggregatedUiClass) {
@@ -165,7 +169,9 @@ bool QtDesignerFormClassCodeGenerator::generateCpp(const FormClassWizardParamete
}
headerStr << namespaceIndent << "};\n\n";
Utils::writeClosingNameSpaces(namespaceList, QString(), headerStr);
headerStr << "#endif // "<< guard << '\n';
if (!parameters.usePragmaOnce)
headerStr << "#endif // " << guard << '\n';
// 2) Source file
QTextStream sourceStr(source);

View File

@@ -939,7 +939,17 @@ QString CustomWizardContext::processFile(const FieldReplacementMap &fm, QString
replaceFields(fm, &in);
QString out;
// Expander needed to handle extra variable "Cpp:PragmaOnce"
QString errorMessage;
Utils::MacroExpander *expander = Utils::globalMacroExpander();
in = Utils::TemplateEngine::processText(expander, in, &errorMessage);
if (!errorMessage.isEmpty()) {
qWarning("Error processing custom widget file: %s\nFile:\n%s",
qPrintable(errorMessage), qPrintable(in));
return QString();
}
if (!Utils::TemplateEngine::preprocessText(in, &out, &errorMessage)) {
qWarning("Error preprocessing custom widget file: %s\nFile:\n%s",
qPrintable(errorMessage), qPrintable(in));

View File

@@ -30,6 +30,8 @@
#include <cpptools/abstracteditorsupport.h>
#include <utils/fileutils.h>
#include <utils/macroexpander.h>
#include <utils/templateengine.h>
#include <QFileInfo>
#include <QDir>
@@ -311,7 +313,20 @@ QString PluginGenerator::processTemplate(const QString &tmpl,
if (!reader.fetch(tmpl, errorMessage))
return QString();
QString cont = QString::fromUtf8(reader.data());
// Expander needed to handle extra variable "Cpp:PragmaOnce"
Utils::MacroExpander *expander = Utils::globalMacroExpander();
QString errMsg;
cont = Utils::TemplateEngine::processText(expander, cont, &errMsg);
if (!errMsg.isEmpty()) {
qWarning("Error processing custom plugin file: %s\nFile:\n%s",
qPrintable(errMsg), qPrintable(cont));
errorMessage = &errMsg;
return QString();
}
const QChar atChar = QLatin1Char('@');
int offset = 0;
for (;;) {

View File

@@ -105,6 +105,7 @@ static inline bool generateFormClass(const GuiAppParameters &params,
fp.className = params.className;
fp.sourceFile = params.sourceFileName;
fp.headerFile = params.headerFileName;
fp.usePragmaOnce = CppTools::AbstractEditorSupport::usePragmaOnce();
QString headerContents;
QString sourceContents;
// Invoke code generation service of Qt Designer plugin.
@@ -224,7 +225,6 @@ bool GuiAppWizard::parametrizeTemplate(const QString &templatePath, const QStrin
if (!reader.fetch(fileName, QIODevice::Text, errorMessage))
return false;
QString contents = QString::fromUtf8(reader.data());
contents.replace(QLatin1String("%QAPP_INCLUDE%"), QLatin1String("QApplication"));
contents.replace(QLatin1String("%INCLUDE%"), params.headerFileName);
contents.replace(QLatin1String("%CLASS%"), params.className);
@@ -236,6 +236,11 @@ bool GuiAppWizard::parametrizeTemplate(const QString &templatePath, const QStrin
else
contents.replace(QLatin1String("%SHOWMETHOD%"), QString::fromLatin1(mainSourceShowC));
// Replace include guards with pragma once
if (CppTools::AbstractEditorSupport::usePragmaOnce()) {
contents.replace(QLatin1String("#ifndef %PRE_DEF%\n#define %PRE_DEF%"), "#pragma once");
contents.replace(QLatin1String("#endif // %PRE_DEF%\n"), QString());
}
const QChar dot = QLatin1Char('.');

View File

@@ -31,25 +31,6 @@
#include <QTextStream>
#include <QStringList>
// Contents of the header defining the shared library export.
#define GUARD_VARIABLE "<GUARD>"
#define EXPORT_MACRO_VARIABLE "<EXPORT_MACRO>"
#define LIBRARY_MACRO_VARIABLE "<LIBRARY_MACRO>"
static const char *globalHeaderContentsC =
"#ifndef " GUARD_VARIABLE "\n"
"#define " GUARD_VARIABLE "\n"
"\n"
"#include <QtCore/qglobal.h>\n"
"\n"
"#if defined(" LIBRARY_MACRO_VARIABLE ")\n"
"# define " EXPORT_MACRO_VARIABLE " Q_DECL_EXPORT\n"
"#else\n"
"# define " EXPORT_MACRO_VARIABLE " Q_DECL_IMPORT\n"
"#endif\n"
"\n"
"#endif // " GUARD_VARIABLE "\n";
namespace QmakeProjectManager {
namespace Internal {
@@ -60,6 +41,7 @@ void LibraryParameters::generateCode(QtProjectParameters:: Type t,
const QString &exportMacro,
const QString &pluginJsonFileName,
int indentation,
bool usePragmaOnce,
QString *header,
QString *source) const
{
@@ -76,8 +58,10 @@ void LibraryParameters::generateCode(QtProjectParameters:: Type t,
// 1) Header
const QString guard = Utils::headerGuard(headerFileName, namespaceList);
headerStr << "#ifndef " << guard
<< "\n#define " << guard << '\n' << '\n';
if (usePragmaOnce)
headerStr << "#pragma once\n\n";
else
headerStr << "#ifndef " << guard << "\n#define " << guard << "\n\n";
if (!sharedHeader.isEmpty())
Utils::writeIncludeFileDirective(sharedHeader, false, headerStr);
@@ -123,7 +107,9 @@ void LibraryParameters::generateCode(QtProjectParameters:: Type t,
headerStr << namespaceIndent << indent << unqualifiedClassName << "();\n";
headerStr << namespaceIndent << "};\n\n";
Utils::writeClosingNameSpaces(namespaceList, indent, headerStr);
headerStr << "#endif // "<< guard << '\n';
if (!usePragmaOnce)
headerStr << "#endif // " << guard << '\n';
/// 2) Source
QTextStream sourceStr(source);
@@ -152,12 +138,28 @@ void LibraryParameters::generateCode(QtProjectParameters:: Type t,
QString LibraryParameters::generateSharedHeader(const QString &globalHeaderFileName,
const QString &projectTarget,
const QString &exportMacro)
const QString &exportMacro,
bool usePragmaOnce)
{
QString contents = QLatin1String(globalHeaderContentsC);
contents.replace(QLatin1String(GUARD_VARIABLE), Utils::headerGuard(globalHeaderFileName));
contents.replace(QLatin1String(EXPORT_MACRO_VARIABLE), exportMacro);
contents.replace(QLatin1String(LIBRARY_MACRO_VARIABLE), QtProjectParameters::libraryMacro(projectTarget));
QString contents;
if (usePragmaOnce) {
contents += "#pragma once\n";
} else {
contents += "#ifndef " + Utils::headerGuard(globalHeaderFileName) + "\n";
contents += "#define " + Utils::headerGuard(globalHeaderFileName) + "\n";
}
contents += "\n";
contents += "#include <QtCore/qglobal.h>\n";
contents += "\n";
contents += "#if defined(" + QtProjectParameters::libraryMacro(projectTarget) + ")\n";
contents += "# define " + exportMacro + " Q_DECL_EXPORT\n";
contents += "#else\n";
contents += "# define " + exportMacro + " Q_DECL_IMPORT\n";
contents += "#endif\n";
contents += "\n";
if (!usePragmaOnce)
contents += "#endif // " + Utils::headerGuard(globalHeaderFileName) + '\n';
return contents;
}

View File

@@ -44,13 +44,15 @@ struct LibraryParameters {
const QString &exportMacro,
const QString &pluginJsonFileName,
int indentation,
bool usePragmaOnce,
QString *header,
QString *source) const;
// Generate the code of the shared header containing the export macro
static QString generateSharedHeader(const QString &globalHeaderFileName,
const QString &projectTarget,
const QString &exportMacro);
const QString &exportMacro,
bool usePragmaOnce);
QString className;
QString baseClassName;

View File

@@ -80,6 +80,7 @@ Core::GeneratedFiles LibraryWizard::generateFiles(const QWizard *w,
const QtProjectParameters projectParams = dialog->parameters();
const QString projectPath = projectParams.projectPath();
const LibraryParameters params = dialog->libraryParameters();
const bool usePragmaOnce = CppTools::AbstractEditorSupport::usePragmaOnce();
const QString sharedLibExportMacro = QtProjectParameters::exportMacro(projectParams.fileName);
@@ -107,7 +108,7 @@ Core::GeneratedFiles LibraryWizard::generateFiles(const QWizard *w,
Core::GeneratedFile globalHeader(globalHeaderName);
globalHeaderFileName = Utils::FileName::fromString(globalHeader.path()).fileName();
globalHeader.setContents(CppTools::AbstractEditorSupport::licenseTemplate(globalHeaderFileName)
+ LibraryParameters::generateSharedHeader(globalHeaderFileName, projectParams.fileName, sharedLibExportMacro));
+ LibraryParameters::generateSharedHeader(globalHeaderFileName, projectParams.fileName, sharedLibExportMacro, usePragmaOnce));
rc.push_back(globalHeader);
}
@@ -115,7 +116,7 @@ Core::GeneratedFiles LibraryWizard::generateFiles(const QWizard *w,
QString headerContents, sourceContents;
params.generateCode(projectParams.type, projectParams.fileName, headerFileName,
globalHeaderFileName, sharedLibExportMacro, pluginJsonFileName,
/* indentation*/ 4, &headerContents, &sourceContents);
/* indentation*/ 4, usePragmaOnce, &headerContents, &sourceContents);
source.setContents(CppTools::AbstractEditorSupport::licenseTemplate(sourceFileName, params.className)
+ sourceContents);