How to link libraries in CLion? - c

I've been at this problem for a while now and couldn't find anything to solve my problem. I'm trying to use the ncurses.h library in my program but the linker failed and told me that I had undefined symbols. I fixed that by creating a new folder called includes and copying the location of ncurses.h from /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/ncurses.h to the new folder. Then I put this line into my CMakeLists.txt file: target_link_libraries(<project name> includes/ncurses.h). But then I got another error saying ld: library not found for -lincludes/ncurses.h. I've tried using add_library() but that gave me an error saying:
The target name "includes/ncurses.h" is reserved or not valid for certain
CMake features, such as generator expressions, and may result in undefined
behavior.
Does anyone have any other suggestions?

To find the location of the ncurses library, you will need to use the find_package() to locate the Curses package. The find_package() will return the CURSES_INCLUDE_DIR and CURSES_LIBRARY environment variables with the location of the include files and library.
Following is minimal example that works in CLion on macOS with:
CMakeLists.txt
cmake_minimum_required(VERSION 2.9)
project(test)
find_package(Curses REQUIRED)
include_directories(${CURSES_INCLUDE_DIR})
add_executable(test test.c)
target_link_libraries(test ${CURSES_LIBRARY})
test.c
#include <ncurses.h>
int main()
{
initscr(); /* Start curses mode */
printw("Hello World !!!"); /* Print Hello World */
refresh(); /* Print it on to the real screen */
getch(); /* Wait for user input */
endwin(); /* End curses mode */
return 0;
}

Related

Why is only the reference to endwin() not defined, when compiling this example code for PDCurses?

When compiling the example hello-world.c for PDCurses, the linker can't seem to find the endwin() function only. Commenting out the line containing endwin(), the code compiles fine and the program runs.
Here's the example code, taken from here (from source/pdce0.c):
#include <curses.h>
/* hello world, initialize curses */
int main()
{
initscr();
printw("Hello World !!!");
refresh();
getch();
endwin();
return 0;
}
When compiling using the mingw64 shell, the following error get's thrown
$ gcc -W -Wall -Ic:/Tools/msys64/mingw64/include/pdcurses -o test hello-world.c -lpdcurses
C:/Tools/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Tools\msys6
4\tmp\ccsKgZ37.o:hello-world.c:(.text+0x39): undefined reference to `endwin_x64_4302'
collect2.exe: error: ld returned 1 exit status
As stated above, commenting out endwin() in the code leads to compilation without error.
My setup is a MSYS2 installation on Win10 and I installed the mingw64 toolchain and PDCurses for mingw64 according to the steps described by the MSYS doc and this question.
I tried linking the curses lib in different ways, -lncurses, -llibpdcurses, but this does not help.
I tried the curses.h found in the above stated GitHub repo, it looks much simpler, but all this does is change the error to undefined reference to 'endwin'.
Edit 1 regarding comments
Concerning the internal definition of endwin() as a macro, I found this part in the include\pdcurses\curses.h
#ifdef PDC_WIDE
#ifdef PDC_FORCE_UTF8
#ifdef CHTYPE_32
#define endwin endwin_u32_4302
#else
#define endwin endwin_u64_4302
#endif
#else
#ifdef CHTYPE_32
#define endwin endwin_w32_4302
#else
#define endwin endwin_w64_4302
#endif
#endif
#else /* 8-bit chtypes */
#ifdef CHTYPE_32
#define endwin endwin_x32_4302
#else
#define endwin endwin_x64_4302
#endif
#endif
A comparable definition is not included in the curses.h from the examples repo.
Still, endwin() doesn't seem to be defined in the lib.
I already tried reinstalling the pdcurses package via pacman, but everything seems to be fine on that end.
Could using another of the MSYS shells or another package be of help? I'll see what I can find out.
Edit 2
I just took a look at some of the other examples and found out, that adding an infinite loop like
int main()
{
initscr();
printw("Hello World !!!");
while(1){
refresh();
}
getch();
endwin();
return 0;
}
also compiles without the error, but of course produces an unresponsive program.
I have to add that I'm rather new to C, compiling and everything, so if this problems requires some further reading, I'd be glad about suggestions.
Using #include <pdcurses.h> lets it compile without error (this is kinda the direction, John Bollinger mentioned in his comment). I found this issue on the MSYS2/MINGW-Packages GitHub, leaving the impression, that my installation/build version of pdcurses might need some attention. Like one of the commenters there, I thought, that linking against pdcurses didn't need changes of the included headers. I'll look into the setup more thoroughly.
But just to get started and try some things out, everything seems to work for now.

OpenAL Library Linking With cMake

I'm trying to get a grasp on audio programming in C with OpenAL. I prefer CLion as an IDE to Visual Studio, but that generally means having to deal with cmake stuff and I ran into an issue regarding this. Right now I'm just trying to link the library (as in getting the definitions of the OpenAL functions) but it seems I've got something out of place. Here's the CMakeLists.txt file,
cmake_minimum_required(VERSION 3.19)
project(AudioTest C)
set(CMAKE_C_STANDARD 99)
set(OPENAL_LIBRARY "C:/Program Files (x86)/OpenAL 1.1 SDK/libs/Win64/") //OpenAL Installed here
find_package(OpenAL REQUIRED)
add_executable(AudioTest main.c)
target_link_libraries(AudioTest "${OPENAL_LIBRARY}")
The Cmake file compiles (or reloads) fine on it's own. But when I try to run this simple program,
#include <stdio.h>
#include <al.h>
int main() {
printf("Hello, World!\n");
alGetError();
return 0;
}
I end up with this,
undefined reference to '_imp__alGetError'
Could I get some pointers to what I might be missing?

Undefined references when compiling gSOAP client

I'm trying to create a client for a web service in C. I was generated C files with the wsdl2h and soapcpp2. In netbeans I'm added the generated files and the gSOAP include dir to the project's include directories.
my main file looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <soapH.h>
#include <webserviceSoap12.nsmap>
int main(int argc, char** argv) {
struct soap *soap1 = soap_new();
struct _ns1__getAllCustomer *quote;
struct _ns1__getAllCustomerResponse *quote2;
if (soap_call___ns2__getAllCustomer(soap1, NULL, NULL, quote, quote2) == SOAP_OK)
printf("asd\n");
else // an error occurred
soap_print_fault(soap1, stderr); // display the SOAP fault on the stderr stream
return (EXIT_SUCCESS);
}
I copied the most of this from the gSOAP website's getting started section.
When I try to compile i get the following error:
build/Debug/MinGW-Windows/main.o: In function `main':
\NetBeansProjects\WebServiceClient/main.c:19: undefined reference to `soap_new_LIBRARY_VERSION_REQUIRED_20808'
\NetBeansProjects\WebServiceClient/main.c:22: undefined reference to `soap_call___ns2__getAllCustomer'
\NetBeansProjects\WebServiceClient/main.c:25: undefined reference to `soap_print_fault'
If I add the "soapC.c" "soapClient.c" "soapClientLib.c" files to the project I get a bunch of more undefinied reference.
What am I doing wrong? I'm using Netbeans ide with MinGW compiler on Win7. What other libraries I need or what other files should I include?
I managed to solve the problem by adding the files "soapC.c" "soapClient.c" "stdsoap.c" to the project files and in the Project propertie - Include Directories adding the files generated by soapcpp2 and the gSOAP toolkit's gsoap directory
You will need to link in the proper libraries. You will need to add the appropriate libraries using the -l switch and you will optionally need to pass the path to where these libraries reside via -L. Also, note that the libraries ending with a ++ are typically the ones you should use if you're using C++. So, your command line shoulde include at least:
For C:
gcc ... -lgsoap -L/path/to/gsoap/binaries
For C++:
g++ ... -lgsoap++ -L/path/to/gsoap/binaries
Also, depending on whether you're using additional features such as SSL, cookies etc. you will need to link these libraries in too:
g++ ... -lgsoap++ -lgsoapssl++ -L/path/...
If you're using a different toolchain, lookup the documentation for the exact switches.
I had this problem in Debian BullsEye (11), -lgsoap++ is necessary and it was solved when I added /gsoap_library_path/libgsoap++.a to g++ compiler command line.

run c program - stdio.h where do i get it?

Looking into learning C. As I understand it when I say #include <stdio.h> it grabs stdio.h from the default location...usually a directory inside your working directory called include. How do I actually get the file stdio.h? Do I need to download a bunch of .h files and move them from project to project inside the include directory? I did the following in a test.c file. I then ran make test and it outputted a binary. When I ran ./test I did not see hello print onto my screen. I thought I wasn't seeing output maybe because it doesn't find the stdio.h library. But then again if I remove the greater than or less than signs in stdio the compiler gives me an error. Any ideas?
I'm on a Mac running this from the command line. I am using: GNU Make 3.81. This program built for i386-apple-darwin10.0
#include <stdio.h>
main()
{
printf("hello");
}
Edit: I have updated my code to include a datatype for the main function and to return 0. I still get the same result...compiles without error and when I run the file ./test it doesn't print anything on screen.
#include <stdio.h>
int main()
{
printf("hello");
return 0;
}
Update:
If I add a \n inside of the printf it works! so this will work:
#include <stdio.h>
int main()
{
printf("hello\n");
return 0;
}
Your code should have preferably
printf("hello\n");
or
puts("hello");
If you want to know where does the standard header file <stdio.h> comes from, you could run your compiler with appropriate flags. If it is gcc, try compiling with
gcc -H -v -Wall hello.c -o hello
Pedantically, a standard header file is even not required to exist as a file; the standard permits an implementation which would process the #include <stdio.h> without accessing the file system (but e.g. by retrieving internal resources inside the compiler, or from a database...). Few compilers behave that way, most really access something in the file system.
If you didn't have the file, you'd get a compilation error.
My guess is the text was printed, but the console closed before you got the chance to see it.
Also, main returns an int, and you should return 0; to signal successful completion.
#include <header.h>, with angle brackets, searches in standard system locations, known to the compiler-- not in your project's subdirectories. In Unix systems (including your Mac, I believe), stdio.h is typically in /usr/include. If you use #include "header.h", you're searching subdirectories first and then the same places as with <header.h>.
But you don't need to find or copy the header to run your program. It is read at compilation time, so your ./test doesn't need it at all. Your program looks like it should have worked. Is it possible that you just typed "test", not "./test", and got the system command "test"? (Suggestion: Don't name your programs "test".)
Just going to leave this here : STILL! in 2018, December... Linux Mint 18.3
has no support for C development.
innocent / # cc ThoseSorts.c
ThoseSorts.c:1:19: fatal error: stdio.h: No such file or directory
compilation terminated.
innocent / # gcc ThoseSorts.c
ThoseSorts.c:1:19: fatal error: stdio.h: No such file or directory
compilation terminated.
innocent / # apt show libc6
(Abbreviated)::
Package: libc6
Version: 2.23-0ubuntu10
Priority: required
Section: libs
Source: glibc
Origin: Ubuntu
Installed-Size: 11.2 MB
Depends: libgcc1
Homepage: http://www.gnu.org/software/libc/libc.html
Description: GNU C Library: Shared libraries
Contains the standard libraries that are used by nearly all programs on
the system. This package includes shared versions of the standard C library
and the standard math library, as well as many others.
innocent / # apt-get install libc6-dev libc-dev
So, magic... and a minute later they are all installed on the
computer and then things work as they should.
Not all distros bundle up all the C support libs in each ISO.
Hunh.
hardlyinnocent / # gcc ThoseSorts.c
hardlyinnocent / # ./a.out
20
18
17
16
... ... ...

compiling FMOD with mingw?

I have the following example from gamedev, and I was wondering how you would go about compiling this. I've downloaded FMOD and its installed in C:\Program Files\FMOD SoundSystem\FMOD Programmers API Win32. And I have the .dll's and a mp3 file in my working directory but I'm not sure what/how to compile and link this through command line?
EDIT: code
#include
#include "inc/fmod.h"
FSOUND_SAMPLE* handle;
int main ()
{
// init FMOD sound system
FSOUND_Init (44100, 32, 0);
// load and play sample
handle=FSOUND_Sample_Load (0,"sample.mp3",0, 0, 0);
FSOUND_PlaySound (0,handle);
// wait until the users hits a key to end the app
while (!_kbhit())
{
}
// clean up
FSOUND_Sample_Free (handle);
FSOUND_Close();
}
That code is for FMOD3, I would recommend getting the latest release of FMODEx aka FMOD4 from www.fmod.org.
When compiling really don't have to do anything special, just ensure you '-I' include the directory that contains "inc/fmod.h" and '-L' the "lib" directory that contains the fmod lib and lastly '-l' the actual fmod lib.

Resources