【发布时间】:2015-10-19 17:27:24
【问题描述】:
注意:我想指出我没有 C/C++ 知识,但我知道bash 所以请尝试提供功能解决方案而不是语言特定的解释。谢谢。
为了更清楚起见,我将把我的问题分成两个不同的部分:
1.)
我正在尝试使以下代码工作:
if (system("which kchmviewer > /dev/null") == 0)
{
// "which kchmviewer" exit code 0
#define USE_KCHMVIEWER 1
}
else
{
// "which kchmviewer" exit code 1
#define USE_KCHMVIEWER 0
}
说明:检查,运行时,kchmviewer在操作系统中是否可用,如果是,将USE_KCHMVIEWER设置为“1”(真) ,否则为“0”(假)。
2.)
我想将上面的代码放到VirtualBox代码库中,然后在以下情况下使用它来代替VBOX_OSE:
a.) 在UIMessageCenter::sltShowHelpHelpDialog(),包含#ifndef VBOX_OSE 的行将被替换为#ifdef USE_KCHMVIEWER;
b.) 在UIMessageCenter::sltShowUserManual(),行包含# ifndef VBOX_OSE 的行将替换为# ifdef USE_KCHMVIEWER;
c.) 在VBoxGlobal::helpFile() 中,包含# if defined VBOX_OSE 的行将替换为# if !defined USE_KCHMVIEWER。
// File: VirtualBox-5.0.6/src/VBox/Frontends/VirtualBox/src/globals/UIMessageCenter.cpp
void UIMessageCenter::sltShowHelpHelpDialog()
{
#ifndef VBOX_OSE
/* For non-OSE version we just open it: */
sltShowUserManual(vboxGlobal().helpFile());
#else /* #ifndef VBOX_OSE */
/* For OSE version we have to check if it present first: */
QString strUserManualFileName1 = vboxGlobal().helpFile();
QString strShortFileName = QFileInfo(strUserManualFileName1).fileName();
QString strUserManualFileName2 = QDir(vboxGlobal().homeFolder()).absoluteFilePath(strShortFileName);
/* Show if user manual already present: */
if (QFile::exists(strUserManualFileName1))
sltShowUserManual(strUserManualFileName1);
else if (QFile::exists(strUserManualFileName2))
sltShowUserManual(strUserManualFileName2);
/* If downloader is running already: */
else if (UIDownloaderUserManual::current())
{
/* Just show network access manager: */
gNetworkManager->show();
}
/* Else propose to download user manual: */
else if (cannotFindUserManual(strUserManualFileName1))
{
/* Create User Manual downloader: */
UIDownloaderUserManual *pDl = UIDownloaderUserManual::create();
/* After downloading finished => show User Manual: */
connect(pDl, SIGNAL(sigDownloadFinished(const QString&)), this, SLOT(sltShowUserManual(const QString&)));
/* Start downloading: */
pDl->start();
}
#endif /* #ifdef VBOX_OSE */
}
…
void UIMessageCenter::sltShowUserManual(const QString &strLocation)
{
#if defined (Q_WS_WIN32)
HtmlHelp(GetDesktopWindow(), strLocation.utf16(), HH_DISPLAY_TOPIC, NULL);
#elif defined (Q_WS_X11)
# ifndef VBOX_OSE
char szViewerPath[RTPATH_MAX];
int rc;
rc = RTPathAppPrivateArch(szViewerPath, sizeof(szViewerPath));
AssertRC(rc);
QProcess::startDetached(QString(szViewerPath) + "/kchmviewer", QStringList(strLocation));
# else /* #ifndef VBOX_OSE */
vboxGlobal().openURL("file://" + strLocation);
# endif /* #ifdef VBOX_OSE */
#elif defined (Q_WS_MAC)
vboxGlobal().openURL("file://" + strLocation);
#endif
}
// File: VirtualBox-5.0.6/src/VBox/Frontends/VirtualBox/src/globals/VBoxGlobal.cpp
QString VBoxGlobal::helpFile() const
{
#if defined (Q_WS_WIN32)
const QString name = "VirtualBox";
const QString suffix = "chm";
#elif defined (Q_WS_MAC)
const QString name = "UserManual";
const QString suffix = "pdf";
#elif defined (Q_WS_X11)
# if defined VBOX_OSE
const QString name = "UserManual";
const QString suffix = "pdf";
# else
const QString name = "VirtualBox";
const QString suffix = "chm";
# endif
#endif
/* Where are the docs located? */
char szDocsPath[RTPATH_MAX];
int rc = RTPathAppDocs (szDocsPath, sizeof (szDocsPath));
AssertRC (rc);
/* Make sure that the language is in two letter code.
* Note: if languageId() returns an empty string lang.name() will
* return "C" which is an valid language code. */
QLocale lang (VBoxGlobal::languageId());
/* Construct the path and the filename */
QString manual = QString ("%1/%2_%3.%4").arg (szDocsPath)
.arg (name)
.arg (lang.name())
.arg (suffix);
/* Check if a help file with that name exists */
QFileInfo fi (manual);
if (fi.exists())
return manual;
/* Fall back to the standard */
manual = QString ("%1/%2.%4").arg (szDocsPath)
.arg (name)
.arg (suffix);
return manual;
}
底线
如何做到这一点?我的操作系统是Trisquel 7.0 (GNU/Linux)。
感谢您的建议。
P.S.:更多详情请见this forum thread。
P.P.S.:由于我还不知道如何仅重建源代码的特定部分,因此尝试您的解决方案很可能需要我重新编译整个应用程序,然后我才能检查它是否工作与否。这可能需要一个小时或更长时间,请耐心等待。
更新:重新表述问题以反映我的发现。这次我尽量做到具体一点。
【问题讨论】:
-
如果进行如此小的更改“可能需要重新编译整个应用程序 [这] 可能需要一个小时或更长时间” 那么 1) 你的代码过度耦合和 2) 你的构建系统由 Rube Goldberg 设计。
-
@LightnessRacesinOrbit:因为我必须这样做。我还没有从开发人员那里得到帮助,所以我自己尝试这样做。
-
您想在构建时还是在运行时检查
kchmviewer? -
@Beta:这是因为我不知道如何仅重新编译已更改的部分。有可能,就是不知道怎么办。
-
@mYself
if (system("which kchmviewer") != 0)可能不会返回您期望的值,请参阅reference docs。
标签: c++ qt g++ virtualbox c-preprocessor