1

I have a Makefile that contains an install section to allow me to make install after building the source code. The install section contains two lines of shell commands:

install: /usr/local/lib
    cp $(LIB_OBJ) $<
    export LD_LIBRARY_PATH=$< 

So the first line copies the libxxx.so to /usr/local/lib and the second line sets the environmental variable LD_LIBRARY_PATH to /usr/local/lib so that final executable can find the libxxx.so file.

But when I run make install from the command line and then type:

echo $LD_LIBRARY_PATH

It shows empty content rather than /usr/local/lib as intended. So why is the second line of command in the Makefile not executed?

2

make is almost certainly executing both lines of commands. However, the line export LD_LIBRARY_PATH=$< (or whatever make expands it) gets executed by a shell that's a child process of the make process. When you type echo $LD_LIBRARY_PATH, you get whatever the environment variable LD_LIBRARY_PATH had in it. Your shell didn't execute the "export", a sub-process of make executed it. You'll have to do the export in your .bashrc or .zshrc or whatever file, or type it in manually.

  • Thanks. So there is no way to put export LD_LIBRARY_PATH= in Makefile so that when user type make install, all libraries built will be in the path? If I export it in .bashrc, it will be permanently set. So I don't want to do that. If I need to manually export it, then make install is not automatic. – tonga Jan 7 '15 at 20:12
  • There might be some weird trick. After all you can re-TTY a process with "reptyr" (github.com/nelhage/reptyr). There's probably some gdb stunt you could do to change LD_LIBRARY_PATH, but I don't think you should do those stunts on a regular basis. – Bruce Ediger Jan 7 '15 at 21:53
  • So what is the rationale that the multiline command is executed by a sub-process of make, instead of by the make process itself? Is this designed intentionally in make utility? – tonga Jan 8 '15 at 14:55
  • I don't think the distinction is multiline vs single line, I think it's if the command(s) contain a shell metacharacter (>, &, ;, etc) then make shells out rather than just forking and execing. The rationale here is probably, "it's really hard to parse shell command lines correctly, let's just hand all the hard work off to the shell." – Bruce Ediger Jan 8 '15 at 16:33
  • 1
    Actually, it's not even a shell metacharacter. Most makes will create a subshell for each line that begins with a tab character. The export is taken as a shell command, not as a make command. – Joe Sewell Jan 8 '15 at 17:27
0

Try:

export LD_LIBRARY_PATH := /usr/local/lib:$(LD_LIBRARY_PATH)

install:
#Do Install actions

See Section 5.3 of the Make manual for an explanation of Bruce's correct assumption on subshells, whivh leads us to this Answer at StackOverflow, which states that all commands should be executed as a one liner.

Update

Since the one liner did not work, use the following, as an example (I'm including the files below so that the final makefile will Work):
Filelist:
hellomacke.c

#include 

int main() {
  // call a function in another file
  myPrintHelloMake();

  return(0);
}

hellofunc.c

#include 
#include 

void myPrintHelloMake(void) {

  printf("Hello makefiles!\n");

  return;
}

hellomake.h

/*
example include file
*/

void myPrintHelloMake(void);

End Filelist


Makefile

IDIR =../include
CC=gcc
CFLAGS=-I$(IDIR)

ODIR=obj
LDIR =../lib

LIBS=-lm

_DEPS = hellomake.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))

_OBJ = hellomake.o hellofunc.o 
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))


$(ODIR)/%.o: %.c $(DEPS)
    $(CC) -c -o $@ $< $(CFLAGS)

hellomake: $(OBJ)
    gcc -o $@ $^ $(CFLAGS) $(LIBS)

.PHONY: clean

clean:
    rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~

The above makefile uses Macros and String Expansion to properly set the include and libraries directories without the need of the export command. In your case, passing /usr/local/libs to LDIR and then compiling should get you started.


References

Colby College, Maine, Computer Science Department - Makefile Tutorial
The M4 Macro Processor - Paste Substitution

  • I put the export command before install but it didn't work. I even put the two commands in one line but not working either. – tonga Jan 8 '15 at 14:53
  • Are you "piping" LIB_OBJ into LD_LIBRARY_PATH? I've never seen $< as in your OP. – eyoung100 Jan 8 '15 at 15:53
  • No, $< is just an automatic variable used by Makefile to denote the first argument in the rule, which is /usr/local/lib. – tonga Jan 8 '15 at 16:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.