/usr/include에 헤더 파일의 복사본이 여러 개 있는 이유는 무엇입니까?

/usr/include에 헤더 파일의 복사본이 여러 개 있는 이유는 무엇입니까?

나는 /usr/include 폴더를 살펴보며 레이아웃에 익숙해지려고 노력했고, 헤더 파일의 복사본이 여러 개 있다는 것을 발견했습니다(적어도 이름으로는, 실제로 파일이 맞는지 비교하지는 않았습니다). 정확한 사본) in / usr/include의 여러 하위 디렉토리에 있습니다. 이는 표준 C 및 C++ 헤더 파일과 POSIX/LSB 표준 헤더 파일의 경우 특히 그렇습니다.

몇 가지 예는 다음과 같습니다(참고 ./는 /usr/include를 나타냄).

./asm-generic/unistd.h
./linux/unistd.h
./unistd.h
./x86_64-linux-gnu/sys/unistd.h
./x86_64-linux-gnu/bits/unistd.h
./x86_64-linux-gnu/asm/unistd.h

./stdlib.h
./x86_64-linux-gnu/bits/stdlib.h
./c++/7/stdlib.h
./c++/7/tr1/stdlib.h

./c++/7/cmath
./c++/7/ext/cmath
./c++/7/tr1/cmath

./asm-generic/termios.h
./linux/termios.h
./x86_64-linux-gnu/sys/termios.h
./x86_64-linux-gnu/bits/termios.h
./x86_64-linux-gnu/asm/termios.h
./termios.h

./linux/time.h
./time.h
./x86_64-linux-gnu/sys/time.h
./x86_64-linux-gnu/bits/time.h

왜 이런거야? 일부 C 표준 헤더 파일이 C++ 위치에 나타나는 이유는 무엇입니까?

컴파일러가 하나만 설치되어 있습니다(GCC 7).

답변1

아니요, 정확한 복제품은 아닙니다.

조사하려는 경우 최상위 수준의 파일에는 /usr/include종종 많은 s 또는 기타 조건이 있으며 아키텍처에 독립적인 부분과 더 깊은 아키텍처 관련 디렉터리의 기타 콘텐츠 #ifdef만 정의한다는 것을 알 수 있습니다. #include일부 아키텍처 관련 부분은 결국 일부 아키텍처 독립적인 부분에 종속될 수 있으므로 서로 위에 여러 개의 포함 계층이 있을 수 있습니다.

마찬가지로 다음 파일에는 /usr/include/c++C++에만 의미가 있는 추가 선언이 있는 반면 #includes는 해당 C 포함 파일에 적용됩니다.

게임 이름은유지 관리성 향상을 위한 데이터 중복 제거: 의도는 glibc 개발자가 새로운 것을 추가해야 할 때 애플리케이션과 glibc 사이의 ABI에만 영향을 미치고 아키텍처 관련 부분은 없으며 이상적으로는 포함 파일 트리의 한 위치에서만 추가가 발생하면 된다는 것입니다. , glibc를 사용하는 모든 하드웨어 아키텍처에 적용됩니다. 또는 예를 들어 새로운 시스템 호출이 Linux 커널에 추가되면 *BSD 또는 GNU Hurd 시스템 호출 정의를 방해하지 않고 이를 추가할 수 있는 장소가 있을 것입니다. 또는 glibc를 다른 하드웨어/커널 아키텍처로 포팅하는 경우 아키텍처 독립적인 작업을 방해하지 않고 필요한 커널 ABI 정의를 플러그인할 수 있는 위치를 찾을 수 있습니다(반드시 필요한 경우는 제외).

예, 매우 복잡합니다.

/usr/include전체 레이아웃은 GCC 및 glibc 프로젝트에서 선택한 ISO C 및 POSIX 표준 요구 사항과 선택 사항의 합계 이므로 참조하기 쉬운 참조가 없습니다.

나는 당신이 당신의건축 삼중항( x86_64-linux-gnu귀하의 경우 gcc -dumpmachineGCC에서 지원하는 모든 아키텍처에서 사용 가능) 그런 다음 컴파일러의 기본 #include <...>파일 검색 경로를 연구하십시오.

다음을 통해 검색 경로를 볼 수 있습니다.

  • cpp -v /dev/null -o /dev/null일반 C의 경우
  • cpp -x c++ -v /dev/null -o /dev/nullC++의 경우

GCC 7을 사용하는 시스템은 없지만 GCC 6의 경우 C에 대한 포함 경로 목록은 다음과 같습니다.

...
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
...

...C++의 경우 다음과 같습니다.

...
#include <...> search starts here:
 /usr/include/c++/6
 /usr/include/x86_64-linux-gnu/c++/6
 /usr/include/c++/6/backward
 /usr/lib/gcc/x86_64-linux-gnu/6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
...

디렉토리가 존재하는 경우 /usr/local/include/<architecture triplet>목록 바로 앞에 추가됩니다 /usr/local/include.

따라서 자신의 프로젝트에 포함 파일의 아키텍처별 버전이 필요한 경우 해당 파일을 에 넣을 수 있고 /usr/[local/]include/<architecture triplet>/, 일반적인 아키텍처 독립적인 포함 파일은 에 넣을 /usr/[local/]include/수 있습니다. 경로 이름에는 컴파일러의 주요 버전 번호가 포함됩니다.

수정하려고 하는데 glibc개발자 문서에서 필요한 것을 찾을 수 없다면 glibc개발 메일링 리스트에 조언을 요청하는 것이 더 나을 것입니다. 이는 GCC 이외의 컴파일러를 사용하는 아키텍처에서도 작동하기 때문입니다. 표준으로서 아키텍처 삼중 규칙이 없을 수 있습니다.glibcglibc

관련 정보