0

Hi so I have been trying to link the kstat library on a solaris server for a project for class. to do this i have put this at the beginning of the header that will use it

#ifdef HAVE_KSTAT
#include <kstat.h>
#endif

and my make file looks like

CC=gcc
#CC=gcc -Wall

mysh: sh.o Funcs.o mp3.o get_path.o part3.o main.c 
    $(CC) -g -pthread -lkstat main.c sh.o Funcs.o mp3.o get_path.o part3.o -o mysh  

Funcs.o: Funcs.h Funcs.c
    $(CC) -g -c Funcs.c

mp3.o: mp3.h mp3.c
    $(CC) -g -c mp3.c

sh.o: sh.c sh.h 
    $(CC) -g -c -pthread -DHAVE_KSTAT sh.c 

get_path.o: get_path.c get_path.h
    $(CC) -g -c get_path.c

clean:
    rm -rf sh.o get_path.o mysh Funcs.o part3.o

sh.o being the parent file that includes part3.o which is the file using kstat. However i get the error

/usr/bin/ld: cannot find -lkstat
collect2: error: ld returned 1 exit status

and also

part3.h:8:19: fatal error: kstat.h: No such file or directory

 #include <kstat.h>
                   ^
compilation terminated.
make: *** [sh.o] Error 1

what have i done wrong, how do i properly link the kstat library. I tried making part3.o its own object for creation within the make file and linking kstat in that one but it gave me the error missing separator.

Zooloo10
  • 45
  • 1
  • 8
  • the `gcc` linker handles command line parameters in the order listed on the command line. so the library paths should be just before the 'short' library names and both those elements should be at the end of the command line. – user3629249 Apr 02 '16 at 20:22
  • when defining a unchanging macro, use `:=` rather than `=` so the macro is only evaluated once. For targets (like: clean) that do not produce a file of the same name, before the target, have a `.PHONY: clean` statement. – user3629249 Apr 02 '16 at 20:26
  • using a macro to replace a system utility, (like gcc), is for the purpose of assuring that the correct utility is executed. Therefore, the macro needs to have the complete path to the utility. (like: CC := /usr/lib/gcc). Note `rm` is also a system utility, so should receive the same treatment. – user3629249 Apr 02 '16 at 20:29
  • the primary dependency file should be listed first, so this: `Funcs.o: Funcs.h Funcs.c` should be: `Funcs.o: Funcs.c Funcs.h` Also, then the recipe can be listed as: `$(CC) -g -c -o $@ $<` However, this has all the compiler warnings turned off. Much better to have a line: `CFLAGS += -ggdb -c -Wall -Wextra -pedantic -Wconversion -std=gnu99` and to include the (optional) `-I.` parameter, so the recipe would be: `$(CC) $(CFLAGS) -o $@ $< -I.` Note: `$@` is the target name and `$<` is the first dependency name – user3629249 Apr 02 '16 at 20:38
  • do no place *.c files in the link statement (I.E. remove the parameter `main.c` and add a new target for compiling `main.c` into `main.o` – user3629249 Apr 02 '16 at 20:41
  • this statement: `$(CC) -g -pthread -lkstat main.c sh.o Funcs.o mp3.o get_path.o part3.o -o mysh` should be: `$(CC) -g main.o sh.o Funcs.o mp3.o get_path.o part3.o -o mysh -pthread -lkstat – user3629249 Apr 02 '16 at 20:44
  • a lot of the clutter and need to be editing the makefile with changes in the project list of files can be eliminated by: `SRCS := $(wildcard *.c) OBJS := $(SRCS:.c=.o)` then using the $(OBJS) to replace the list of objects in the `mysh` target. – user3629249 Apr 02 '16 at 20:49

1 Answers1

0

You have to find the files of this library (e.g. kstat.a or kstat.so) and its headers. Then pass the paths to headers and the lib with -I and -L respectively.

For example: $CC -I /usr/include/kstat -L /usr/lib/kstat files -lkstat

ForceBru
  • 43,482
  • 10
  • 63
  • 98