我正在尝试通过SDL2 KISS(在第4页上找到)学习如何使用example provided in the manual项目/工具包/库事物。然而,每当我链接它时,它都会失败,引用重复的符号错误。 repo中提供的两个 example files 构建,编译并正常工作。
我的假设是,因为我正在尝试将手册中的示例代码编写到C ++文件中,并且库是纯C89的,所以会有一些愤怒的内部编译器爆炸。如果我使用相同的代码转发声明一个C函数,一切似乎都没问题,但我真的希望没有一堆C ++文件纯粹作为委托来调用C函数。
在项目readme(在第一段末尾)确实说一切都是C ++兼容的,并且实际上是以写入SDL2库的方式编写的 - 我可以毫无问题地使用它。似乎正确设置了SDL2 KISS标头,以便与C ++一起使用:
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
};
#endif
尽可能导致Undefined symbols for architecture x86_64
链接器错误的原因,我有三个嫌疑人:我对将纯C与C ++混合的无知,我为项目编写的CMakeLists,或者库本身的问题(我觉得非常不可能)。我已经在几天内弄乱了不同的潜在解决方案,但没有遇到任何比向前声明更好的事情(再次,我不想这样做)。 Bellow你会找到确切的错误,我的main.cpp
文件,其中只包含手册中的代码,以及我写的CMakeLists
文件。发布的代码对我来说不构建,但我可以发布正在工作的C ++文件,该文件向前声明一个C函数,如果这样做会有帮助。
Scanning dependencies of target Test_KISS
[ 16%] Linking CXX executable bin/Test_KISS
duplicate symbol _kiss_border in:
CMakeFiles/Test_KISS.dir/src/main.cpp.o
CMakeFiles/Test_KISS.dir/include/kiss_draw.c.o
duplicate symbol _kiss_green in:
CMakeFiles/Test_KISS.dir/src/main.cpp.o
CMakeFiles/Test_KISS.dir/include/kiss_draw.c.o
duplicate symbol _kiss_progress_interval in:
CMakeFiles/Test_KISS.dir/src/main.cpp.o
CMakeFiles/Test_KISS.dir/include/kiss_draw.c.o
duplicate symbol _kiss_click_interval in:
CMakeFiles/Test_KISS.dir/src/main.cpp.o
CMakeFiles/Test_KISS.dir/include/kiss_draw.c.o
duplicate symbol _kiss_black in:
CMakeFiles/Test_KISS.dir/src/main.cpp.o
CMakeFiles/Test_KISS.dir/include/kiss_draw.c.o
duplicate symbol _kiss_slider_padding in:
CMakeFiles/Test_KISS.dir/src/main.cpp.o
CMakeFiles/Test_KISS.dir/include/kiss_draw.c.o
duplicate symbol _kiss_spacing in:
CMakeFiles/Test_KISS.dir/src/main.cpp.o
CMakeFiles/Test_KISS.dir/include/kiss_draw.c.o
duplicate symbol _kiss_textfont_size in:
CMakeFiles/Test_KISS.dir/src/main.cpp.o
CMakeFiles/Test_KISS.dir/include/kiss_draw.c.o
duplicate symbol _kiss_buttonfont_size in:
CMakeFiles/Test_KISS.dir/src/main.cpp.o
CMakeFiles/Test_KISS.dir/include/kiss_draw.c.o
duplicate symbol _kiss_lightblue in:
CMakeFiles/Test_KISS.dir/src/main.cpp.o
CMakeFiles/Test_KISS.dir/include/kiss_draw.c.o
duplicate symbol _kiss_blue in:
CMakeFiles/Test_KISS.dir/src/main.cpp.o
CMakeFiles/Test_KISS.dir/include/kiss_draw.c.o
duplicate symbol _kiss_white in:
CMakeFiles/Test_KISS.dir/src/main.cpp.o
CMakeFiles/Test_KISS.dir/include/kiss_draw.c.o
duplicate symbol _kiss_edge in:
CMakeFiles/Test_KISS.dir/src/main.cpp.o
CMakeFiles/Test_KISS.dir/include/kiss_draw.c.o
ld: 13 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [bin/Test_KISS] Error 1
make[1]: *** [CMakeFiles/Test_KISS.dir/all] Error 2
make: *** [all] Error 2
#include "kiss_sdl.h"
void button_event(kiss_button *button, SDL_Event *e, int *draw, int *quit)
{
if (kiss_button_event (button, e, draw))
*quit = 1;
}
int main (int argc, char *argv[])
{
SDL_Renderer *renderer;
SDL_Event e;
kiss_array objects;
kiss_window window;
kiss_label label;
kiss_button button;
char message[KISS_MAX_LENGTH];
int draw = 1;
int quit = 0;
kiss_array_new (&objects);
renderer = kiss_init ("Test KISS SDL", &objects, 320, 120);
kiss_window_new (&window, NULL, 0, 0, 0, kiss_screen_width, kiss_screen_height);
strcpy (message, "Hello, world!");
kiss_label_new (&label, &window, message, window.rect.w / 2 - strlen (message) * kiss_textfont.advance / 2, window.rect.h / 2 - (kiss_textfont.fontheight + 2 * kiss_normal.h) / 2);
label.textcolor.r = 255;
kiss_button_new (&button, &window, "Okay", window.rect.w / 2 - kiss_normal.w / 2, label.rect.y + kiss_textfont.fontheight + kiss_normal.h);
window.visible = 1;
while (!quit)
{
SDL_Delay (10);
while (SDL_PollEvent (&e))
{
if (e.type == SDL_QUIT)
quit = 1;
kiss_window_event (&window, &e, &draw);
button_event (&button, &e, &draw, &quit);
}
if (!draw)
continue;
SDL_RenderClear (renderer);
kiss_window_draw (&window, renderer);
kiss_label_draw (&label, renderer);
kiss_button_draw (&button, renderer);
SDL_RenderPresent (renderer);
draw = 0;
}
kiss_clean (&objects);
return 0;
}
cmake_minimum_required(VERSION 3.3)
project(Test_KISS)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${Test_KISS_SOURCE_DIR}/cmake")
set(BIN_DIR ${Test_KISS_SOURCE_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
#Define Preprocessor Macros (RESDIR found in include/kiss_sdl.h)
add_definitions(-DRESDIR=\"../../resources/\")
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIR})
find_package(SDL2_ttf REQUIRED)
include_directories(${SDL2_TTF_INCLUDE_DIR})
find_package(SDL2_image REQUIRED)
include_directories(${SDL2_IMAGE_INCLUDE_DIR})
include_directories(include)
add_executable(Test_KISS src/main.cpp include/kiss_draw.c include/kiss_general.c include/kiss_posix.c include/kiss_widgets.c)
target_link_libraries(Test_KISS ${SDL2_LIBRARY} ${SDL2_TTF_LIBRARY} ${SDL2_IMAGE_LIBRARY})
install(TARGETS Test_KISS RUNTIME DESTINATION ${BIN_DIR})
如果我可以提供更多帮助信息,请告诉我们!
谢谢!
答案 0 :(得分:2)
kiss_sdl.h实际上定义众多变量:
double kiss_spacing;
int kiss_textfont_size, kiss_buttonfont_size;
int kiss_click_interval, kiss_progress_interval;
int kiss_slider_padding;
int kiss_border, kiss_edge;
int kiss_screen_width, kiss_screen_height;
在#include
个文件的每个C / C ++文件中定义这些变量。因此,您会得到重复的符号 - 因为是重复的符号。
修复?修复代码以使其正确declares the variables instead of defining them。
换句话说,代码被破坏了。
答案 1 :(得分:0)
现在修好了。 extern" C"虽然意味着它下面的声明就像C ++,其余的代码就像C一样编译,就像我的C89一样。如果使用C编译器编译,则使用c扩展名编译。正确理解这是解决问题的原因。
SDL2 https://github.com/actsl/kiss_sdl的简单通用GUI小部件工具包,由我编写。