Development Environment Setting for Mac

6 minute read

Written by SGLee, VCANUS

1. Basic Tools

1.1 XCode

install XCode

  • install Xcode on App Store
  • install XCode Command Line Tools: command line tools가 이미 설치되어 있으면 필요 없음
    $ xcode-select --install
    
  • install XCode in App Store

1.2 Homebrew

install homebrew

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

add path to .zshrc

  • terminal에서 homebrew 설치 경로 확인 후 HOMEBREW_HOME 변수를 .zshrc에 추가
    # for arm chip
    export HOMEBREW_HOME="/opt/homebrew"
    # for intel chip
    #export HOMEBREW_HOME="/usr/local/Homebrew"
    export PATH="$HOMEBREW_HOME/bin:$PATH"
    export PATH="$HOMEBREW_HOME/sbin:$PATH"
    
  • .zshrc 수정 후 시스템 반영 필요
    cd
    source .zshrc
    
  • 이하 .zhrc 파일 내용 ```

    for arm chip

    export HOMEBREW_HOME=”/opt/homebrew”

    for intel chip

    #export HOMEBREW_HOME=”/usr/local/Homebrew”

jenv config

export PATH=”$HOME/.jenv/bin:$PATH”

#export ANDROID_HOME=”/Users/«user_id»/Library/Android/sdk”

export PATH=”$HOMEBREW_HOME/bin:$PATH” export PATH=”$HOMEBREW_HOME/sbin:$PATH” export PATH=”$JAVA_HOME/bin:$PATH” export PATH=”$HOME/.pyenv/bin:$PATH” export PATH=”$HOMEBREW_HOME/opt/curl/bin:$PATH” #export PATH=”ANDROID_HOME:$PATH” #export PATH=”/Users/«user_id»/Library/Python/3.8/bin:$PATH” #export PATH=”/Users/«user_id»/virtualenvs/jupyter/bin:$PATH” #export PATH=”/Applications/CMake.app/Contents/bin:$PATH”

poetry

#export PATH=”/Users/«user_id»/Library/Application\ Support/pypoetry/venv/bin:$PATH”

essential for x86 mac

#export CPLUS_INCLUDE_PATH=”/usr/local/include” #export LIBRARY_PATH=”/usr/local/lib”

essential for arm mac

export CPLUS_INCLUDE_PATH=”/opt/homebrew/include” export LIBRARY_PATH=”/opt/homebrew/lib”

for android development

#export PATH=$PATH:$ANDROID_HOME/emulator #export PATH=$PATH:$ANDROID_HOME/tools #export PATH=$PATH:$ANDROID_HOME/tools/bin #export PATH=$PATH:$ANDROID_HOME/platform-tools

eval “$(jenv init -)”

»> conda initialize »>

!! Contents within this block are managed by ‘conda init’ !!

__conda_setup=”$(‘/Users/«user_id»/miniconda3/bin/conda’ ‘shell.zsh’ ‘hook’ 2> /dev/null)” if [ $? -eq 0 ]; then eval “$__conda_setup” else if [ -f “/Users/«user_id»/miniconda3/etc/profile.d/conda.sh” ]; then . “/Users/«user_id»/miniconda3/etc/profile.d/conda.sh” else export PATH=”/Users/«user_id»/miniconda3/bin:$PATH” fi fi unset __conda_setup

«< conda initialize «<

The following lines have been added by Docker Desktop to enable Docker CLI completions.

fpath=(/Users/«user_id»/.docker/completions $fpath) autoload -Uz compinit compinit

End of Docker CLI completions

### 라이브러리 설치 전 homebrew 업데이트

$brew update


## Rosetta 2 (생략)
- Intel chip용으로 개발된 App을 Arm chip (M1, M2...) Mac에서 실행하기 위함
- 구형 App을 구동하기 위함이 아니면 설치 의미 없을 듯 (Pytorch 초기 버전에서 M1 chip을 지원하기 위해 Rosetta 설치가 필요한 적이 있었음)

sudo softwareupdate –install-rosetta


## 1.3 C/C++
### CMake 설치

$ brew install cmake

### curl, zlib
boost나 opencv 설치 시 기본적으로 필요함

$ brew install curl $ brew install zlib

### C/C++ 환경 설정
- C/C++ 기본 include 및 library 파일 경로 설정: .zshrc 파일 내 아래 내용 추가 필요

Arm 및 Intel 칩과 같이 칩 종류에 따라 homebrew 설치 경로 다름

export CPLUS_INCLUDE_PATH=”/opt/homebrew/include” export LIBRARY_PATH=”/opt/homebrew/lib” #

### Make 참고
- LDFLAGS 설정: 외부 library 사용 시 Linker가 참조하는 경로

-L을 시작(-L…)으로 여러 개의 경로를 공백으로 나영

LDFLAGS = -L/usr/local/lib -L/opt/mylibs -L/home/user/project/lib

LDFLAGS 사용하여 컴파일 및 링크하는 예시

g++ main.o -o myapp $(LDFLAGS) -lmylib

이렇게 하면 링커는 다음 순서대로 libmylib.so(또는 libmylib.a)를 찾습니다:

/usr/local/lib

/opt/mylibs

/home/user/project/lib

시스템 기본 경로(/usr/lib, /lib 등)

- CPPFLAGS, CXXFLGS, LDFLAGS, LDLIBS 정리

| 변수명          | 적용 단계 | 주요 역할                       | 예시 옵션                                                                                |
| ------------ | ----- | --------------------------- | ------------------------------------------------------------------------------------ |
| **CPPFLAGS** | 전처리기  | 헤더 경로 추가, 매크로 정의            | `-Iinclude` (헤더 폴더 지정)<br>`-DDEBUG` (매크로 정의)<br>`-UDEBUG` (매크로 해제)                   |
| **CXXFLAGS** | 컴파일러  | C++ 소스 컴파일 시 최적화, 경고, 표준 지정 | `-O2` (최적화)<br>`-Wall` (경고 표시)<br>`-std=c++20` (언어 표준)                               |
| **LDFLAGS**  | 링커    | 라이브러리 경로 및 링크 옵션 지정         | `-L/usr/local/lib` (라이브러리 경로 추가)<br>`-Wl,-rpath,./lib` (런타임 경로)<br>`-static` (정적 링크) |
| **LDLIBS**   | 링커    | 실제로 링크할 라이브러리 지정            | `-lm` (수학 라이브러리)<br>`-lpthread` (pthread)<br>`-lssl -lcrypto` (OpenSSL)              |

실제 사용하는 라이브러리 이름은 LDLIBS에 지정

LDFLAGS = -L/usr/local/lib -L./lib LDLIBS = -lm -lpthread

그럼 Makefile에서:

g++ main.o -o myapp $(LDFLAGS) $(LDLIBS)

- Make 참고 예시

CXX = g++ CPPFLAGS = -Iinclude -DDEBUG CXXFLAGS = -O2 -Wall -std=c++20 LDFLAGS = -L/usr/local/lib -L./lib LDLIBS = -lm -lpthread

TARGET = myapp OBJS = main.o util.o

$(TARGET): $(OBJS) $(CXX) $(OBJS) -o $@ $(LDFLAGS) $(LDLIBS)

clean: rm -f $(OBJS) $(TARGET)


### CMake 참고
- 디렉토리 구조

project-root/ ├── CMakeLists.txt ├── include/ # 헤더 파일 │ └── util.h ├── src/ # 애플리케이션 소스 │ ├── main.cpp │ └── util.cpp ├── tests/ # 테스트 코드 │ └── test_util.cpp └── build/ # 빌드 산출물 ├── Debug/ └── Release/


- CMake 참고 예시 (최상위 CMakeList.txt)

cmake_minimum_required(VERSION 3.15) project(MyApp CXX)

C++ 표준

set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON)

소스 파일

file(GLOB SRC_FILES ${CMAKE_SOURCE_DIR}/src/*.cpp)

메인 실행 파일

add_executable(myapp ${SRC_FILES})

——————————-

include 경로 설정

——————————-

PRIVATE: myapp 내부에서만 사용

PUBLIC: myapp을 링크하는 다른 target도 참조 가능 (예: 라이브러리 경우)

INTERFACE: myapp 자체는 사용하지 않고, 링크하는 쪽만 참조 가능

target_include_directories(myapp PRIVATE ${CMAKE_SOURCE_DIR}/include )

빌드 타입 기본값

if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING “Build type” FORCE) endif()

컴파일 옵션

set(CMAKE_CXX_FLAGS_DEBUG “-O0 -g3 -Wall”) set(CMAKE_CXX_FLAGS_RELEASE “-O2 -DNDEBUG -Wall”)

링커 옵션 (라이브러리 경로, LDFLAGS 해당)

target_link_directories(myapp PRIVATE /usr/local/lib ./lib)

실제 라이브러리 링크 (LDLIBS 해당)

target_link_libraries(myapp PRIVATE m pthread)

——————————-

GoogleTest 설정

——————————-

enable_testing() add_subdirectory(tests)


- 사용 방법

빌드 폴더 분리

mkdir -p build/Debug mkdir -p build/Release

Debug 빌드

cd build/Debug cmake -DCMAKE_BUILD_TYPE=Debug ../.. cmake –build .

Release 빌드

cd ../Release cmake -DCMAKE_BUILD_TYPE=Release ../.. cmake –build .

실행

./myapp


- CMake 참고 예시 (tests/CMakeList.txt)

include(FetchContent)

GoogleTest 자동 다운로드

FetchContent_Declare( googletest URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip ) set(gtest_force_shared_crt ON CACHE BOOL “” FORCE) FetchContent_MakeAvailable(googletest)

테스트 소스

file(GLOB TEST_SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)

테스트 실행 파일

add_executable(runTests ${TEST_SRC_FILES})

——————————-

include 경로

——————————-

PRIVATE: runTests 내부에서만 사용

target_include_directories(runTests PRIVATE ${CMAKE_SOURCE_DIR}/include )

GoogleTest 및 myapp 링크

target_link_libraries(runTests GTest::gtest_main myapp # myapp 내부 코드를 테스트할 때 링크 )

테스트 자동 등록

include(GoogleTest) gtest_discover_tests(runTests)


- 빌드 & 실행 방법

Debug 빌드

mkdir -p build/Debug && cd build/Debug cmake -DCMAKE_BUILD_TYPE=Debug ../.. cmake –build .

Release 빌드

mkdir -p ../Release && cd ../Release cmake -DCMAKE_BUILD_TYPE=Release ../.. cmake –build .

테스트 실행

cd ../Debug ctest

  
## 1.4 Java 

### AdoptOpenJdk: Deprecated
### Install Temurin (https://adoptium.net/installation/)

brew install –cask temurin@8 brew install –cask temurin@11 brew install –cask temurin@17 brew install –cask temurin@21

### jenv (java version switching tool)
#### install

brew install jenv

update .zshrc

jenv config

export PATH=”$HOME/.jenv/bin:$PATH” eval “$(jenv init -)”

#### register jdk path to jenv

jenv add /Library/Java/JavaVirtualMachines/temurin-8.jdk/Contents/Home jenv add /Library/Java/JavaVirtualMachines/temurin-11.jdk/Contents/Home jenv add /Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home jenv add /Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home

#### check installed java version

jenv versions

#### set default java version
설치된 java 버전 확인 후 설정

jenv global temurin64-17.0.16

#### enable jenv plugin

jenv enable-plugin export


## 1.5 Python
- 가상환경: conda 사용
- 패키지 관리: poetry 사용
- python 버전은 가상 환경에서 관리 (homebrew로 전역으로 사용하는 python 설치하지 말 것) 
- Target: Pytorch, OpenCV, Tensorflow   
https://developer.apple.com/metal/pytorch/
https://pytorch.org/get-started/locally/#mac-python
### Conda
- install miniconda: 필요한 최소 라이브러리 제공
- download: https://www.anaconda.com/download/success
- sh 파일 다운로드 후 설치

$chomod +x $sh


- conda 오류 해결 방법: "CondaToSNonInteractiveError: Terms of Service have not been accepted"

conda tos view # Vewing Terms of Service conda tos accept

  
- 사용 방법
create env

conda create -n {env-name} python={version}

remove env

conda env remove -n {env-name}

search env list

conda env list

activate/deactivate

conda activate {env-name} conda deactivate

### PyCharm에서 활용
#### conda env 생성
python 버전 설정으로 동일 환경 유지

conda create -n flowbroker python=3.11

#### PyCharm 설정
Settings > Projejct > Python Interpreter > Add Interpreter > Conda Environment > Use Existing Environment
#### PyCharm 프로젝트 내 패키지 설치
##### github repository
poetry로 설치, poetry add <package-name>

poetry add numpy

pip로 설치 (github 연동 패키지 설치)

pip install git+https://github.com/vcanus/vpy-util.git@develop pip install git+https://github.com/vcanus/vpy-communication-api.git@develop

##### 일반 패키지
가상 환경 내 설치 => poetry 사용 권장

conda install poetry add


### Jupyter
#### install Jupyter notebook
https://jupyter.org/install
https://towardsdatascience.com/how-to-set-up-anaconda-and-jupyter-notebook-the-right-way-de3b7623ea4a
https://bbooo.tistory.com/25

conda install -c conda-forge jupyterlab conda install -c conda-forge nb_conda_kernels

#### install libraries

conda activate {conda-env} conda install ipykernel

#### run Jupyter 

jupyter lab # run jupyter notebook


# 2. Essential libraries
### maven, openssl, etc.

#### install maven (필요 시 설치)

$ brew install maven

#### install openssl (참고만 하고 설치하지 말 것)

$ brew install openssl ==> intel chip openssl@1.1 is keg-only, which means it was not symlinked into /usr/local, because macOS provides LibreSSL.

If you need to have openssl@1.1 first in your PATH, run: echo ‘export PATH=”/usr/local/opt/openssl@1.1/bin:$PATH”’ » ~/.zshrc

For compilers to find openssl@1.1 you may need to set: export LDFLAGS=”-L/usr/local/opt/openssl@1.1/lib” export CPPFLAGS=”-I/usr/local/opt/openssl@1.1/include” ==> M1 chip openssl@1.1 is keg-only, which means it was not symlinked into /opt/homebrew, because macOS provides LibreSSL.

If you need to have openssl@1.1 first in your PATH, run: echo ‘export PATH=”/opt/homebrew/opt/openssl@1.1/bin:$PATH”’ » ~/.zshrc

For compilers to find openssl@1.1 you may need to set: export LDFLAGS=”-L/opt/homebrew/opt/openssl@1.1/lib” export CPPFLAGS=”-I/opt/homebrew/opt/openssl@1.1/include”


## Etc. libraries

brew install hiredis brew install boost brew search google brew install googletest brew install protobuf protobuf-c brew install cnats brew install protobuf protobuf-c brew install –cask flutter ```

Leave a comment