lkde / edu

Educational repository for all sorts of experiments
2 stars 0 forks source link

Определяем хеадер, через который подключается необходимый макрос. #7

Open BadEugene opened 11 years ago

BadEugene commented 11 years ago

Итаааак... я добрался до жит хабаааа!!! (Скромные аплодисменты)

И в первой статье я расскажу Вам как вычислить, через какой хеадер подключается макрос.

Для начала опишем ситуацию, допустим у нас есть большой проект, влючающий в себя еще кучу проектов, в одном из этих проектов нас интересует вот такой исходник main.cpp, вот его примерный код:

#include <KApplication>
#include <KAboutData>
#include <KCmdLineArgs>

// И еще куча инклудов

extern "C"
KDE_EXPORT int kdemain(int argc, char **argv)
{

  // bla bla bla
  // bla bla bla

  return 0;
}

Внимание вопрос! Через какой хеадер подключается макрос KDE_EXPORT?

Конечно если мы откроем проект в среде разработки, например в KDevelop, и наведем курсор мышки на этот макрос, то мы узнаем, что макрос находится в файле kdemacros.h. Но вот беда, нет среди подключенных хеадеров этого файла, это значит он включен в другой хеадер, а тот в другой хеадер, а тот еще в другой, и вот этот последний подключен в нашем main.cpp.

Ответ прост, для начала сконфигурируем этот проект. Затем выполним команду "make VERBOSE=1 | grep main.cpp". Опция VERBOSE указывает команде make выводить наиподробнейшую информацию об этапах сборки. А grep отфильтрует все лишнее и оставит только строки с main.cpp. В процессе сборки мы увидим сообщение подобное этому:

cd /home/test/kde/build-kicker/kicker4 && /usr/bin/c++   -DDISABLE_NEPOMUK_LEGACY -DHAVE_CONFIG_H=1 -DKDE4_CMAKE_TOPLEVEL_DIR_LENGTH=31 -DKDE_DEPRECATED_WARNINGS -DQT_NO_CAST_TO_ASCII -DQT_NO_STL -DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS -D_BSD_SOURCE -D_REENTRANT -D_XOPEN_SOURCE=500 -Dkdeinit_kicker4_EXPORTS -Wnon-virtual-dtor -Wno-long-long -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wformat-security -fno-exceptions -DQT_NO_EXCEPTIONS -fno-check-new -fno-common -Woverloaded-virtual -fno-threadsafe-statics -fvisibility=hidden -Werror=return-type -fvisibility-inlines-hidden -O2 -g -DNDEBUG -DQT_NO_DEBUG -fPIC -I/home/test/kde/build-kicker/kicker4 -I/home/test/kde/sources/jeka/KDE/kde-workspace/kicker4 -I/home/test/kde/sources/jeka/KDE/kde-workspace -I/home/test/kde/build-kicker -I/home/test/kde/sources/jeka/KDE/kde-workspace/libs -I/usr/include/KDE -I/usr/include/QtXmlPatterns -I/usr/include/QtXml -I/usr/include/QtWebKit -I/usr/include/QtUiTools -I/usr/include/QtTest -I/usr/include/QtSvg -I/usr/include/QtSql -I/usr/include/QtScriptTools -I/usr/include/QtScript -I/usr/include/QtOpenGL -I/usr/include/QtNetwork -I/usr/include/QtMultimedia -I/usr/include/QtHelp -I/usr/include/QtDesigner -I/usr/include/QtDeclarative -I/usr/include/QtDBus -I/usr/include/Qt3Support -I/usr/include/QtGui -I/usr/include/QtCore -I/usr/include/Qt -I/usr/share/qt4/mkspecs/default    -D_GNU_SOURCE -D_LARGEFILE64_SOURCE -o CMakeFiles/kdeinit_kicker4.dir/main.o -c /home/test/kde/sources/jeka/KDE/kde-workspace/kicker4/main.cpp

Первая команда "cd" с параметрами нас не интересует, а вот "/usr/bin/c++ -DDISABLE..." - это то что надо. Копируем команду со всеми параметрами "/usr/bin/c++ -DDISABLE...", меняем параметр опции "-o" на "-o main.txt", сразу же за этой опцией добавляем опцию "-E" и команду для препроцессора "-Xpreprocessor -dI".

Опция "-o main.txt" указывает компиллятору сохранить результат работы в файл main.txt

Опция "-E" остановит компиллятор сразу после окончания работы препроцессора. Тоесть до компиляции исполняемого файла дело не дойдет. Опция с параметрами "-Xpreprocessor -dI" укажет препроцессору дополнить вывод информацией о всех директивах "#include".

Таким образом, наша новая команда будет выглядеть вот так:

/usr/bin/c++   -DDISABLE_NEPOMUK_LEGACY -DHAVE_CONFIG_H=1 -DKDE4_CMAKE_TOPLEVEL_DIR_LENGTH=31 -DKDE_DEPRECATED_WARNINGS -DQT_NO_CAST_TO_ASCII -DQT_NO_STL -DQT_USE_FAST_CONCATENATION -DQT_USE_FAST_OPERATOR_PLUS -D_BSD_SOURCE -D_REENTRANT -D_XOPEN_SOURCE=500 -Dkdeinit_kicker4_EXPORTS -Wnon-virtual-dtor -Wno-long-long -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wformat-security -fno-exceptions -DQT_NO_EXCEPTIONS -fno-check-new -fno-common -Woverloaded-virtual -fno-threadsafe-statics -fvisibility=hidden -Werror=return-type -fvisibility-inlines-hidden -O2 -g -DNDEBUG -DQT_NO_DEBUG -fPIC -I/home/test/kde/build-kicker/kicker4 -I/home/test/kde/sources/jeka/KDE/kde-workspace/kicker4 -I/home/test/kde/sources/jeka/KDE/kde-workspace -I/home/test/kde/build-kicker -I/home/test/kde/sources/jeka/KDE/kde-workspace/libs -I/usr/include/KDE -I/usr/include/QtXmlPatterns -I/usr/include/QtXml -I/usr/include/QtWebKit -I/usr/include/QtUiTools -I/usr/include/QtTest -I/usr/include/QtSvg -I/usr/include/QtSql -I/usr/include/QtScriptTools -I/usr/include/QtScript -I/usr/include/QtOpenGL -I/usr/include/QtNetwork -I/usr/include/QtMultimedia -I/usr/include/QtHelp -I/usr/include/QtDesigner -I/usr/include/QtDeclarative -I/usr/include/QtDBus -I/usr/include/Qt3Support -I/usr/include/QtGui -I/usr/include/QtCore -I/usr/include/Qt -I/usr/share/qt4/mkspecs/default    -D_GNU_SOURCE -D_LARGEFILE64_SOURCE -o main.txt -E -Xpreprocessor -dI -c /home/test/kde/sources/jeka/KDE/kde-workspace/kicker4/main.cpp

После выполнения мы получим файл main.txt, заглянув в который, мы обнаружим такие строки:

#1 "/home/test/kde/sources/jeka/KDE/kde-workspace/kicker4/main.cpp"
#1 "/home/test/kde/build-kicker/kicker4//"
#1 "<command-line>"
#1 "/home/test/kde/sources/jeka/KDE/kde-workspace/kicker4/main.cpp"
#include <KApplication>
#1 "/home/test/kde/sources/jeka/KDE/kde-workspace/kicker4/main.cpp"
#1 "/usr/include/KDE/KApplication" 1
#include "../kapplication.h"
#1 "/usr/include/KDE/KApplication"
#1 "/usr/include/KDE/../kapplication.h" 1
#26 "/usr/include/KDE/../kapplication.h"
#include "kdeversion.h"
#26 "/usr/include/KDE/../kapplication.h"
#1 "/usr/include/KDE/../kdeversion.h" 1
#30 "/usr/include/KDE/../kdeversion.h"
#include <kdecore_export.h>
#30 "/usr/include/KDE/../kdeversion.h"
#1 "/usr/include/kdecore_export.h" 1 3 4
#24 "/usr/include/kdecore_export.h" 3 4
#include <kdemacros.h>
#24 "/usr/include/kdecore_export.h" 3 4
#1 "/usr/include/kdemacros.h" 1 3 4
#162 "/usr/include/kdemacros.h" 3 4
#include <QtCore/qglobal.h>
#162 "/usr/include/kdemacros.h" 3 4
#1 "/usr/include/QtCore/qglobal.h" 1 3 4
#45 "/usr/include/QtCore/qglobal.h" 3 4
#include <stddef.h>
#45 "/usr/include/QtCore/qglobal.h" 3 4
#1 "/usr/lib64/gcc/x86_64-suse-linux/4.7/include/stddef.h" 1 3 4
#150 "/usr/lib64/gcc/x86_64-suse-linux/4.7/include/stddef.h" 3 4
typedef long int ptrdiff_t;
#213 "/usr/lib64/gcc/x86_64-suse-linux/4.7/include/stddef.h" 3 4
typedef long unsigned int size_t;
#46 "/usr/include/QtCore/qglobal.h" 2 3 4
#62 "/usr/include/QtCore/qglobal.h" 3 4
#include <QtCore/qconfig.h>
#62 "/usr/include/QtCore/qglobal.h" 3 4
#1 "/usr/include/QtCore/qconfig.h" 1 3 4
#63 "/usr/include/QtCore/qglobal.h" 2 3 4
#920 "/usr/include/QtCore/qglobal.h" 3 4

Из этого списка можно понять, что: kdemacros.h подключается к kdecore_export.h в 24-й строке kdecore_export.h подключается к kdeversion.h в 30-й строке kdeversion.h в свою очередь подключается к kapplication.h в 26-й строке kapplication.h подключается к KApplication в 1-й строке KApplication наконец подключается к main.cpp в 1-й строке.

Итак, макрос KDE_EXPORT определен посредством файла KApplication.h!!! Вот мы его и вычислили. Всем спасибо, ставим лайки!

midenok commented 11 years ago

Ставлю лайк! :) +1

Единственное замечание (которое нужно добавить в текст):

-DDISABLE_NEPOMUK_LEGACY -DHAVE_CONFIG_H=1 ... и прочая шушера-мушера нам конечно не нужны, если мы ставим опцию -E. Мы их оставляем чисто по причине экономии телодвижений.