/ usr / local / include непреднамеренно добавленный в мои команды компиляции приводит к сбою сборки - PullRequest
0 голосов
/ 24 февраля 2020

Фон

Я компилирую на машине с MacOS 10.15 проект, который в качестве подмодуля поставляет старую версию libpng (1.6.17). Соответствующий код доступен по адресу https://github.com/glennrp/libpng. У меня также есть libpng 1.6.37, установленный Homebrew.

Пока не очень долго, go, я смог без проблем скомпилировать libpng 1.6.17, используя CMake. Так как совсем недавно (но точная дата мне неизвестна), сборка завершается с ошибками типа:

FAILED: CMakeFiles/png16_static.dir/pngwutil.o
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc  -I/usr/local/include -I. -I../ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -MD -MT CMakeFiles/png16_static.dir/pngwutil.o -MF CMakeFiles/png16_static.dir/pngwutil.o.d -o CMakeFiles/png16_static.dir/pngwutil.o   -c ../pngwutil.c
../pngwutil.c:2413:20: error: use of undeclared identifier 'PNG_WEIGHT_SHIFT'
                   PNG_WEIGHT_SHIFT;
                   ^

Я провел несколько проверок на копию моего проекта, который у меня был, который все еще скомпилирован правильно, поскольку CMake не не повторяю себя на этом. Единственное различие между этими двумя случаями заключается в добавлении флага -I/usr/local/include к вызовам компилятора (я добавил некоторую разметку, чтобы помочь увидеть разницу):

  • suceeds:
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -Dpng16_EXPORTS -Iext_build/libpng -I../../ext/libpng -O3 -DNDEBUG -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -fPIC   -fno-stack-protector -fomit-frame-pointer -fno-math-errno -ffp-contract=fast -march=native -MD -MT ext_build/libpng/CMakeFiles/png16.dir/pngrio.o -MF ext_build/libpng/CMakeFiles/png16.dir/pngrio.o.d -o ext_build/libpng/CMakeFiles/png16.dir/pngrio.o   -c ../../ext/libpng/pngrio.c
                                                                                             <---------------------------------->
    
  • терпит неудачу :
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -Dpng16_EXPORTS -I/usr/local/include -Iext_build/libpng -I../../ext/libpng -O3 -DNDEBUG -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -fPIC   -fno-stack-protector -fomit-frame-pointer -fno-math-errno -ffp-contract=fast -march=native -MD -MT ext_build/libpng/CMakeFiles/png16.dir/pngrio.o -MF ext_build/libpng/CMakeFiles/png16.dir/pngrio.o.d -o ext_build/libpng/CMakeFiles/png16.dir/pngrio.o   -c ../../ext/libpng/pngrio.c
                                                                                             <------------------------------------------------------->
    

Я перезапустил CMake на работающей копии проекта, и я получил ту же ошибку, которая указала мне на проблему, связанную с системой. Затем я напрямую проверил исходники libpng и получил ту же ошибку.

Шаги для воспроизведения

  1. Клонируйте репозиторий libpng и проверьте v1.6.17
    git clone https://github.com/glennrp/libpng.git
    cd libpng
    git checkout v1.6.17
    
  2. Build libpng
    cmake . -B build && cmake --build build
    

Вопрос

Что добавило этот флаг -I/usr/local/include к моим вызовам компилятора?

Бонусный вопрос ( может быть, интереснее)

Теперь это становится смешным. Если вы извлечете более свежую версию libpng (я пробовал с 1.6.21, 1.6.25, 1.6.28, 1.6.33 и 1.6.37), проблема исчезнет, ​​хотя флаг все еще здесь:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc  -I/usr/local/include -I. -I../ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -MD -MT CMakeFiles/png16_static.dir/pngrio.o -MF CMakeFiles/png16_static.dir/pngrio.o.d -o CMakeFiles/png16_static.dir/pngrio.o   -c ../pngrio.c

Это означает, что я мог бы обновить свой подмодуль, используя один из этих выпусков, и моя проблема исчезнет go.

Однако, если я не ошибаюсь, -I флаги разрешаются слева направо правильно: поэтому я подозреваю, что мои исходные заголовки используются вместо исходных. Если я прав, то это не гарантирует, что обновление libpng для Homebrew больше не повредит сборке: оно просто показывает, что API libpng был стабильным с v1.6.21 и что я могу использовать свои заголовки Homebrew с исходным кодом Я пытаюсь скомпилировать. Я прав, или я что-то упустил?

Ответы [ 3 ]

1 голос
/ 25 февраля 2020
  1. ответ на вопрос: системный путь добавления добавляется компилятором / препроцессором ( эта страница объяснит больше данных)
  2. порядок включения в проект CMake может быть изменен (не уверен, сколько), CMake позволяет предварительно включить в список; попробуйте сравнить сценарии сборки CMake между выпусками. Я верю, что будет упомянуто изменение.
0 голосов
/ 25 февраля 2020

Я наконец докопался до сути. Оказалось, что зависимость liblib от zlib доставила мне неприятности (косвенно).

Что случилось

MacOS поставляет zlib, и это обычно известно разработчикам, которые поэтому не чувствуют необходимости установить сторонний zlib. Однако CMake find_package не знает об этом предпочтении и подберет реализацию zlib, найденную в /usr/local, например, если она установлена ​​Homewbrew. По какой-то причине zlib был установлен сторонним программным обеспечением в этом месте на моей системе, а не пакетом Homebrew, что усложнило обнаружение и было обнаружено find_package.

Соответствующим каталогом include это /usr/local/include. Код CMake в libpng таков, что этот каталог затем добавляется в список включаемых каталогов, что приводит к конфликтам заголовков, упомянутым в вопросе. Я понял, что происходит, пройдя через CMakeCache.txt (поиск /usr/local/include), поэтому основной урок: не забудьте проверить свой кэш CMake в таких ситуациях .

Как решить проблему

Ленивый путь . Удалите ненужные файлы lib. Я запустил brew doctor и удалил файлы, которых здесь не должно быть. Это, однако, может иметь нежелательные последствия, если конкретная версия c zlib, находящаяся в /usr/local, действительно требуется некоторым программным обеспечением.

Грязный путь CMake . Измените код CMake верхнего уровня, чтобы подсказка find_package о том, где он должен выбрать zlib. Либо жестко закодируйте подсказку, используя аргумент PATHS, либо установите его, используя аргумент ZLIB_ROOT (вам, возможно, придется определить политику для этого).

Я уверен, что есть лучший способ справиться с этим "делать правильно CMake" в libpng и форсировать поиск библиотек по системным путям, но мои навыки CMake недостаточно хороши, чтобы точно сказать, что нужно делать. И вообще, это немного не так c в отношении вопроса.

0 голосов
/ 25 февраля 2020

Да, иногда cmake подбирает различные библиотеки и включает в себя dirs и свободно смешивает и сочетает. Если вам нужно поддерживать несколько версий, вы должны использовать команду cmake для передачи правильных пакетов.

...