views:

72

answers:

4

I have 4 .c files hello.c,here.c,bye.c and main.c. One header file mylib.h

The contents are as follows

hello.c

#include<stdio.h>

void hello()
{
    printf("Hello!\n");
}

here.c

#include<stdio.h>

void here()
{
     printf("I am here \n");
}

bye.c

#include<stdio.h>

void bye()
{
    printf("Bye,Bye");
}

main.c

#include<stdio.h>
#include "mylib.h"

int main()
{ 

  hello();
  here();
  bye();
  return 1;
}

mylib.h

#ifndef _mylib_
#define _mylib_

void hello();
void here();
void bye();

#endif

The makefile for creating a static lib is : Makefile

#Which Compiler
CC = gcc

#Compiler Flags
CFLAGS = - Wall -c -fPIC

DYNLINKFLAGS = -shared -W1,-soname,[email protected]

PROG = main

PROG_OBJS = main.c

LIB = mylib

LIB_FILES = libmylib.so

LIB_MINOR = $(LIB_FILES).0.1

LIB_RELEASE = $(LIB_MINOR).0

LIB_OBJS = hello.o here.o bye.o

PATH = /home/srinivasa/cspp51081/labs/srinivasa.lab2.1

all:    $(LIB_FILES) $(PROG)

#Create Lib with this file
$(LIB_FILES):   $(LIB_OBJS)
            $(CC) $(DYNLINKFLAGS) $^
            ln -sf $(LIB_RELEASE) $(LIB_MINOR)
            ln -sf $(LIB_MINOR) $@
            ln -sf $@ [email protected]

#Compiling main program and link with shared library
$(PROG):        $(PROG_OBJS)
            $(CC) -o $(PROG) $(PORG_OBJS) -l$(LIB) -L$(PATH)

main.o:         main.c
hello.o:        hello.c
here.o:         here.c
bye.o:          bye.c

#clean files
clean:
            rm -rf $(LIB_OBJS) $(LIB_FILES) $(LIB_RELEASE) $(LIB_MINOR) libmylib.so.0

Problem: When I execute the command

make -f Makefile all 

I get the error:

gcc -Wall -fPIC -c -o hello.o hello.c make: gcc: Command not found make: * [hello.o] Error 127

Questions : How do I resolve this?

+1  A: 

There are a few bugs (just typos) I can see is:

  1. space between - and Wall:

    CFLAGS = - Wall -c -fPIC
              ^
    
  2. PORG_OBJS should be PROG_OBJS

    $(CC) -o $(PROG) $(PORG_OBJS) -L$(PATH)
                       ^^^^
    
  3. You are doing an absolute assignment to PATH. Now every executable called in makefile will be search in that directory. Since gcc is not found in that directory you get this error. To fix this you can either use a different variable name or add your directory to current path as:

     PATH := $(PATH):/home/srinivasa/cspp51081/labs/srinivasa.lab2.1
          ^  ^^^^^^^^
    
codaddict
@codaddict - thanks , changed the question. Hope you can view it what the change was.
Eternal Learner
+1  A: 

Try changing this line from:

$(CC) -o $(PROG) $(PORG_OBJS) -l$(LIB) -L$(LIBPATH)

to:

$(CC) -o $(PROG) $(PORG_OBJS) -L$(LIBPATH) -l$(LIB)

The -L flag needs to precede the -l flags.

Ziffusion
@Ziffusion - Changed it . get the same error gcc -o main main.c -L/home/srinivasa/cspp51081/labs/srinivasa.lab2.1 -lmylib/usr/bin/ld: cannot find -lmylibcollect2: ld returned 1 exit statusmake: *** [main] Error 1
Eternal Learner
Well, first check the directory to see which library files are being produced. Next, try passing "-dynamic" flag to the compiler. Then post the entire make output (including the library build, and the executable build).
Ziffusion
Oh, and I see that you are using DYNLINKFLAGS, but you don't ever define it. Chances are that you are actually producing a static library, even though it has the ".so" suffix.
Ziffusion
@Ziffusion: Libraries being created `libmylib.so.0 -> libmylib.solibmylib.so -> libmylib.so.0.1libmylib.so.0.1 -> libmylib.so.0.1.0`
Eternal Learner
@Ziffusion - make output:`gcc -Wall -c -fPIC -c -o hello.o hello.cgcc -Wall -c -fPIC -c -o here.o here.cgcc -Wall -c -fPIC -c -o bye.o bye.cgcc -dynamic -shared -W1,-soname,libmylib.so.0 hello.o here.o bye.oln -sf libmylib.so.0.1.0 libmylib.so.0.1ln -sf libmylib.so.0.1 libmylib.soln -sf libmylib.so libmylib.so.0gcc -o main main.c -L/home/srinivasa/cspp51081/labs/srinivasa.lab2.1 -lmylib/usr/bin/ld: cannot find -lmylibcollect2: ld returned 1 exit statusmake: *** [main] Error 1`
Eternal Learner
@Ziffusion - I do use the DYNLINKFLAGS - this line $(LIB_FILES): $(LIB_OBJS) $(CC) $(DYNLINKFLAGS) $^
Eternal Learner
The library naming and linking seems a little off. You link the objects into a shared library called "libmylib.so.0", then one of your soft links go "ln -sf libmylib.so libmylib.so.0". That doesn't seem right. One thing you need to fix is get the order of links light. I would just link from the real library i.e. "libmylib.so.0" to all other names. After, post the libraries produced and the final link again.
Ziffusion
@ Ziffusion - Changed the order of links . Now I create a soft link from the real library $(CC) $(DYNLINKFLAGS) $^ ln -sf $(LIB_RELEASE) $(LIB_FILES) ln -sf $(LIB_RELEASE) $(LIB_FILES).1
Eternal Learner
@Ziffusion - make output gcc -Wall -c -fPIC -c -o hello.o hello.cgcc -Wall -c -fPIC -c -o here.o here.cgcc -Wall -c -fPIC -c -o bye.o bye.cgcc -dynamic -shared -W1,-soname,libmylib.so.0 hello.o here.o bye.oln -sf libmylib.so.0.1.0 libmylib.soln -sf libmylib.so.0.1.0 libmylib.so.1gcc -o main main.c -L/home/srinivasa/cspp51081/labs/srinivasa.lab2.1 -lmylib/usr/bin/ld: cannot find -lmylibcollect2: ld returned 1 exit statusmake: *** [main] Error 1
Eternal Learner
But that's still not right. The real linked library is "libmylib.so.0". And you are linking "libmylib.so.0.1.0" to other names.
Ziffusion
@Ziffusion- Ohh, now I am a little confused about the order of linking files. Could you kindly write down the order of creating the softlinks.
Eternal Learner
@Ziffusion - I have changed the ordering now. It is ln -sf libmylib.so.0 libmylib.so.0.1ln -sf libmylib.so.0 libmylib.so.0.1.0
Eternal Learner
@Ziffusion - now the make output reads gcc -Wall -c -fPIC -c -o hello.o hello.cgcc -Wall -c -fPIC -c -o here.o here.cgcc -Wall -c -fPIC -c -o bye.o bye.cgcc -dynamic -shared -W1,-soname,libmylib.so.0 hello.o here.o bye.oln -sf libmylib.so.0 libmylib.so.0.1ln -sf libmylib.so.0 libmylib.so.0.1.0gcc -o main main.c -L/home/srinivasa/cspp51081/labs/srinivasa.lab2.1 -lmylib/usr/bin/ld: cannot find -lmylibcollect2: ld returned 1 exit statusmake: *** [main] Error 1
Eternal Learner
You didn't do exactly what I asked you to :) You did not change DYNLINKFLAGS. And you didn't fix the links like I asked.
Ziffusion
A: 

OK. First change:

DYNLINKFLAGS = -shared -W1,-soname,[email protected]

to

DYNLINKFLAGS = -shared -W1,-soname,$@

Then change:

ln -sf $(LIB_RELEASE) $(LIB_MINOR)
ln -sf $(LIB_MINOR) $@
ln -sf $@ [email protected]

To:

ln -sf $@ $(LIB_RELEASE)
ln -sf $@ $(LIB_MINOR)
ln -sf $@ [email protected]

Then post the library links and the final executable link.

Ziffusion
make output :gcc -Wall -c -fPIC -c -o hello.o hello.cgcc -Wall -c -fPIC -c -o here.o here.cgcc -Wall -c -fPIC -c -o bye.o bye.cgcc -dynamic -shared -W1,-soname,libmylib.so hello.o here.o bye.oln -sf libmylib.so libmylib.so.0.1.0ln -sf libmylib.so libmylib.so.0.1ln -sf libmylib.so libmylib.so.0gcc -o main main.c -L/home/srinivasa/cspp51081/labs/srinivasa.lab2.1 -lmylib/usr/bin/ld: cannot find -lmylibcollect2: ld returned 1 exit statusmake: *** [main] Error 1
Eternal Learner
library links : libmylib.so.0 -> libmylib.solibmylib.so.0.1 -> libmylib.solibmylib.so.0.1.0 -> libmylib.so
Eternal Learner
Now add "-dynamic" to the final link of the executable. Then post the make output.
Ziffusion
gcc -Wall -c -fPIC -c -o hello.o hello.cgcc -Wall -c -fPIC -c -o here.o here.cgcc -Wall -c -fPIC -c -o bye.o bye.cgcc -dynamic -shared -W1,-soname,libmylib.so hello.o here.o bye.oln -sf libmylib.so libmylib.so.0.1.0ln -sf libmylib.so libmylib.so.0.1ln -sf libmylib.so libmylib.so.0gcc -dynamic -o main main.c -L/home/srinivasa/cspp51081/labs/srinivasa.lab2.1 -lmylibmain.c:1: warning: The C parser does not support -dy, option ignored/usr/bin/ld: cannot find -lmylibcollect2: ld returned 1 exit statusmake: *** [main] Error 1Hope the -dynamic flag is in correct place
Eternal Learner
Now replace "-dynamic" by "-Wl,-Bdynamic" (only in the final executable link). And post the make output.
Ziffusion
gcc -Wall -c -fPIC -c -o hello.o hello.cgcc -Wall -c -fPIC -c -o here.o here.cgcc -Wall -c -fPIC -c -o bye.o bye.cgcc -dynamic -shared -W1,-soname,libmylib.so hello.o here.o bye.oln -sf libmylib.so libmylib.so.0.1.0ln -sf libmylib.so libmylib.so.0.1ln -sf libmylib.so libmylib.so.0gcc -Wl,-Bdynamic -o main main.c -L/home/srinivasa/cspp51081/labs/srinivasa.lab2.1 -lmylib/usr/bin/ld: cannot find -lmylibcollect2: ld returned 1 exit statusmake: *** [main] Error 1
Eternal Learner
Strange. Can you do "objdump libmylib.so"?
Ziffusion
And try moving "-Wl,-Bdynamic" right in front of "-lmylib". Otherwise I am out of ideas for now. Maybe someone else can pick this up. Or we could try it again tomorrow.
Ziffusion
@Ziffusion - Thanks for all your help. We can definitely carry on tomorrow , idf you wish. Ill do a objdump and post it.
Eternal Learner
Are you sure you are cleaning out the old links before each build? Just do a "rm -f lib*", and build again.
Ziffusion
@Ziffusion - objdump -f libmylib.soobjdump: 'libmylib.so': No such file
Eternal Learner
That's what I thought. Try cleaning the libs before building. Do the "rm -f lib*" and build again.
Ziffusion
BTW I just noticed, in the definition of DYNLINKFLAGS "-W1,-soname,libmylib.so" - that looks like a "1 (one)" instead of an "l (el)". That should be an "l (el)".
Ziffusion
No Luck - I get the same error gcc -Wall -c -fPIC -c -o hello.o hello.cgcc -Wall -c -fPIC -c -o here.o here.cgcc -Wall -c -fPIC -c -o bye.o bye.cgcc -dynamic -shared -W1,-soname,libmylib.so hello.o here.o bye.oln -sf libmylib.so libmylib.so.0.1.0ln -sf libmylib.so libmylib.so.0.1ln -sf libmylib.so libmylib.so.0gcc -Wl,-Bdynamic -o main main.c -L/home/srinivasa/cspp51081/labs/srinivasa.lab2.1 -lmylib/usr/bin/ld: cannot find -lmylibcollect2: ld returned 1 exit statusmake: *** [main] Error 1 objdump -f libmylib.soobjdump: 'libmylib.so': No such file
Eternal Learner
See last comment. Repeat - BTW I just noticed, in the definition of DYNLINKFLAGS "-W1,-soname,libmylib.so" - that looks like a "1 (one)" instead of an "l (el)". That should be an "l (el)".
Ziffusion
@Ziffusion - Changed the 1(one) to l(el) - no change in output
Eternal Learner
Lets try one more thing. See the answer marked by "+++++".
Ziffusion
@Ziffusion -Sry,but I dint get what you mean by "+++++"
Eternal Learner
I posted another answer (better formatting) and marked it with a line "+++++" on the top.
Ziffusion
+1  A: 

+++++

OK. Lets revert to your original code, but with a small difference.

Change DYNLINKFLAGS back to:

DYNLINKFLAGS = -shared -Wl,-soname,[email protected]

Then change the library link to:

$(CC) $(DYNLINKFLAGS) -o $(LIB_RELEASE) $^
ln -sf $(LIB_RELEASE) $(LIB_MINOR)
ln -sf $(LIB_MINOR) $@
ln -sf $@ [email protected]

Do "rm -f lib*", build and then post make output.

Ziffusion
@Ziffusion - I guess this works :). Make output gcc -Wall -c -fPIC -c -o hello.o hello.cgcc -Wall -c -fPIC -c -o here.o here.cgcc -Wall -c -fPIC -c -o bye.o bye.cgcc -shared -Wl,-soname,libmylib.so.0 -o libmylib.so.0.1 hello.o here.o bye.oln -sf libmylib.so.0.1 libmylib.so.0.1.0ln -sf libmylib.so.0.1.0 libmylib.sogcc -Wl,-Bdynamic -o main main.c -L/home/srinivasa/cspp51081/labs/srinivasa.lab2.1 -lmylib
Eternal Learner
Well, there you go. Wasn't that easy :)
Ziffusion
Thanks for all the help and time. Now to see the output I did the following 1. Set Library Path: export LD_LIBRARY_PATH=/home/srinivasa/cspp51081/labs/srinivasa.lab2.12. Recompile 3. ldd main - I see that the main cannot find the shared library ldd main linux-vdso.so.1 => (0x00007fff89ef2000) libmylib.so.0 => not found libc.so.6 => /lib/libc.so.6 (0x00007f1d4d94d000) /lib64/ld-linux-x86-64.so.2 (0x00007f1d4dca1000)
Eternal Learner
I am not sure I got this. This is happening when you run the executable? Which shared library is it unable to find?
Ziffusion