How to CORRECTLY install gsl library in Linux? - c

I got a problem while installing the GNU Scientific Library (gsl).
I put the package on my desktop, and did "./configure", "make", and "sudo make install", according to the document included. I checked the /usr/local/include directory, there is a newly created "gsl" folder in there. But When I tried to use the functions provided by the library, the "undefined reference to 'gsl_sf_beta_inc'" error occurred. Here is my code.
#include <stdio.h>
#include <gsl/gsl_sf_gamma.h>
int main (void)
{
double a = 20;
double b = 1000;
double x = 0.5;
double result = gsl_sf_beta_inc(a, b, x);
printf("%f/d", result);
return 0;
}
I sensed that the problem might be caused by the fact I put the package on the desktop, so the binary code generated by the "make" command goes there, which is wrong.
So, is my guess correct? If it is, where should I put them? If it is not, what should I do?
Thanks.

You need to link the library, assuming the make install was successful.
The gsl's documentation says this should work
(note the two necessary linking options for gsl to work: "-lgsl -lgslcblas"):
gcc -I/usr/local/include -L/usr/local/lib main.c -o main -lgsl -lgslcblas -lm
Alternative "cblas" instead of gsl's cblas is also possible as per: alternate cblas for gsl

Use pkg-config --libs gsl to find out what the necessary linkers are to be and then just link them. An optional thing would be to check pkg-config --cflags gsl. The second gives you the directory of the include files if they are not installed in the default /usr/include/ directory. If you've installed it there you can just ignore that.
The output of pkg-config --libs gsl would be
-lgsl -lgslcblas -lm
That means that those three have to be linked. So while compiling your program you do that by,
gcc name.c -lgsl -lgslcblas -lm

Related

Running Ruby in C compile and link issues

I've been trying all day to build and run a simple Ruby inside of C program.
This is a recurring topic here, and none of them are identical to my issue nor have any of the solutions helped me. I have the ruby-dev installed.
The pkg-config command gives this:
$ pkg-config --cflags --libs ruby-2.7
-I/usr/include/x86_64-linux-gnu/ruby-2.7.0 -I/usr/include/ruby-2.7.0 -lruby-2.7 -lm
The compile command gives this:
$ gcc -I/usr/include/x86_64-linux-gnu/ruby-2.7.0 -I/usr/include/ruby-2.7.0 -I. -lruby-2.7 -o hello *.c
/usr/bin/ld: /tmp/ccdKXtnU.o: in function 'main':
hello.c:(.text+0x9): undefined reference to 'ruby_setup'
collect2: error: ld returned 1 exit status
I have tried switching up the order of the includes. I have tried removing one then the other include. I have tried using a Makefile and running it thru make. I have tried breaking the program up into multiple files. I have tried symbolically linking the architecture relative config.h file into the main header file directory.
The only thing I can think of that I haven't tried is putting the name of the ruby object library that needs to be linked in on the command line, but I don't know the name, or location, of that file.
Here's the latest rendition of the program:
#include <stdio.h>
#include <ruby.h>
int main(void)
{
if (ruby_setup()){
puts("Hola!");
}
else{
printf("Hello World\n");
}
return(0);
}
One of the reasons that pkg-config separates cflags and libs is that they go in different places in the command-line (and sometimes different commands).
If you're going to compile and link in one command, it goes like this:
c99 -o hello $(pkg-config --cflags ruby-2.7) *.c $(pkg-config --libs ruby-2.7)
There's a certain logic to this arrangement. First, we tell the compiler where to look for header files (which it must see before it compiles your program), then where to find the program to compile, and finally where to find the libraries which are referred to by the program.

What are the correct flags for linking to gslcblas libraries when they are not in /usr/local/lib?

On my personal laptop I enter
gcc -std=gnu99 -lm -lgsl -lgslcblas equal_runtimes.c particle_filters.c solvers.c -o equal_runtimes
in the terminal to compile my C code and have no issues. As far as I know this is because the gsl headers and libraries are on the standard search paths /usr/local/include and /usr/local/lib respectively (https://www.gnu.org/software/gsl/doc/html/usage.html).
However, when I try to compile the same code with the above commands on a system in which the headers/libraries are located in /apps/gsl/2.1/include and /apps/gsl/2.1/lib respectively, I get the warning
warning: implicit declaration of function ‘gsl_blas_dgemv’ [-Wimplicit-function-declaration]
Therefore it seems the compiler is not linking the gsl libraries, as it's assuming gsl_blas_dgemv is my function. To try to fix this I've followed the guidance at the above gnu.org link, for which the best I can come up with is
gcc -L/apps/gsl/2.1/lib -std=gnu99 -lm -lgsl -lgslcblas equal_runtimes.c particle_filters.c solvers.c -o equal_runtimes
but still no success. Is there an issue with the above syntax I'm using or is there something else here that I'm missing?
Following on from #Eric Potpischil's comments, the problem was the wrong header <gsl/gsl_cblas.h> being used for gsl_blas_dgemv instead of the correct <gsl/gsl_blas.h>. This was not an issue on my own system as the blas library would automatically be found by virtue of its location, which was not the case when using the external system.

Having trouble linking to a static library with GCC

I'm working on a big project with glfw but I have been stymied trying to link to a static library with gcc, hence this toy example. I'm not sure why I'm having so much trouble with such a simple thing.
This is the extent of my source code:
#include <stdio.h>
#include <ft2build.h>
#include FT_FREETYPE_H
int main(){
FT_Library ft;
if (FT_Init_FreeType(&ft))
{
printf("ERROR::FREETYPE: Could not init FreeType Library\n");
}
FT_Face face;
if (FT_New_Face(ft, "fonts/arial.ttf", 0, &face))
{
printf("ERROR::FREETYPE: Failed to load font\n");
}
return 0;
}
I'm running Linux Mint. I downloaded the FreeType library and built it using CMake and my version of GCC. The libfretype.a file is in a subdirectory called junk. The headers are in a subdirectory called include.
We compile it with the following:
gcc -Wall -Wextra -g -v -Iinclude -Ljunk vex.c -lfreetype -o vex
and I get a ton of errors like sfnt.c:(.text+0x218): undefined reference to 'png_get_error_ptr' .
Thanks in advance for telling me the silly mistake I made.
It basically means that the implementation of the function png_get_error_ptr is missing. So, the compiler could not generate an executable because some code is missing.
The function png_get_error_ptr is implemented in a library named libpng. Sometimes, some libraries have some dependencies on another project, in the general case, you need to include all the dependencies to your build to resolve the linker errors.
You need to include these libraries in the linker:
gcc -Wall -Wextra -g -v -Iinclude -Ljunk vex.c -lfreetype -lpng -lz -o vex
^ ^
-lz is to link against zlib because libpng rely on zlib if I remember correctly.
http://libpng.org/pub/png/libpng-manual.txt

C - Build options for SDLGFX

I'm not sure if the correct term is "build options". Here's the code that doesn't work :
#include <SDL2/SDL.h>
#include <SDL2/SDL2_gfxPrimitives.h>
polygonRGBA(renderer, x, y, 6, 255, 0, 0, 155); // this part
I've used this to compile it :
gcc -o test main.c `sdl2-config --cflags --libs̀
polygonRGBA() is a function from SDLGFX. It seems I've not added the correct options to build it (except this part, SDL2's compilation works). The given error is :
undefined reference to 'polygonRGBA'
What is the correct option to add ?
Generally, you can use pkg-config --list-all and grep for the name of the package you want to add compile or link flags for. But I was a little surprised to see that there is no pkg-config option for SDLGFX even though I have the -dev package installed on my (Ubuntu) system. Nor does sdl-config include the libraries for it (not that it necessarily should).
So try adding -lSDL2_gfx to your invocation,
gcc -o test main.c `sdl2-config --cflags --libs` -lSDL2_gfx
When pkg-config fails, you can make a good guess by searching for the library by name,
$ find /usr/lib | grep gfx
....
/usr/lib/x86_64-linux-gnu/libSDL2_gfx.so
...
and using -l with the part between lib and .so: libSDL2_gfx.so

MinGW external libraries location

I'm running MinGW for the first time and I have trouble understanding where to put the external packages like the gsl library.
I'm showing first the program that I'm trying to run (it's in C:\Projects\C\)
#include <gsl/gsl_cdf.h>
#include <stdio.h>
int main() {
double bottom_tail = gsl_cdf_gaussian_P(-1.96, 1);
printf("A between [-1.96, 1.96]: %f\n", 1 - 2 * bottom_tail);
return 0;
}
this example is from the book 21st Century C
I've installed correctly pkg-config in order to obtain the flags for the compiler automatically. This is my makefile
CFLAGS= -g -Wall -O3
LDLIBS= `pkg-config --libs gsl`
CC=gcc
program:
I've downloaded the gsl library and put it in c:\gsl, and set $PKG_CONFIG_PATH to this location (where the .pc file is)
just running the command pkg-config --libs gsl I get the correct flags, but the make command crashes, telling me that
>>#include <gsl/gsl_cdf.h> No such file or directory
now I'm guessing that the install location is bad, but where should i put it?

Resources