리눅스 커널 모듈에 로컬 헤더 파일을 포함시키는 방법


17

mymod다음과 같이 소스 파일 이있는 모듈이 있다고 가정하십시오 .

src / mod / mymod.c
src / inc / mymod.h

다음과 같이 mymod.h를 포함하려고합니다.

#include <mymod.h>

내 makefile에 포함되어 EXTRA_CFLAGS= -I$(shell pwd)/../inc/있지만 커널을 만들면 오류가 발생합니다.

mymod.h를 찾을 수 없습니다

커널 모듈을 만들 때이 명령이 makefile에서 실행되기 때문입니다 ( makeV1 사용 ).

make -C <path/to/linux/src> M=<path/to/mymod> modules

다른 작품에서 나는 $(shell pwd)확장되었다 <path/to/linux>. 이것은 내가 원하는 것이 아닙니다. 어떻게 지정할 수 있습니다 -I에 포인트 매개 변수를 src/inc내의 mymod소스 트리?

답변:


19

Linux 커널 makefile은 Kbuild 프레임 워크를 사용합니다. 이것들은 GNU make로 해석되지만 Kbuild는 고유 한 사용 규칙을 가진 큰 매크로 세트로 구성되므로 일반적인 makefile 지침은 적용되지 않습니다. Kbuild의 좋은 점은 작업의 복잡성을 고려할 때 상용구가 거의 필요 없다는 것입니다.

Kbuild는의 커널 소스에 설명되어 Documentation/kbuild있습니다. 모듈 라이터로서, 특히 읽어야합니다 modules.txt(적어도 다른 것을 훑어 보십시오 ).

변수를 사용할 $(shell pwd)때 확장되어 현재 수행중인 작업이 작동하지 않습니다 EXTRA_CFLAGS. makefile은 모듈의 디렉토리가 아닌 커널 소스 트리에서 실행되므로 (이것은 Kbuild의 많은 명백하지 않은 측면 중 하나입니다) 잘못된 디렉토리를 선택합니다.

트리 외부 모듈에 포함 디렉토리를 지정하는 공식 관용구는의 5.3에 modules.txt있습니다. src변수는 모듈의 최상위 디렉토리로 설정됩니다. 따라서:

EXTRA_CFLAGS := -I$(src)/src/inc

이 선언은 Kbuild모듈 트리의 루트 에있는 파일에 있어야합니다 . ( src디렉토리를 모듈 트리의 루트 로 간주 할 수 있습니다 . 그렇다면 디렉토리를 넣고 Kbuild위의 값을로 바꾸십시오 -I$(src)/inc). 그것들을에 넣는 것도 가능 Makefile하지만 (커널 모듈을 빌드 할 때만 적용되는 한)이 정의는 조건부 지시문 내에 있어야한다는 것을 명심하십시오 ifeq ($(KERNELRELEASE),). 의 §4.1을 참조하십시오 modules.txt.

Kbuild아직 파일 이없고 파일로 전환하려면의 §4.1을 읽으십시오 modules.txt. 별도의 Kbuild파일 을 갖는 것이 약간 더 명확합니다. 호출 규칙 이외의 기본 makefile에 커널에 적용되는 것은 넣지 마십시오 make -C $(KERNELDIR) M=$(pwd). 에서 Kbuild필요한 최소한은 빌드하려는 모듈 목록 (종종 하나만)과 모듈에 포함 할 파일 목록 및 종속성 선언입니다.

EXTRA_CFLAGS := -I$(src)/inc
obj-m := mymod.o
mymod-y := $(src)/mod/mymod.o
$(src)/mod/mymod.o: $(src)/inc/mymod.h

평판이 충분하지 않아서 게시물을 업데이트 할 수 없습니다.
옴 나라 심한

1
@Om Narasimhan : 이것이 해결책을 찾는 데 도움이 되었다면 대답을 수락 된 것으로 표시해야합니다.
CVn

1

전통적 #include으로 현재 소스 코드의 디렉토리에 상대적인 경로를 가진 파일로 가는 방법 은 꺾쇠 괄호 대신 따옴표를 사용하는 것입니다.

#include <stdio.h>
#include "mygreatfunctions.h"

이 경우 첫 번째 #include는 컴파일러의 검색 경로 (gcc의 경우 -I명령 행 스위치로 제어 됨 )를 참조하는 반면, 두 번째는 소스 파일이 포함 된 디렉토리에서를 찾습니다 #include.

이러한 경로도 상대적 일 수 있습니다. 따라서 src / mod / mymod.c에서 다음과 같이 말할 수 있습니다.

#include "../inc/mymod.h"

"그냥 작동"해야합니다.

이것이 리눅스 커널 트리에서 일반적인 관행인지는 모르겠지만 의도하지 않은 부작용을 일으킬 수있는 include 경로를 사용하는 것보다 낫습니다.


1
일반적으로 좋은 조언이지만 Linux 커널 makefile은 매우 독특합니다. 그들은 Kbuild라는 상당히 복잡한 매크로 세트를 요구합니다. Kbuild를 거의 완전히는 아니지만 완전히 다른 언어로 취급하는 것이 가장 좋습니다.
Gilles 'SO- 악마 그만해'

1
물론, 구성된 디렉토리 세트에서 <foo>를 찾고 "bar"가 현재 디렉토리를 먼저보고 이전에 언급 한 경로로 넘어가는 C 컴파일러의 동작은 기괴한 의미가 무엇인지에 따라 바뀌지 않습니다. 처음에 컴파일러.
vonbrand 2016 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.