2013-01-21 2 views
3

내가이 메이크 건너 온 (오픈 소스 프로젝트라고 sendip를 통해 발견)

I가이 파일에 대한이 혼란 -

.c 파일로 지정되고
  1. 여기에 종속? ipv6.so, tcp.so과 같은 모든 라이브러리가 제대로 생성되지만 여기에는 어떤 라인이 포함되어 있습니까?

나는이 줄이 .....라고 생각한다.

%.so: %.c $(LIBS) 
        $(CC) -o [email protected] $(CFLAGS) $(LIBCFLAGS) $+ $(LIBS) 

그러나 $(LIBS)은 일부 .o 파일 만 지정합니다. 이 $+은 무엇인가하고 있습니까?

2. 나는 $+을 들어 본 적이 없습니다. 나는 그것을 찾으려고 노력했고 $?, [email protected], $<, 등등과 같은 많은 다른 사람을 우연히 만났지만 결코 이것을 보지 못했습니다. 나는 그것이 $?처럼 행동한다고 ​​생각하지만, 여전히 .c depndencies가 요구된다.

메이크 :

이들 중 일부는 GNU에 대한 확장입니다
#configureable stuff 

PREFIX ?= /usr/local 
BINDIR ?= $(PREFIX)/bin 
MANDIR ?= $(PREFIX)/share/man/man1 
LIBDIR ?= $(PREFIX)/lib/sendip 

#For most systems, this works 
INSTALL ?= install 

#For Solaris, you may need 
#INSTALL=/usr/ucb/install 

CFLAGS= -fPIC -fsigned-char -pipe -Wall -Wpointer-arith -Wwrite-strings \ 
-Wstrict-prototypes -Wnested-externs -Winline -Werror -g -Wcast-align \ 
-DSENDIP_LIBS=\"$(LIBDIR)\" 

#-Wcast-align causes problems on solaris, but not serious ones 

LDFLAGS=  -g -rdynamic -lm -ldl 
#LDFLAGS_SOLARIS= -g -lsocket -lnsl -lm 
LDFLAGS_SOLARIS= -g -lsocket -lnsl -lm -ldl 
LDFLAGS_LINUX= -g -rdynamic -lm -ldl 
LIBCFLAGS= -shared 
CC=  gcc-4.4 

PROGS= sendip 
BASEPROTOS= ipv4.so ipv6.so 
IPPROTOS= tcp.so udp.so icmp.so 
UDPPROTOS= rip.so ripng.so ntp.so 
TCPPROTOS= bgp.so 
PROTOS= $(BASEPROTOS) $(IPPROTOS) $(UDPPROTOS) $(TCPPROTOS) 
LIBS= libsendipaux.a 
LIBOBJS= csum.o compact.o protoname.o headers.o parseargs.o 
     cryptomod.o crc32.o 
SUBDIRS= mec 

all: $(LIBS) subdirs sendip $(PROTOS) sendip.1 sendip.spec 

#there has to be a nice way to do this 

sendip: sendip.o  gnugetopt.o gnugetopt1.o compact.o 
    sh -c "if [ `uname` = Linux ] ; then \ 
$(CC) -o [email protected] $(LDFLAGS_LINUX) $(CFLAGS) $+ ; \ 
elif [ `uname` = SunOS ] ; then \ 
    $(CC) -o [email protected] $(LDFLAGS_SOLARIS) $(CFLAGS) $+ ;\ 
else \ 
$(CC) -o [email protected] $(LDFLAGS) $(CFLAGS) $+ ; \ 
fi" 

libsendipaux.a: $(LIBOBJS) 
    ar vr [email protected] $? 

subdirs: 
    for subdir in $(SUBDIRS) ; do \ 
      cd $$subdir ;\ 
      make ;\ 
      cd .. ;\ 
      done 

protoname.o: mec/protoname.c 
    $(CC) -o [email protected] -c -I. $(CFLAGS) $+ 

headers.o:  mec/headers.c 
    $(CC) -o [email protected] -c -I. $(CFLAGS) $+ 

parseargs.o: mec/parseargs.c 
    $(CC) -o [email protected] -c -I. $(CFLAGS) $+ 

cryptomod.o: mec/cryptomod.c 
    $(CC) -o [email protected] -c -I. $(CFLAGS) $+ 

crc32.o: mec/crc32table.h mec/crc32.c 
    $(CC) -o [email protected] -c -I. $(CFLAGS) mec/crc32.c 

mec/crc32table.h: mec/gen_crc32table 
    mec/gen_crc32table > mec/crc32table.h 

sendip.1:  ./help2man $(PROGS) $(PROTOS) subdirs VERSION 
        ./help2man -n "Send arbitrary IP packets" -N >sendip.1 

답변

4

네가 맞습니다.

대상 정의가 % 문자로 시작하는 경우 특정 패턴이 아닌 대상 패턴을 정의합니다. 따라서 %.so은 다른 대상에서 필요로하거나 사용자가 필요로하는 모든 .so 파일을 생성하는 대상을 의미합니다. %.c은 또한 패턴이며 모든 .c 파일을 의미합니다.

는 그래서 $(CC) -o [email protected] $(CFLAGS) $(LIBCFLAGS) $+ $(LIBS) 명령 출력이 생성되는 대상의 이름이 의미 ($ @ - 패턴과 일치하는 대상의> 이름) ... 그리고 $+prerequisite 패턴과 일치하는 모든 파일을 의미합니다 (예 : %.c).

GNU 제작 매뉴얼, 특히 Catalogue of Rules을보고 $+, $^, ... 의미를 확인하십시오.

1

(일명 "gmake를")을 확인 :

GNU make는 두 가지 단계로 작동합니다. 첫 번째 단계에서 은 모든 메이크 파일, 포함 된 메이크 파일 등을 읽고 모든 변수와 해당 값, 암시 적 및 명시 적 규칙을 내부화하며 은 모든 대상과 해당하는 필수 구성 요소의 종속성 그래프를 구성합니다. 두 번째 단계에서 make는 이러한 내부 구조를 사용하여 재 구축해야 할 대상을 결정하고이를 수행하는 데 필요한 규칙을 호출합니다. 이 경우 메이크 같은 구조의 부분은 해석됩니다 에 어떤 변수 나 기능을 확장 할 수 있도록 :

... 우리는 첫 단계에서 발생하는 경우 확장 즉시 것을 말한다. 즉시 확장을 실시하지 않으면, 의 확장이 이 연기되어가됩니다. 지연된 구문의 확장은 구조가 즉각적인 컨텍스트에서 나중에 나타나거나 두 번째 단계까지 나타날 때까지 수행되지 않습니다.