Комментарии 6
Доброго дня. Очень интересно. Но есть вопрос. А обязательно использовать Keil MDK, можно ли вместо него тулчейн GCC?
Да, конечно, можно и GCC — оно идет по-умолчанию, и уже сто лет как поддерживается.
Просто если хочется отладки с GCC, то нужно выбирать «поставщиков» отладки типа GDB (например, OpenOCD, StLink Utility и прочее).
А вот если хочется отладки с Keil — то «поставщиков» отладки типа UVSC (тех, что имеют префиксы uVision).
А вот чтобы миксовать их, например для GCC использовать поставщик от uVision — я не пробовал. Хотя обратное работает — когда мы отлаживаем код, скомпиленный компилятором от Keil-а в GDB.
xtensa не поддерживается LLVM/CLang, как результат парсинг и модель ломается в QtC. Для себя решил подобным хаком:
diff --git a/src/tools/clangbackend/source/clangtranslationunitupdater.cpp b/src/tools/clangbackend/source/clangtranslationunitupdater.cpp
index 0383a1028f..6aedc231c4 100644
--- a/src/tools/clangbackend/source/clangtranslationunitupdater.cpp
+++ b/src/tools/clangbackend/source/clangtranslationunitupdater.cpp
@@ -106,22 +106,48 @@ void TranslationUnitUpdater::createTranslationUnitIfNeeded()
if (!m_cxTranslationUnit) {
m_cxTranslationUnit = CXTranslationUnit();
- const auto args = commandLineArguments();
- if (isVerboseModeEnabled())
- args.print();
-
- UnsavedFilesShallowArguments unsaved = m_in.unsavedFiles.shallowArguments();
-
- m_parseErrorCode = clang_parseTranslationUnit2(m_cxIndex,
- nullptr,
- args.data(),
- args.count(),
- unsaved.data(),
- unsaved.count(),
- defaultParseOptions(),
- &m_cxTranslationUnit);
-
-
+ auto compilationArguments = m_in.compilationArguments;
+
+ for (int i = 0; i < 2; ++i) {
+ const auto args = CommandLineArguments(m_in.filePath.constData(),
+ compilationArguments,
+ isVerboseModeEnabled());
+ if (isVerboseModeEnabled())
+ args.print();
+
+ UnsavedFilesShallowArguments unsaved = m_in.unsavedFiles.shallowArguments();
+
+ m_parseErrorCode = clang_parseTranslationUnit2(m_cxIndex,
+ nullptr,
+ args.data(),
+ args.count(),
+ unsaved.data(),
+ unsaved.count(),
+ defaultParseOptions(),
+ &m_cxTranslationUnit);
+
+
+
+ if (parseWasSuccessful()) {
+ break;
+ }
+
+ // Give a second chance without `--target=xxx` option:
+ // LLVM does not support all GCC targets, like: Microblaze, Xtensa and so on
+ // in such cases, parsing fails. By default, LLVM fallback to i386 or x86_64 targets
+ // according -m32/-m64 options.
+ int j;
+ for (j = 0; j < compilationArguments.count(); ++j) {
+ if (compilationArguments.at(j).startsWith("--target="))
+ break;
+ }
+ if (j < compilationArguments.count()) {
+ compilationArguments.remove(j);
+ } else {
+ // `--target=` not found
+ break;
+ }
+ }
if (parseWasSuccessful()) {
updateIncludeFilePaths();
@@ -217,11 +243,4 @@ bool TranslationUnitUpdater::reparseWasSuccessful() const
return m_reparseErrorCode == 0;
}
-CommandLineArguments TranslationUnitUpdater::commandLineArguments() const
-{
- return CommandLineArguments(m_in.filePath.constData(),
- m_in.compilationArguments,
- isVerboseModeEnabled());
-}
-
} // namespace ClangBackEnd
diff --git a/src/tools/clangbackend/source/clangtranslationunitupdater.h b/src/tools/clangbackend/source/clangtranslationunitupdater.h
index a0f0d0ba3b..fa535e2c69 100644
--- a/src/tools/clangbackend/source/clangtranslationunitupdater.h
+++ b/src/tools/clangbackend/source/clangtranslationunitupdater.h
@@ -85,7 +85,6 @@ public:
TranslationUnitUpdateResult update(UpdateMode mode);
- CommandLineArguments commandLineArguments() const;
static uint defaultParseOptions();
private:
Аналогичная ситуация с Microblaze (патч решает и для него). Первый нужен как часть хобби, второй был нужен (и, возможно, потребуется) по работе.
PS мне проще, я регулярно собираю QtC из исходников с master'а, поэтому наложить патч не проблема.
Да, у QtC шного парсера (что clang, что дефолтного) проблемы с парсингом кода для специфичных архитектур. Например, если имеются какие-нибудь особенные ключевые слова (например, для 8051 такие как 'data', 'xdata', 'sfr' и прочие), которых парсер не знает.
Я даже баг-трекер создавал с предложением расширить парсеры так, чтобы можно было из любых плагинов QtC дополнять словарь ключевых слов для текущего выбранного тулчейна (хотя-бы для встроенного не-clang парсера). Например, если используем тулчейн от Keil и архитектура 8051 — то «подключаем» ключевые слова именно для этой архитектуры и этого тулчейна и т.д. Но что-то никто не хочет с этим связываться.
Но а по поводу xtensa я что-то не понял в чем там проблема? Ведь там используется обычный GCC. Правда, я использую с xtensa (esp8266) всегда встроенный парсер вместо clang-овского, т.к. он менее глючный.
Ведь там используется обычный GCC.
так GCC не используется для построения кодовой модели. А libllvm сталкивается с тем, что не знает xtensa. Если коротко (можно поглядеть на патч) то передаётся триплет target= с указанием xstensa-что-то-там и парсер для юнита тупо завершается ошибкой. В результате юнит вообще не парсится и спользуется только базовая подстветка синтаксиса. Как бы так. WA заключается в том, что сначала попытаться парсить с переданной строкой, а потом исключать "--target" и попытаться снова. Да, будет сделано предположение, что это x86 или x86_64, но для моих целей этого оказалось достаточно.
В общем, парсер на основе clang будет ломаться всегда, если clang не знает каких-то архитектур. И то, что для сборки используется GCC, IAR или что-то ещё никакой роли не играет :)
Обзор возможностей Qt Creator 4.13 и QBS 1.17 для программирования микроконтроллеров