CMake--C--多个源文件忽略头保护

CMake--C--多个源文件忽略头保护,c,gcc,linker,cmake,C,Gcc,Linker,Cmake,好的,我已经用CMake和Gtk做了一些实验。在经历了相当多的没有用的文档之后,我终于用Gtk等工具正确地编译了它。 像往常一样,我用一个定义了一个回调函数的文件开始我的项目,只是为了测试一些基本功能。然而,我通常将我的程序分割成多个文件,每个文件一个函数,并使用包含所有原型的include-guard创建一个公共头文件。 这对我来说基本上是一个标准的程序,过去我做过很多次,没有任何问题。 然而,不知何故,我的CMake进程正在做一些我不理解的事情(嗯,很多事情),我得到了以下错误: CMake

好的,我已经用CMake和Gtk做了一些实验。在经历了相当多的没有用的文档之后,我终于用Gtk等工具正确地编译了它。 像往常一样,我用一个定义了一个回调函数的文件开始我的项目,只是为了测试一些基本功能。然而,我通常将我的程序分割成多个文件,每个文件一个函数,并使用包含所有原型的include-guard创建一个公共头文件。 这对我来说基本上是一个标准的程序,过去我做过很多次,没有任何问题。 然而,不知何故,我的CMake进程正在做一些我不理解的事情(嗯,很多事情),我得到了以下错误:

CMakeFiles/gte.dir/src/main.c.o:在函数
gte\u handler\u about'中:
main.c:(.text+0xb0):gte_handler_about'的多个定义
CMakeFiles/gte.dir/src/gte_handler_about.c.o:gte_handler_about.c:(.text+0x0):首先在此处定义
collect2:错误:ld返回了1个退出状态

main.c文件相当简单,只需使用gtk_builder加载一个glade ui文件并显示它:

#  include "gtk/gtk.h"
#  include "gtksourceview/gtksourceview.h"
#  include "gte.h"

int main( int argc, char* argv[] )
{
    GtkWidget   *wGTEMain;
    GtkBuilder  *bGTEMain;
    GError      *eGTE;

    gtk_init( &argc, &argv );

    bGTEMain = gtk_builder_new();   

    gtk_builder_add_from_file( bGTEMain, "gte.glade", &eGTE );
    wGTEMain = GTK_WIDGET (gtk_builder_get_object ( bGTEMain, "GTEMain" ));
    gtk_builder_connect_signals ( bGTEMain, NULL ); 

    g_object_unref( G_OBJECT( bGTEMain));

    gtk_widget_show( wGTEMain );

    gtk_main();

    return 0;
}
当我开始在界面中使用这个小部件时,我已经包括了gtksourceview.h

glade文件非常标准,只包含两个信号,一个用于gtk_main_quit(自动退出),另一个用于gte_handler_about。我会把最后一个也包括在内

我以通常的方式创建了gte.h,具有一些独特的标题保护,如下所示:

#ifndef PSKT_INCLUDE_GTE_H__
#  define PSKT_INCLUDE_GTE_H__ 1

G_MODULE_EXPORT void gte_handler_about( GtkWidget *widget, gpointer data );

#endif /* PSKT_INCLUDE_GTE_H__ */
find_package(PkgConfig)
pkg_check_modules(DEPS REQUIRED
    gmodule-2.0
    gtk+-3.0
    gtksourceview-3.0
)

SET(CFLAGS
    ${DEPS_CFLAGS} ${DEPS_CFLAGS_OTHER}
)
SET(LIB_PATHS
    ${DEPS_LIBRARY_DIRS}
)

add_definitions(${CFLAGS})
link_directories(${LIB_PATHS})
link_libraries( gte ${DEPS_LIBRARIES} )

file(GLOB_RECURSE SRC_FILES src/*.c)

ADD_EXECUTABLE( gte ${SRC_FILES} )
我使用了G_模块导出,因为我已经读到它们在win32平台上是必需的。我通常不会为宏指定一个显式值,但我在测试中已经这样做了,以确定这是否会产生影响。(事实并非如此)。 最初我在这个文件中也有gtk头文件,但我考虑得更好,把它们移回了源文件

当然,我有一个函数about callback,它只是从glade ui文件加载一个gtk about框:

#include "gtk/gtk.h"
#include "gte.h"

G_MODULE_EXPORT void gte_handler_about( GtkWidget *widget, gpointer data )
{
    GtkWidget   *wGTEAbout;
    GtkBuilder  *bGTEAbout;

    bGTEAbout = gtk_builder_new();
    gtk_builder_add_from_file( bGTEAbout, "gte.glade", NULL );

    wGTEAbout = GTK_WIDGET( gtk_builder_get_object( bGTEAbout, "GTEAbout" ) );

    gtk_dialog_run( GTK_DIALOG( wGTEAbout ) );

    g_object_unref( G_OBJECT( bGTEAbout ) );
    gtk_widget_destroy( wGTEAbout );
}
我现在不太担心任何预加载或优化,当它在main.c文件中时,该函数工作正常,原型位于主函数之上

CMakeLists.txt文件如下:

#ifndef PSKT_INCLUDE_GTE_H__
#  define PSKT_INCLUDE_GTE_H__ 1

G_MODULE_EXPORT void gte_handler_about( GtkWidget *widget, gpointer data );

#endif /* PSKT_INCLUDE_GTE_H__ */
find_package(PkgConfig)
pkg_check_modules(DEPS REQUIRED
    gmodule-2.0
    gtk+-3.0
    gtksourceview-3.0
)

SET(CFLAGS
    ${DEPS_CFLAGS} ${DEPS_CFLAGS_OTHER}
)
SET(LIB_PATHS
    ${DEPS_LIBRARY_DIRS}
)

add_definitions(${CFLAGS})
link_directories(${LIB_PATHS})
link_libraries( gte ${DEPS_LIBRARIES} )

file(GLOB_RECURSE SRC_FILES src/*.c)

ADD_EXECUTABLE( gte ${SRC_FILES} )
我应该注意到,我花了很多年才达到这一点。我在链接库部分遇到了问题。我应该注意到,我只是在末尾添加了这个文件(GLOB_RECURSE…),以避免在ADD_可执行文件中单独列出这些文件,我并不担心此时会秘密注入源文件

然后刚才作为一个理智的检查,我刚刚尝试了以下命令,但它们也失败了,这让我相信我简直成了一个白痴,不再知道如何编写代码,这可能根本不是CMAKE的问题。(正确地说,反勾号在那里,但当我引用命令时,它们似乎没有显示出来

gcc-c gte_handler_about.c
pkg config--cflags gmodule-2.0 gtk+-3.0 gtksourceview-3.0

gcc-c main.c
pkg config--cflags gmodule-2.0 gtk+-3.0 gtksourceview-3.0

gcc-o gte main.o gte_handler_about.o
pkg config--libs gtk+-3.0 gtksourceview-3.0

gte_handler_about.o:在函数
gte_handler_about'中:
gte_handler_about.c:(.text+0x0):对
gte_handler_about' main.o:main.c:(.text+0xb0):首先在这里定义 collect2:错误:ld返回了1个退出状态

在过去,我从.o文件构建归档似乎没有问题,每个文件中都有单独的功能,所有这些功能都包括一个公共头,大致如下:

# makefile
MYSRC= $(wildcard *.c)
MYOBJ= $(patsubst %c, %.o, $(MYSRC)

all: $(MYOBJ)
    ar -ru mya.a $(MYOBJ)

%.o: %.c
    gcc -Wall -O0 -g -c $^
然后毫无问题地编译:

gcc-o myut myut.c mya.a-lX11

编译.a中的所有源代码,包括“mya.h”,myut.c也包括“mya.h”,“mya.h”包括“X11/Xlib.h”

我想我的问题是,我在这里做的与以前不同的是什么?我只是需要睡觉,还是我编译Gtk的方式有什么不同

仅针对S&G,这里是glade文件gte.glade:

<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<!-- interface-requires gtksourceview 3.0 -->
<object class="GtkAboutDialog" id="GTEAbout">
<property name="can_focus">False</property>
<property name="border_width">5</property>
<property name="title" translatable="yes">About Geoff's Text Editor</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="window_position">center-always</property>
<property name="type_hint">dialog</property>
<property name="has_resize_grip">False</property>
<property name="program_name">Geoff's Text Editor</property>
<property name="version">0.0.1.0</property>
<property name="copyright" translatable="yes">Copyright (c) 2014, polarysekt, kb3c.uX</property>
<property name="website">[redacted]</property>
<property name="authors">polarysekt</property>
<property name="license_type">gpl-3-0</property>
<child internal-child="vbox">
  <object class="GtkBox" id="aboutdialog-vbox1">
    <property name="can_focus">False</property>
    <property name="orientation">vertical</property>
    <property name="spacing">2</property>
    <child internal-child="action_area">
      <object class="GtkButtonBox" id="aboutdialog-action_area1">
        <property name="can_focus">False</property>
        <property name="layout_style">end</property>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="pack_type">end</property>
        <property name="position">0</property>
      </packing>
    </child>
    <child>
      <placeholder/>
    </child>
  </object>
</child>
</object>
<object class="GtkWindow" id="GTEMain">
<property name="can_focus">False</property>
<property name="title" translatable="yes">GTEr</property>
<signal name="delete-event" handler="gtk_main_quit" swapped="no"/>
<child>
  <object class="GtkBox" id="box1">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="orientation">vertical</property>
    <child>
      <object class="GtkMenuBar" id="menubar1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkMenuItem" id="menuitem1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">_File</property>
            <property name="use_underline">True</property>
            <child type="submenu">
              <object class="GtkMenu" id="menu1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <child>
                  <object class="GtkImageMenuItem" id="imagemenuitem1">
                    <property name="label">gtk-new</property>
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="use_underline">True</property>
                    <property name="use_stock">True</property>
                  </object>
                </child>
                <child>
                  <object class="GtkImageMenuItem" id="imagemenuitem2">
                    <property name="label">gtk-open</property>
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="use_underline">True</property>
                    <property name="use_stock">True</property>
                  </object>
                </child>
                <child>
                  <object class="GtkImageMenuItem" id="imagemenuitem3">
                    <property name="label">gtk-save</property>
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="use_underline">True</property>
                    <property name="use_stock">True</property>
                  </object>
                </child>
                <child>
                  <object class="GtkImageMenuItem" id="imagemenuitem4">
                    <property name="label">gtk-save-as</property>
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="use_underline">True</property>
                    <property name="use_stock">True</property>
                  </object>
                </child>
                <child>
                  <object class="GtkSeparatorMenuItem" id="separatormenuitem1">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                  </object>
                </child>
                <child>
                  <object class="GtkImageMenuItem" id="menuitem5">
                    <property name="label">gtk-media-rewind</property>
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="use_underline">True</property>
                    <property name="use_stock">True</property>
                    <child type="submenu">
                      <object class="GtkRecentChooserMenu" id="recentchoosermenu1">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="limit">10</property>
                      </object>
                    </child>
                  </object>
                </child>
                <child>
                  <object class="GtkSeparatorMenuItem" id="separatormenuitem2">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                  </object>
                </child>
                <child>
                  <object class="GtkImageMenuItem" id="imagemenuitem5">
                    <property name="label">gtk-quit</property>
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="use_underline">True</property>
                    <property name="use_stock">True</property>
                  </object>
                </child>
              </object>
            </child>
          </object>
        </child>
        <child>
          <object class="GtkMenuItem" id="menuitem2">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">_Edit</property>
            <property name="use_underline">True</property>
            <child type="submenu">
              <object class="GtkMenu" id="menu2">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <child>
                  <object class="GtkImageMenuItem" id="imagemenuitem6">
                    <property name="label">gtk-cut</property>
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="use_underline">True</property>
                    <property name="use_stock">True</property>
                  </object>
                </child>
                <child>
                  <object class="GtkImageMenuItem" id="imagemenuitem7">
                    <property name="label">gtk-copy</property>
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="use_underline">True</property>
                    <property name="use_stock">True</property>
                  </object>
                </child>
                <child>
                  <object class="GtkImageMenuItem" id="imagemenuitem8">
                    <property name="label">gtk-paste</property>
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="use_underline">True</property>
                    <property name="use_stock">True</property>
                  </object>
                </child>
                <child>
                  <object class="GtkImageMenuItem" id="imagemenuitem9">
                    <property name="label">gtk-delete</property>
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="use_underline">True</property>
                    <property name="use_stock">True</property>
                  </object>
                </child>
              </object>
            </child>
          </object>
        </child>
        <child>
          <object class="GtkMenuItem" id="menuitem3">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">_View</property>
            <property name="use_underline">True</property>
          </object>
        </child>
        <child>
          <object class="GtkMenuItem" id="mcAbout">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">_Help</property>
            <property name="use_underline">True</property>
            <child type="submenu">
              <object class="GtkMenu" id="menuAbout">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <child>
                  <object class="GtkImageMenuItem" id="miAbout">
                    <property name="label">gtk-about</property>
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="use_underline">True</property>
                    <property name="use_stock">True</property>
                    <signal name="activate" handler="gte_handler_about" swapped="no"/>
                  </object>
                </child>
              </object>
            </child>
          </object>
        </child>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">0</property>
      </packing>
    </child>
    <child>
      <object class="GtkToolbar" id="toolbar1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="toolbar_style">icons</property>
        <property name="icon_size">2</property>
        <child>
          <object class="GtkToolButton" id="tbbNew">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="has_tooltip">True</property>
            <property name="tooltip_markup" translatable="yes">New File</property>
            <property name="tooltip_text" translatable="yes">New File</property>
            <property name="label" translatable="yes">New</property>
            <property name="use_underline">True</property>
            <property name="stock_id">gtk-new</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="homogeneous">True</property>
          </packing>
        </child>
        <child>
          <object class="GtkToolButton" id="tbbLoad">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="has_tooltip">True</property>
            <property name="tooltip_markup" translatable="yes">Open File</property>
            <property name="tooltip_text" translatable="yes">Open File</property>
            <property name="label" translatable="yes">Load</property>
            <property name="use_underline">True</property>
            <property name="stock_id">gtk-open</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="homogeneous">True</property>
          </packing>
        </child>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">1</property>
      </packing>
    </child>
    <child>
      <object class="GtkNotebook" id="notebook1">
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="show_tabs">False</property>
        <child>
          <object class="GtkScrolledWindow" id="scrolledwindow1">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <property name="shadow_type">in</property>
            <child>
              <object class="GtkSourceView" id="gtksourceview1">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="has_tooltip">True</property>
                <property name="left_margin">2</property>
                <property name="right_margin">2</property>
                <property name="show_line_numbers">True</property>
                <property name="tab_width">4</property>
                <property name="auto_indent">True</property>
                <property name="show_right_margin">True</property>
                <property name="right_margin_position">73</property>
                <property name="highlight_current_line">True</property>
                <property name="indent_on_tab">False</property>
              </object>
            </child>
          </object>
        </child>
        <child type="tab">
          <object class="GtkLabel" id="tab">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">untitled1</property>
          </object>
          <packing>
            <property name="tab_fill">False</property>
          </packing>
        </child>
        <child>
          <placeholder/>
        </child>
        <child type="tab">
          <placeholder/>
        </child>
        <child>
          <placeholder/>
        </child>
        <child type="tab">
          <placeholder/>
        </child>
      </object>
      <packing>
        <property name="expand">True</property>
        <property name="fill">True</property>
        <property name="position">2</property>
      </packing>
    </child>
    <child>
      <object class="GtkStatusbar" id="statusbar1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <property name="spacing">2</property>
      </object>
      <packing>
        <property name="expand">False</property>
        <property name="fill">True</property>
        <property name="position">3</property>
      </packing>
    </child>
  </object>
</child>
</object>
</interface>
Grr,我知道这是简单和/或平凡的事情,但我真的不能把我的手指放在上面……每次我尝试使用某种平台工具包时,似乎都会发生类似的事情,我总是放弃使用X/carbon/win32。

正如用户指出的,问题在于主.c文件

当我最初启动这个简单的测试应用程序时,我只是将我的
main.c
gte.glade
文件放在项目的根文件夹中,慢慢向外扩展。 一旦我正确加载了最初的
GtkBuilder
对象——见下文——我就开始玩弄
cmake
,因为这是这个小测试的另一个原因

我立即注意到
cmake
随着我的文件夹越来越接近工作状态,它确实把我的文件夹弄得乱七八糟,所以我遵循了我在其他类似项目中注意到的设计范例:
lmms
simon
,等等……并自动创建一个构建文件夹,并从该文件夹中运行
cmake..

一旦我进一步掌握了cmake的窍门,最终使
--cflags
--libs
正常工作,因为之前我只在命令行或makefiles中使用了
pkg config…

最难理解的部分是
link\u libraries(…)
函数,我最初认为该函数是
target\u link\u libraries(…)
,然后在尝试指定哪个参数时弄得一团糟。我最初尝试了
$(GTK_LIBRARIES}
但这似乎不够具体——然后是
目标链接库(…)
函数的各种位置

一旦我开始工作,我想开始扩展我的小测试应用程序多一点,我把源文件移到
src/
目录中并找到了它