diff options
author | Bill Hoffman <bill.hoffman@kitware.com> | 2008-04-08 12:22:51 -0400 |
---|---|---|
committer | Bill Hoffman <bill.hoffman@kitware.com> | 2008-04-08 12:22:51 -0400 |
commit | d55ed678344b220dd9bb93282969bdcef719802d (patch) | |
tree | e4bca7cfaf47b78a98db44d50015f60e2c9824eb | |
parent | 9aecdb0652cc46a50ffdb046bf768364c346cd0a (diff) | |
download | cmake-d55ed678344b220dd9bb93282969bdcef719802d.tar.gz |
ENH: merge in changes from main tree
33 files changed, 610 insertions, 353 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4edba354e9..38f44dc954 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -354,7 +354,7 @@ ENDMACRO (CMAKE_BUILD_UTILITIES) SET(CMake_VERSION_MAJOR 2) SET(CMake_VERSION_MINOR 6) SET(CMake_VERSION_PATCH 0) -SET(CMake_VERSION_RC 6) +SET(CMake_VERSION_RC 61) # CVS versions are odd, if this is an odd minor version # then set the CMake_VERSION_DATE variable IF("${CMake_VERSION_MINOR}" MATCHES "[13579]$") @@ -417,12 +417,13 @@ ENDIF(BUILD_CursesDialog) IF(BUILD_QtDialog) IF(APPLE) - SET(CMAKE_INSTALL_SUBDIR + SET(CMAKE_BUNDLE_NAME "CMake ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}-${CMake_VERSION_PATCH}") IF(CMake_VERSION_DATE) - SET(CMAKE_INSTALL_SUBDIR + SET(CMAKE_BUNDLE_NAME "CMake ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}-${CMake_VERSION_DATE}") ENDIF(CMake_VERSION_DATE) + SET(CMAKE_BUNDLE_LOCATION "${CMAKE_INSTALL_PREFIX}") # make sure CMAKE_INSTALL_PREFIX ends in / STRING(LENGTH "${CMAKE_INSTALL_PREFIX}" LEN) MATH(EXPR LEN "${LEN} -1" ) @@ -430,8 +431,8 @@ IF(BUILD_QtDialog) IF(NOT "${ENDCH}" STREQUAL "/") SET(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/") ENDIF(NOT "${ENDCH}" STREQUAL "/") - SET(CMAKE_BUNDLE_LOCATION "${CMAKE_INSTALL_PREFIX}${CMAKE_INSTALL_SUBDIR}") - SET(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}${CMAKE_INSTALL_SUBDIR}/cmake-gui.app/Contents") + SET(CMAKE_INSTALL_PREFIX + "${CMAKE_INSTALL_PREFIX}${CMAKE_BUNDLE_NAME}.app/Contents") ENDIF(APPLE) SET(QT_NEED_RPATH FALSE) diff --git a/ChangeLog.manual b/ChangeLog.manual index 7475492b55..5687b33bae 100644 --- a/ChangeLog.manual +++ b/ChangeLog.manual @@ -1,3 +1,12 @@ +Changes in CMake 2.6.0 RC 61 +- Change install location on mac for cmake-gui +- Fix for bugs 6730 and 6720 in FindQt4 configured headers in binary dir +- Add VS9 support to InstallRequiredSystemLibraries.cmake +- Fix some bugs in framework support +- Have make edit_cache work with cmake-gui and eclipse generator +- Fix find_* to not mistakenly construct network paths on windows +- Several bug fixes in cmake-gui Qt program. + Changes in CMake 2.6.0 RC 6 - Added ChangeLog.manual diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake index 40616646b4..3dfe1df674 100644 --- a/Modules/FindQt4.cmake +++ b/Modules/FindQt4.cmake @@ -992,7 +992,17 @@ IF (QT4_QMAKE_FOUND) # macro used to create the names of output files preserving relative dirs MACRO (QT4_MAKE_OUTPUT_FILE infile prefix ext outfile ) - FILE(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${infile}) + STRING(LENGTH ${CMAKE_CURRENT_BINARY_DIR} _binlength) + STRING(LENGTH ${infile} _infileLength) + SET(_checkinfile ${CMAKE_CURRENT_SOURCE_DIR}) + IF(_infileLength GREATER _binlength) + STRING(SUBSTRING "${infile}" 0 ${_binlength} _checkinfile) + ENDIF(_infileLength GREATER _binlength) + IF(CMAKE_CURRENT_BINARY_DIR MATCHES "${_checkinfile}") + FILE(RELATIVE_PATH rel ${CMAKE_CURRENT_BINARY_DIR} ${infile}) + ELSE(CMAKE_CURRENT_BINARY_DIR MATCHES "${_checkinfile}") + FILE(RELATIVE_PATH rel ${CMAKE_CURRENT_SOURCE_DIR} ${infile}) + ENDIF(CMAKE_CURRENT_BINARY_DIR MATCHES "${_checkinfile}") SET(_outfile "${CMAKE_CURRENT_BINARY_DIR}/${rel}") GET_FILENAME_COMPONENT(outpath ${_outfile} PATH) GET_FILENAME_COMPONENT(_outfile ${_outfile} NAME_WE) diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake index 560beec39c..2b963bf83a 100644 --- a/Modules/InstallRequiredSystemLibraries.cmake +++ b/Modules/InstallRequiredSystemLibraries.cmake @@ -118,8 +118,6 @@ IF(MSVC) "${MSVC80_MFC_DIR}/mfcm80.dll" "${MSVC80_MFC_DIR}/mfcm80u.dll" ) - ENDIF(MSVC80) - IF(MSVC80) # include the language dll's for vs8 as well as the actuall dll's SET(MSVC80_MFCLOC_DIR "${MSVC80_REDIST_DIR}/x86/Microsoft.VC80.MFCLOC") # Install the manifest that allows DLLs to be loaded from the @@ -137,6 +135,47 @@ IF(MSVC) "${MSVC80_MFCLOC_DIR}/mfc80kor.dll" ) ENDIF(MSVC80) + IF(MSVC90) + IF(CMAKE_INSTALL_DEBUG_LIBRARIES) + SET(MSVC90_MFC_DIR + "${MSVC90_REDIST_DIR}/Debug_NonRedist/x86/Microsoft.VC90.DebugMFC") + SET(__install__libs ${__install__libs} + "${MSVC90_MFC_DIR}/Microsoft.VC90.DebugMFC.manifest" + "${MSVC90_MFC_DIR}/mfc90d.dll" + "${MSVC90_MFC_DIR}/mfc90ud.dll" + "${MSVC90_MFC_DIR}/mfcm90d.dll" + "${MSVC90_MFC_DIR}/mfcm90ud.dll" + ) + ENDIF(CMAKE_INSTALL_DEBUG_LIBRARIES) + + SET(MSVC90_MFC_DIR "${MSVC90_REDIST_DIR}/x86/Microsoft.VC90.MFC") + # Install the manifest that allows DLLs to be loaded from the + # directory containing the executable. + SET(__install__libs ${__install__libs} + "${MSVC90_MFC_DIR}/Microsoft.VC90.MFC.manifest" + "${MSVC90_MFC_DIR}/mfc90.dll" + "${MSVC90_MFC_DIR}/mfc90u.dll" + "${MSVC90_MFC_DIR}/mfcm90.dll" + "${MSVC90_MFC_DIR}/mfcm90u.dll" + ) + # include the language dll's for vs9 as well as the actuall dll's + SET(MSVC90_MFCLOC_DIR "${MSVC90_REDIST_DIR}/x86/Microsoft.VC90.MFCLOC") + # Install the manifest that allows DLLs to be loaded from the + # directory containing the executable. + SET(__install__libs ${__install__libs} + "${MSVC90_MFCLOC_DIR}/Microsoft.VC90.MFCLOC.manifest" + "${MSVC90_MFCLOC_DIR}/mfc90chs.dll" + "${MSVC90_MFCLOC_DIR}/mfc90cht.dll" + "${MSVC90_MFCLOC_DIR}/mfc90enu.dll" + "${MSVC90_MFCLOC_DIR}/mfc90esp.dll" + "${MSVC90_MFCLOC_DIR}/mfc90deu.dll" + "${MSVC90_MFCLOC_DIR}/mfc90fra.dll" + "${MSVC90_MFCLOC_DIR}/mfc90ita.dll" + "${MSVC90_MFCLOC_DIR}/mfc90jpn.dll" + "${MSVC90_MFCLOC_DIR}/mfc90kor.dll" + ) + ENDIF(MSVC90) + ENDIF(CMAKE_INSTALL_MFC_LIBRARIES) FOREACH(lib ${__install__libs} diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt index 2e61c296ff..37f96ed6f5 100644 --- a/Source/QtDialog/CMakeLists.txt +++ b/Source/QtDialog/CMakeLists.txt @@ -57,6 +57,10 @@ ELSE(NOT QT4_FOUND) ADD_EXECUTABLE(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS}) TARGET_LINK_LIBRARIES(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${QT_LIBRARIES}) IF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.4) + IF(APPLE) + SET_TARGET_PROPERTIES(cmake-gui PROPERTIES + OUTPUT_NAME ${CMAKE_BUNDLE_NAME}) + ENDIF(APPLE) SET(CMAKE_INSTALL_DESTINATION_ARGS BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}") ENDIF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.4) @@ -84,8 +88,10 @@ ELSE(NOT QT4_FOUND) "${CMake_BINARY_DIR}/Source/QtDialog/postflight.sh") configure_file("${CMake_SOURCE_DIR}/Source/QtDialog/postupgrade.sh.in" "${CMake_BINARY_DIR}/Source/QtDialog/postupgrade.sh") - INSTALL(CODE "set(input_file - \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/MacOS/cmake-gui\")") + INSTALL(CODE "execute_process(COMMAND ln -s \"../MacOS/${CMAKE_BUNDLE_NAME}\" cmake-gui + WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin)") + INSTALL(CODE "set(input_file + \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/MacOS/${CMAKE_BUNDLE_NAME}\")") INSTALL(SCRIPT "${CMake_SOURCE_DIR}/Source/QtDialog/CMakeIngestOSXBundleLibraries.cmake") ENDIF(APPLE) CONFIGURE_FILE("${QtDialog_SOURCE_DIR}/QtDialogCPack.cmake.in" diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index bdc8a662da..bf7889027b 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -66,6 +66,7 @@ static const char * cmDocumentationOptions[][3] = int main(int argc, char** argv) { + cmSystemTools::FindExecutableDirectory(argv[0]); QApplication app(argc, argv); // clean out standard Qt paths for plugins, which we don't use anyway @@ -113,7 +114,12 @@ int main(int argc, char** argv) // Construct and print requested documentation. cmake hcm; hcm.AddCMakePaths(); - doc.SetCMakeRoot(hcm.GetCacheDefinition("CMAKE_ROOT")); + // just incase the install is bad avoid a seg fault + const char* root = hcm.GetCacheDefinition("CMAKE_ROOT"); + if(root) + { + doc.SetCMakeRoot(root); + } std::vector<cmDocumentationEntry> commands; std::vector<cmDocumentationEntry> compatCommands; std::map<std::string,cmDocumentationSection *> propDocs; diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index 734fc1a533..1c5e25d475 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -31,6 +31,7 @@ #include <QMimeData> #include <QUrl> #include <QShortcut> +#include <QMacInstallDialog.h> #include "QCMake.h" #include "QCMakeCacheView.h" @@ -83,7 +84,7 @@ CMakeSetupDialog::CMakeSetupDialog() this->DeleteCacheAction = FileMenu->addAction(tr("&Delete Cache")); QObject::connect(this->DeleteCacheAction, SIGNAL(triggered(bool)), this, SLOT(doDeleteCache())); - this->ExitAction = FileMenu->addAction(tr("&Exit")); + this->ExitAction = FileMenu->addAction(tr("E&xit")); QObject::connect(this->ExitAction, SIGNAL(triggered(bool)), this, SLOT(close())); @@ -96,11 +97,23 @@ CMakeSetupDialog::CMakeSetupDialog() this->GenerateAction = ToolsMenu->addAction(tr("&Generate")); QObject::connect(this->GenerateAction, SIGNAL(triggered(bool)), this, SLOT(doGenerate())); - this->SuppressDevWarningsAction = ToolsMenu->addAction(tr("&Suppress dev Warnings (-Wno-dev)")); - QObject::connect(this->SuppressDevWarningsAction, SIGNAL(triggered(bool)), +#if defined(Q_WS_MAC) + this->InstallForCommandLineAction + = ToolsMenu->addAction(tr("&Install For Command Line Use")); + QObject::connect(this->InstallForCommandLineAction, SIGNAL(triggered(bool)), + this, SLOT(doInstallForCommandLine())); +#endif + QMenu* OptionsMenu = this->menuBar()->addMenu(tr("&Options")); + QAction* supressDevWarningsAction = OptionsMenu->addAction(tr("&Suppress dev Warnings (-Wno-dev)")); + QObject::connect(supressDevWarningsAction, SIGNAL(triggered(bool)), this, SLOT(doSuppressDev())); - this->SuppressDevWarningsAction->setCheckable(true); - + + supressDevWarningsAction->setCheckable(true); + QAction* debugAction = OptionsMenu->addAction(tr("&Debug Output")); + debugAction->setCheckable(true); + QObject::connect(debugAction, SIGNAL(toggled(bool)), + this, SLOT(setDebugOutput(bool))); + QMenu* HelpMenu = this->menuBar()->addMenu(tr("&Help")); QAction* a = HelpMenu->addAction(tr("About")); QObject::connect(a, SIGNAL(triggered(bool)), @@ -168,7 +181,10 @@ void CMakeSetupDialog::initialize() QObject::connect(this->CMakeThread->cmakeInstance(), SIGNAL(sourceDirChanged(QString)), this, SLOT(updateSourceDirectory(QString))); - + QObject::connect(this->CMakeThread->cmakeInstance(), + SIGNAL(binaryDirChanged(QString)), + this, SLOT(updateBinaryDirectory(QString))); + QObject::connect(this->CMakeThread->cmakeInstance(), SIGNAL(progressChanged(QString, float)), this, SLOT(showProgress(QString,float))); @@ -237,6 +253,7 @@ void CMakeSetupDialog::doConfigure() return; } + // make sure build directory exists QString bindir = this->CMakeThread->cmakeInstance()->binaryDirectory(); QDir dir(bindir); if(!dir.exists()) @@ -257,10 +274,13 @@ void CMakeSetupDialog::doConfigure() dir.mkpath("."); } - // prompt for generator if one doesn't exist + // prompt for generator if it hasn't been set if(this->CMakeThread->cmakeInstance()->generator().isEmpty()) { - this->promptForGenerator(); + if(!this->promptForGenerator()) + { + return; + } } // remember path @@ -315,6 +335,12 @@ void CMakeSetupDialog::doSuppressDev() SetSuppressDevWarnings(this->SuppressDevWarnings); } +void CMakeSetupDialog::doInstallForCommandLine() +{ + QMacInstallDialog setupdialog(0); + setupdialog.exec(); +} + void CMakeSetupDialog::doGenerate() { if(this->CurrentState == Generating) @@ -422,7 +448,7 @@ void CMakeSetupDialog::doSourceBrowse() tr("Enter Path to Source"), this->SourceDirectory->text()); if(!dir.isEmpty()) { - this->setSourceDirectory(QDir::fromNativeSeparators(dir)); + this->setSourceDirectory(dir); } } @@ -436,13 +462,23 @@ void CMakeSetupDialog::updateSourceDirectory(const QString& dir) } } +void CMakeSetupDialog::updateBinaryDirectory(const QString& dir) +{ + if(this->BinaryDirectory->currentText() != dir) + { + this->BinaryDirectory->blockSignals(true); + this->BinaryDirectory->setEditText(dir); + this->BinaryDirectory->blockSignals(false); + } +} + void CMakeSetupDialog::doBinaryBrowse() { QString dir = QFileDialog::getExistingDirectory(this, tr("Enter Path to Build"), this->BinaryDirectory->currentText()); if(!dir.isEmpty() && dir != this->BinaryDirectory->currentText()) { - this->setBinaryDirectory(QDir::fromNativeSeparators(dir)); + this->setBinaryDirectory(dir); } } @@ -520,7 +556,7 @@ void CMakeSetupDialog::setEnabledState(bool enabled) this->RemoveEntry->setEnabled(false); // let selection re-enable it } -void CMakeSetupDialog::promptForGenerator() +bool CMakeSetupDialog::promptForGenerator() { QSettings settings; settings.beginGroup("Settings/StartPath"); @@ -540,19 +576,25 @@ void CMakeSetupDialog::promptForGenerator() { combo->setCurrentIndex(idx); } - QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok, + QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok | + QDialogButtonBox::Cancel, Qt::Horizontal, &dialog); QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept())); + QObject::connect(btns, SIGNAL(rejected()), &dialog, SLOT(reject())); QVBoxLayout* l = new QVBoxLayout(&dialog); l->addWidget(lab); l->addWidget(combo); l->addWidget(btns); - dialog.exec(); - - lastGen = combo->currentText(); - settings.setValue("LastGenerator", lastGen); - this->CMakeThread->cmakeInstance()->setGenerator(combo->currentText()); + if(dialog.exec() == QDialog::Accepted) + { + lastGen = combo->currentText(); + settings.setValue("LastGenerator", lastGen); + this->CMakeThread->cmakeInstance()->setGenerator(combo->currentText()); + return true; + } + + return false; } void CMakeSetupDialog::updateGeneratorLabel(const QString& gen) @@ -778,7 +820,7 @@ void CMakeSetupDialog::enterState(CMakeSetupDialog::State s) this->setEnabledState(false); this->GenerateButton->setEnabled(false); this->GenerateAction->setEnabled(false); - this->ConfigureButton->setText(tr("Stop")); + this->ConfigureButton->setText(tr("&Stop")); } else if(s == Generating) { @@ -786,7 +828,7 @@ void CMakeSetupDialog::enterState(CMakeSetupDialog::State s) this->setEnabledState(false); this->ConfigureButton->setEnabled(false); this->GenerateAction->setEnabled(false); - this->GenerateButton->setText(tr("Stop")); + this->GenerateButton->setText(tr("&Stop")); } else if(s == ReadyConfigure) { @@ -795,8 +837,8 @@ void CMakeSetupDialog::enterState(CMakeSetupDialog::State s) this->GenerateButton->setEnabled(false); this->GenerateAction->setEnabled(false); this->ConfigureButton->setEnabled(true); - this->ConfigureButton->setText(tr("Configure")); - this->GenerateButton->setText(tr("Generate")); + this->ConfigureButton->setText(tr("&Configure")); + this->GenerateButton->setText(tr("&Generate")); } else if(s == ReadyGenerate) { @@ -805,8 +847,8 @@ void CMakeSetupDialog::enterState(CMakeSetupDialog::State s) this->GenerateButton->setEnabled(true); this->GenerateAction->setEnabled(true); this->ConfigureButton->setEnabled(true); - this->ConfigureButton->setText(tr("Configure")); - this->GenerateButton->setText(tr("Generate")); + this->ConfigureButton->setText(tr("&Configure")); + this->GenerateButton->setText(tr("&Generate")); } } @@ -851,4 +893,9 @@ void CMakeSetupDialog::startSearch() this->Search->selectAll(); } +void CMakeSetupDialog::setDebugOutput(bool flag) +{ + QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(), + "setDebugOutput", Qt::QueuedConnection, Q_ARG(bool, flag)); +} diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h index ae9128ec2e..211dfcb023 100644 --- a/Source/QtDialog/CMakeSetupDialog.h +++ b/Source/QtDialog/CMakeSetupDialog.h @@ -45,6 +45,7 @@ protected slots: void doConfigure(); void doGenerate(); void doSuppressDev(); + void doInstallForCommandLine(); void doHelp(); void doAbout(); void doInterrupt(); @@ -58,9 +59,10 @@ protected slots: void doReloadCache(); void doDeleteCache(); void updateSourceDirectory(const QString& dir); + void updateBinaryDirectory(const QString& dir); void showProgress(const QString& msg, float percent); void setEnabledState(bool); - void promptForGenerator(); + bool promptForGenerator(); void updateGeneratorLabel(const QString& gen); void setExitAfterGenerate(bool); void addBinaryPath(const QString&); @@ -73,6 +75,7 @@ protected slots: void selectionChanged(); void addCacheEntry(); void startSearch(); + void setDebugOutput(bool); protected: @@ -93,6 +96,7 @@ protected: QAction* ConfigureAction; QAction* GenerateAction; QAction* SuppressDevWarningsAction; + QAction* InstallForCommandLineAction; State CurrentState; }; diff --git a/Source/QtDialog/CMakeSetupDialog.ui b/Source/QtDialog/CMakeSetupDialog.ui index fb80cc021c..12984b24e7 100644 --- a/Source/QtDialog/CMakeSetupDialog.ui +++ b/Source/QtDialog/CMakeSetupDialog.ui @@ -37,7 +37,7 @@ <item row="0" column="2" > <widget class="QPushButton" name="BrowseSourceDirectoryButton" > <property name="text" > - <string>Browse...</string> + <string>Browse &Source...</string> </property> </widget> </item> @@ -66,7 +66,7 @@ <item row="1" column="2" > <widget class="QPushButton" name="BrowseBinaryDirectoryButton" > <property name="text" > - <string>Browse...</string> + <string>Browse &Build...</string> </property> </widget> </item> @@ -129,7 +129,7 @@ <item> <widget class="QCheckBox" name="Advanced" > <property name="text" > - <string>Show Advanced Entries</string> + <string>Show Ad&vanced Entries</string> </property> </widget> </item> @@ -155,7 +155,7 @@ <string>Add New Entry</string> </property> <property name="text" > - <string>Add Entry</string> + <string>&Add Entry</string> </property> <property name="icon" > <iconset resource="CMakeSetup.qrc" >:/Icons/Plus16.png</iconset> @@ -171,7 +171,7 @@ <string>Remove Selected Entries</string> </property> <property name="text" > - <string>Remove Entry</string> + <string>&Remove Entry</string> </property> <property name="icon" > <iconset resource="CMakeSetup.qrc" >:/Icons/Delete16.png</iconset> @@ -220,14 +220,14 @@ <item> <widget class="QPushButton" name="ConfigureButton" > <property name="text" > - <string>Configure</string> + <string>&Configure</string> </property> </widget> </item> <item> <widget class="QPushButton" name="GenerateButton" > <property name="text" > - <string>Generate</string> + <string>&Generate</string> </property> </widget> </item> diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index 43db641a73..60ca2fe337 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -86,8 +86,8 @@ void QCMake::setSourceDirectory(const QString& dir) { if(this->SourceDirectory != dir) { - this->SourceDirectory = dir; - emit this->sourceDirChanged(dir); + this->SourceDirectory = QDir::fromNativeSeparators(dir); + emit this->sourceDirChanged(this->SourceDirectory); } } @@ -95,12 +95,14 @@ void QCMake::setBinaryDirectory(const QString& dir) { if(this->BinaryDirectory != dir) { + this->BinaryDirectory = QDir::fromNativeSeparators(dir); + emit this->binaryDirChanged(this->BinaryDirectory); cmCacheManager *cachem = this->CMakeInstance->GetCacheManager(); - this->BinaryDirectory = dir; this->setGenerator(QString()); - if(!this->CMakeInstance->GetCacheManager()->LoadCache(dir.toLocal8Bit().data())) + if(!this->CMakeInstance->GetCacheManager()->LoadCache( + this->BinaryDirectory.toLocal8Bit().data())) { - QDir testDir(dir); + QDir testDir(this->BinaryDirectory); if(testDir.exists("CMakeCache.txt")) { cmSystemTools::Error("There is a CMakeCache.txt file for the current binary " @@ -362,6 +364,21 @@ void QCMake::reloadCache() props = this->properties(); emit this->propertiesChanged(props); } + +void QCMake::setDebugOutput(bool flag) +{ + if(flag != this->CMakeInstance->GetDebugOutput()) + { + this->CMakeInstance->SetDebugOutputOn(flag); + emit this->debugOutputChanged(flag); + } +} + +bool QCMake::getDebugOutput() const +{ + return this->CMakeInstance->GetDebugOutput(); +} + void QCMake::SetSuppressDevWarnings(bool value) { diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h index ab7040c203..c46aab6d60 100644 --- a/Source/QtDialog/QCMake.h +++ b/Source/QtDialog/QCMake.h @@ -87,6 +87,8 @@ public slots: void deleteCache(); /// reload the cache in binary directory void reloadCache(); + /// set whether to do debug output + void setDebugOutput(bool); public: /// get the list of cache properties @@ -99,6 +101,8 @@ public: QString generator() const; /// get the available generators QStringList availableGenerators() const; + /// get whether to do debug output + bool getDebugOutput() const; signals: /// signal when properties change (during read from disk or configure process) @@ -108,6 +112,8 @@ signals: /// signal when the source directory changes (binary directory already /// containing a CMakeCache.txt file) void sourceDirChanged(const QString& dir); + /// signal when the binary directory changes + void binaryDirChanged(const QString& dir); /// signal for progress events void progressChanged(const QString& msg, float percent); /// signal when configure is done @@ -118,6 +124,8 @@ signals: void outputMessage(const QString& msg); /// signal when there is an error message void errorMessage(const QString& msg); + /// signal when debug output changes + void debugOutputChanged(bool); protected: cmake* CMakeInstance; diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx index 74492bfea2..8a8f8193aa 100644 --- a/Source/QtDialog/QCMakeCacheView.cxx +++ b/Source/QtDialog/QCMakeCacheView.cxx @@ -372,10 +372,15 @@ bool QCMakeCacheModel::insertRows(int row, int num, const QModelIndex&) } QCMakeCacheModelDelegate::QCMakeCacheModelDelegate(QObject* p) - : QItemDelegate(p) + : QItemDelegate(p), FileDialogFlag(false) { } +void QCMakeCacheModelDelegate::setFileDialogFlag(bool f) +{ + this->FileDialogFlag = f; +} + QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* p, const QStyleOptionViewItem&, const QModelIndex& idx) const { @@ -388,13 +393,21 @@ QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* p, } else if(type == QCMakeCacheProperty::PATH) { - return new QCMakeCachePathEditor(p, + QCMakeCachePathEditor* editor = + new QCMakeCachePathEditor(p, var.data(Qt::DisplayRole).toString()); + QObject::connect(editor, SIGNAL(fileDialogExists(bool)), this, + SLOT(setFileDialogFlag(bool))); + return editor; } else if(type == QCMakeCacheProperty::FILEPATH) { - return new QCMakeCacheFilePathEditor(p, + QCMakeCacheFilePathEditor* editor = + new QCMakeCacheFilePathEditor(p, var.data(Qt::DisplayRole).toString()); + QObject::connect(editor, SIGNAL(fileDialogExists(bool)), this, + SLOT(setFileDialogFlag(bool))); + return editor; } return new QLineEdit(p); @@ -443,6 +456,17 @@ bool QCMakeCacheModelDelegate::editorEvent(QEvent* e, QAbstractItemModel* model, return model->setData(index, state, Qt::CheckStateRole); } +bool QCMakeCacheModelDelegate::eventFilter(QObject* object, QEvent* event) +{ + // workaround for what looks like a bug in Qt on Mac OS X + if(event->type() == QEvent::FocusOut && this->FileDialogFlag) + { + return false; + } + return QItemDelegate::eventFilter(object, event); +} + + QCMakeCacheFileEditor::QCMakeCacheFileEditor(QWidget* p, const QString& var) : QLineEdit(p), Variable(var) { @@ -492,7 +516,9 @@ void QCMakeCacheFilePathEditor::chooseFile() title = tr("Select File for %1"); title = title.arg(this->Variable); } + this->fileDialogExists(true); path = QFileDialog::getOpenFileName(this, title, info.absolutePath()); + this->fileDialogExists(false); if(!path.isEmpty()) { @@ -514,7 +540,9 @@ void QCMakeCachePathEditor::chooseFile() title = tr("Select Path for %1"); title = title.arg(this->Variable); } + this->fileDialogExists(true); path = QFileDialog::getExistingDirectory(this, title, this->text()); + this->fileDialogExists(false); if(!path.isEmpty()) { this->setText(QDir::fromNativeSeparators(path)); diff --git a/Source/QtDialog/QCMakeCacheView.h b/Source/QtDialog/QCMakeCacheView.h index fd8c2fe488..45a858e4a2 100644 --- a/Source/QtDialog/QCMakeCacheView.h +++ b/Source/QtDialog/QCMakeCacheView.h @@ -108,6 +108,11 @@ public: const QModelIndex& index ) const; bool editorEvent (QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index); + bool eventFilter(QObject* object, QEvent* event); +protected slots: + void setFileDialogFlag(bool); +protected: + bool FileDialogFlag; }; /// Editor widget for editing paths or file paths @@ -118,6 +123,8 @@ public: QCMakeCacheFileEditor(QWidget* p, const QString& var); protected slots: virtual void chooseFile() = 0; +signals: + void fileDialogExists(bool); protected: void resizeEvent(QResizeEvent* e); QToolButton* ToolButton; diff --git a/Source/QtDialog/QMacInstallDialog.cxx b/Source/QtDialog/QMacInstallDialog.cxx index c3daaf2471..70293f82b3 100644 --- a/Source/QtDialog/QMacInstallDialog.cxx +++ b/Source/QtDialog/QMacInstallDialog.cxx @@ -1,4 +1,5 @@ #include "QMacInstallDialog.h" +#include <QMessageBox> #include "cmSystemTools.h" #include <iostream> #include <QFileDialog> @@ -33,6 +34,22 @@ void QMacInstallDialog::DoInstall() { QDir installDir(this->Internals->InstallPrefix->text()); std::string installTo = installDir.path().toStdString(); + if(!cmSystemTools::FileExists(installTo.c_str())) + { + QString message = tr("Build install does not exist, " + "should I create it?") + + "\n\n" + + tr("Directory: "); + message += installDir.path(); + QString title = tr("Create Directory"); + QMessageBox::StandardButton btn; + btn = QMessageBox::information(this, title, message, + QMessageBox::Yes | QMessageBox::No); + if(btn == QMessageBox::Yes) + { + cmSystemTools::MakeDirectory(installTo.c_str()); + } + } QDir cmExecDir(QApplication::applicationDirPath()); cmExecDir.cd("../bin"); QFileInfoList list = cmExecDir.entryInfoList(); @@ -40,10 +57,20 @@ void QMacInstallDialog::DoInstall() { QFileInfo fileInfo = list.at(i); std::string filename = fileInfo.fileName().toStdString(); + if(filename.size() && filename[0] == '.') + { + continue; + } std::string file = fileInfo.absoluteFilePath().toStdString(); std::string newName = installTo; newName += "/"; newName += filename; + // Remove the old files + if(cmSystemTools::FileExists(newName.c_str())) + { + std::cout << "rm [" << newName << "]\n"; + cmSystemTools::RemoveFile(newName.c_str()); + } std::cout << "ln -s [" << file << "] ["; std::cout << newName << "]\n"; cmSystemTools::CreateSymlink(file.c_str(), diff --git a/Source/QtDialog/postflight.sh.in b/Source/QtDialog/postflight.sh.in index 88dd06659e..33be352060 100755 --- a/Source/QtDialog/postflight.sh.in +++ b/Source/QtDialog/postflight.sh.in @@ -1,4 +1,3 @@ #!/bin/bash -echo "$2/@CMAKE_INSTALL_SUBDIR@/cmake-gui.app/Contents/MacOS/cmake-gui" >>/tmp/mylog -"$2/@CMAKE_INSTALL_SUBDIR@/cmake-gui.app/Contents/MacOS/cmake-gui" --mac-install +"$2@CMAKE_INSTALL_SUBDIR@/@CMAKE_BUNDLE_NAME@.app/Contents/MacOS/@CMAKE_BUNDLE_NAME@" --mac-install exit 0 diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index fc9bf47438..878c3d64de 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -611,18 +611,8 @@ void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt) std::string lib = tgt->GetFullPath(config, implib, true); this->Depends.push_back(lib); - if(tgt->IsFrameworkOnApple()) - { - // Frameworks on OS X need only the framework directory to - // link. - std::string fw = tgt->GetDirectory(config, implib); - this->AddFrameworkItem(fw); - } - else - { - this->AddTargetItem(lib, tgt); - this->AddLibraryRuntimeInfo(lib, tgt); - } + this->AddTargetItem(lib, tgt); + this->AddLibraryRuntimeInfo(lib, tgt); } } else @@ -1023,7 +1013,7 @@ void cmComputeLinkInformation::AddTargetItem(std::string const& item, // For compatibility with CMake 2.4 include the item's directory in // the linker search path. - if(this->OldLinkDirMode && + if(this->OldLinkDirMode && !target->IsFrameworkOnApple() && this->OldLinkDirMask.find(cmSystemTools::GetFilenamePath(item)) == this->OldLinkDirMask.end()) { diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 19bbe225ca..8572c61267 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -654,12 +654,24 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const || (t->first=="test") || (t->first=="Experimental") || (t->first=="Nightly") + || (t->first=="edit_cache") || (t->first=="package") || (t->first=="package_source") || (t->first=="rebuild_cache") )) { break; } + // add the edit_cache target only if it's not ccmake + // otherwise ccmake will be executed in the log view of Eclipse, + // which is no terminal, so curses don't work there, Alex + if (t->first=="edit_cache") + { + if (strstr(mf->GetRequiredDefinition("CMAKE_EDIT_COMMAND"), + "ccmake")!=NULL) + { + break; + } + } } case cmTarget::EXECUTABLE: case cmTarget::STATIC_LIBRARY: diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index aa9731bb72..68ccbb28f9 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -1244,7 +1244,8 @@ void cmFileCommand bool cmFileCommand::HandleInstallDestination(cmFileInstaller& installer, std::string& destination) { - if ( destination.size() < 2 ) + // allow for / to be a valid destination + if ( destination.size() < 2 && destination != "/" ) { this->SetError("called with inapropriate arguments. " "No DESTINATION provided or ."); @@ -1406,8 +1407,10 @@ bool cmFileCommand::HandleChrpathCommand(std::vector<std::string> const& args) else { cmOStringStream e; - e << "CHRPATH could not write new RPATH \"" - << newRPath << "\" to the file \"" << file << "\": " + e << "CHRPATH could not write new RPATH:\n" + << " " << newRPath << "\n" + << "to the file:\n" + << " " << file << "\n" << emsg; this->SetError(e.str().c_str()); return false; diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index f5f14300cb..8b54a91151 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -495,7 +495,15 @@ void cmFindBase::ExpandRegistryAndCleanPath(std::vector<std::string>& paths) this->SearchPathSuffixes.begin(); j != this->SearchPathSuffixes.end(); ++j) { - std::string p = *i + std::string("/") + *j; + // if *i is only / then do not add a // + // this will get incorrectly considered a network + // path on windows and cause huge delays. + std::string p = *i; + if(p.size() && p[p.size()-1] != '/') + { + p += std::string("/"); + } + p += *j; // add to all paths because the search path may be modified // later with lib being replaced for lib64 which may exist paths.push_back(p); diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 32323e58cb..33820aa05f 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -803,8 +803,14 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, copyFilesBuildPhase->AddAttribute("dstSubfolderSpec", this->CreateString("6")); cmOStringStream ostr; - if ( mit->first != "MacOS" ) + if (cmtarget.IsFrameworkOnApple()) { + // dstPath in frameworks is relative to Versions/<version> + ostr << mit->first; + } + else if ( mit->first != "MacOS" ) + { + // dstPath in bundles is relative to Contents/MacOS ostr << "../" << mit->first.c_str(); } copyFilesBuildPhase->AddAttribute("dstPath", @@ -1357,11 +1363,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, target.GetType() == cmTarget::EXECUTABLE) { std::string pndir = target.GetDirectory(); - if(target.IsFrameworkOnApple()) - { - pndir += "/.."; - pndir = cmSystemTools::CollapseFullPath(pndir.c_str()); - } buildSettings->AddAttribute("SYMROOT", this->CreateString(pndir.c_str())); buildSettings->AddAttribute("EXECUTABLE_PREFIX", @@ -1429,17 +1430,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, fileType = "wrapper.framework"; productType = "com.apple.product-type.framework"; - const char* version = target.GetProperty("FRAMEWORK_VERSION"); - if(!version) - { - version = target.GetProperty("VERSION"); - } - if(!version) - { - version = "A"; - } + std::string version = target.GetFrameworkVersion(); buildSettings->AddAttribute("FRAMEWORK_VERSION", - this->CreateString(version)); + this->CreateString(version.c_str())); } else { @@ -1649,18 +1642,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, if(target.GetType() == cmTarget::SHARED_LIBRARY) { // Get the install_name directory for the build tree. - install_name_dir = target.GetInstallNameDirForBuildTree(configName); - if(target.GetPropertyAsBool("FRAMEWORK")) - { - if(install_name_dir.find(".framework") != install_name_dir.npos) - { - install_name_dir = install_name_dir + "/.."; - install_name_dir = - cmSystemTools::CollapseFullPath(install_name_dir.c_str()); - //std::cerr << "new install name " << install_name_dir << "\n"; - } - } - + install_name_dir = target.GetInstallNameDirForBuildTree(configName, true); if(install_name_dir.empty()) { // Xcode will not pass the -install_name option at all if INSTALL_PATH @@ -2868,26 +2850,9 @@ cmGlobalXCodeGenerator { if(config) { - if(dir.find(".framework") != dir.npos) - { - // Remove trailing slashes (so that the rfind does not find the one at - // the very end...!) - // - cmSystemTools::ConvertToUnixSlashes(dir); - std::string::size_type pos = dir.rfind("/"); - std::string framework = dir.substr(pos); - std::string newDir = dir.substr(0, pos); - newDir += "/"; - newDir += config; - dir = newDir; - dir += framework; - } - else - { - dir += prefix; - dir += config; - dir += suffix; - } + dir += prefix; + dir += config; + dir += suffix; } } } diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index f05c3756a8..5fd408e366 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -239,16 +239,17 @@ cmInstallTargetGenerator // Compute the build tree location of the framework directory std::string from1 = fromDirConfig; - // Remove trailing slashes... so that from1 ends with ".framework": - // - cmSystemTools::ConvertToUnixSlashes(from1); + from1 += targetName; + from1 += ".framework"; files.push_back(from1); type = cmTarget::INSTALL_DIRECTORY; // Need to apply install_name_tool and stripping to binary // inside framework. - toInstallPath += ".framework/"; + toInstallPath += ".framework/Versions/"; + toInstallPath += this->Target->GetFrameworkVersion(); + toInstallPath += "/"; toInstallPath += this->GetInstallFilename(this->Target, config, NameNormal); diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 7ee40fc128..e16af18e4c 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -668,7 +668,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout, if ( this->Version >= 8 ) { // Check the filesystem type where the target will be written. - if(cmLVS6G_IsFAT(target.GetDirectory(configName))) + if(cmLVS6G_IsFAT(target.GetDirectory(configName).c_str())) { // Add a flag telling the manifest tool to use a workaround // for FAT32 file systems, which can cause an empty manifest diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index 1715fe96f3..29be46ce78 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -147,9 +147,11 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) } else { + cmSystemTools::MakeDirectory(outpath.c_str()); if(!targetNameImport.empty()) { outpathImp = this->Target->GetDirectory(0, true); + cmSystemTools::MakeDirectory(outpathImp.c_str()); outpathImp += "/"; } } diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 1c7f10841f..70978c3272 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -39,20 +39,11 @@ cmMakefileLibraryTargetGenerator if(this->Target->IsFrameworkOnApple()) { - if(const char* fversion = this->Target->GetProperty("FRAMEWORK_VERSION")) - { - this->FrameworkVersion = fversion; - } - else if(const char* tversion = this->Target->GetProperty("VERSION")) - { - this->FrameworkVersion = tversion; - } - else - { - this->FrameworkVersion = "A"; - } + this->FrameworkVersion = this->Target->GetFrameworkVersion(); this->MacContentDirectory = this->Target->GetDirectory(); - this->MacContentDirectory += "/Versions/"; + this->MacContentDirectory += "/"; + this->MacContentDirectory += this->TargetNameOut; + this->MacContentDirectory += ".framework/Versions/"; this->MacContentDirectory += this->FrameworkVersion; this->MacContentDirectory += "/"; } @@ -244,50 +235,82 @@ void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink) } //---------------------------------------------------------------------------- -void cmMakefileLibraryTargetGenerator::CreateFramework( - std::string& targetName, - std::string& outpath) +void cmMakefileLibraryTargetGenerator::CreateFramework() { - std::string symlink; - std::string symlink2; + // TODO: Use the cmMakefileTargetGenerator::ExtraFiles vector to + // drive rules to create these files at build time. + std::string oldName; + std::string newName; + + // Compute the location of the top-level foo.framework directory. + std::string top = this->Target->GetDirectory(); + top += "/"; + top += this->TargetNameOut; + top += ".framework/"; + // Make foo.framework/Versions - std::string dir = outpath; - dir += "Versions"; - cmSystemTools::MakeDirectory(dir.c_str()); - std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); - // cd foo.framework to setup symlinks with relative paths - cmSystemTools::ChangeDirectory((outpath+"Versions").c_str()); + std::string versions = top; + versions += "Versions"; + cmSystemTools::MakeDirectory(versions.c_str()); + + // Make foo.framework/Versions/version + std::string version = versions; + version += "/"; + version += this->FrameworkVersion; + cmSystemTools::MakeDirectory(version.c_str()); + // Current -> version - symlink = this->FrameworkVersion; - symlink2 = "Current"; - cmSystemTools::RemoveFile("Current"); - cmSystemTools::CreateSymlink(symlink.c_str(), symlink2.c_str()); - this->Makefile->AddCMakeOutputFile((outpath + "Versions/Current").c_str()); - // change to top level of framework to create next set of symlinks - cmSystemTools::ChangeDirectory(outpath.c_str()); + oldName = this->FrameworkVersion; + newName = versions; + newName += "/Current"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + // foo -> Versions/Current/foo - symlink = "Versions/Current/"; - symlink += targetName; - symlink2 = targetName; - cmSystemTools::CreateSymlink(symlink.c_str(), symlink2.c_str()); - this->Makefile->AddCMakeOutputFile((outpath + targetName).c_str()); - // Resources -> Versions/Current/Resources - symlink = "Versions/Current/Resources"; - symlink2 = "Resources"; - cmSystemTools::CreateSymlink(symlink.c_str(), symlink2.c_str()); - this->Makefile->AddCMakeOutputFile((outpath + "Resources").c_str()); + oldName = "Versions/Current/"; + oldName += this->TargetNameOut; + newName = top; + newName += this->TargetNameOut; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + + // Resources -> Versions/Current/Resources + if(this->MacContentFolders.find("Resources") != + this->MacContentFolders.end()) + { + oldName = "Versions/Current/Resources"; + newName = top; + newName += "Resources"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + } + // Headers -> Versions/Current/Headers - symlink = "Versions/Current/Headers"; - symlink2 = "Headers"; - cmSystemTools::CreateSymlink(symlink.c_str(), symlink2.c_str()); - this->Makefile->AddCMakeOutputFile((outpath + "Headers").c_str()); + if(this->MacContentFolders.find("Headers") != + this->MacContentFolders.end()) + { + oldName = "Versions/Current/Headers"; + newName = top; + newName += "Headers"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + } + // PrivateHeaders -> Versions/Current/PrivateHeaders - symlink = "Versions/Current/PrivateHeaders"; - symlink2 = "PrivateHeaders"; - cmSystemTools::CreateSymlink(symlink.c_str(), symlink2.c_str()); - this->Makefile->AddCMakeOutputFile((outpath + "PrivateHeaders").c_str()); - // go back to where we were - cmSystemTools::ChangeDirectory(cwd.c_str()); + if(this->MacContentFolders.find("PrivateHeaders") != + this->MacContentFolders.end()) + { + oldName = "Versions/Current/PrivateHeaders"; + newName = top; + newName += "PrivateHeaders"; + cmSystemTools::RemoveFile(newName.c_str()); + cmSystemTools::CreateSymlink(oldName.c_str(), newName.c_str()); + this->Makefile->AddCMakeOutputFile(newName.c_str()); + } } //---------------------------------------------------------------------------- @@ -354,7 +377,12 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules // Construct the full path version of the names. std::string outpath; std::string outpathImp; - if(relink) + if(this->Target->IsFrameworkOnApple()) + { + outpath = this->MacContentDirectory; + this->CreateFramework(); + } + else if(relink) { outpath = this->Makefile->GetStartOutputDirectory(); outpath += cmake::GetCMakeFilesDirectory(); @@ -369,20 +397,16 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules else { outpath = this->Target->GetDirectory(); + cmSystemTools::MakeDirectory(outpath.c_str()); outpath += "/"; if(!targetNameImport.empty()) { outpathImp = this->Target->GetDirectory(0, true); + cmSystemTools::MakeDirectory(outpathImp.c_str()); outpathImp += "/"; } } - // If we're creating a framework, place the output into a framework directory - if(this->Target->IsFrameworkOnApple()) - { - this->CreateFramework(targetName, outpath); - } - std::string targetFullPath = outpath + targetName; std::string targetFullPathPDB = outpath + targetNamePDB; std::string targetFullPathSO = outpath + targetNameSO; diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h index a1a4bf79da..75177850b6 100644 --- a/Source/cmMakefileLibraryTargetGenerator.h +++ b/Source/cmMakefileLibraryTargetGenerator.h @@ -37,8 +37,7 @@ protected: bool relink); // MacOSX Framework support methods void WriteFrameworkRules(bool relink); - void CreateFramework(std::string& targetName, - std::string& outpath); + void CreateFramework(); // Store the computd framework version for OS X Frameworks. std::string FrameworkVersion; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index b15410b356..cd08bdb1e9 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -334,6 +334,9 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source, macdir += pkgloc; cmSystemTools::MakeDirectory(macdir.c_str()); + // Record use of this content location. + this->MacContentFolders.insert(pkgloc); + // Get the input file location. std::string input = source.GetFullPath(); @@ -1456,11 +1459,8 @@ void cmMakefileTargetGenerator if(cmTarget* tgt = this->GlobalGenerator->FindTarget(0, lib->first.c_str())) { - if(const char* location = - tgt->GetLocation(this->LocalGenerator->ConfigurationName.c_str())) - { - depends.push_back(location); - } + const char* config = this->LocalGenerator->ConfigurationName.c_str(); + depends.push_back(tgt->GetFullPath(config, false)); } // depend on full path libs as well else if(cmSystemTools::FileIsFullPath(lib->first.c_str())) @@ -1594,6 +1594,7 @@ cmMakefileTargetGenerator responseFileNameFull += "/"; responseFileNameFull += name; cmGeneratedFileStream responseStream(responseFileNameFull.c_str()); + responseStream.SetCopyIfDifferent(true); responseStream << options << "\n"; // Add a dependency so the target will rebuild when the set of diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index 3a6ec0d637..0b55c6eb87 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -204,6 +204,7 @@ protected: // Mac OS X content info. std::string MacContentDirectory; + std::set<cmStdString> MacContentFolders; // Target-wide Fortran module output directory. bool FortranModuleDirectoryComputed; diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 32c77970da..26b2b580c2 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -2229,7 +2229,13 @@ bool cmSystemTools::ChangeRPath(std::string const& file, } if(emsg) { - *emsg = "The current RPATH does not begin with that specified."; + cmOStringStream e; + e << "The current RPATH is:\n" + << " " << se->Value << "\n" + << "which does not begin with:\n" + << " " << oldRPath << "\n" + << "as was expected."; + *emsg = e.str(); } return false; } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index aa4c403ceb..e7bf4eca22 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -1626,42 +1626,30 @@ void cmTarget::MarkAsImported() } //---------------------------------------------------------------------------- -const char* cmTarget::GetDirectory(const char* config, bool implib) +std::string cmTarget::GetDirectory(const char* config, bool implib) { if (this->IsImported()) { - return this->ImportedGetDirectory(config, implib); - } - else - { - return this->NormalGetDirectory(config, implib); - } -} - -//---------------------------------------------------------------------------- -const char* cmTarget::ImportedGetDirectory(const char* config, bool implib) -{ - this->Directory = - cmSystemTools::GetFilenamePath( + // Return the directory from which the target is imported. + return + cmSystemTools::GetFilenamePath( this->ImportedGetFullPath(config, implib)); - return this->Directory.c_str(); -} - -//---------------------------------------------------------------------------- -const char* cmTarget::NormalGetDirectory(const char* config, bool implib) -{ - if(config && *config) - { - // Do not create the directory when config is given: - this->Directory = this->GetAndCreateOutputDir(implib, true); - // Add the configuration's subdirectory. - this->Makefile->GetLocalGenerator()->GetGlobalGenerator()-> - AppendDirectoryForConfig("/", config, "", this->Directory); - return this->Directory.c_str(); } else { - return this->GetOutputDir(implib); + // Return the directory in which the target will be built. + if(config && *config) + { + // Add the configuration's subdirectory. + std::string dir = this->GetOutputDir(implib); + this->Makefile->GetLocalGenerator()->GetGlobalGenerator()-> + AppendDirectoryForConfig("/", config, "", dir); + return dir; + } + else + { + return this->GetOutputDir(implib); + } } } @@ -1688,22 +1676,31 @@ const char* cmTarget::ImportedGetLocation(const char* config) //---------------------------------------------------------------------------- const char* cmTarget::NormalGetLocation(const char* config) { - this->Location = this->GetDirectory(config); + // Handle the configuration-specific case first. + if(config) + { + this->Location = this->GetFullPath(config, false); + return this->Location.c_str(); + } + + // Now handle the deprecated build-time configuration location. + this->Location = this->GetDirectory(); if(!this->Location.empty()) { this->Location += "/"; } - if(!config) + const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR"); + if(cfgid && strcmp(cfgid, ".") != 0) { - // No specific configuration was given so it will not appear on - // the result of GetDirectory. Add a name here to be replaced at - // build time. - const char* cfgid = this->Makefile->GetDefinition("CMAKE_CFG_INTDIR"); - if(cfgid && strcmp(cfgid, ".") != 0) - { - this->Location += cfgid; - this->Location += "/"; - } + this->Location += cfgid; + this->Location += "/"; + } + if(this->IsFrameworkOnApple()) + { + this->Location += this->GetFullName(config, false); + this->Location += ".framework/Versions/"; + this->Location += this->GetFrameworkVersion(); + this->Location += "/"; } this->Location += this->GetFullName(config, false); return this->Location.c_str(); @@ -2203,6 +2200,14 @@ std::string cmTarget::NormalGetFullPath(const char* config, bool implib, std::string fpath = this->GetDirectory(config, implib); fpath += "/"; + if(this->IsFrameworkOnApple()) + { + fpath += this->GetFullName(config, false); + fpath += ".framework/Versions/"; + fpath += this->GetFrameworkVersion(); + fpath += "/"; + } + // Add the full name of the target. if(implib) { @@ -2474,7 +2479,8 @@ void cmTarget::GetLibraryNamesInternal(std::string& name, const char* version = this->GetProperty("VERSION"); const char* soversion = this->GetProperty("SOVERSION"); if((type != cmTarget::SHARED_LIBRARY && type != cmTarget::MODULE_LIBRARY) || - !this->Makefile->GetDefinition(sonameFlag.c_str())) + !this->Makefile->GetDefinition(sonameFlag.c_str()) || + this->IsFrameworkOnApple()) { // Versioning is supported only for shared libraries and modules, // and then only when the platform supports an soname flag. @@ -2801,13 +2807,14 @@ bool cmTarget::NeedRelinkBeforeInstall() } //---------------------------------------------------------------------------- -std::string cmTarget::GetInstallNameDirForBuildTree(const char* config) +std::string cmTarget::GetInstallNameDirForBuildTree(const char* config, + bool for_xcode) { // If building directly for installation then the build tree install_name // is the same as the install tree. if(this->GetPropertyAsBool("BUILD_WITH_INSTALL_RPATH")) { - return GetInstallNameDirForInstallTree(config); + return GetInstallNameDirForInstallTree(config, for_xcode); } // Use the build tree directory for the target. @@ -2817,6 +2824,13 @@ std::string cmTarget::GetInstallNameDirForBuildTree(const char* config) { std::string dir = this->GetDirectory(config); dir += "/"; + if(this->IsFrameworkOnApple() && !for_xcode) + { + dir += this->GetFullName(config, false); + dir += ".framework/Versions/"; + dir += this->GetFrameworkVersion(); + dir += "/"; + } return dir; } else @@ -2826,7 +2840,8 @@ std::string cmTarget::GetInstallNameDirForBuildTree(const char* config) } //---------------------------------------------------------------------------- -std::string cmTarget::GetInstallNameDirForInstallTree(const char*) +std::string cmTarget::GetInstallNameDirForInstallTree(const char* config, + bool for_xcode) { // Lookup the target property. const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR"); @@ -2836,6 +2851,13 @@ std::string cmTarget::GetInstallNameDirForInstallTree(const char*) { std::string dir = install_name_dir; dir += "/"; + if(this->IsFrameworkOnApple() && !for_xcode) + { + dir += this->GetFullName(config, false); + dir += ".framework/Versions/"; + dir += this->GetFrameworkVersion(); + dir += "/"; + } return dir; } else @@ -2845,7 +2867,7 @@ std::string cmTarget::GetInstallNameDirForInstallTree(const char*) } //---------------------------------------------------------------------------- -const char* cmTarget::GetAndCreateOutputDir(bool implib, bool create) +std::string cmTarget::GetOutputDir(bool implib) { // The implib option is only allowed for shared libraries, module // libraries, and executables. @@ -2862,7 +2884,7 @@ const char* cmTarget::GetAndCreateOutputDir(bool implib, bool create) if(implib && !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) { - std::string msg = "GetAndCreateOutputDir, imlib set but there is no " + std::string msg = "GetOutputDir, imlib set but there is no " "CMAKE_IMPORT_LIBRARY_SUFFIX for target: "; msg += this->GetName(); this->GetMakefile()-> @@ -2879,62 +2901,36 @@ const char* cmTarget::GetAndCreateOutputDir(bool implib, bool create) msg.c_str()); } + return this->ComputeBaseOutputDir(implib); +} + +//---------------------------------------------------------------------------- +std::string const& cmTarget::ComputeBaseOutputDir(bool implib) +{ // Select whether we are constructing the directory for the main // target or the import library. - std::string& out = implib? this->OutputDirImplib : this->OutputDir; + std::string& out = implib? this->BaseOutputDirImplib : this->BaseOutputDir; - if(out.empty()) + // Return immediately if the directory has already been computed. + if(!out.empty()) + { + return out; + } + + // Look for a target property defining the target output directory + // based on the target type. + const char* propertyName = 0; + switch(this->GetType()) { - // Look for a target property defining the target output directory - // based on the target type. - const char* propertyName = 0; - switch(this->GetType()) + case cmTarget::SHARED_LIBRARY: { - case cmTarget::SHARED_LIBRARY: - { - // For non-DLL platforms shared libraries are treated as - // library targets. For DLL platforms the DLL part of a - // shared library is treated as a runtime target and the - // corresponding import library is treated as an archive - // target. - if(this->DLLPlatform) - { - if(implib) - { - propertyName = "ARCHIVE_OUTPUT_DIRECTORY"; - } - else - { - propertyName = "RUNTIME_OUTPUT_DIRECTORY"; - } - } - else - { - propertyName = "LIBRARY_OUTPUT_DIRECTORY"; - } - } break; - case cmTarget::STATIC_LIBRARY: - { - // Static libraries are always treated as archive targets. - propertyName = "ARCHIVE_OUTPUT_DIRECTORY"; - } break; - case cmTarget::MODULE_LIBRARY: + // For non-DLL platforms shared libraries are treated as + // library targets. For DLL platforms the DLL part of a + // shared library is treated as a runtime target and the + // corresponding import library is treated as an archive + // target. + if(this->DLLPlatform) { - // Module libraries are always treated as library targets. - // Module import libraries are treated as archive targets. - if(implib) - { - propertyName = "ARCHIVE_OUTPUT_DIRECTORY"; - } - else - { - propertyName = "LIBRARY_OUTPUT_DIRECTORY"; - } - } break; - case cmTarget::EXECUTABLE: - { - // Executables are always treated as runtime targets. - // Executable import libraries are treated as archive targets. if(implib) { propertyName = "ARCHIVE_OUTPUT_DIRECTORY"; @@ -2943,69 +2939,93 @@ const char* cmTarget::GetAndCreateOutputDir(bool implib, bool create) { propertyName = "RUNTIME_OUTPUT_DIRECTORY"; } - } break; - default: break; - } - - // Select an output directory. - if(const char* outdir = this->GetProperty(propertyName)) - { - // Use the user-specified output directory. - out = outdir; - } - else if(this->GetType() == cmTarget::EXECUTABLE) - { - // Lookup the output path for executables. - out = this->Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH"); - } - else if(this->GetType() == cmTarget::STATIC_LIBRARY || - this->GetType() == cmTarget::SHARED_LIBRARY || - this->GetType() == cmTarget::MODULE_LIBRARY) - { - // Lookup the output path for libraries. - out = this->Makefile->GetSafeDefinition("LIBRARY_OUTPUT_PATH"); - } - if(out.empty()) + } + else + { + propertyName = "LIBRARY_OUTPUT_DIRECTORY"; + } + } break; + case cmTarget::STATIC_LIBRARY: { - // Default to the current output directory. - out = "."; - } - // Convert the output path to a full path in case it is - // specified as a relative path. Treat a relative path as - // relative to the current output directory for this makefile. - out = - cmSystemTools::CollapseFullPath - (out.c_str(), this->Makefile->GetStartOutputDirectory()); - - // TODO: Make AppBundle and Framework directory computation in - // target consistent. Why do we add the .framework part here for - // frameworks but not the .app part for bundles? We should - // probably not add it for either. - if(this->IsFrameworkOnApple()) + // Static libraries are always treated as archive targets. + propertyName = "ARCHIVE_OUTPUT_DIRECTORY"; + } break; + case cmTarget::MODULE_LIBRARY: { - out += "/"; - out += this->GetFullName(0, implib); - out += ".framework"; - } - - // Optionally make sure the output path exists on disk. - if(create) + // Module libraries are always treated as library targets. + // Module import libraries are treated as archive targets. + if(implib) + { + propertyName = "ARCHIVE_OUTPUT_DIRECTORY"; + } + else + { + propertyName = "LIBRARY_OUTPUT_DIRECTORY"; + } + } break; + case cmTarget::EXECUTABLE: { - if(!cmSystemTools::MakeDirectory(out.c_str())) + // Executables are always treated as runtime targets. + // Executable import libraries are treated as archive targets. + if(implib) { - cmSystemTools::Error("Error failed to create output directory: ", - out.c_str()); + propertyName = "ARCHIVE_OUTPUT_DIRECTORY"; } - } - } + else + { + propertyName = "RUNTIME_OUTPUT_DIRECTORY"; + } + } break; + default: break; + } + + // Select an output directory. + if(const char* outdir = this->GetProperty(propertyName)) + { + // Use the user-specified output directory. + out = outdir; + } + else if(this->GetType() == cmTarget::EXECUTABLE) + { + // Lookup the output path for executables. + out = this->Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH"); + } + else if(this->GetType() == cmTarget::STATIC_LIBRARY || + this->GetType() == cmTarget::SHARED_LIBRARY || + this->GetType() == cmTarget::MODULE_LIBRARY) + { + // Lookup the output path for libraries. + out = this->Makefile->GetSafeDefinition("LIBRARY_OUTPUT_PATH"); + } + if(out.empty()) + { + // Default to the current output directory. + out = "."; + } - return out.c_str(); + // Convert the output path to a full path in case it is + // specified as a relative path. Treat a relative path as + // relative to the current output directory for this makefile. + out = (cmSystemTools::CollapseFullPath + (out.c_str(), this->Makefile->GetStartOutputDirectory())); + return out; } //---------------------------------------------------------------------------- -const char* cmTarget::GetOutputDir(bool implib) +std::string cmTarget::GetFrameworkVersion() { - return this->GetAndCreateOutputDir(implib, true); + if(const char* fversion = this->GetProperty("FRAMEWORK_VERSION")) + { + return fversion; + } + else if(const char* tversion = this->GetProperty("VERSION")) + { + return tversion; + } + else + { + return "A"; + } } //---------------------------------------------------------------------------- diff --git a/Source/cmTarget.h b/Source/cmTarget.h index f90a059783..f7a21db932 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -253,7 +253,7 @@ public: configuration name is given then the generator will add its subdirectory for that configuration. Otherwise just the canonical output directory is given. */ - const char* GetDirectory(const char* config = 0, bool implib = false); + std::string GetDirectory(const char* config = 0, bool implib = false); /** Get the location of the target in the build tree for the given configuration. This location is suitable for use as the LOCATION @@ -348,8 +348,10 @@ public: /** Return true if builtin chrpath will work for this target */ bool IsChrpathUsed(); - std::string GetInstallNameDirForBuildTree(const char* config); - std::string GetInstallNameDirForInstallTree(const char* config); + std::string GetInstallNameDirForBuildTree(const char* config, + bool for_xcode = false); + std::string GetInstallNameDirForInstallTree(const char* config, + bool for_xcode = false); cmComputeLinkInformation* GetLinkInformation(const char* config); @@ -384,6 +386,10 @@ public: /** Return whether this target is an executable Bundle on Apple. */ bool IsAppBundleOnApple(); + /** Return the framework version string. Undefined if + IsFrameworkOnApple returns false. */ + std::string GetFrameworkVersion(); + /** Get a backtrace from the creation of the target. */ cmListFileBacktrace const& GetBacktrace() const; @@ -464,19 +470,14 @@ private: void SetPropertyDefault(const char* property, const char* default_value); // Get the full path to the target output directory. - const char* GetAndCreateOutputDir(bool implib, bool create); - - // Get the full path to the target output directory. - const char* GetOutputDir(bool implib); + std::string GetOutputDir(bool implib); + std::string const& cmTarget::ComputeBaseOutputDir(bool implib); const char* ImportedGetLocation(const char* config); const char* NormalGetLocation(const char* config); std::string GetFullNameImported(const char* config, bool implib); - const char* ImportedGetDirectory(const char* config, bool implib); - const char* NormalGetDirectory(const char* config, bool implib); - std::string ImportedGetFullPath(const char* config, bool implib); std::string NormalGetFullPath(const char* config, bool implib, bool realname); @@ -503,9 +504,8 @@ private: bool HaveInstallRule; std::string InstallPath; std::string RuntimeInstallPath; - std::string OutputDir; - std::string OutputDirImplib; - std::string Directory; + std::string BaseOutputDir; + std::string BaseOutputDirImplib; std::string Location; std::string ExportMacro; std::set<cmStdString> Utilities; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 88aed1dd9b..5e5859b3b0 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -618,7 +618,7 @@ void cmake::SetArgs(const std::vector<std::string>& args) else if(arg.find("--debug-output",0) == 0) { std::cout << "Running with debug output on.\n"; - this->DebugOutputOn(); + this->SetDebugOutputOn(true); } else if(arg.find("-G",0) == 0) { @@ -786,6 +786,19 @@ int cmake::AddCMakePaths() cMakeSelf = cmSystemTools::GetRealPath(cMakeSelf.c_str()); cMakeSelf += "/cmake"; cMakeSelf += cmSystemTools::GetExecutableExtension(); +#if __APPLE__ + // on the apple this might be the gui bundle + if(!cmSystemTools::FileExists(cMakeSelf.c_str())) + { + cMakeSelf = cmSystemTools::GetExecutableDirectory(); + cMakeSelf = cmSystemTools::GetRealPath(cMakeSelf.c_str()); + cMakeSelf += "../../../.."; + cMakeSelf = cmSystemTools::GetRealPath(cMakeSelf.c_str()); + cMakeSelf = cmSystemTools::CollapseFullPath(cMakeSelf.c_str()); + cMakeSelf += "/cmake"; + std::cerr << cMakeSelf.c_str() << "\n"; + } +#endif if(!cmSystemTools::FileExists(cMakeSelf.c_str())) { cmSystemTools::Error("CMake executable cannot be found at ", diff --git a/Source/cmake.h b/Source/cmake.h index 3f0c59887e..c1e9a728b0 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -317,7 +317,7 @@ class cmake // Do we want debug output during the cmake run. bool GetDebugOutput() { return this->DebugOutput; } - void DebugOutputOn() { this->DebugOutput = true;} + void SetDebugOutputOn(bool b) { this->DebugOutput = b;} // Define a property void DefineProperty(const char *name, cmProperty::ScopeType scope, diff --git a/Tests/Framework/CMakeLists.txt b/Tests/Framework/CMakeLists.txt index 58c2cfb111..3eb0dbc32d 100644 --- a/Tests/Framework/CMakeLists.txt +++ b/Tests/Framework/CMakeLists.txt @@ -10,8 +10,11 @@ add_library(foo SHARED fooNeither.h fooBoth.h test.lua + fooDeepPublic.h ) - +set_property(SOURCE fooDeepPublic.h + PROPERTY MACOSX_PACKAGE_LOCATION Headers/Deep + ) set(foo_ver ver4) set_target_properties(foo PROPERTIES @@ -20,6 +23,7 @@ set_target_properties(foo PROPERTIES PRIVATE_HEADER "fooPrivate.h;fooBoth.h" PUBLIC_HEADER "foo.h;foo2.h;fooPublic.h;fooBoth.h" RESOURCE "test.lua" + INSTALL_NAME_DIR "@executable_path/../../../Library/Frameworks" ) # fooBoth.h is listed as both public and private... (private wins...) # fooNeither.h is listed as neither public nor private... |