[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을 생성할 수 있도록 수정했습니다.
'C & C++' 카테고리의 다른 글
[C/C++] C 언어에서 상속과 다형성 구현하기 (0) | 2024.07.29 |
---|---|
[C/C++] 개발 환경 구성하기 04 (github action, norminette, codecov) (1) | 2024.07.22 |
[C/C++] 개발 환경 구성하기 03 (gcovr, codecov) (0) | 2024.07.22 |
[C/C++] 개발 환경 구성하기 02 (cmake, libft, google test) (1) | 2024.07.22 |
[C/C++] 개발 환경 구성하기 01 (아키텍처 설계, 브랜치 전략) (0) | 2024.07.21 |