У меня новый M2 Mac Mini. У меня есть этот простой тестовый файл С++:
% cat conftest.cpp
#include <limits>
#include <cmath>
#include <algorithm>
int main(int argc, char **argv) { return 0;}
Мне нужно скомпилировать его с помощью c++, а не clang++ (настоящая проблема заключается в создании зависимости conan, которая делает это, поэтому я не могу легко ее переключить).
У меня есть XCode 14.2 (думаю, последняя) и этот С++
% g++ --version
Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: arm64-apple-darwin22.3.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
Из моего чтения я знаю, что, поскольку Catalina XCode g++ не находит автоматически стандартные заголовочные файлы и каталоги lib, как это делает clang на Mac, поэтому я думаю, что мне нужно установить CPATH и LIBPATH.
% echo $LIBRARY_PATH
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
% echo $CPATH
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include
К сожалению, компиляция этого приводит к ошибке, которая, по-видимому, является конфликтом между cmath и algorithm, потому что удаление любого из них приводит к компиляции и компоновке:
% /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ conftest.cpp
In file included from conftest.cpp:4:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:653:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:499:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional/bind_back.h:15:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional/perfect_forward.h:17:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/tuple:159:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional_base:22:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/exception:83:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cstdlib:130:9: error: target of using declaration conflicts with declaration already in scope
using ::abs _LIBCPP_USING_IF_EXISTS;
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdlib.h:132:6: note: target of using declaration
int abs(int) __pure2;
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cmath:338:1: note: conflicting declaration
using ::abs _LIBCPP_USING_IF_EXISTS;
^
Я должен упустить что-то простое. Эта тестовая программа компилируется и отлично работает на godbolt и Windows. Любые идеи, кто-нибудь?
Я предполагаю, что это какое-то странное поведение Apple, поэтому я удалил свой ответ. Я мало что знаю об этом. Я предлагаю вам удалить вызов ::abs из примера, так как нет необходимости воспроизводить проблему и это может сбивать с толку, поскольку потенциально это также отдельная проблема.
Это конкретно Каталина? Потому что я на Вентуре, и без установки переменных среды я могу собрать вашу тестовую программу с помощью g++? Всегда полезно посмотреть, что делает оболочка, используя -### в аргументах компилятора.
@AnyaShenanigans ага, вот подсказка: g++ (/usr/bin/g++) работает нормально, а /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ нет! Хотя они оба Apple clang 14.0.0.
Используя вашу идею -###, я вижу, что простой g++ передает несколько дополнительных флагов -isysroot и -internal-isystem. Это должно быть так. Не стесняйтесь публиковать свой комментарий в качестве ответа, чтобы я мог его принять.
Здесь проблема заключается в упаковке. Когда вы вызываете компилятор цепочки инструментов напрямую, он использует определенный набор заголовков для самой цепочки инструментов и опускает заголовки для платформы. Когда мы используем -###, чтобы увидеть все пути включения, указанные для компилятора цепочки инструментов, мы видим следующее от прямого компилятора цепочки инструментов:
Итак, компиляция с /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++:
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1"
"/usr/local/include"
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include"
"/usr/include"
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include"
При компиляции с оберткой /usr/bin/c++ получаем следующие заголовки:
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
"-I/usr/local/include"
"-stdlib=libc++"
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/v1"
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/local/include"
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.0/include"
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include"
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include"
Он добавляет заголовки для macOS, потому что предполагает, что он собирается для MacOS, потому что это локальная оболочка.
Мы можем успешно скомпилировать с помощью компилятора цепочки инструментов, когда мы передаем дополнительную опцию -isysroot как извлеченную, используя:
-isysroot $(xcrun --sdk macosx --show-sdk-path)
Так:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -isysroot $(xcrun --sdk macosx --show-sdk-path) -o conftest conftest.cpp
Собирается и работает чисто. В случае попытки получить зависимости для правильной сборки вам нужно будет выбрать соответствующий компилятор для цели.
Если вы хотите обойти построение, две переменные, которые имеют значение в этом случае, — это, как правило, CPPFLAGS и CXXFLAGS — флаги для препроцессора и компилятора C++. Вы должны иметь возможность установить CPPFLAGS на:
-isysroot $(xcrun --sdk macosx --show-sdk-path)
И он должен собираться для вас, если в используемых вами инструментах действует стандартная логика makefile.
$ export CPPFLAGS = "-isysroot $(xcrun --sdk macosx --show-sdk-path)"
$ export CXX=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
$ make conftest
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk conftest.cpp -o conftest
Это потрясающе! Кстати, причина, по которой это происходит, заключается в том, что CMake и/или Conan "слишком усердно" пытаются автоматически определить компилятор в некоторых ситуациях и в конечном итоге используют компилятор цепочки инструментов.
В моем случае он все еще показывает ошибку /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator15.2.sdk/usr/include/c++/v1/ алгоритмrithm:1513:19: ошибка: нет элемента с именем '__search' в пространстве имен 'std::__1' return _VSTD::__search<typename add_lvalue_reference<_BinaryPredicate>::type>
Привет @JamshedAlam - это, вероятно, связано с тем, что в вашей компиляции не включен С++ 17 или новее.
Вы можете увидеть все сообщения об ошибках в моем посте выше. Первый — «ошибка: цель использования объявления конфликтует с объявлением».