Skip to content

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

Description

@BadEugene

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

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

Для начала опишем ситуацию, допустим у нас есть большой проект, влючающий в себя еще кучу проектов, в одном из этих проектов нас интересует вот такой исходник 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!!! Вот мы его и вычислили. Всем спасибо, ставим лайки!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions