Unable to compile with gsl on Mac - c

I am trying to implement gsl_rng.h on a Montecarlo simulation on my MacBook Pro (13-inch, Mid 2012). The simulation is all written in C. My problem is that gcc-6 complains it cannot find the gsl library despite the compilation flags which I think are fine.
The top of declare.h, which is included in all .c files I am working on:
/* __________________ LIBRARIES ___________________*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <gsl/gsl_rng.h>
The error:
fatal error: gsl/gsl_rng.h: No such file or directory
The compilation flags included in my makefile:
INCLUDE = -I/usr/local/Cellar/gsl/2.4/include
LINK = -L/usr/local/Cellar/gsl/2.4/lib -lgsl -lgslcblas
I installed both gcc-6 and gsl via Homebrew.
How can I make gcc-6 find gsl? Are my flags wrong?
The makefile:
CC = g++-6
CFLAGS = -lm -O3 -ansi -pedantic -Wall -Wextra\
-Wconversion -Wredundant-decls -fmax-errors=7\
-Wunsafe-loop-optimizations -Wmissing-braces\
-Wparentheses
# -Wdouble-promotion
INCLUDE = -I/usr/local/Cellar/gsl/2.4/include
LINK = -L/usr/local/Cellar/gsl/2.4/lib -lgsl -lgslcblas
../bin/bidimensional_MC: random.o functions.o subroutines.o\
main.o
$(CC) -o ../bin/bidimensional_MC random.o functions.o\
subroutines.o main.o $(CFLAGS) $(LINK) $(INLCUDE)
random.o: random.c
$(CC) -c random.c -lm -O3 $(CFLAGS) $(INCLUDE)
functions.o: functions.c
$(CC) -c functions.c $(CFLAGS) $(INCLUDE)
main.o: main.c
$(CC) -c main.c $(CFLAGS) $(INCLUDE)
suboutines.o: subroutines.c
$(CC) -c subroutines.c $(CFLAGS) $(INCLUDE)
clean:
rm *.o
The output of ls /usr/local/Cellar/gsl/2.4/include/gsl/ is:
/usr/local/Cellar/gsl/2.4/include/gsl/gsl_rng.h
The output of ls /usr/local/Cellar/gsl/2.4/include/ is:
gsl/
The output of ls /usr/local/Cellar/gsl/2.4/include/gsl/ is too long to post, but everything is there, as it should.
EXTRA INFORMATION:
I am using g++-6 instead of gcc-6 because the cluster in which I'm going to finally execute the simulation requires code to be C++ compliant.

In the makefile, you have (or, more precisely, at one time claimed to have):
random.o: random.c
$(CC) -c random.c -lm -O3 $(CFLAGS)
You shouldn't specify the library when compiling the object file. Your CFLAGS do not include the ${INCLUDE} (or $(INCLUDE)) macro. You need something like:
random.o: random.c
$(CC) -c random.c -O3 $(CFLAGS) $(INCLUDE)
This is a minimal change; I'd add $(INCLUDE) to CFLAGS (and remove the -lm again — you don't even need that on a Mac though it does no specific harm). I'd also add -Werror -Wmissing-prototypes -Wstrict-prototypes, and using -ansi (aka -std=c90) isn't sensible — it is an archaic standard. You should be using -std=c11.
CFLAGS = -O3 -g -std=c11 -pedantic -Wall -Wextra \
-Wconversion -Wredundant-decls -fmax-errors=7 \
-Wunsafe-loop-optimizations -Wmissing-braces \
-Wparentheses $(INCLUDE) \
-Werror -Wmissing-prototypes -Wstrict-prototypes
Also, I added -g to get debugging code. Always include -g, even with optimization. It doesn't have a run-time cost; it does have a benefit if you need to debug the code. Granted, it isn't as easy to debug optimized code, but you can do more than if you don't have -g. Include it in both the 'compilation to object' and the 'linking' phases.
(And, in point of detail, I'd have a bunch of separate macros so that each flag can be turned on or off independently, rather than having to rewrite the whole of CFLAGS. However, that can await another day.)

Related

I've created a Makefile in c that should creates more than one executable, but it does not work

WHAT I NEED TO DO
I'm trying to create a Makefile in c that should create three executable from three different .c files.
I'll want to create Lez4Es1, Lez4Es1v2 and Lez4Es3 as my executable compiling and linking in two different stages.
Something as:
gcc -std=c99 -Wall -pedantic Lez4Es1.c -c
gcc -std=c99 -Wall -pedantic Lez4Es1.o -o Lez4Es1
gcc -std=c99 -Wall -pedantic Lez4Es1v2.c -c
gcc -std=c99 -Wall -pedantic Lez4Es1.v2 -o Lez4Es1v2
gcc -std=c99 -Wall -pedantic Lez4Es3.c -c
gcc -std=c99 -Wall -pedantic Lez4Es3.o -o Lez4Es3
MY SOLUTION
Assuming to have all .c files in the same directory i created this Makefile but it does not work:
CC = gcc
CFLAGS += -std=c99 -Wall -pedantic -g
TARGETS = Lez4Es1 \
Lez4Es1v2 \
Lez4Es3 \
.PHONY: all clean cleanall
% : %.o
$(CC) $(CFLAGS) $^ -o $#
%.o : %.c
$(CC) $(CFLAGS) -c $^
all : $(TARGETS)
clean :
-rm *.o *~ core
cleanall :
-rm *.o *.txt -f $(TARGETS) *~ core
PROBLEMS
When i run $ make it creates executable from .c file and not from .o, this is output of compiler:
$ make
gcc -std=c99 -Wall -pedantic -g Lez4Es1.c -o Lez4Es1
gcc -std=c99 -Wall -pedantic -g Lez4Es1v2.c -o Lez4Es1v2
gcc -std=c99 -Wall -pedantic -g Lez4Es3.c -o Lez4Es3
How to fix to let him do the things i want to do?
There is a method to give executable files a different name than .o files?
Sorry for my bad english and if i didn't explain it well i'm ready to edit it and give you more details, thank you.
Try deleting the built-in rule that creates executables from source files:
% : %.c
(a pattern rule with no recipe cancels that rule).

undefined reference to pthread_create and pthread_join

I am trying to build my program but keep getting the same error messages:
undefined reference to pthread_create
undefined reference to pthread_join
I have included pthread.h and in my makefile im compiling with -pthread.
int threadAmount = strtol(nrthr, NULL, 0);
threadAmount--;
if(threadAmount > 0){
pthread_t tids[threadAmount];
for(int i = 0;i < threadAmount; i++){
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&tids[i],&attr,search,&t1);
}
for(int i = 0;i < threadAmount; i++){
pthread_join(tids[i],NULL);
}
}
It's where I'm calling create and join where it's complaining. What could be the problem?
The makefile used to build:
CC=gcc
CFLAGS= -pthread -std=gnu11 -Wall -Wextra -Werror -Wmissing-declarations -Wmissing-prototypes -Werror-implicit-function-declaration -Wreturn-type -Wparentheses -Wunused -Wold-style-definition -Wundef -Wshadow -Wstrict-prototypes -Wswitch-default -Wunreachable-code
all: mfind
list.o: list.c list.h
$(CC) -c list.c $(CFLAGS)
mfind.o: mfind.c list.h
$(CC) -c mfind.c $(CFLAGS)
mfind: mfind.o list.o
$(CC) mfind.o list.o -o mfind
clean:
rm -f *.o mfind
mfind is the main program and list.c is an implemented list.
list.o: list.c list.h
$(CC) -c list.c $(CFLAGS)
mfind.o: mfind.c list.h
$(CC) -c mfind.c $(CFLAGS)
mfind: mfind.o list.o
$(CC) mfind.o list.o -o mfind
It looks like some of your recipes are missing CFLAGS, which includes the option -pthread. I believe it should be:
list.o: list.c list.h
$(CC) $(CFLAGS) -c list.c
mfind.o: mfind.c list.h
$(CC) $(CFLAGS) -c mfind.c
mfind: mfind.o list.o
$(CC) $(CFLAGS) mfind.o list.o -o mfind
...
Its OK to CFLAGS to the output artifact. In fact, you should use the same CFLAGS (and CXXFLAGS) when the compiler driver drives link. You should also always use the compiler driver because it takes care of turning options, like -pthread, -fopenmp and -fsanitize=undefined, into the proper options and libraries for the linker.
If interested, here are the default rule used with GNUmake: Catalogue of Built-In Rules. Notice the recipe for *.c files includes CFLAGS:
Compiling C programs
n.o is made automatically from n.c with a recipe of the form $(CC) $(CPPFLAGS) $(CFLAGS) -c.
If you use the following from the GNU Make manual, then you should also add -pthread to LDFLAGS. But I recommend you follow what the compiler guys tell us, and that is to drive link through the compiler driver.
Linking a single object file
n is made automatically from n.o by running the linker (usually
called ld) via the C compiler. The precise recipe used is $(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS).
-pthread doesn't belong in CFLAGS. As you already found, the libraries that are needed must be at the end of the command line options after all the object files. You need to put -pthread in LDLIBS since you have a makefile.
From https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html:
LDLIBS
Library flags or names given to compilers when they are supposed to invoke the linker, ‘ld’. LOADLIBES is a deprecated (but still supported) alternative to LDLIBS. Non-library linker flags, such as -L, should go in the LDFLAGS variable.

GCC Linking with .o file

I'm trying to compile my code but it isn't working. I got this to compile at school but I can't compile this on my home computer. I can't seem to figure out why. I need this error fixed in order to continue my assignment. Also, this list.o file is the profs file. I have to use this file.
Solutions I've tried kind of?
I've updated gcc to gcc-7.
I've located libc.a
/usr/lib/x86_64-linux-gnu/libc.a
/usr/share/doc/libklibc/README.klibc.arch
Edit: I have tried compiling without -fPIC
gcc -m64 -pthread -Wall -std=c99 -o run main.o as2.o list.o
/usr/bin/ld: list.o: relocation R_X86_64_32S against undefined symbol...
This is from the terminal:
gcc -m64 -pthread -Wall -std=c99 -fPIC -o run main.o as2.o list.o
/usr/bin/ld: list.o: relocation R_X86_64_32S against undefined symbol `headlist' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
This is my make file:
CC = gcc
CFLAGS = -m64 -pthread -Wall -std=c99 -fPIC
PROG = run
OBJS = main.o as2.o list.o
run: $(OBJS)
$(CC) $(CFLAGS) -o $(PROG) $(OBJS)
main.o: main.c list.h as2.h
$(CC) $(CFLAGS) -c main.c
as2.o: as2.c as2.h list.h
$(CC) $(CFLAGS) -c as2.c
clean:
rm main.o as2.o run
This is my includes:
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "list.h"
#include "as2.h"
Any ideas/solutions?
EDIT:
changed the spelling from LFLAGS to LDFLAGS to appease some comment.
EDIT:
moved the -c option to appease some comment.
Note: all is normally the first target in a make file.
Note: used := rather than = so the macros would only be evaluated once.
Note: the list.o is already available in the current directory (per the OPs question) so is not compiled in the makefile. But is only linked with the other object files to produce the executable
your makefile seems to have a few oversights. Suggest:
CC := gcc
RM := rm -f
CFLAGS := -ggdb -m64 -pthread -Wall -Wextra -pedantic -std=c99
#LDFLAGS := <-- use the default value
PROG := run
OBJS := main.o as2.o list.o
HDRS := list.h as2.h
.PSEUDO: all clean
all: $(PROG)
$(PROG): $(OBJS)
$(CC) -ggdb -o $(PROG) $(OBJS) $(LDFLAGS)
main.o: main.c $(HDRS)
$(CC) $(CFLAGS) -c main.c -o main.o -I.
as2.o: as2.c $(HDRS)
$(CC) $(CFLAGS) -c as2.c -o as2.o -I.
clean:
$(RM) main.o as2.o run

How to create a makefile?

I need to create a makefile for an assignment I need to run on Linux. I have no idea how to write makefiles.
The structure of the project is as follows:
Logic.h
Max.h which includes Logic using a header guard in the following way:
#ifndef _GUI
#include "Logic.h"
#endif
GUI.h which includes max.h and logic.h in the following way:
#ifndef _GUI
#define _GUI
#include "Logic.h"
#include "Minimax.h"
#endif
prog.h which includes GUI.h (prog is the main file - the main function is there)
All the header files have corresponding .c files that include only their respective header.
GUI.h uses SDL 1.2 so it includes also the following
#include "SDL.h"
#include "SDL_video.h"
I understand that special flags have to be inserted to the makefile so the SDL can run properly.
This is an example of a makefile that includes only one SDL file so it has the flags for sdl and the flags they require for notifying about errors and warnings:
all: sdl_test
clean:
-rm sdl_test.o sdl_test
sdl_test: sdl_test.o
gcc -o sdl_test sdl_test.o -lm -std=c99 -pedantic-errors -g `sdl-config --libs`
sdl_test.o: sdl_test.c
gcc -std=c99 -pedantic-errors -c -Wall -g -lm sdl_test.c `sdl-config --cflags`
But I don't know how to create a makefile for this file (project) structure, and where to put the SDL flag - only for the files that have SDL, or only the file that have SDL and include files that have SDL or all files.
This is a simple example
OBJECTS = sdl_test.o # add more files just separated by spaces -> filename.o
LDFLAGS = -lm `sdl-config --libs`
CFLAGS = -Wall -Werror -pedantic -g3 -O0 # full debugging on
CC = gcc
TARGET = sdl_test
all:
$(CC) -o $(TARGET) $(OBJECTS) $(LDFLAGS)
clean:
#rm $(OBJECTS) $(TARGET)
%.o: %.c
$(CC) $(CFLAGS) -c $<
Don't copy and paste because Makfiles require tabs for indentation.
A quick and dirty Makefile (i.e., one you don't really want to distribute for a finished product) could be just
SRCS = Max.c GUI.c prog.c
OBJS := $(patsubst %.c, %.o, $(SRCS))
.PHONY: all clean
.DEFAULT_GOAL = all
all: sdl_test
clean:
-rm $(OBJS) sdl_test
sdl_test: $(OBJS)
gcc -o $# $^ -lm -std=c99 -pedantic-errors -g `sdl-config --libs`
%.o: %.c
gcc -std=c99 -pedantic-errors -c -Wall -g -lm $< `sdl-config --cflags`
See Make automatic variables for details, but briefly the special make variables mean
$# - the thing that comes before the colon
$< - the first thing that comes after the colon
$^ - everything that comes after the colon

Makefile fails with warning message

This is a makefile that fails to link the .o files to make an executeable.
enter code here
CC = c99
CFLAGS = -g -Wall -Wextra -O0
OBJECTS = main.o getoptions.o
P = testprog
$(P): $(OBJECTS)
$(CC) $(OBJECTS) -o $(P)
main.o : main.c
$(CC) $(CFLAGS) $(OBJECTS) -c main.c
getoptions.o : getoptions.c getoptions.h
$(CC) $(CFLAGS) -c getoptions.o
I get this warning:
gcc: warning: getoptions.o: linker input file unused because linking not done
When I manually use:
c99 *.o -o testprog
linking succeeds.
Two issues here:
First, in your target for getoptions.o, you're passing getoptions.o for the -c option. You should be giving it the value of the source file getoptions.c
Second, get rid of $(OBJECTS) in the target for main.o. You don't need to pass in the object files for this step.
With those fixes you'll get a successful compilation:
c99 -g -Wall -Wextra -O0 -c main.c
c99 -g -Wall -Wextra -O0 -c getoptions.c
c99 main.o getoptions.o -o testprog
Edit:
The target line for main.o should be:
main.o : main.c getoptions.h
That way, if getoptions.h changes, main.o gets rebuilt.

Resources