GCC 6.2.1을 사용하여 GCC 4.7.0을 컴파일할 때 오류를 처리하는 방법

GCC 6.2.1을 사용하여 GCC 4.7.0을 컴파일할 때 오류를 처리하는 방법

저는 Arch Linux를 사용하고 있으며 수업에는 GCC 4.7.0이 필요합니다.

현재 내 시스템에는 GCC 6.2.1만 설치되어 있습니다.

모든 설치 지침을 올바르게 따랐지만 초기 make.

$ make
.
.
In file included from /home/flounder/src/gcc-4.7.0/gcc-4.7.0/gcc/cp/except.c:987:0:
cfns.gperf: At top level:
cfns.gperf:101:1: error: ‘gnu_inline’ attribute present on ‘libc_name_p’
cfns.gperf:26:14: error: but not here
.
.
make[3]: *** [Makefile:1055: cp/except.o] Error 1
make[3]: Leaving directory '/home/flounder/src/gcc_compile/gcc'
make[2]: *** [Makefile:4101: all-stage1-gcc] Error 2
make[2]: Leaving directory '/home/flounder/src/gcc_compile'
make[1]: *** [Makefile:19342: stage1-bubble] Error 2
make[1]: Leaving directory '/home/flounder/src/gcc_compile'
make: *** [Makefile:898: all] Error 2

나는 다음과 같은 이유로 최신 버전으로 이전 버전의 GCC를 구축하려고 할 때 이런 일이 발생할 수 있다는 것을 읽었습니다.

릴리스가 계속됨에 따라 GCC에는 새로운 버그가 추가되므로 이전 버전의 GCC 소스 코드가 최신 버전의 GCC에서 항상 유효한 것으로 간주되지는 않습니다.

나는 읽었다여기,여기, 그리고여기.

그래서이 문제를 해결하려면 어떻게 해야 할까요??

나는 두 가지 가능한 해결책을 생각합니다.

  1. 학교 Linux 시스템을 사용하여 내 시스템에 대해 GCC 4.7.0을 크로스 컴파일합니다(GCC 4.7.0도 있지만 32비트이고 저는 64비트 OS를 사용합니다).
  2. 먼저 내 컴퓨터에서 GCC 6.2.1을 사용하여 GCC 5.4.x를 컴파일한 다음 GCC 5.4.x를 사용하여 GCC 4.7.0을 컴파일했습니다.

첫 번째 옵션이 더 안전한 것 같습니다. 둘 다 일할 수 있나요? 그것보다 이게 낫나요?

편집하다:

아래 @Kenneth B. Jensen이 언급한 것처럼 플래그가 설정된 상태에서 구성을 실행해 보았고, --disable-werror플래그가 설정된 상태에서 초기 구성을 실행해 보았으나 여전히 문제가 발생합니다. 다음은 오류 출력입니다.make-k

$ make -k
.
.
.
if [ xinfo = xinfo ]; then \
    makeinfo --split-size=5000000 --split-size=5000000 --split-size=5000000 --no-split -I . -I /home/flounder/src/gcc-4.7.0/gcc/doc \
            -I /home/flounder/src/gcc-4.7.0/gcc/doc/include -o doc/cppinternals.info /home/flounder/src/gcc-4.7.0/gcc/doc/cppinternals.texi; \
fi
echo timestamp > gcc.pod
perl /home/flounder/src/gcc-4.7.0/gcc/../contrib/texi2pod.pl /home/flounder/src/gcc-4.7.0/gcc/doc/invoke.texi > gcc.pod
Unescaped left brace in regex is deprecated, passed through in regex; marked by <-- HERE in m/^\@strong{ <-- HERE (.*)}$/ at /home/flounder/src/gcc-4.7.0/gcc/../contrib/texi2pod.pl line 319.
echo timestamp > doc/gcc.1
(pod2man --center="GNU" --release="gcc-4.7.0" --date=2012-03-22 --section=1 gcc.pod > doc/gcc.1.T$$ && \
    mv -f doc/gcc.1.T$$ doc/gcc.1) || \
    (rm -f doc/gcc.1.T$$ && exit 1)
echo timestamp > gpl.pod
perl /home/flounder/src/gcc-4.7.0/gcc/../contrib/texi2pod.pl /home/flounder/src/gcc-4.7.0/gcc/doc/include/gpl_v3.texi > gpl.pod
Unescaped left brace in regex is deprecated, passed through in regex; marked by <-- HERE in m/^\@strong{ <-- HERE (.*)}$/ at /home/flounder/src/gcc-4.7.0/gcc/../contrib/texi2pod.pl line 319.
echo timestamp > doc/gpl.7
(pod2man --center="GNU" --release="gcc-4.7.0" --date=2012-03-22 --section=7 gpl.pod > doc/gpl.7.T$$ && \
    mv -f doc/gpl.7.T$$ doc/gpl.7) || \
    (rm -f doc/gpl.7.T$$ && exit 1)
cp doc/gcc.1 doc/g++.1
make[3]: Target 'all' not remade because of errors.
rm gcc.pod
make[3]: Leaving directory '/home/flounder/src/gcc_compile/gcc'
make[2]: *** [Makefile:4101: all-stage1-gcc] Error 2
make[2]: Target 'all-stage1' not remade because of errors.
make[2]: Leaving directory '/home/flounder/src/gcc_compile'
make[1]: *** [Makefile:19342: stage1-bubble] Error 2
make[1]: Target 'stage3-bubble' not remade because of errors.
make[1]: Leaving directory '/home/flounder/src/gcc_compile'
make: *** [Makefile:898: all] Error 2

답변1

나는 최신 gcc를 사용하는 것이 일반적으로 좋은 선택이 아니라는 데 동의합니다. Pengutronix를 실행하는 임베디드 ARM v4 시스템을 위한 새 프로그램을 작성해야 하는데, 이 프로그램은 2.6 커널과 오래된 glibc에 고정되어 있습니다. 그래서 내 시스템에서 기존 툴체인을 컴파일해야 합니다.

최신 GCC 버전에서는 꽤 오랫동안 존재했던 소스 코드의 버그를 발견하는 경우가 많습니다. 오류 검사를 끄지 말고 소스 코드를 수정하는 것이 좋습니다.

오류 로그에 따르면 함수 선언과 함수 헤더가 일치하지 않습니다.

const char * libc_name_p (const char *, unsigned int);

Except.c에 포함된 cfns.h 파일에서

cfns.h를 편집하고 함수 선언을 변경합니다.

#ifdef __GNUC__
__inline
#endif
const char * libc_name_p (const char *, unsigned int);

도착하다

#ifdef __GNUC__
__inline
#ifdef __GNUC_STDC_INLINE__
__attribute__ ((__gnu_inline__))
#endif
#endif
const char * libc_name_p (const char *, unsigned int);

그러면 컴파일이 작동할 것입니다.

답변2

@AxelBe의 답변을 확장하려면 최신 GCC를 사용하면 cfns.h의 함수 선언 및 정의를 변경해야 할 수도 있습니다.

#ifdef __GNUC__
__inline
#endif
const char * libc_name_p (const char *, unsigned int);

또는

#ifdef __GNUC__
__inline
#ifdef __GNUC_STDC_INLINE__
__attribute__ ((__gnu_inline__))
#endif
#endif
const char * libc_name_p (const char *, unsigned int);

도착하다

#ifdef __GNUC__
#ifdef __GNUC_STDC_INLINE__
__attribute__ ((__gnu_inline__))
#else
__inline
#endif
#endif
const char * libc_name_p (const char *, unsigned int);

및 속성을 모두 갖는 것을 방지합니다 __inline(오류 발생). 이는 GCC 9.2와 함께 GCC 5.3을 컴파일할 때 효과적이었습니다.__gnu_inline__redeclared inline with 'gnu_inline' attribute

답변3

현재 시스템에서 GCC 4.7을 구축하는 데 많은 시간을 소비하게 될 수도 있고 결국에는 여전히 결과를 확신할 수 없습니다. 학교 컴퓨터의 GCC 버전에는 배포 패치가 포함될 수도 있고 심지어는 버전에 따른 변경 사항에 대한 로컬 패치도 포함될 수 있습니다. 가지고 있지 않습니다.

학교에서 사용하는 배포판을 가상 머신에서 실행하는 것이 좋습니다. 학교에서 RHEL을 사용하고 있으며 귀하도 다음을 수행할 수 있습니다. 다음에서 무료 개발자 구독을 받을 수 있습니다.레드햇 개발자; 일단 구독하면 아직 지원되는 모든 RHEL 버전의 ISO를 다운로드할 수 있으므로 학교 컴퓨터에 사용 중인 것과 동일한 버전을 설치할 수 있습니다.

어쨌든 채점을 위한 것이므로 제출하기 전에 학교 컴퓨터에서 코드를 확인해야 합니다!

답변4

이는 단지 버그를 "수정"하기 위한 것입니다. 수정한 후 또 다른 오류가 나타났습니다.

이 문제를 해결하려면 -

./gcc/cp/cfns.gperf 파일의 23--26행

#ifdef __GNUC__
__inline
#endif
const char * libc_name_p (const char *, unsigned int);

진술에 주석을 달면 됩니다 ifdef.

새로운 오류 -

cp/except.o: In function `nothrow_libfn_p':
/home/user/Documents/build/gcc464objdir/gcc/../../gcc-4.6.4/gcc/cp/except.c:932: undefined reference to `libc_name_p'
collect2: error: ld returned 1 exit status

관련 정보