I'm trying to learn how to use the SDL2 KISS project/toolkit/library-thing, via the example provided in the manual (found on page 4). Whenever I link it, however, it fails, citing duplicate symbol errors. The two example files provided in the repo build, compile, and work fine.
My hypothesis is that because I'm trying to write the example code from the manual into a C++ file, and the library is pure C89, there is some angry internal compiler explosion going on. If I forward declare a C function with the same code, everything seems to be okay, but I'd really like to not have a bunch of C++ files that exist purely as delegates to call C functions.
It does say in the project readme (at the end of the first paragraph) that everything is C++ compatible, and is actually written in the same way that the SDL2 library is written- which I can use without issue. The SDL2 KISS header seems to be correctly setup for use with C++, using:
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
};
#endif
As far as possible causes for the Undefined symbols for architecture x86_64
linker errors go, I have three suspects: my ignorance about mixing pure C with C++, the CMakeLists I wrote for the project, or an issue in the library itself (which I think is incredibly unlikely). I've been messing with different potential solutions for a few days, but haven't come across anything better than forward declaring (which, again, I don't want to do). Bellow you'll find the exact errors, my main.cpp
file, which contains exclusively the code from the manual, and the CMakeLists
file I wrote. The code posted does not build for me, but I can post the working C++ file which forward declares a C function, if that would be helpful.
Make error from terminal
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
main.cpp
#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;
}
CMakeLists
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})
If I can provide any more information to help, please let me know!
Thanks!