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