Как устранить ошибку линкера?
Многоуровневый cmake-проект
- main.cpp
- CMakeLists.txt
- /Main
- --CmakeLists.txt
- --mainwindow.cpp
- --main.h
CmakeLists.txt:
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
set(PROJECT_NAME r21)
project(${PROJECT_NAME} VERSION 0.0.1)
...
message(${RESOURCE_LIST})
compile_gresources(
RESOURCE_FILE
XML_OUT
TYPE EMBED_C
RESOURCES ${RESOURCE_LIST}
PREFIX /r21
)
add_custom_target(
gladeGeneratedResource
ALL
DEPENDS ${RESOURCE_FILE}
)
set(sources main.cpp ${CMAKE_CURRENT_SOURCE_DIR}/build/resources.c)
set(headers Main/main.h)
message("use ${CMAKE_CURRENT_SOURCE_DIR}resources.c")
add_executable(retom21 WIN32 ${sources} ${headers})
message("Coping necessary mingw DLLs")
set(dlls_file "dlls.txt")
set(MINGW_DLL_DIR "C:/msys64/mingw64/bin")
set(BIN_DIR, "/build/bin")
find_package(PkgConfig)
pkg_check_modules(GTKMM gtkmm-3.0 REQUIRED)
add_subdirectory(Main)
target_include_directories(retom21 PRIVATE ${GTKMM_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/Main)
target_link_libraries(retom21 PRIVATE ${GTKMM_LIBRARIES} Main)
main.cpp:
#include <gtkmm.h>
#include <iostream>
#include <string>
#include "Main/main.h"
int add_glade_res(Glib::RefPtr<Gtk::Builder> refBuilder, char* gxml_path)
{
try{
refBuilder->add_from_resource(gxml_path);
} catch (...){
std::cerr << "Error loading glade map resource" << gxml_path << std::endl;
return 0;
}
return 1;
}
int on_cmd(const Glib::RefPtr<Gio::ApplicationCommandLine> &,
Glib::RefPtr<Gtk::Application> &app) {
app->activate(); // <----
return 0;
}
int main(int argc, char **argv){
auto app = Gtk::Application::create(argc, argv, "r21", Gio::APPLICATION_HANDLES_COMMAND_LINE);
app->signal_command_line().connect(sigc::bind(sigc::ptr_fun(on_cmd), app), false);
// Load the GtkBuilder file and instantiate its widgets:
auto refBuilder = Gtk::Builder::create();
if(!add_glade_res(refBuilder, "/r21/glade/main.glade")) return 1;
MainWindow *wnd = nullptr;
refBuilder->get_widget_derived("main_window", wnd);
if (wnd){
app->run(*wnd);
}
delete wnd;
return 0;
}
Main/main.h:
#include <gtkmm.h>
#include <iostream>
#include <string>
class MainWindow : public Gtk::ApplicationWindow {
public:
MainWindow(BaseObjectType* obj, Glib::RefPtr<Gtk::Builder> const& builder);
MainWindow(BaseObjectType* obj, Glib::RefPtr<Gtk::Builder> const& builder, char *gladefile);
virtual ~MainWindow();
private:
Glib::RefPtr<Gtk::Builder> builder;
Glib::RefPtr<Gio::SimpleActionGroup> ActionsGroup;
...
Gtk::Button btn1;
};
Main/mainwindow.cpp:
#include <gtkmm.h>
#include <iostream>
#include <string>
class MainWindow : public Gtk::ApplicationWindow {
public:
MainWindow(BaseObjectType* obj, Glib::RefPtr<Gtk::Builder> const& builder)
: Gtk::ApplicationWindow(obj)
, builder{builder}
{
...
}
MainWindow(BaseObjectType* obj, Glib::RefPtr<Gtk::Builder> const& builder, char *gladefile): Gtk::ApplicationWindow(obj)
{
}
private:
...
};
Main/CMakeLists.txt:
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
set(PROJECT_NAME Main) # Название проекта
project(${PROJECT_NAME} VERSION 0.0.1)
set(SOURCE_LIB mainwindow.cpp main.h) # Установка переменной со списком исходников
add_library(${PROJECT_NAME} STATIC ${SOURCE_LIB})# Создание статической библиотеки
target_include_directories(${PROJECT_NAME} PUBLIC ${GTKMM_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PUBLIC ${GTKMM_LIBRARIES})
На этапе линковки выдает ошибку:
undefined reference to `MainWindow::MainWindow(_GtkApplicationWindow*, Glib::RefPtrGtk::Builder const&)
Причем, когда все было в одном файле ошибок не было. Когда попробовал разделить на подпроекты пошли ерроры.
Ответы (1 шт):
Автор решения: Anton Kuzmich
→ Ссылка
Я сделал лишнее описание класса. Надо было:
#include <gtkmm.h>
#include <iostream>
#include <string>
#include "main.h"
MainWindow::MainWindow(BaseObjectType* obj, Glib::RefPtr<Gtk::Builder> const& builder)
: Gtk::ApplicationWindow(obj)
, builder{builder}
{
...
}
MainWindow::MainWindow(BaseObjectType* obj, Glib::RefPtr<Gtk::Builder> const& builder, char *gladefile): Gtk::ApplicationWindow(obj)
{
}