Вопрос или проблема
CMake выдает ошибку неопределенной ссылки, даже если используется команда link_libraries
Я пытаюсь подключить GLFW, используя git submodule. Вот мой CMakeLists.txt
:
cmake_minimum_required(VERSION 3.0.0)
project(guitest VERSION 0.1.0 LANGUAGES C CXX)
add_executable(guitest main.cpp)
add_subdirectory(glfw)
include_directories(glfw/include)
link_directories(glfw/src)
link_libraries(glfw)
Я не получаю ошибок в CMake, но когда я пытаюсь собрать свой проект, я получаю
[build] C:/Users/Konstantin/Documents/sasha/guitest/main.cpp:7: неопределенная ссылка на `glfwInit'
Вот мой код
#include <iostream>
#include <GLFW/glfw3.h>
int main(int, char**){
GLFWwindow *window;
if(!glfwInit()){
std::cout << "Ошибка инициализации!"<<std::endl;
exit(EXIT_FAILURE);
}
}
Я использую Visual Studio Code и компилятор GCC 6.3.0 MinGW.
Команда link_libraries
влияет только на цели, которые создаются после. Поскольку вызов add_executable
предшествует link_libraries
, ваша исполняемая программа не связана.
Корректно (но не лучший вариант):
add_subdirectory(glfw)
link_libraries(glfw)
add_executable(guitest main.cpp)
Предпочтительнее использовать target_link_libraries
вместо link_libraries
.
add_subdirectory(glfw)
add_executable(guitest main.cpp)
target_link_libraries(guitest PRIVATE glfw)
В обоих случаях вызов include_directories
можно опустить, так как связь с целью glfw также включает ваши каталоги для заголовков GLFW в исполняемую программу.
Ответ или решение
Для решения проблемы с "undefined reference" в CMake, возникающей при использовании команды link_libraries
, важно понимать, как работает связывание библиотек. В вашем случае причина заключается в том, что команда link_libraries
применяется к целям, которые создаются после неё. Так как вы вызываете add_executable
до link_libraries
, ваша исполняемая программа не подключена к библиотеке GLFW.
Вместо использования link_libraries
, рекомендуется использовать target_link_libraries
, так как это более современный и предпочтительный подход в CMake. Он позволяет точно указать, какие библиотеки связывать с конкретной целью, что повышает читаемость и контроль.
Вот как можно изменить ваш CMakeLists.txt
:
cmake_minimum_required(VERSION 3.0.0)
project(guitest VERSION 0.1.0 LANGUAGES C CXX)
add_subdirectory(glfw)
add_executable(guitest main.cpp)
target_link_libraries(guitest PRIVATE glfw)
В этом изменённом варианте кода:
- Сначала вызывается
add_subdirectory(glfw)
, чтобы добавить GLFW как подкаталог. - Затем создаётся исполняемый файл
guitest
с помощьюadd_executable
. - Наконец, используется
target_link_libraries
, чтобы связать вашу программу с библиотекой GLFW. Здесь мы указываемPRIVATE
, что означает, что библиотека будет доступна только для данной цели (в данном случае, дляguitest
).
Также, как вы заметили, также можно опустить вызов include_directories
, так как при связывании с целевой библиотекой CMake автоматически добавляет необходимые директории для включения.
Таким образом, данный подход не только решит вашу проблему с "undefined reference", но и улучшит структуру вашего проекта. Теперь ваше приложение должно успешно собираться и линковаться с библиотекой GLFW.