📄 makefiledeps.cpp
字号:
}
}
if(!exists) { //heuristic lookup
lfn = findFileForDep(QMakeLocalFileName(inc), file->file);
if((exists = !lfn.isNull()))
lfn = fixPathForFile(lfn);
}
} else {
exists = QFile::exists(lfn.real());
}
if(!lfn.isNull()) {
dep = files->lookupFile(lfn);
if(!dep) {
dep = new SourceFile;
dep->file = lfn;
dep->type = QMakeSourceFileInfo::TYPE_C;
files->addFile(dep);
includes->addFile(dep, inc, false);
}
dep->exists = exists;
}
}
if(dep) {
dep->included_count++;
if(dep->exists) {
debug_msg(5, "%s:%d Found dependency to %s", file->file.real().toLatin1().constData(),
line_count, dep->file.local().toLatin1().constData());
file->deps->addChild(dep);
}
}
}
}
if(dependencyMode() == Recursive) { //done last because buffer is shared
for(int i = 0; i < file->deps->used_nodes; i++) {
if(!file->deps->children[i]->deps)
findDeps(file->deps->children[i]);
}
}
return true;
}
bool QMakeSourceFileInfo::findMocs(SourceFile *file)
{
if(file->moc_checked)
return true;
files_changed = true;
file->moc_checked = true;
int buffer_len;
char *buffer = 0;
{
struct stat fst;
int fd;
#if defined(_MSC_VER) && _MSC_VER >= 1400
if (_sopen_s(&fd, fixPathForFile(file->file, true).local().toLocal8Bit().constData(),
_O_RDONLY, _SH_DENYRW, _S_IREAD) != 0)
fd = -1;
#else
fd = open(fixPathForFile(file->file, true).local().toLocal8Bit().constData(), O_RDONLY);
#endif
if(fd == -1 || fstat(fd, &fst) || S_ISDIR(fst.st_mode))
return false; //shouldn't happen
buffer = getBuffer(fst.st_size);
for(int have_read = buffer_len = 0;
(have_read = QT_READ(fd, buffer + buffer_len, fst.st_size - buffer_len));
buffer_len += have_read);
QT_CLOSE(fd);
}
debug_msg(2, "findMocs: %s", file->file.local().toLatin1().constData());
int line_count = 1;
bool ignore_qobject = false, ignore_qgadget = false;
/* qmake ignore Q_GADGET */
/* qmake ignore Q_OBJECT */
for(int x = 0; x < buffer_len; x++) {
if(*(buffer + x) == '/') {
++x;
if(buffer_len >= x) {
if(*(buffer + x) == '/') { //c++ style comment
for(;x < buffer_len && !qmake_endOfLine(*(buffer + x)); ++x);
++line_count;
} else if(*(buffer + x) == '*') { //c style comment
for(;x < buffer_len; ++x) {
if(*(buffer + x) == 't' || *(buffer + x) == 'q') { //ignore
if(buffer_len >= (x + 20) &&
!strncmp(buffer + x + 1, "make ignore Q_OBJECT", 20)) {
debug_msg(2, "Mocgen: %s:%d Found \"qmake ignore Q_OBJECT\"",
file->file.real().toLatin1().constData(), line_count);
x += 20;
ignore_qobject = true;
} else if(buffer_len >= (x + 20) &&
!strncmp(buffer + x + 1, "make ignore Q_GADGET", 20)) {
debug_msg(2, "Mocgen: %s:%d Found \"qmake ignore Q_GADGET\"",
file->file.real().toLatin1().constData(), line_count);
x += 20;
ignore_qgadget = true;
}
} else if(*(buffer + x) == '*') {
if(buffer_len >= (x+1) && *(buffer + (x+1)) == '/') {
x += 2;
break;
}
} else if(Option::debug_level && qmake_endOfLine(*(buffer + x))) {
++line_count;
}
}
}
}
}
if(((buffer_len > x+2 && *(buffer+x+1) == 'Q' && *(buffer+x+2) == '_')
||
(buffer_len > x+4 && *(buffer+x+1) == 'Q' && *(buffer+x+2) == 'O'
&& *(buffer+x+3) == 'M' && *(buffer+x+4) == '_'))
&&
*(buffer + x) != '_' &&
(*(buffer + x) < 'a' || *(buffer + x) > 'z') &&
(*(buffer + x) < 'A' || *(buffer + x) > 'Z') &&
(*(buffer + x) < '0' || *(buffer + x) > '9')) {
++x;
int match = 0;
static const char *interesting[] = { "OBJECT", "GADGET",
"M_OBJECT" };
for(int interest = 0, m1, m2; interest < 3; ++interest) {
if(interest == 0 && ignore_qobject)
continue;
else if(interest == 1 && ignore_qgadget)
continue;
for(m1 = 0, m2 = 0; *(interesting[interest]+m1); ++m1) {
if(*(interesting[interest]+m1) != *(buffer+x+2+m1)) {
m2 = -1;
break;
}
++m2;
}
if(m1 == m2) {
match = m2 + 2;
break;
}
}
if(match && *(buffer+x+match) != '_' &&
(*(buffer+x+match) < 'a' || *(buffer+x+match) > 'z') &&
(*(buffer+x+match) < 'A' || *(buffer+x+match) > 'Z') &&
(*(buffer+x+match) < '0' || *(buffer+x+match) > '9')) {
if(Option::debug_level) {
*(buffer+x+match) = '\0';
debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s", file->file.real().toLatin1().constData(),
line_count, buffer+x);
}
file->mocable = true;
return true;
}
}
if(Option::debug_level && qmake_endOfLine(*(buffer+x)))
++line_count;
}
return true;
}
void QMakeSourceFileInfo::saveCache(const QString &cf)
{
#ifdef QMAKE_USE_CACHE
if(cf.isEmpty())
return;
QFile file(QMakeLocalFileName(cf).local());
if(file.open(QIODevice::WriteOnly)) {
QTextStream stream(&file);
stream << qmake_version() << endl << endl; //version
{ //cache verification
QMap<QString, QStringList> verify = getCacheVerification();
stream << verify.count() << endl;
for(QMap<QString, QStringList>::iterator it = verify.begin();
it != verify.end(); ++it) {
stream << it.key() << endl << it.value().join(";") << endl;
}
stream << endl;
}
if(files->nodes) {
for(int file = 0; file < files->num_nodes; ++file) {
for(SourceFiles::SourceFileNode *node = files->nodes[file]; node; node = node->next) {
stream << node->file->file.local() << endl; //source
stream << node->file->type << endl; //type
//depends
stream << ";";
if(node->file->deps) {
for(int depend = 0; depend < node->file->deps->used_nodes; ++depend) {
if(depend)
stream << ";";
stream << node->file->deps->children[depend]->file.local();
}
}
stream << endl;
stream << node->file->mocable << endl; //mocable
stream << endl; //just for human readability
}
}
}
stream.flush();
file.close();
}
#else
Q_UNUSED(cf);
#endif
}
void QMakeSourceFileInfo::loadCache(const QString &cf)
{
if(cf.isEmpty())
return;
#ifdef QMAKE_USE_CACHE
QMakeLocalFileName cache_file(cf);
int fd = open(QMakeLocalFileName(cf).local().toLatin1(), O_RDONLY);
if(fd == -1)
return;
QFileInfo cache_fi = findFileInfo(cache_file);
if(!cache_fi.exists() || cache_fi.isDir())
return;
QFile file;
if(!file.open(QIODevice::ReadOnly, fd))
return;
QTextStream stream(&file);
if(stream.readLine() == qmake_version()) { //version check
stream.skipWhiteSpace();
bool verified = true;
{ //cache verification
QMap<QString, QStringList> verify;
int len = stream.readLine().toInt();
for(int i = 0; i < len; ++i) {
QString var = stream.readLine();
QString val = stream.readLine();
verify.insert(var, val.split(';', QString::SkipEmptyParts));
}
verified = verifyCache(verify);
}
if(verified) {
stream.skipWhiteSpace();
if(!files)
files = new SourceFiles;
while(!stream.atEnd()) {
QString source = stream.readLine();
QString type = stream.readLine();
QString depends = stream.readLine();
QString mocable = stream.readLine();
stream.skipWhiteSpace();
QMakeLocalFileName fn(source);
QFileInfo fi = findFileInfo(fn);
SourceFile *file = files->lookupFile(fn);
if(!file) {
file = new SourceFile;
file->file = fn;
files->addFile(file);
file->type = (SourceFileType)type.toInt();
file->exists = fi.exists();
}
if(fi.exists() && fi.lastModified() < cache_fi.lastModified()) {
if(!file->dep_checked) { //get depends
if(!file->deps)
file->deps = new SourceDependChildren;
file->dep_checked = true;
QStringList depend_list = depends.split(";", QString::SkipEmptyParts);
for(int depend = 0; depend < depend_list.size(); ++depend) {
QMakeLocalFileName dep_fn(depend_list.at(depend));
QFileInfo dep_fi(findFileInfo(dep_fn));
SourceFile *dep = files->lookupFile(dep_fn);
if(!dep) {
dep = new SourceFile;
dep->file = dep_fn;
dep->exists = dep_fi.exists();
dep->type = QMakeSourceFileInfo::TYPE_UNKNOWN;
files->addFile(dep);
}
dep->included_count++;
file->deps->addChild(dep);
}
}
if(!file->moc_checked) { //get mocs
file->moc_checked = true;
file->mocable = mocable.toInt();
}
}
}
}
}
#endif
}
QMap<QString, QStringList> QMakeSourceFileInfo::getCacheVerification()
{
return QMap<QString, QStringList>();
}
bool QMakeSourceFileInfo::verifyCache(const QMap<QString, QStringList> &v)
{
return v == getCacheVerification();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -