-I и -isystem различное поведение при компиляции - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть 3 проекта CMake: myapp-avr (исполняемый файл для AVR), myapp-unix (исполняемый файл для Unix) и my_lib (статическая библиотека c ++, импортируемая исполняемыми файлами). Когда я компилирую проект MyLib, у меня нет проблем вообще. Я также могу успешно скомпилировать проекты myapp-avr и myapp-unix. Тем не менее, я получаю ошибки при связывании моего app-avr, такие как «неопределенная ссылка на».

Я загрузил пример в GitHub: https://github.com/cajomferro/basic-cmake. Я основал свою структуру CMake на примере проекта Pablo Ariasal: https://github.com/pabloariasal/modern-cmake-sample.

Теперь я знаю, что проблема связана с параметром -isystem. Как может получиться, что та же самая точная команда работает с опцией -I, но не с опцией -isystem (которая предназначена для библиотек импортированных / вендоров)?

Не работает: (автоматически генерируется CMake)

/ usr / local / CrossPack-AVR / bin / avr-g ++ -DARDUINO = 10805 -DF_CPU = 16000000L - isystem mylib / include -Os -g -w -fpermissive -fno- исключения -функция-разделы -fdata-section -fno-threadsafe-statics -MMD -flto -mmcu = atmega328p -std = gnu ++ 11 -o src / main.cpp.obj -c src / main.cpp

Работает:

/ usr / local / CrossPack-AVR / bin / avr-g ++ -DARDUINO = 10805 -DF_CPU = 16000000L - I mylib / include -Os -g -w -fpermissive -fno- исключения -функция-разделы -fdata-section -fno-threadsafe-statics -MMD -flto -mmcu = atmega328p -std = gnu ++ 11 -o src / main.cpp.obj -c src / main.cpp


Согласно руководству по avr-g ++, -isystem означает: Поиск в каталоге заголовочных файлов после всех каталогов, указанных в -I, но перед стандартными системными каталогами. Отметьте его как системный каталог, чтобы он получал ту же специальную обработку, которая применяется к стандартным системным каталогам

Более того, читая об опциях -I, avr-g ++ говорит: вы не должны использовать эту опцию для добавления каталогов, содержащих файлы заголовков системы, поставляемые поставщиком (для этого используйте -isystem)

Полагаю, именно поэтому CMake автоматически генерирует файл Make с опцией -isystem вместо использования -I . Поскольку в моей конфигурации CMake я связываю библиотеки с помощью команды find_package (), CMake интерпретирует это как предоставляемую поставщиком систему?!

Этот проект прекрасно работает с clang (который также использует -isystem). Моя проблема с avr-g ++.

У кого-нибудь были проблемы с -системой , использующей avr-g ++? Можно ли заставить CMake использовать -I ?? Спасибо !!

1 Ответ

0 голосов
/ 10 октября 2018

Проблема решена! Очевидно -isystem имеет другое поведение на компиляторе GNU, в соответствии с https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html:

В очень старых системах некоторые из предопределенных системных каталогов заголовков получить еще более специальное лечение. GNU C ++ считает код в заголовках находится в этих каталогах в окружении внешнего блока "C".

У этих ребят была похожая проблема: https://github.com/conan-io/conan/issues/269.

Итак, чтобы избежать этого беспорядка, просто сообщите CMake, чтобы использовать вместо него -I. Требуется простая строка: NO_SYSTEM_FROM_IMPORTED ON (https://cmake.org/cmake/help/latest/prop_tgt/NO_SYSTEM_FROM_IMPORTED.html).

Пример:

set_target_properties(my_target
    PROPERTIES
    NO_SYSTEM_FROM_IMPORTED ON
    )

Полный пример находится в моем CMakeLists.txt исполняемого файла myapp-avr: https://github.com/cajomferro/basic-cmake/blob/master/myapp-avr/CMakeLists.txt.

...