Linking GSL to C via make

17,094

Solution 1

Ok, so I figured out what the problem is. Turns out that I had another version of make as discussed on this thread.

Solution 2

You should add -LC:/gsl to the list of searched directories , -I adds an include directory to be searched for headers, and -L adds a directory to be searched for libraries with -l<lib>. However, I don't see you actually compiling anything, maybe you should start with a Makefile template instead:

CC=gcc
CFLAGS=-c -Wall -Ic:/gsl
LDFLAGS= -Lc:/gsl
LIBS= -lgsl
SOURCES=main.c
OBJECTS=$(SOURCES:.c=.o)
EXECUTABLE=hello

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
    $(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@

.c.o:
    $(CC) $(CFLAGS) $< -o $@

Solution 3

Your latest error indicates that GNU make is having trouble running a command. In windows, it uses the CreateProcess function, and that function is failing. This has nothing to do with gsl anymore. Is gcc on your path? What do you get if you just type gcc instead of make?

Share:
17,094

Related videos on Youtube

tchakravarty
Author by

tchakravarty

Statistician.

Updated on September 15, 2022

Comments

  • tchakravarty
    tchakravarty over 1 year

    Umpteenth linking question. I am trying to build some simple C code that calls the GNU scientific library. However, the GSL folder is not nested in my project folder. So, the code lives in, say, C:/c-examples/ and the GSL library is C:/gsl.

    This is the C code

    #include <stdio.h>
    #include <gsl_math.h>
    #include <fit/gsl_fit.h>
    
         int
         main (void)
         {
           int i, n = 4;
           double x[4] = { 1970, 1980, 1990, 2000 };
           double y[4] = {   12,   11,   14,   13 };
           double w[4] = {  0.1,  0.2,  0.3,  0.4 };
    
           double c0, c1, cov00, cov01, cov11, chisq;
    
           gsl_fit_wlinear (x, 1, w, 1, y, 1, n,
                            &c0, &c1, &cov00, &cov01, &cov11,
                            &chisq);
    
           printf ("# best fit: Y = %g + %g X\n", c0, c1);
           printf ("# covariance matrix:\n");
           printf ("# [ %g, %g\n#   %g, %g]\n",
                   cov00, cov01, cov01, cov11);
           printf ("# chisq = %g\n", chisq);
    
           for (i = 0; i < n; i++)
             printf ("data: %g %g %g\n",
                            x[i], y[i], 1/sqrt(w[i]));
    
           printf ("\n");
    
           for (i = -30; i < 130; i++)
             {
               double xf = x[0] + (i/100.0) * (x[n-1] - x[0]);
               double yf, yf_err;
    
               gsl_fit_linear_est (xf,
                                   c0, c1,
                                   cov00, cov01, cov11,
                                   &yf, &yf_err);
    
               printf ("fit: %g %g\n", xf, yf);
               printf ("hi : %g %g\n", xf, yf + yf_err);
               printf ("lo : %g %g\n", xf, yf - yf_err);
             }
           return 
    }
    

    And here is the makefile I wrote for it:

    CC=gcc
    CFLAGS=-Wall -IC:/gsl -lgsl
    OLSexample: OLSexample.o 
    
    clean:
        rm -f OLSexample OLSexample.o
    

    However, running make on this exits with error 2, file not found. I think I might be doing something wrong in the makefile specifying the dependencies, or in linking the libraries. Any help is welcome.


    EDIT2:

    Following mux's advice, and the template here I changed the makefile to the following (including the full paths to the library). I continue to get the previous error (e=2).

    CC=gcc
    CFLAGS=-c -Wall -IE:/programming/c/libraries/gsl-1.15.tar/gsl-1.15/
    LDFLAGS= -LE:/programming/c/libraries/gsl-1.15.tar/gsl-1.15/
    LIBS= -lgsl
    SOURCES=OLSexample.c
    OBJECTS=$(SOURCES:.c=.o)
    EXECUTABLE=OLSexample
    
    all: $(SOURCES) $(EXECUTABLE)
    
    $(EXECUTABLE): $(OBJECTS)
        $(CC) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $@
    
    .c.o:
        $(CC) $(CFLAGS) $< -o $@
    

    The complete error message is included here for reference:

    e:\programming\c\WorkingFolder\gslExamples\1-ols>make
    make
    gcc -c -Wall -IE:/programming/c/libraries/gsl-1.15.tar/gsl-1.15/   -c -o OLSexample.o OLSexample.c
    process_begin: CreateProcess((null), gcc -c -Wall -IE:/programming/c/libraries/gsl-1.15.tar/gsl-1.15/ -c -o OLSexample.o OLSexample.c, ...) failed.
    make (e=2): The system cannot find the file specified.
    make: *** [OLSexample.o] Error 2
    
    • iabdalkader
      iabdalkader over 11 years
      First, that's not the complete Makefile, you're missing the last bit, second, now that you use LDFLAGS when linking the object files you should add any linker flags to a variable called LDFLAGS and also the Libraries should go after the $(OBJECTS)
  • tchakravarty
    tchakravarty over 11 years
    Ok, so I was using the wrong switch -I instead of -L. Thanks for the correction. I still get the e=2 error -- The system cannot find the file specified.
  • tchakravarty
    tchakravarty over 11 years
    Mux, I have added to the question following your suggestions. I continue to get the same error -- could you take a look?
  • tchakravarty
    tchakravarty over 11 years
    Thanks David. I am using MinGW on 64-bit Windows, and the path to the bin is in my global path variable: e:\programming\c\WorkingFolder\gslExamples\1-ols>gcc gcc gcc: fatal error: no input files compilation terminated.
  • tchakravarty
    tchakravarty over 11 years
    Furthermore: e:\programming\c\WorkingFolder\gslExamples\1-ols>gcc -Wall OLSexample.c gcc -Wall OLSexample.c OLSexample.c:2:22: fatal error: gsl_math.h: No such file or directory compilation terminated.
  • HonkyTonk
    HonkyTonk over 11 years
    Why have you added -c to CFLAGS? This flag should be used when compiling .c to .o file without linking and not for every compilation. Further, it's typically better to not define rules for this translation but use the built in rules.
  • iabdalkader
    iabdalkader over 11 years
    That's exactly why it's there, multiple files are compiled separately and then linked once, I don't see the problem ?