쉘 스크립트의 위치 매개변수 변환

쉘 스크립트의 위치 매개변수 변환

전달된 위치 인수를 아래와 같이 변환하는 쉘 스크립트를 작성하려고 합니다.

셸 스크립트는 이러한 매개변수를 프런트 엔드( ) ffigen에서 파생된 바이너리 실행 파일에 전달하므로 후속 명령줄 매개변수도 매개변수이며 와 동일한 의미를 갖습니다 .gcc 4.0gccgcc

다음 명령줄을 고려하세요.

./htest.sh -I/usr/include/gtk-2.0 -I /usr/include/glib-2.0 -include \
/usr/include/gtk-2.0/gtk/gtk.h -include/usr/include/bar.h /usr/include/myheader.h

여기에는 본질적으로 두 가지 다른 옵션이 있습니다. 하나 -I는 포함 파일을 검색하기 위해 디렉터리를 전달하는 것이고 gcc, 다른 하나 -include는 헤더 파일을 #include "file"기본 소스 파일의 첫 번째 줄에 나타나는 것처럼 처리하는 것입니다.

여기에 제공된 두 가지 다른 버전은 옵션 플래그와 인수 사이에 공백이 있는지 여부가 다릅니다. 둘 다 허용되는 것 같습니다.

현재 업스트림에서 사용할 수 있는 유일한 버전은 다음과 같습니다.

-I/usr/include/gtk-2.0 and -include /usr/include/gtk-2.0/gtk/gtk.h

그러나 나중에 누군가가 이러한 다른 양식을 추가하는 경우를 대비하여 이 코드를 미래에도 사용할 수 있도록 시도하는 것은 나쁜 생각이 아닌 것 같습니다.

대부분의 경우 업스트림 스크립트가 수행하는 작업은 에 매개변수를 추가한 CFLAGS다음 최종 매개변수를 에 전달하는 것입니다 ffigen. 여기에 무엇이 있는지는 중요하지 않습니다 ffigen. 제 질문은 의 반환 값에 관한 것입니다 CFLAGS. 이것은 업스트림 스크립트입니다.

while [ $# -gt 1 ]
do
    echo $CFLAGS
    case ${1} in
      -pthread*)
        CFLAGS="${CFLAGS} -D_REENTRANT"
        shift
        ;;
      -x)
        shift
        shift
        ;;
      *)
        CFLAGS="${CFLAGS} ${1}"
        shift
        ;;
   esac
done

echo $CFLAGS

내가 원하는 것은 위 줄에 헤더 파일 이름을 지정하는 것입니다. 즉, 포함된 디렉터리에 상대적인 상대 경로 이름으로 변환하는 것입니다. 그래서 제가 보고 싶은 반환 값 은 다음 CFLAGS과 같습니다.

-I/usr/include/gtk-2.0 -I /usr/include/glib-2.0 -include gtk-2.0/gtk/gtk.h -includebar.h

업스트림에서 생성되는 것은 변경되지 않은 매개변수일 뿐입니다.

-I/usr/include/gtk-2.0 -I /usr/include/glib-2.0 -include \
/usr/include/gtk-2.0/gtk/gtk.h -include/usr/include/bar.h

이유: Debian이 multilib로 전환했기 때문에 헤더 파일은 더 이상 기존 위치에 없습니다. 이제 ffigen상위 항목과 마찬가지로 gcc헤더 파일의 포함 경로를 검색할 수 있습니다.만약에 상대 경로만 지정하십시오. 절대 경로가 지정되면 당연히 그렇지 않습니다.

이상적으로는 여러 아키텍처에서 작동하도록 설계된 도구를 사용하고 싶지만 빠르고 더러운 해결 방법은 단순히 헤더 절대 경로를 상대 경로 이름으로 제거하고 ffigen이 올바른 포함 경로를 제공하는 경우 헤더 파일을 검색하고 발견하는 것입니다.

현재 제가 가지고 있는 버전은 아래와 같습니다. 그것은 생산한다

-I/usr/include/gtk-2.0 -I glib-2.0 -include gtk-2.0/gtk/gtk.h bar.h

이것은 짜증나지만 실제로 업스트림에서 발생하는 두 가지 시나리오를 올바르게 처리합니다. 네 가지 경우를 모두 올바르게 처리하는 버전이 가장 인기가 있습니다. 네, 저는 게으릅니다. 나는 또한 쉘 스크립팅에도 서툴다.

while [ $# -gt 1 ]
do
    echo $CFLAGS
    case ${1} in
      -pthread*)
        CFLAGS="${CFLAGS} -D_REENTRANT"
        shift
        ;;
      -x)
        shift
        shift
        ;;
      -I*)
        CFLAGS="${CFLAGS} ${1}"
        shift
        ;;
      *)
        RELPATH_AFTER_INCLUDE="${1##*include/}"
        CFLAGS="${CFLAGS} ${RELPATH_AFTER_INCLUDE}"
        shift
        ;;
   esac
done

echo $CFLAGS

다음은 이것을 테스트하는 데 사용한 작은 스크립트입니다.

#!/bin/sh

PROGRAM=htest.sh
#PROGRAM=upstream.sh

./${PROGRAM} -I/usr/include/gtk-2.0 -I /usr/include/glib-2.0 -include \     
/usr/include/gtk-2.0/gtk/gtk.h -include/usr/include/bar.h /usr/include/myheader.h

이식성에 대한 마지막 요점입니다. 위의 스크립트는 대시 아래에서 실행되며 이식 가능한 것처럼 보입니다. 따라서 휴대용 버전이 있으면 좋겠지만 꼭 필요한 것은 아닙니다. 이 코드 업스트림이 보이지 않으므로... 이식성이 없다면 bash는 괜찮을 것입니다.

###################################################################

이것의 배경에 관심이 있는 분들을 위해 이것은 포장의 맥락에 있습니다.클로저 커먼 리스프데비안의 경우.

바라보다데비안 패키징특히 README.소스 파일.

업스트림 패치 보기 http://svn.clozure.com/publicsvn/ffigen4/trunk/ffigen4/source/h-to-ffi-common 그리고 http://svn.clozure.com/publicsvn/ffigen4/trunk/ffigen4/source/linuxx8664-gcc-4.0.0-h-to-ffi.sh , 이는 업스트림 스크립트를 만들기 위해 결합되며 h-to-ffi.sh그 중 일부는 여기에서 논의됩니다.

여기서 다루려고 하는 특정 문제에 대해서는 스레드를 참조하세요. 데비안 다중 아키텍처에서 인터페이스 데이터베이스 구축 문제.

위의 근거에 대한 논의는 이 스레드의 세 번째 메시지에 나와 있습니다.

답변1

-Ior 뒤에 공백이 있는 경우도 있고 없는 경우도 있기 때문에 옵션을 유지할 -include수 없습니다.$1그리고값.

나는 "-pthread*", "-x" 및 "*" 대소문자를 선택하는 원래 버전을 고수하겠습니다. 그런 다음 CFLAGS 변수를 누적한 후 sed를 호출하여 -include 옵션이 있는 경로의 일부만 제거합니다.

CFLAGS=$(echo "$CFLAGS" | sed 's#\(-include \?\)/usr/include/#\1#g')

답변2

다음은 작동하지만 약간 깁니다. 개선을 위한 제안을 환영합니다.

while [ $# -gt 1 ]
do
    echo $CFLAGS
    case ${1} in
      -pthread*)
        CFLAGS="${CFLAGS} -D_REENTRANT"
        shift
        ;;
      -x)
        shift
        shift
        ;;
      -I)
        CFLAGS="${CFLAGS} ${1}"
        shift
        CFLAGS="${CFLAGS} ${1}"
        shift
        ;;
      -include)
        CFLAGS="${CFLAGS} ${1}"
        shift
        RELPATH_AFTER_INCLUDE="${1##*include/}"
        CFLAGS="${CFLAGS} ${RELPATH_AFTER_INCLUDE}"
        shift
        ;;
      -I*)
        CFLAGS="${CFLAGS} ${1}"
        shift
        ;;
      -include*)
        # strip off leading -include                                                                                                                              
        REMOVE_LEADING_INCLUDE="${1##-include}"
        echo "REMOVE-LEADING-INCLUDE" ${REMOVE_LEADING_INCLUDE}
        RELPATH_AFTER_INCLUDE="${REMOVE_LEADING_INCLUDE##*include/}"
        CFLAGS="${CFLAGS} -include${RELPATH_AFTER_INCLUDE}"
        shift
        ;;
      *)
       CFLAGS="${CFLAGS} ${1}"
        shift
        ;;
   esac
done

echo $CFLAGS

관련 정보