본문 바로가기
C & C++

[C/C++] 개발 환경 구성하기 05 (miniLibX)

by yhames 2024. 7. 23.
728x90

[C/C++] 개발 환경 구성하기 01 (아키텍처 설계, 브랜치 전략)
[C/C++] 개발 환경 구성하기 02 (cmake, libft, google test)
[C/C++] 개발 환경 구성하기 03 (gcovr, codecov)
[C/C++] 개발 환경 구성하기 04 (github action, norminette, codecov)
[C/C++] 개발 환경 구성하기 05 (miniLibX)

개발 환경을 구성하는 마지막 글입니다.
 
이번에는 42서울에서 사용하는 그래픽 라이브러리인 miniLibX를 실행파일에 추가하도록 하겠습니다. google test, libft와 마찬가지로 FetchContent를 사용하여 빌드 시점에 동적으로 가져오도록 설정했습니다.
 

FetchContent_Declare(
    minilibx
    GIT_REPOSITORY https://github.com/shelldivers/minilibx.git
    GIT_TAG v1.0.1
)
FetchContent_MakeAvailable(minilibx)
add_custom_target(build_minilibx ALL
	COMMAND make -C ${minilibx_SOURCE_DIR} -j1
	COMMAND cp ${minilibx_SOURCE_DIR}/libmlx.dylib ${CMAKE_BINARY_DIR}
)
set(MINILIBX_LIBRARY ${minilibx_SOURCE_DIR}/libmlx.dylib)

add_executable(${EXEC_NAME} "minirt.c")
add_dependencies(${EXEC_NAME} build_minilibx)
target_link_libraries(${EXEC_NAME} ${LIB_NAME} libft ${MINILIBX_LIBRARY})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/includes ${CMAKE_LIBFT_SRC_DIR}/includes ${minilibx_SOURCE_DIR})



다만 몇 가지 주의사항이 있습니다.
 

  • make -j 병렬처리 옵션
  • miniLibX의 macOS 의존성
  • swiftmodule 컴파일 에러

 

make -j 병렬처리 옵션

/opt/homebrew/bin/cmake --build /Users/jeongwpa/projects/miniRT/build --config Debug --target all -j 10 --

 
make로 miniLibX 라이브러리를 컴파일하면 cmake에서 기본적으로 -j 옵션을 사용해서 10개의 스레드로 병렬처리를 하게 됩니다. 
 

[build] interface.swift:4:8: error: no such module 'mlx_window'
[build] mlx_init.swift:4:8: error: no such module 'mlx_window'
[build] import mlx_window
[build]        ^
[build] import mlx_window
[build]        ^
[build] mlx_window.swift:7:8: error: no such module 'mlx_image'
[build] import mlx_image
[build]        ^

 
하지만 miniLibX 라이브러리는 컴파일시 병렬 처리를 하게되면 mlx_image.swift, mlx_window.swift, mlx_init.swift, interface.swift 파일을 컴파일할 때 모듈을 참조할 수 없다는 오류가 발생합니다.
 

COMMAND make -C ${minilibx_SOURCE_DIR} -j1

 
따라서 컴파일시 스레드 개수를 1개로 제한하여 모듈 참조 오류를 해결했습니다.
 

miniLibX의 macOS 의존성

저희가 사용한 miniLibX는 miniLibX_mms_20210621 버전입니다. 해당 라이브러리는 macOS에서만 동작하고, 우분투에서 사용하려면 miniLibX_linux가 별도로 필요합니다. 저희 클러스터 환경은 macOS이기 때문에 github action의 Runner 환경을 macOS로 변경했습니다.
 

jobs:
  run-tests:
    runs-on: macos-latest

    steps:
      # ...
      - name: 🛒 Install build-essentials
        run: brew install gcc cmake make gcovr
      # ...
jobs:
  check-norminette:
    runs-on: macos-latest

    steps:
      # ...
      - name: 🛒 Install 42-norminette
        run: |
          python3 -m venv norminette_venv
          source norminette_venv/bin/activate
          python3 -m pip install --upgrade pip setuptools
          python3 -m pip install --upgrade norminette
      # ...


  check-compile-flags:
    runs-on: macos-latest

    steps:
      # ...
      - name: 🛒 Install build-essentials
        run: brew install gcc make
      # ...

 
워크플로의 runs-os를 macos-latest로 설정하고, 필요한 패키지는 brew를 사용해서 설치합니다. norminette의 경우 python3 버전이 맞지 않아서 norminette_venv 가상환경에서 동작하도록 설정했습니다.
 

swiftmodule 컴파일 에러

마지막으로 Github Acation에서 컴파일시 swiftmodule 컴파일 오류가 발생했습니다.
 

SwiftDriverExecution/MultiJobExecutor.swift:207: Fatal error: multiple producers for output mlx_image.swiftmodule: Compiling mlx_image mlx_image.swift & Emitting module for mlx_image

 
이는 -o로 생성된 swiftmodule 파일 이름-emit-module로 생성된 swiftmodule 파일의 이름이 동일하기 때문에 발생하는 오류입니다. 이를 해결하기 위해서는 miniLibX 라이브러리의 Makefile을 수정해야합니다.
 

  • before
%.swiftmodule: %.swift
	swiftc $(OPTI) $(INC) -parse-as-library -c $< -o $@ -emit-module -module-name $(patsubst %.swift,%,$<) -module-link-name $(patsubst %.swift,%,$<)

 

  • after
%.swiftmodule: %.swift
	swiftc $(OPTI) $(INC) -parse-as-library -c $< -emit-module -module-name $(patsubst %.swift,%,$<) -module-link-name $(patsubst %.swift,%,$<)

 
위와 같이 %.swiftmodule 컴파일 규칙에서  -o -@를 제거해서 -emit-module로만 swiftmodule을 생성할 수 있도록 수정했습니다.

반응형