Альтернативное название: Почему мой dylib включает в себя дополнительные экспортированные символы при компиляции Xcode vs Makefile?Почему порядок флагов компилятора clang влияет на итоговый двоичный размер?
Наша компания строит динамическую библиотеку C++ с использованием clang, и мы недавно перенесли наш обработанный вручную Makefile в систему сборки CMake и теперь используем сгенерированные проекты Xcode. Убедившись, что все флаги компилятора/компоновщика и переменные среды точно совпадают между двумя системами, мы заметили, что dylib, созданный CMake/Xcode, был немного больше. Более тщательное обследование показало, что в нем содержатся некоторые дополнительные экспортированные символы (из шаблонных функций, которые никогда не ссылались и, следовательно, никогда не должны были быть созданы), конкретные шаблоны имели свои определения и специализации в исходных файлах, поскольку мы часто используем явные экземпляры, хотя в этом случае они не были явно созданы). Изучение разборки некоторых объектных файлов также показало небольшие различия в инструкциях. Единственное, что получило библиотеки в соответствии с размерами и символами, было именно в соответствии с порядком флагов компилятора точно. По-видимому, это демонстрирует некоторое зависящее от порядка взаимодействие между флагами компилятора, которые выглядят как ошибка компилятора или, по крайней мере, плохо документированное поведение.
Для этого конкретного вопроса, это был компилятор вызовы:
clang++ -fvisibility=hidden -fvisibility-ms-compat -c foo.cpp -o foo.o
clang++ -fvisibility-ms-compat -fvisibility=hidden -c foo.cpp -o foo.o
И это компоновщик призывание:
clang++ -dynamiclib -o libfoo.dylib foo.o
Отображения экспортируемых символов с:
nm -g libfoo.dylib
показал различия. Я представил это LLVM Bug.
Есть ли когда-нибудь какие-либо правильные ситуации, когда вопросы заказа флагов компилятора важны?
Также обратите внимание, что если вы пытаетесь точно соответствовать бинарным размерам, каталог, в котором выполняется компиляция, имеет значение, если вы включаете в себя отладочные символы (-g), поскольку путь к файлу будет содержаться в объектных файлах. – jinxcat2008