У меня есть Linux-приложение, работающее под Ubuntu 12.04 LTS, которое скомпилировано, связано и работает без проблем.
Недавно я обновил Ubuntu до 14.04 LTS и столкнулся с проблемами компиляции и компоновки приложения.
Проблемы с компиляцией были решены путем ручной модификации моей локальной копии Boost 1.48 в двух файлах (include/boost/config/stdlib/libstdcpp3.hpp и include/boost/thread/xtime.hpp). На этом этапе приложение успешно скомпилировалось.
Проблема заключается в том, что связь с сообщением об ошибке не выполняется:
c++: error: unrecognized command line option ‘-Wl
Я использую CMake для включения компиляции приложения на нескольких платформах. Вот сценарий компоновщика, сгенерированный CMake. Обратите внимание, что опции -Wl теперь необъяснимо непризнаны /usr/bin/c++:
/usr/bin/c++
-fno-stack-protector
-g
-Wl
CMakeFiles/Project.dir/main.cpp.o
CMakeFiles/Project.dir/TestCallback.cpp.o
CMakeFiles/Project.dir/utils.cpp.o
CMakeFiles/Project.dir/Request1.cpp.o
CMakeFiles/Project.dir/Response1.cpp.o
CMakeFiles/Project.dir/TextChatRequest.cpp.o
CMakeFiles/Project.dir/TextChatResponse.cpp.o
-o
/home/user/private/Project/Project_Release_1_2_Codename/Build/bin/Debug/Project
-L/home/user/Libraries/Ubuntu32_12.04/boost_1.48/lib
-L/home/user/Libraries/Ubuntu32_12.04/SqlLite_3.6/lib
-L/home/user/Libraries/Ubuntu32_12.04/taglib_1.7/lib
-L/home/user/Libraries/Ubuntu32_12.04/JSON_1.0/lib/Debug
-L/home/user/private/Project/Project_Release_1_2_Codename/Build/../lib/libUbuntu32/Debug
-rdynamic
/home/user/private/Project/Project_Release_1_2_Codename/lib/libUbuntu32/Debug/libAPI.a
/home/user/private/Project/Project_Release_1_2_Codename/lib/libUbuntu32/Debug/libInternals.a
-lboost_thread
-lboost_system
-lboost_filesystem
-lboost_program_options
-ltaglib
-lJSON
-lpthread
-Wl,-Bstatic
-lsqlite3
-Wl,-Bdynamic
-ldl
-Wl,-rpath,/home/user/Libraries/Ubuntu32_12.04/boost_1.48/lib:/home/user/Libraries/Ubuntu32_12.04/SqlLite_3.6/lib:/home/user/Libraries/Ubuntu32_12.04/taglib_1.7/lib:/home/user/Libraries/Ubuntu32_12.04/JSON_1.0/lib/Debug:/home/user/private/Project/Project_Release_1_2_Codename/Build/../lib/libUbuntu32/Debug
Вот информация о версии программного обеспечения, которое я использую:
Ubuntu:
14.04.1 LTS (trusty)
c++ compiler/linker:
(Ubuntu 4.8.2-19ubuntu1) 4.8.2
CMake:
Version 2.8.12.2
Почему линкер не распознает команды -Wl? Мое обновление до 14.04 LTS изменило библиотеки программного обеспечения компоновщика? Как я могу вернуть свое приложение и связать его?
В строке 4 команды у вас есть -Wl
без каких-либо фактических ссылок.
https://gcc.gnu.org/gcc-4.7/porting_to.html
В верхней части этой страницы находится следующее:
Более ранние выпуски не предупреждали об ошибках об абсолютно недействительных параметрах в командных строках gcc/g++/gfortran и т.д., Если ничего не было скомпилировано, но выполнялась только привязка. Это уже не так. Например,
gcc -Wl -o foo foo.o -mflat_namespace
Теперь выдается следующая ошибка
ошибка: непризнанная опция командной строки '-Wl
ошибка: непризнанная опция командной строки '-mflat_namespace
Неверные параметры необходимо удалить из командной строки или заменить на что-то действительное.
12.04 LTS упакованный GCC 4.6, вы теперь подпрыгнули до 4.8, а -Wl
по себе больше не является допустимым вариантом (точнее, он никогда не был, GCC сейчас больше педантичен).
-Wl
сам по себе, это был -Wl,-rpath,...
который кажется действительным в команде компоновщика.
-Wl
на четвертой строчке.
Как уже упоминалось ранее, действительно оказалось, что мой сценарий CMake вводил одиночный, одиночный, казалось бы, ненужный "-Wl" через параметр CMAKE_EXE_LINKER_FLAGS:
if(LINUX)
set(THIRDPARTY_LIBS boost_thread boost_system boost_filesystem boost_program_options taglib JSON)
set(OS_LIBS pthread sqlite3.a dl)
set(CMAKE_EXE_LINKER_FLAGS "-Wl")
set(PREPROCESSOR_DEFINITIONS ${PREPROCESSOR_DEFINITIONS};/DTAGLIB_STATIC)
endif(LINUX)
Когда я удалил этот параметр, сборка завершилась успешно. Этот надзор был примерно в то время, когда более ранняя версия gcc не возражала. Последний gcc, однако, более педантичен и помечен как ошибка.
cmake
запоминает полностью запаздывающие вещи в своем файле кеша.