Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
BadEugene opened this issue Nov 6, 2013 · 1 comment

Comments

@BadEugene
Copy link

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

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

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

midenok commented Nov 6, 2013

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

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

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

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

No branches or pull requests

2 participants