Undefined symbols for x86 - KISS 0.10.6 (sorry!)
AVividLight opened this issue · 8 comments
Hello!
Sorry for creating another issue here, I hope I'm not becoming bothersome! After upgrading my test project to the latest version of KISS_SDL, 0.10.6, I'm seeing undefined linker errors. Specifically, the following.
Undefined symbols for architecture x86_64:
"kiss_clean(kiss_array*)", referenced from:
_main in main.cpp.o
"kiss_array_new(kiss_array*)", referenced from:
_main in main.cpp.o
"kiss_label_new(kiss_label*, kiss_window*, char*, int, int)", referenced from:
_main in main.cpp.o
"kiss_button_new(kiss_button*, kiss_window*, char*, int, int)", referenced from:
_main in main.cpp.o
"kiss_label_draw(kiss_label*, SDL_Renderer*)", referenced from:
_main in main.cpp.o
"kiss_window_new(kiss_window*, kiss_window*, int, int, int, int, int)", referenced from:
_main in main.cpp.o
"kiss_button_draw(kiss_button*, SDL_Renderer*)", referenced from:
_main in main.cpp.o
"kiss_window_draw(kiss_window*, SDL_Renderer*)", referenced from:
_main in main.cpp.o
"kiss_button_event(kiss_button*, SDL_Event*, int*)", referenced from:
button_event(kiss_button*, SDL_Event*, int*, int*) in main.cpp.o
"kiss_window_event(kiss_window*, SDL_Event*, int*)", referenced from:
_main in main.cpp.o
"kiss_init(char*, kiss_array*, int, int)", referenced from:
_main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
In my main.cpp, changing
#include "kiss_sdl.h
to
extern "C" {
#include "kiss_sdl.h"
}
fixes the issues, and the project then builds, links, and runs as expected. Adding the following back to the header fixed this for me.
#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
};
#endif
Here's a pull request to add the above definition back to kiss_sdl.h, but please ignore it if there are better ways!
Sorry for creating so many issues! Please let me know if you'd appreciate some radio silence, or if I need to learn a bit more about how to use my compiler, or something. Thank you for the support!
This is not enough information to solve the issue, and reproduce the problem you may have.
My Linux is 64 bits also, and it perfectly builds and runs on it, with C++ compiler, as well as with C compiler.
Have you tried to build it just using the kiss_makefile, how it is built for Linux? I have no Macintosh to try, but i can figure that that may be the only thing that is necessary, just to build with an ordinary makefile, without changing anything, no need for CMake at all. Only change the compiler to C++, and delete -std=c89, you may do that everywhere you see it. And then just write in the terminal, make -f kiss_makefile . Have you tried it?
Because, the only reason how adding this extern "C" can change anything, by any straight thinking, is when the source files are compiled in C++, and linked with C, when only a C++ compiler, that is g++ or clang++, is used for both compiling and linking, this construct shouldn't change anything. Because both with it and without it, the linking happens by the same C++ convention. Unless something very weird is going on, which i can never exclude when it is about software, but it is highly unlikely.
To reproduce the problem, it is inevitable to know how exactly did you build, all your project with CMake and all its files. Important is also what extensions the files had. I somewhat suspect that CMake, the way you configured it, compiled the files with a C++ compiler, and linked with a C compiler, this can explain the linker output.
But if you can try to build the kiss_sdl examples with its makefile, and then something goes wrong, then it makes it much easier, all that is necessary to know is kiss_makefile, the way you changed it, and the make output.
Until you can get more information, i cannot do anything by now. I cannot reproduce the problem. Because for me in my 64 bit Linux, when compiling with C++, everything works.
All i can reproduce by now, if i compile and link everything with a C++ compiler, but examples with a C compiler, then i get
kiss_example1.c:(.text+0x101c): undefined reference to `kiss_window_draw'
kiss_example1.c:(.text+0x1032): undefined reference to `kiss_label_draw'
kiss_example1.c:(.text+0x1048): undefined reference to `kiss_label_draw'
kiss_example1.c:(.text+0x105e): undefined reference to `kiss_textbox_draw'
kiss_example1.c:(.text+0x1074): undefined reference to `kiss_vscrollbar_draw'
kiss_example1.c:(.text+0x108a): undefined reference to `kiss_textbox_draw'
kiss_example1.c:(.text+0x10a0): undefined reference to `kiss_vscrollbar_draw'
kiss_example1.c:(.text+0x10b6): undefined reference to `kiss_label_draw'
kiss_example1.c:(.text+0x10cc): undefined reference to `kiss_entry_draw'
kiss_example1.c:(.text+0x10e2): undefined reference to `kiss_button_draw'
kiss_example1.c:(.text+0x10f8): undefined reference to `kiss_button_draw'
Plenty more of that.
Without being able to reproduce it, there are though too many possibilities that could happen. Like if you compiled the source files with a 32 bit compiler, but linked with a 64 bit compiler. I don't know how that could happen, but i cannot exclude anything. CMake is too obscure in what it does, and completely everything that it does cannot be controlled. This is one reason why i didn't use it, and used only a traditional makefile.
I will try using the makefile; I've been using CMake because the makefile doesn't find my SDL2, SDL2 TTF, and SDL2 Image libraries, and I don't know enough about makefiles to add search paths. Sorry that I didn't provide more details, I'm using the exact same test project (same CMakeLists too) that I used to build 0.10.4, so I assumed it wasn't a problem caused by something I've done. I'll do some more testing, and get back to you.
Thank you for the quick response!
If it's helpful, here's the compressed project that's throwing the errors.
Test_KISS.zip
I'm using the exact same test project
This means that you didn't try to do anything to use only a C++ compiler. Then it can be said beforehand that it fails, it must fail, because some of your files are c and some cpp, CMake in its configuration by default finds C compiler for C files and C++ compiler for C++ files. It does that rightly, and it certainly fails because everything is not compiled with a C++ compiler.
To change that, you supposed to add CXX to your project statement in CMakeLists.txt, this forces CMake to use only C++ compiler. Like this:
project(Test_KISS CXX)
Which i did, but then it said
Unknown extension ".c" for file
And this is a big problem, this is how inflexible CMake is. Now i can make it to work in some way, sure, but i know that in this case, this will not be simple, as it would be something like forcing CMake to do something it finds not valid. And therefore i'm not going to do that. Also my project is made using makefile, i said it can also be used in C++, which now is true, but i did not say that it can be used with CMake, this promise i never gave.
You can certainly solve that by copying all c files into cpp files, that's only one command, and it works, you don't even have to change the project statement or anything else then. But it is a stupid solution, this toolkit is made to be compiled both in C and C++, and CMake prevents that.
Adding that extern "C" into the code is not a solution at all, as it not only is an improper solution, but it also causes problems.
Aren't SDL libraries in Macintosh in the system locations like in Linux, so that it is not necessary to add library paths at all? Try first, maybe they are. sdl2-config --cflags --libs gives sdl library paths, but it is not so easy with sdl_image and sdl_ttf. You can also use CMake only to locate libraries.
If you build with makefile with only a C++ compiler, you almost beyond doubt succeed.
OK, i used the extern "C" now, as this is how it is considered to be correct. Couldn't use the pull request though, as it is not entirely correct.
However, with extern "C", a C compiler compiling the c file as C++, this is not consistent, they add features that are against the rules.
The new version of kiss_sdl 0.10.8, with improved using with C++. is now in GitHub.
With CMake, only the file's extension c or cpp, determines what compiler it uses. For the files with an extension c, it uses a C compiler, and for the files with an extension cpp, it uses a C++ compiler.
With that new version, your test project with CMake builds and runs well. However, this statement in CMakeLists.txt
add_definitions(-DRESDIR=\"../../resources/\")
is not correct, as you now have resources in ./resources, and executable in ./bin, thus one directory up and one down, not two directories up. You have also source files in ./include, which is not correct, only *.h files should be in the include directory. With that, it however works. But the statement above has to be replaced with that one
add_definitions(-DRESDIR=\"../resources/\")
And then it works.
The file below is my version of building the project with CMake.
The new version, 0.10.8, has fixed the issue for me, thanks for doing such a great job! My test project now compiles and links without any issues! I had to change one line in the CMakeLists.txt from the example project above, because it couldn't find the cmake folder. If you're interested, the error it gave me was as follows.
CMake Error at CMakeLists.txt:6 (find_package):
By not providing "FindSDL2.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "SDL2", but
CMake did not find one.
Could not find a package configuration file provided by "SDL2" with any of
the following names:
SDL2Config.cmake
sdl2-config.cmake
Add the installation prefix of "SDL2" to CMAKE_PREFIX_PATH or set
"SDL2_DIR" to a directory containing one of the above files. If "SDL2"
provides a separate development package or SDK, be sure it has been
installed.
I changed line 6 to set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${Test_KISS_SOURCE_DIR}/cmake")
, and everything worked very well!
Thank you again for helping me with this! I really appreciate your support, and am excited to begin using KISS_SDL in earnest. If I can help at all, with development or testing, or even proof reading, or something, please let me know!
Thanks!