gtk/gtk.h not found on Ubuntu c++

2020-02-28 08:04发布

问题:

I'm rather new to programming and especially when it comes to how to including libraries and alike activities. I've been programming a bit using Python in the past and I've been using GTK to create windows, something I've intended to do when programming with c++ as well. To get things started, here's my code:

#include <stdlib.h>
#include <gtk/gtk.h>

static void helloWorld (GtkWidget *wid, GtkWidget *win)
{
  GtkWidget *dialog = NULL;

  dialog = gtk_message_dialog_new (GTK_WINDOW (win), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "Hello World!");
  gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
  gtk_dialog_run (GTK_DIALOG (dialog));
  gtk_widget_destroy (dialog);
}

int main (int argc, char *argv[])
{
  GtkWidget *button = NULL;
  GtkWidget *win = NULL;
  GtkWidget *vbox = NULL;

  /* Initialize GTK+ */
  g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL);
  gtk_init (&argc, &argv);
  g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL);

  /* Create the main window */
  win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_default_size(GTK_WINDOW (win), 400, 300);
  gtk_container_set_border_width (GTK_CONTAINER (win), 8);
  gtk_window_set_title (GTK_WINDOW (win), "test");
  gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER);
  gtk_widget_realize (win);
  g_signal_connect (win, "destroy", gtk_main_quit, NULL);

  /* Create a vertical box with buttons */
  vbox = gtk_vbox_new (TRUE, 6);
  gtk_container_add (GTK_CONTAINER (win), vbox);

  button = gtk_button_new_from_stock (GTK_STOCK_DIALOG_INFO);
  g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (helloWorld), (gpointer) win);
  gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);

  button = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
  g_signal_connect (button, "clicked", gtk_main_quit, NULL);
  gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);

  /* Enter the main loop */
  gtk_widget_show_all (win);
  gtk_main ();
  return 0;
}

The code was taken from a "Hello world" example I found on the internet a while back.

I'm aware that this issue have already gotten an answer, but my situation is much more complex (from my perspective at least). First off, I've installed all packages required. I run Ubuntu 14.04 by the way.

When I compile the code using g++ main.cpp I get the following error:

main.cpp:2:21: fatal error: gtk/gtk.h: No such file or directory
 #include <gtk/gtk.h>
                     ^
compilation terminated.

There is a fix for this particular error, which is to extend the compile command like this: g++ main.cpp -I/usr/include/gtk-2.0. This however will provide another, similar error:

In file included from /usr/include/gtk-2.0/gdk/gdk.h:32:0,
                 from /usr/include/gtk-2.0/gtk/gtk.h:32,
                 from main.cpp:2:
/usr/include/gtk-2.0/gdk/gdkapplaunchcontext.h:30:21: fatal error: gio/gio.h: No such file or directory
 #include <gio/gio.h>
                     ^
compilation terminated.

You can fix this as well by extending the command like this (all commands are fund on the internet and I don't quite understand it all): g++ -g -Wall -c -o program.o main.cpp -I/usr/include/gtk-2.0 $(pkg-config --libs --cflags glib-2.0). There will now be an error with cairo.h.

As you can see there are similar errors. I have no idea what's wrong but I must believe there is a relatively easy fix.

Also, I tried a fresh install of Ubuntu (just installed packages necessary) and the same errors occur.

回答1:

The pkgconfig command gives you all of the necessary -I (include) and -l (linker) statements for the compiler, when including a certain package.

Take a look what is given by running:

pkgconfig --cflags --libs gtk+-2.0

I've tried compiling your code on my Ubuntu 14.04.1 and it went fine, when I used:

g++ main.cpp `pkg-config --cflags --libs gtk+-2.0`

Probably pkg-config --libs --cflags glib-2.0 wasn't enough to provide all of the necessary include paths and shared libraries.



回答2:

When you don't have a file installed on Ubuntu, the place to go is http://packages.ubuntu.com and use the second search form to look for the filename.

In this case, the answer is (for trusty):

File                                                Package
-----------------------------------------------------------------
/usr/include/gtk-2.0/gtk/gtk.h                      libgtk2.0-dev
/usr/include/gtk-3.0/gtk/gtk.h                      libgtk-3-dev
/usr/lib/R/site-library/RGtk2/include/RGtk2/gtk.h   r-cran-rgtk2

You need to select which one of those is most suitable, and install it.

I'm guessing this one: libgtk2.0-dev

You can then repeat the process for the gio/gio.h header file.



回答3:

It's works (Ubuntu):

export CPATH=$CPATH:/usr/include/gtk-2.0
export CPATH=$CPATH:/usr/include/glib-2.0/
export CPATH=$CPATH:/usr/lib/glib-2.0/include/
export CPATH=$CPATH:/usr/include/pango-1.0/
export CPATH=$CPATH:/usr/lib/gtk-2.0/include/
export CPATH=$CPATH:/usr/include/atk-1.0/

With Fedora >=25:

export CPATH=$CPATH:/usr/include/gtk-3.0
export CPATH=$CPATH:/usr/include/glib-2.0/
export CPATH=$CPATH:/lib64/glib-2.0/include/
export CPATH=$CPATH:/usr/include/pango-1.0/
export CPATH=$CPATH:/usr/lib64/gtk-3.0/3.0.0/
export CPATH=$CPATH:/usr/include/atk-1.0/
export CPATH=$CPATH:/usr/include/cairo/

into ~/.bashrc or into ~/.zshrc

Remember to run: source ~/.bashrc



回答4:

I also immigranted to C++ from Python and I am just not used with how the C++ include way of working. Here's what I do to make life easier in C++. I make a Makefile with the following contents:

all:
     g++-5 main.cpp -o main `pkg-config --libs --cflags gtkmm-3.0`

Instead of main.cpp, include all your *.cpp files and headers. (Also, please notice I use gtkmm-3.0) And in gtkmm-3.0, your Application with one window, one button and the button being linked to a function [which says: Hello World! of course] would look like this

#include <iostream>
#include <gtkmm/application.h>
#include <gtkmm/window.h>
#include <gtkmm/button.h>


class HelloWorld : public Gtk::Window{

public:
  HelloWorld();
  virtual ~HelloWorld();

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

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

// implementing the class HelloWorld
HelloWorld::HelloWorld(): m_button("Click me, Xweque"){
 set_border_width(20); // Sets the border width of the window.

// Connecting the button's clicked signal to an arbitrary function
m_button.signal_clicked().connect(sigc::mem_fun(*this, &HelloWorld::on_button_clicked));

add(m_button);
m_button.show();
}

HelloWorld::~HelloWorld()
{
}

void HelloWorld::on_button_clicked(){
  std::cout << "Hello World" << std::endl;
}


int main(int argc, char** argv){
    Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

HelloWorld mywindow;
app->run(mywindow);

return 0;
}