.PHONY: help setup install compress run clean test dev check-deps status # 기본 설정 PYTHON := uv run python UV := uv VOICEBANK_DIR := voice/hanseol CVC COMPRESSED_FILE := voice/hanseol_CVC_compressed.h5 PORT := 7860 # 기본 타겟 help: ## 도움말 출력 @echo "🎵 UTAU WebUI - 개발 환경 자동화 도구" @echo "" @echo "📋 사용 가능한 명령어:" @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' @echo "" @echo "🚀 빠른 시작:" @echo " 1. make setup # 개발 환경 설정" @echo " 2. make compress # 보이스뱅크 압축" @echo " 3. make run # 웹UI 실행" @echo "" setup: ## 개발 환경 초기 설정 @echo "🔧 개발 환경을 설정합니다..." @if ! command -v uv >/dev/null 2>&1; then \ echo "❌ uv가 설치되지 않았습니다. https://docs.astral.sh/uv/ 에서 설치하세요."; \ exit 1; \ fi @echo "📦 의존성을 설치합니다..." $(UV) sync @echo "📁 필요한 디렉토리를 생성합니다..." @mkdir -p voice @echo "✅ 개발 환경 설정 완료!" install: setup ## setup의 별칭 check-deps: ## 의존성 및 환경 확인 @echo "🔍 환경을 확인합니다..." @echo "UV 버전: $$($(UV) --version 2>/dev/null || echo '❌ uv 없음')" @echo "Python 버전: $$($(PYTHON) --version 2>/dev/null || echo '❌ Python 없음')" @if [ -f "$(COMPRESSED_FILE)" ]; then \ echo "✅ 압축된 보이스뱅크: $(COMPRESSED_FILE)"; \ $(PYTHON) -c "import h5py; f=h5py.File('$(COMPRESSED_FILE)', 'r'); print(f'📊 메타데이터: {dict(f[\"metadata\"].attrs)}')"; \ else \ echo "❌ 압축된 보이스뱅크가 없음: $(COMPRESSED_FILE)"; \ fi @if [ -d "$(VOICEBANK_DIR)" ]; then \ echo "✅ 원본 보이스뱅크: $(VOICEBANK_DIR) ($$(find "$(VOICEBANK_DIR)" -name "*.wav" | wc -l)개 WAV 파일)"; \ else \ echo "❌ 원본 보이스뱅크가 없음: $(VOICEBANK_DIR)"; \ fi compress: ## 보이스뱅크를 HDF5 형태로 압축 @echo "🗜️ 보이스뱅크를 압축합니다..." @if [ ! -d "$(VOICEBANK_DIR)" ]; then \ echo "❌ 원본 보이스뱅크를 찾을 수 없습니다: $(VOICEBANK_DIR)"; \ echo "📋 해결 방법:"; \ echo " 1. hanseol CVC 보이스뱅크를 $(VOICEBANK_DIR) 에 배치"; \ echo " 2. 또는 다른 보이스뱅크를 사용하려면:"; \ echo " make compress VOICEBANK_DIR=your/voicebank/path"; \ exit 1; \ fi @echo "📁 원본 위치: $(VOICEBANK_DIR)" @echo "💾 압축 파일: $(COMPRESSED_FILE)" $(PYTHON) -c "\ from voice_data_converter import convert_voicebank_to_compressed_format; \ success = convert_voicebank_to_compressed_format('$(VOICEBANK_DIR)', '$(COMPRESSED_FILE)'); \ print('✅ 압축 완료!' if success else '❌ 압축 실패')" @echo "🎉 보이스뱅크 압축이 완료되었습니다!" run: ## 웹UI 실행 @echo "🚀 UTAU WebUI를 시작합니다..." @if [ ! -f "$(COMPRESSED_FILE)" ]; then \ echo "❌ 압축된 보이스뱅크가 없습니다."; \ echo "📋 먼저 다음 명령어를 실행하세요: make compress"; \ exit 1; \ fi @echo "🌐 웹 브라우저에서 http://localhost:$(PORT) 을 열어주세요" $(PYTHON) webui.py dev: ## 개발 모드로 실행 (auto-reload) @echo "🔧 개발 모드로 UTAU WebUI를 시작합니다..." @if [ ! -f "$(COMPRESSED_FILE)" ]; then \ echo "❌ 압축된 보이스뱅크가 없습니다."; \ echo "📋 먼저 다음 명령어를 실행하세요: make compress"; \ exit 1; \ fi @echo "🌐 웹 브라우저에서 http://localhost:$(PORT) 을 열어주세요" @echo "🔄 파일 변경 시 자동으로 재시작됩니다" $(UV) run --env GRADIO_AUTO_RELOAD=1 python webui.py test: ## 압축된 보이스뱅크 테스트 @echo "🧪 압축된 보이스뱅크를 테스트합니다..." @if [ ! -f "$(COMPRESSED_FILE)" ]; then \ echo "❌ 압축된 보이스뱅크가 없습니다: $(COMPRESSED_FILE)"; \ echo "📋 먼저 다음 명령어를 실행하세요: make compress"; \ exit 1; \ fi $(PYTHON) test_compressed_voicebank.py status: ## 현재 상태 확인 @echo "📊 UTAU WebUI 상태" @echo "====================" @make check-deps @echo "" @if [ -f "$(COMPRESSED_FILE)" ] && [ -d "$(VOICEBANK_DIR)" ]; then \ echo "🎉 모든 준비가 완료되었습니다! 'make run'으로 시작하세요."; \ elif [ -f "$(COMPRESSED_FILE)" ]; then \ echo "✅ 압축된 보이스뱅크가 준비되었습니다! 'make run'으로 시작하세요."; \ elif [ -d "$(VOICEBANK_DIR)" ]; then \ echo "⚠️ 보이스뱅크가 있지만 압축되지 않았습니다. 'make compress'를 실행하세요."; \ else \ echo "❌ 보이스뱅크가 없습니다. 먼저 보이스뱅크를 준비하고 'make compress'를 실행하세요."; \ fi clean: ## 임시 파일 및 캐시 정리 @echo "🧹 임시 파일을 정리합니다..." @find . -type f -name "*.pyc" -delete 2>/dev/null || true @find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true @find . -type f -name "*.tmp" -delete 2>/dev/null || true @find . -type f -name ".DS_Store" -delete 2>/dev/null || true @rm -rf .pytest_cache 2>/dev/null || true @echo "✅ 정리 완료!" clean-all: clean ## 모든 생성된 파일 삭제 (압축 파일 포함) @echo "🗑️ 모든 생성된 파일을 삭제합니다..." @if [ -f "$(COMPRESSED_FILE)" ]; then \ echo "⚠️ 압축된 보이스뱅크도 삭제됩니다: $(COMPRESSED_FILE)"; \ read -p "계속하시겠습니까? (y/N): " confirm; \ if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \ rm -f "$(COMPRESSED_FILE)"; \ echo "✅ 모든 파일이 삭제되었습니다."; \ else \ echo "❌ 취소되었습니다."; \ fi \ else \ echo "✅ 정리할 파일이 없습니다."; \ fi # 개발자를 위한 추가 명령어 update: ## 의존성 업데이트 @echo "📦 의존성을 업데이트합니다..." $(UV) sync --upgrade @echo "✅ 업데이트 완료!" shell: ## 프로젝트 쉘 진입 @echo "🐚 프로젝트 쉘에 진입합니다..." $(UV) shell info: ## 프로젝트 정보 출력 @echo "📋 UTAU WebUI 프로젝트 정보" @echo "============================" @echo "프로젝트: UTAU WebUI" @echo "설명: 한국어 CVC 보이스뱅크를 사용한 웹 기반 UTAU 음성 합성기" @echo "기술 스택: Python, Gradio, HDF5, UV" @echo "포트: $(PORT)" @echo "보이스뱅크: $(VOICEBANK_DIR)" @echo "압축 파일: $(COMPRESSED_FILE)" @echo "" @echo "📁 디렉토리 구조:" @find . -maxdepth 2 -type f -name "*.py" | head -10 @echo "" # 전체 워크플로우 all: setup compress run ## 전체 설정 및 실행 (setup → compress → run) # 기본 타겟을 help로 설정 .DEFAULT_GOAL := help