【问题标题】:"Undefined symbols for architecture x86_64" error when compiling a GTKmm program编译 GTKmm 程序时出现“架构 x86_64 的未定义符号”错误
【发布时间】:2021-02-24 15:54:56
【问题描述】:

我最近一直在尝试在我的 MacBook 上开始使用 GTKmm,并且我已经使用 Homebrew 安装了许多依赖项。但是,当我去编译我的程序时,我得到了这个错误:

Undefined symbols for architecture x86_64:
  "HelloWorld::HelloWorld()", referenced from:
      _main in main-88dc5e.o
  "HelloWorld::~HelloWorld()", referenced from:
      _main in main-88dc5e.o
  "Gtk::Application::run(Gtk::Window&)", referenced from:
      _main in main-88dc5e.o
  "Gtk::Application::create(int&, char**&, Glib::ustring const&, Gio::ApplicationFlags)", referenced from:
      _main in main-88dc5e.o
  "Glib::ustring::ustring(char const*)", referenced from:
      _main in main-88dc5e.o
  "Glib::ustring::~ustring()", referenced from:
      _main in main-88dc5e.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我的程序是这样的:

helloworld.h:

#ifndef GTKMM_EXAMPLE_HELLOWORLD_H
#define GTKMM_EXAMPLE_HELLOWORLD_H

#include <gtkmm-3.0/gtkmm/button.h>
#include <gtkmm-3.0/gtkmm/window.h>

class HelloWorld : public Gtk::Window {
    public:
        HelloWorld();
        virtual ~HelloWorld();

    protected:
        //Signal handlers:
        void on_button_clicked();

        //Member widgets:
        Gtk::Button m_button;
};

#endif

helloworld.cpp:

#include "helloworld.h"
#include <iostream>

HelloWorld::HelloWorld()
: m_button("Hello World")   // creates a new button with label "Hello World".
{
    // Sets the border width of the window.
    set_border_width(10);

    // When the button receives the "clicked" signal, it will call the
    // on_button_clicked() method defined below.
    m_button.signal_clicked().connect(sigc::mem_fun(*this,
              &HelloWorld::on_button_clicked));

    // This packs the button into the Window (a container).
    add(m_button);

    // The final step is to display this newly created widget...
    m_button.show();
}

main.cpp:

#include "helloworld.h"
#include <gtkmm-3.0/gtkmm/application.h>

int main (int argc, char *argv[]) {
    auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

    HelloWorld helloworld;

    //Shows the window and returns when it is closed.
    return app->run(helloworld);
}

...来自here

我正在使用 Makefile 来包含所有 Homebrew 安装的库:

# the Makefile for the helloworld GTK+ example
cellar=/usr/local/Cellar
inc_dir=/usr/local/include

gtk_inc=$(cellar)/gtk+3/3.24.25/include/gtk-3.0
gtk_lib=$(cellar)/gtk+3/3.24.25/lib

gtkmm_inc=$(cellar)/gtkmm3/3.24.3_3/include/gtkmm-3.0
gtkmm_lib_inc=$(cellar)/gtkmm3/3.24.3_3/lib/gtkmm-3.0/include
gtkmm_lib=$(cellar)/gtkmm3/3.24.3_3/lib

glibmm_inc=$(cellar)/glibmm@2.66/2.66.0/include/glibmm-2.4
glibmm_lib_inc=$(cellar)/glibmm@2.66/2.66.0/lib/glibmm-2.4/include
glibmm_lib=$(cellar)/glibmm@2.66/2.66.0/lib

glib_inc=$(cellar)/glib/2.66.7/include/glib-2.0
glib_lib_inc=$(cellar)/glib/2.66.7/lib/glib-2.0/include
glib_lib=$(cellar)/glib/2.66.7/lib

sigcpp_inc=$(cellar)/libsigc++@2/2.10.6/include/sigc++-2.0/sigc++
sigcpp_inc_parent=$(cellar)/libsigc++@2/2.10.6/include/sigc++-2.0
sigcpp_lib_inc=$(cellar)/libsigc++@2/2.10.6/lib/sigc++-2.0/include
sigcpp_lib=$(cellar)/libsigc++@2/2.10.6/lib

gdkmm_inc=$(cellar)/gtkmm3/3.24.3_3/include/gdkmm-3.0
gdkmm_lib_inc=$(cellar)/gtkmm3/3.24.3_3/lib/gdkmm-3.0/include
gdlmm_lib=$(cellar)/gtkmm3/3.24.3_3/lib

pango_inc=$(cellar)/pango/1.48.2/include/pango-1.0
#pango_lib_inc=$(cellar)/pango/1.48.2/lib
pango_lib=$(cellar)/pango/1.48.2/lib

pangomm_inc=$(cellar)/pangomm@2.46/2.46.0/include/pangomm-1.4
pangomm_lib_inc=$(cellar)/pangomm@2.46/2.46.0/lib/pangomm-1.4/include
pangomm_lib=$(cellar)/pangomm@2.46/2.46.0/lib

harfbuzz_inc=$(cellar)/harfbuzz/2.7.4/include/harfbuzz
harfbuzz_lib=$(cellar)/harfbuzz/2.7.4/lib

cairo_inc=$(cellar)/cairo/1.16.0_4/include/cairo
cairo_lib=$(cellar)/cairo/1.16.0_4/lib

cairomm_inc=$(cellar)/cairomm@1.14/1.14.2/include/cairomm-1.0
cairomm_lib_inc=$(cellar)/cairomm@1.14/1.14.2/lib/cairomm-1.0/include
cairomm_lib=$(cellar)/cairomm@1.14/1.14.2/lib

freetype_inc=$(cellar)/freetype/2.10.4/include/freetype2
freetype_lib=$(cellar)/freetype/2.10.4/lib

atk_inc=$(cellar)/atk/2.36.0/include/atk-1.0
atk_lib=$(cellar)/atk/2.36.0/lib

atkmm_inc=$(cellar)/atkmm@2.28/2.28.1_1/include/atkmm-1.6
atkmm_lib_inc=$(cellar)/atkmm@2.28/2.28.1_1/lib/atkmm-1.6/include
atkmm_lib=$(cellar)/atkmm@2.28/2.28.1_1/lib

gdk-pixbuf_inc=$(cellar)/gdk-pixbuf/2.42.2/include/gdk-pixbuf-2.0
gdk-pixbuf_lib=$(cellar)/gdk-pixbuf/2.42.2/lib

giomm_inc=$(cellar)/glibmm@2.66/2.66.0/include/giomm-2.4
giomm_lib_inc=$(cellar)/glibmm@2.66/2.66.0/lib/giomm-2.4/include
giomm_lib=$(cellar)/glibmm@2.66/2.66.0/lib

INC_LIST=$(gtk_inc) \
    $(gtkmm_inc) \
    $(gtkmm_lib_inc) \
    $(glibmm_inc) \
    $(glibmm_lib_inc) \
    $(glib_inc) \
    $(glib_lib_inc) \
    $(sigcpp_inc) \
    $(sigcpp_inc_parent) \
    $(sigcpp_lib_inc) \
    $(gdkmm_inc) \
    $(gdkmm_lib_inc) \
    $(pango_inc) \
    $(pangomm_inc) \
    $(pangomm_lib_inc) \
    $(harfbuzz_inc) \
    $(cairo_inc) \
    $(cairomm_inc) \
    $(cairomm_lib_inc) \
    $(freetype_inc) \
    $(atk_inc) \
    $(atkmm_inc) \
    $(atkmm_lib_inc) \
    $(gdk-pixbuf_inc) \
    $(giomm_inc) \
    $(giomm_lib_inc)

INC=$(foreach d, $(INC_LIST), -I$d)

LIB_LIST=$(gtk_lib) \
    $(gtkmm_lib) \
    $(glibmm_lib) \
    $(glib_lib) \
    $(sigcpp_lib) \
    $(gdkmm_lib) \
    $(pango_lib) \
    $(pangomm_lib) \
    $(harfbuzz_lib) \
    $(cairo_lib) \
    $(cairomm_lib) \
    $(freetype_lib) \
    $(atk_lib) \
    $(atkmm_lib) \
    $(gdk-pixbuf_lib) \
    $(giomm_lib)

LIB=$(foreach d, $(LIB_LIST), -L$d)

default: main
    
main: main.cpp
    g++ -std=c++17 $(INC) $(LIB) main.cpp -o helloworld
    
clean:
    rm helloworld

我真的不明白这个错误。这是什么意思?我需要做什么来解决它?

感谢您的帮助。

更新:尝试链接库 .dylib 文件,但我仍然遇到同样的错误。

【问题讨论】:

  • 这意味着你没有链接到实现这些功能的库。
  • “包含头文件”与-I 与链接库不同。头文件为您提供了使用事物所需接口的描述,因此您的代码可以知道如何调用函数等。库为您提供这些事物的实际实现,这是运行程序所需的。
  • 奇怪的是你所有的_lib 变量都指向更多的include 目录。此外,这些包中是否真的有include/pangomm-1.4lib/pangomm-1.4/include 目录(例如)?这很奇怪,但我从不低估 MacOS 上的奇怪之处。
  • @MadScientist _lib 变量指向更多include 目录,因为其中很多都包含[library]config.h。为了更清楚起见,我将重命名它们。

标签: c++ makefile gtk gtkmm


【解决方案1】:

您的 Makefile 中缺少 helloworld.cpp。它应该在 main.cpp 旁边

【讨论】:

  • 什么意思?不包括头文件也链接cpp实现?
  • 不,您必须指定要链接的内容。这不仅限于您的目标文件,还包括库。您尚未在 Makefile 中指定任何 libray -lfoo。我建议使用 pkg-config 为您的 gtkmm 应用程序指定编译器和链接器标志
  • 我认为您应该重新阅读编译器的工作原理。 helloworld.cpp 是您的源文件。您需要在 Makefile 中指定它,以便编译器将其转换为目标文件。然后链接器将所有目标文件链接在一起。 make 有如何做到这一点的默认规则,但你仍然必须指定它应该处理哪些源,以及它应该使用哪些库
猜你喜欢
  • 2017-03-03
  • 2015-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多