레이블이 Tools-Build인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Tools-Build인 게시물을 표시합니다. 모든 게시물 표시

10/06/2022

Cmake 와 Kconfig

1. Kconfig 와 Autotools

Cmake 를 접하게 된 것은 오래된것 같은데, Cmake와 Ninja를 본격적으로 접하게 된 것이 ESP Series를 접하면서 부터 였던걸로 기억한다. 
이전에 Cmake 언제 사용했는지는 나도 좀 많이 헷갈린다.  
이전에 사용했다면, 별 대수롭지 않게 생각하고, 기존 것과 비슷하게 고쳐서 사용했던 것 같다. 

일단, 오래전 각 Solution들을 만들면서, Open Source Application들을 구성할 일이 많이 있었는데, 
주로 전체 설정구성 과 연결을 시스템을 Autotools 구성했다. 
사실 autoconf의 script를 보면, Cmake도 생각나기도 하는 것 같다. 

개발자는, 
autotools 기반 (Autoconf/automake/makefile)으로 Script 설정하여 만들고, 
유저는 configure를 통해 처음설정(CONFIG)하며, 빌드환경인, Makefile이 자동생성되어 로 build를 하면되는 구조이다. 
보통 autotools은 Open Application 많이 사용되어졌으며, 현재 사용되어지는지는 나도 정확히 잘 모르겠다. 

Kconfig 역시 Linux Kernel에서 사용되어지만, Kconfig 문법만 매번 보고, 이를 추가하여  Linux Device Driver 구현하였다. 

기본원리만 알아서 완벽히 세부적인 설명(둘 사이 차이)을 설명을 못하겠지만, 
Autotools의 경우는 Automake 기반으로 Makefile의 설정 변경하여, Makefile 만들어서 Build 환경을 만들걸로 기억한다.
현재 Kconfig 와 Cmake 조합도, 역시 이 구성가능하다. 


이 것이 중요한 이유는 설정(Config)에 따라 전체 Build 구성 환경변경되기 때문이다. 
  1. 언어(C언어) 입장에서 config.h 설정으로, 쉽게 각 기능 ON/OFF 가능 (Preprocessing)
  2. Build 환경(Make or Cmake)입장에서는 각 언어의 Build 여부 및 Build 환경선택가능

사실 만드는 사람입장에서는 script로 다양하게, 각 설정해야하기 때문에 복잡하다.
그 복잡성을 보고 싶다면, 아래링크를 간단히 참조를 하면 되겠다.   
 
  • Autoconf 의 구성 및 Script 
간단하게 설명하면, configure.ac 가 있고, m4 script 와 이용하여 각 헤더 구성과 환경설정 하고, 
최종적으로 configure.ac 와 Makefile.am으로 Makefile을 만들어준다고 보면된다. 
(나도 너무 오래되어서 틀리수 도 있다.)

  • Linux Kconfig 
Kconfig 의 경우, 아래와 같이 문법이 존재하여, 이 부분이 Makefile 과 연결되고 autoconf와 비슷하게 전체 header를 자동으로 생성해준다. 

나중에 다시 직접 구현할 기회가 있다면, 그 때 세부적으로 정리하도록 하겠다. 

Kconfig 기본문법 

Python Kconfig 
요즘 Python으로 안되는 것이 없는 것 같으며, 확장도 쉽게되어 진다니, 신기할 뿐이며, ESP-IDF는 이것을 사용한다고 한다


1.1 Cmake 란?

Cmake는 script로 build 환경을 쉽게 구축하여 가능하고, 버전 업이되면, ninja가 추가되어 build 속도가 빨라졌다고 한다.  
하지만 지금까지 Manaul 구성보고, ESP-IDF를 이용해보고 있지만,  별도의 Config는 KConfig를 사용하고 있다.  
별도의 Linux Kernel의 Kconfig or Autoconf 같은 것의 도움이 필요한걸로 보인다. 
ninja 역할은 빌드 속도를 높이기 위해서 사용되어지는다고 하는데, Cmake에 이제는 기본으로 들어가서 동작되어진다고 한다. 

ESP, ESP-IDF 구성보면, Autoconf/Automake/Makefile 이 아니라. Kconfig/Cmake 구성되는 구조이며, Linux Kernel 구조와 거의 유사하다.
다르다면, Linux Kernel 나의 기억으로는 Cmake를 사용안했던 걸로 기억한다 (이 부분 추후 확인)  

Zephyr 구성역시 보면 Kconfig/Cmake 구성으로 ESP와 거의 유사하다. 

둘 다 OS기반으로 한 설정을 해야 하니, Linux Kernel 구조와 비슷하게 했으리라 본다. 


결론적으로 Cmake는 기본 Make 를 보다 사용하기 편한 Make로 만들어 줄 수 있도록 다양한 Command Script를 제공한다. 
이는 각 Script를 이용하여 쉽게 확장 및 독자적인 함수 구성이 가능하다.  
그래서, Zephyr  와 ESP 의 경우 세부적으로 분석하면, 독자적인 Cmake Function들이 많다.


Cmake Main Home 

Cmake 의 문서 

Cmake Manual
 
Cmake 의 Ninja


1.2 Make 와 Cmake 차이 

Makefile 과 CMakelist.txt 비교 

Cmake 와 Raspberry Pico
아래의 글을 읽어보면, Cmake도 내부에 Make를 사용한다고 한다. 

상위글 과 Manual을 보면, Cmake역시 기본적으로는  Cmakelist.txt를 이용하고 있지만, 결과적으로 Makefile을 이용하고 있으며, 대신에 부족한 부분기능들을 
Cmake에서 제공하는 각 Script로 쉽게 설정 및 Function으로 확장가능하며, 이를 사용하는 것 같다.  

cmake CMakelist.txt 


1.3 CMakelist.txt 구조 및 문법 

일단 CMakelist.txt 문법은 마치 Shell Script 처럼 구성이 되어있으며, 각 Version에 따라 다양한 기능들을 제공해준다. 

Cmake manual (최신, 본인 버전에 맞게 선택해서 보자)

CMake Tutorial 

Cmakelist.txt에서 주로 구성해서 사용하는 것들이 Cmake Script/Project Command가 주로 될 것이라고 생각되어진다. 

  • Cmake Commands
가장 중요한 Manaul로 반드시 숙지해야하며, 반드시 버전과 같이 확인해야 한다. 
Cmake-commands 전체구성  
  1. Scripting Commands
  2. Project Commands
  3. CTest Commands
  4. Deprecated Commands : 사라질 것이므로 가급적 사용말자 

Cmake Script Commands 
Cmake Script Commands 의 Function Command 와 macro 확인 
Zephyr or ESP에서 각 독자적인 Function을 만들어 구성 (아래 참조)

Cmake Project Commands

Cmake Ctest Commands

주로 사용되어지는 Command는 일반적인 Script 와 Project Build 설정 및 관리를 위해서 사용되어지는 Command들이다. 
Ctest는 아직 잘모르기에 링크만 연결한다. (단위테스트용으로 사용하는 것으로 추측 혹은 build 관련 테스트 일 것 같다.) 


  • CMakelist.txt 에서의 Script Commands 예제 
기본 if/elseif/elese/endif
if( condition)
elseif (condition)
else (condition)
endif(condition)

다음과 같이 사용하면 되겠으며, Shell Script 처럼 사용가능하며, 쉽게 확장도 가능하다  

if(ENABLE_A AND ENABLE_B )      # AND 연산 
    
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error")           # Shell Script 처럼 변수 값을 설정 
    set(CMAKE_C_FLAGS_ASAN "${CMAKE_C_FLAGS_ASAN} -Wno-error")
    set(CMAKE_C_FLAGS_ASANDBG "${CMAKE_C_FLAGS_ASANDBG} -Wno-error")
    
elseif (ENABLE_A OR ENABLE_B)   # OR 연산 
    
    list(APPEND crt_paths ${DEFAULT_CRT_DIR}/cacrt_all.pem)
    list(APPEND args --filter ${DEFAULT_CRT_DIR}/cmn_crt_authorities.csv)

elseif (NOT ENABLE_B)   # NOT 연산 
    
    if(NOT (sodium_DLL_RELEASE MATCHES ".*-NOTFOUND"))    # MATCHES를 보면, regex를 사용하여 wild card 형식
      set_target_properties(sodium
                            PROPERTIES IMPORTED_LOCATION_RELWITHDEBINFO
                                       "${sodium_DLL_RELEASE}"
                                       IMPORTED_LOCATION_MINSIZEREL
                                       "${sodium_DLL_RELEASE}"
                                       IMPORTED_LOCATION_RELEASE
                                       "${sodium_DLL_RELEASE}")
    endif()

else ()     # 재미있는 것은 else에 condition을 넣을 수 있지만, 잘 사용하지 않는 것 같다. 추후 테스트 
endif()

상위 구성을 봐도 거의 Shell Script 구조이며, 내가 보기에는 다양한 예제만 있다면, 거의 쉽게 따라 할수가 있을 거라고 본다. 
다양한 예제는 Zephyr 와 ESP를 참조하도록 하자 

Cmake 관련 자료링크 


2. Kconfig 와 Cmake 구성 

ESP-IDF 와 Zephyr 의 구성은 위에서 설명했듯이 Kconfig 와 Cmake 기반 구성이며, 이를 간단히 비교해보자. 
Kconfig의 경우, Linux Kernel을 많이 보신분들이라면 쉽게 아는 구성이다.


  • Kconfig (Linux Kernel Config)
make menuconfig로 설정하면 이 설정된 값이 config에 저장되고, 저장된 config가 Build 환경환경설정하고, 
별도의 C의 header File을 생성하여, 각 Linux Kernel 소스의 preprocessor 반영한다. 

Kconfig에서 이를 설정을 정의하면, User는 이를 쉽게 선택이 가능하다. 
위에서 설명했듯이, 
Build 환경인,Cmake를 통하여 빌드 여부와 Build 환경설정 변경가능하다.
또한 Kconfig를 통해 최종 config.h 최종설정된 Header file을 얻어 C 언어에서 이를 기반으로 Preprocessing이 가능하다. 


2.1 Zephyr 의 Kconfig/Cmake구성 

Zephyr의 경우는 현재 소스가 없고, 빌드를 못하기 때문에 아래와 같이 소스로만 간단히 보도록하자. 
너무 분석할게 많아 추후 Zephyr를 사용할 기회가 있다면 그때 세부적으로 분석하고 이해하도록 하겠다. 
거의 Linux Kernel을 알고 ESP도 안다면 쉽게 이해하리라 본다. 

  • Zephyr Kconfig 구성 
항상 source로 추가되어지는 구조이므로, 전체소스를 분석하기 보다는 한번 실행해보면, 구조가 어떻게 구성되는 쉽게 파악되어진다. 
실행은 make menuconfig 

Kconfig 
....
config CODE_DATA_RELOCATION
	bool "Relocate code/data sections"
	depends on ARM
	help
	  When selected this will relocate .text, data and .bss sections from
	  the specified files and places it in the required memory region. The
	  files should be specified in the CMakeList.txt file with
	  a cmake API zephyr_code_relocate().
.......
CMakefileLists.txt
if (CONFIG_CODE_DATA_RELOCATION)
  set(CODE_RELOCATION_DEP code_relocation_source_lib)
endif() # CONFIG_CODE_DATA_RELOCATION

  • Zephyr의 Cmake 독자함수 구성 
이곳이 중요한 이유는 Zephyr의 독자적인 Cmake Function을 비롯하여 관련부분을 제공하기 때문에 중요하다.

  • Zephyr의 Cmake 독자함수 구성의 세부분석 
Kconfig 관련 구성 및 각 동작분석 

Zephyr에서 제공하는 Cmake Command로 Function 으로 Zephyr에서 독자적으로 구현했으므로, 이 관련 Manaul은 반드시 참조  

Zephyr도 이제 QEMU을 지원가능한걸로 보임 (QEMU 에뮬레이터?) 
ESP도 최근부터 지원가능하며, QEMU을 통해 PC에서 테스트 가능하다 

Linker 에 관련된 Cmake로 각 Macro를 확인  

각 Python 파일구성으로 ESP처럼 Tools로 역할할 것으로 생각되어지며, 이를 이용하여 개발환경 Tool을 구성한 것 같다. 
Python 개발 Tool 환경에 관심있다면, 이부분이 중요할 것 같다. 


2.2 ESP-IDF 의 Kconfig/Cmake구성 

개인적은 ESP32 와 ESP-IDF는 너무 잘만들어 놓았기에, 실제 이를 이용하여 사용하는 개발자 입장에서는 감사할 뿐이다. 

  • ESP-IDF Kconfig 구성 
항상 source로 추가되어지는 구조이므로, 전체소스를 분석하기 보다는 한번 실행해보면, 구조가 어떻게 구성되는 쉽게 파악되어진다. 
실행은 make menuconfig 하여 Kconfig 설정확인을 한다. 
이를 저장하면 sdkconfig 가 생성되며, 이는 build 에 config/sdkconfig.h 생성되어 모든 소스에서 이를 참조 적용가능하다    

ESP-IDF Kconfig Mainmenu 
ESP-IDF에서 menuconfig 를 실행하면 실행되어지는 Main Kconfig (mainmenu 검색)
  1. source "$COMPONENT_KCONFIGS_PROJBUILD_SOURCE_FILE"  //각 Project 별의 Kconfig.projbuld 추가 확장 
  2. source "$COMPONENT_KCONFIGS_SOURCE_FILE" //각 Component 의 Kconfig 추가확장


ESP-IDF config  sdkconfig 의 확장사항 
sdkconfig.default 설정 및 다양한 설정 

  • ESP-IDF의 Cmake 독자함수구성 및 구현 
이곳이 중요한 이유는 ESP의 독자적인 Cmake Function을 비롯하여 관련부분을 제공하기 때문에 중요하다.
Espressif에서 독자 구축한 함수이므로 관련사용법은 아래의 ESP Manual을 참조하고 구현된 것은 이곳을 보도록하자.


  • ESP-IDF의 Cmake 독자함수구성 세부분석 
Kconfig 와 Cmake 관련구성으로  sdkconfig.h 생성확인  (이외 Json 파일확인)

상위 Command로 Function 각 독자적인 구성확인  

ESP의 component function 

ESP32의 Build 기본빌드환경 

ESP-IDF 기반으로 Project 구성시 


  • ESP-IDF의 Cmake 독자함수 사용법 및 빌드 Manual 
각 Espressif에서 독자 구축한 Cmake 환경구성 사용하는 방법으로 반드시 ESP-IDF 개발자는 알아야 하는 곳이다. 
Manual 구성이 잘되어 있어 기본 Kconfig 문법부터 ESP-IDF Cmake 사용법 부터 구성까지 잘 되어있다.  
이 Manual을 보고 상위 Function들을 이용목적과 사용방법을 쉽게 익혀 사용가능하다. (반드시 참조)