CMake 编译gtk文件

tt posted @ 2007年10月18日 17:29 in cmake , 11437 阅读

CMakeLists.txt也可以通过读取配置文件(pkgconfig下的pc文件 )编译程序,如编译gtk时,通常需要编译就选项`pkg-config --cflags --libs gtk+-2.0`,而在CMakeLists.txt中却不能那么写,下面看如何用CMake调用配置文件对代码进行编译,

一个简单gtk代码如下,main.c:

  1. #include <stdlib.h>
  2. #include <gtk/gtk.h>
  3.  
  4. void selection_received( GtkWidget        *widget,
  5.                          GtkSelectionData *selection_data,
  6.                          gpointer          data );
  7.  
  8. /* 当用户点击"Get Targets"按钮时调用的信息处理函数 */
  9. void get_targets( GtkWidget *widget,
  10.                   gpointer data )
  11. {
  12.   static GdkAtom targets_atom = GDK_NONE;
  13.   GtkWidget *window = (GtkWidget *)data;       
  14.  
  15.   /* 得到"TARGETS"字符串对应的原子 */
  16.   if (targets_atom == GDK_NONE)
  17.     targets_atom = gdk_atom_intern ("TARGETS", FALSE);
  18.  
  19.   /* 要求获取主选中区的"TARGETS"形式的目标 */
  20.   gtk_selection_convert (window, GDK_SELECTION_PRIMARY, targets_atom,
  21.                          GDK_CURRENT_TIME);
  22. }
  23.  
  24. /* 当选中区所有者返回数据时调用的信号处理函数 */
  25. void selection_received( GtkWidget        *widget,
  26.                          GtkSelectionData *selection_data,
  27.                          gpointer          data )
  28. {
  29.   GdkAtom *atoms;
  30.   GList *item_list;
  31.   int i;
  32.  
  33.   /* **** 重要 **** 检测获取信息是否成功  */
  34.   if (selection_data->length < 0)
  35.     {
  36.       g_print ("Selection retrieval failed\n");
  37.       return;
  38.     }
  39.   /* 确认得到的数据为原来要求的形式 */
  40.   if (selection_data->type != GDK_SELECTION_TYPE_ATOM)
  41.     {
  42.       g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
  43.       return;
  44.     }
  45.  
  46.   /* 打印接收到的原子 */
  47.   atoms = (GdkAtom *)selection_data->data;
  48.  
  49.   item_list = NULL;
  50.   for (i = 0; i < selection_data->length / sizeof(GdkAtom); i++)
  51.     {
  52.       char *name;
  53.       name = gdk_atom_name (atoms[i]);
  54.       if (name != NULL)
  55.         g_print ("%s\n",name);
  56.       else
  57.         g_print ("(bad atom)\n");
  58.     }
  59.  
  60.   return;
  61. }
  62.  
  63. int main( int   argc,
  64.           char *argv[] )
  65. {
  66.   GtkWidget *window;
  67.   GtkWidget *button;
  68.  
  69.   gtk_init (&argc, &argv);
  70.  
  71.   /* 创建顶级窗口 */
  72.  
  73.   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  74.   gtk_window_set_title (GTK_WINDOW (window), "Event Box");
  75.   gtk_container_set_border_width (GTK_CONTAINER (window), 100);
  76.  
  77.   g_signal_connect (G_OBJECT (window), "destroy",
  78.                     G_CALLBACK (exit), NULL);
  79.  
  80.   /* 创建一个按钮,用户按它以获取目标 */
  81.  
  82.   button = gtk_button_new_with_label ("Get Targets");
  83.   gtk_container_add (GTK_CONTAINER (window), button);
  84.  
  85.   g_signal_connect (G_OBJECT (button), "clicked",
  86.                     G_CALLBACK (get_targets), window);
  87.   g_signal_connect (G_OBJECT (window), "selection_received",
  88.                     G_CALLBACK (selection_received), NULL);
  89.  
  90.   gtk_widget_show (button);
  91.   gtk_widget_show (window);
  92.  
  93.   gtk_main ();
  94.  
  95.   return 0;
  96. }

下面为用于编译这个Gtk程序的CMakeLists.txt文件

INCLUDE(UsePkgConfig)
 
FIND_PACKAGE(GTK)
 
IF (GTK_FOUND)
     INCLUDE_DIRECTORIES(${GTK_INCLUDE_DIR})
      ADD_DEFINITIONS(-DHAVE_GTK)
     MESSAGE("GTK 1.x found and used as GUI\n")
ELSE (GTK_FOUND)
     PKGCONFIG(gtk+-2.0 GTK2_INCLUDE_DIR GTK2_LINK_DIR GTK2_LINK_FLAGS GTK2_CFLAGS)
     PKGCONFIG(gthread-2.0 GTHREAD_INCLUDE_DIR GTHREAD_LINK_DIR GTHREAD_LINK_FLAGS+- GTHREAD_CFLAGS)
      IF (GTK2_INCLUDE_DIR)
          SET(CMAKE_C_FLAGS "${GTK2_CFLAGS} ${GTHREAD_CFLAGS}")
          STRING(REGEX REPLACE "-l" "" GTK_LIBRARIES "${GTK2_LINK_FLAGS}                                          ${GTHREAD_LINK_FLAGS}")
          SEPARATE_ARGUMENTS(GTK_LIBRARIES)
          ADD_DEFINITIONS(-DHAVE_GTK2)
          MESSAGE("GTK 2.x found and used as GUI\n")
      ELSE (GTK2_INCLUDE_DIR)
          MESSAGE(FATAL_ERROR "GTK or GTK2 is required to build this project.")
      ENDIF (GTK2_INCLUDE_DIR)
ENDIF (GTK_FOUND)

ADD_EXECUTABLE(main main.c)
TARGET_LINK_LIBRARIES(main ${GTK2_LINK_FLAGS})

 上面的文件首先看是否有gtk的配置文件,如果有则调用gtk的配置文件进行编译,否则查看gtk2.0的配置文件。如果想直接用gtk2.0的配置编译选项,则上面的CMakeLists.txt可改成下面内容:

  1. INCLUDE(UsePkgConfig)
  2.  
  3. FIND_PACKAGE(GTK)
  4.  
  5. PKGCONFIG(gtk+-2.0 GTK2_INCLUDE_DIR GTK2_LINK_DIR GTK2_LINK_FLAGS GTK2_CFLAGS)
  6. PKGCONFIG(gthread-2.0 GTHREAD_INCLUDE_DIR GTHREAD_LINK_DIR GTHREAD_LINK_FLAGS+- GTHREAD_CFLAGS)
  7.  
  8. IF (GTK2_INCLUDE_DIR)
  9.     SET(CMAKE_C_FLAGS "${GTK2_CFLAGS} ")
  10.     STRING(REGEX REPLACE "-l" "" GTK_LIBRARIES "${GTK2_LINK_FLAGS} ")
  11.     SEPARATE_ARGUMENTS(GTK_LIBRARIES)
  12.     ADD_DEFINITIONS(-DHAVE_GTK2)
  13. ELSE (GTK2_INCLUDE_DIR)
  14.     MESSAGE(FATAL_ERROR "GTK or GTK2 is required to build this project.")
  15. ENDIF (GTK2_INCLUDE_DIR)
  16.  
  17. ADD_EXECUTABLE(main main.c)
  18. TARGET_LINK_LIBRARIES(imain ${GTK2_LINK_FLAGS})

接下来的事就是

    $> cmake .

    $> make

    $> ./main

下面简单介绍第二个CMakeLists.txt中的代码

第1行 包含配置文件模块;

第3行 查找gtk配置文件;

第5行 用配置文件gtk+-2.0对几个变量GTK2_INCLUDE_DIR、GTK2_LINK_DIR、GTK2_LINK_FLAGS、GTK2_CFLAGS赋值;

第6行用配置文件gthread-2.0对几个变量GTHREAD_INCLUDE_DIR GTHREAD_LINK_DIR GTHREAD_LINK_FLAGS+- GTHREAD_CFLAGS赋值;

第8行判断GTK2_INCLUDE_DIR是否有值;

第9行用变量GTK2_CFLAGS的值对CMAKE_C_FLAGS赋值,其中为有编译选项;

第10行将变量GTK2_LINK_FLAGS中的"-l"用空格“”替换;

第11行将变量GTK_LIBRARIES中的所有空格用分号“;”替换;

第12行将 -D定义的选项添加到C或者C++编译行中;

第14行如果GTK2_INCLUDE_DIR没有值,则输出错误信息:

    "GTK or GTK2 is required to build this project."

第17行用于将源文件main.c生成可执行文件main;

第18行指定程序运行时所需要的库。

 

 

 

 

 

 

Avatar_small
s3e 说:
2008年5月06日 06:19 您好!我想问问GTHREAD_LINK_FLAGS+-这个加减号是什么意思呢?谢谢您的好帖子!
Head_small
tt 说:
2008年5月20日 16:55 不好意思,我也不知道。。。

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter