101 lines
9.1 KiB
Markdown
101 lines
9.1 KiB
Markdown
# MSVC 빌드 접근 오류와 Ninja 전환
|
|
|
|
- 작성 목적: MITC4 질량행렬·FEAST 구현 준비 중 발생한 Windows 빌드 환경 오류와 조치 기록
|
|
- Feature ID: `mitc4-shell-feast-eigen`
|
|
- Owner: `Root` (사용자 요청 설명문서)
|
|
- 입력 계약: `r2`, 구현 환경 `E8`
|
|
- 작성일: 2026-09-06
|
|
- 상태: MSVC 컴파일·링크 및 후속 CTest 통과 확인. 최초 GoogleTest discovery 오류와 wrapper 비정상 종료로 전체 준비 검증 미완료
|
|
|
|
MSVC 컴파일러와 x64/Debug 조건을 유지하면서 CMake의 빌드 generator를 Visual Studio에서 프로젝트가 이미 지원하는 Ninja로 바꿨다. 기본 `workspace-write` 권한에서 MSVC 컴파일·링크까지 진행했고, 이후 별도 GoogleTest discovery 문제를 확인했다. 최초 manual 빌드가 실패했으므로 전체 준비 검증은 아직 완료되지 않았다.
|
|
|
|
## 관찰된 오류
|
|
|
|
Visual Studio generator의 다음 명령이 native `workspace-write` 실행에서 실패했다.
|
|
|
|
```powershell
|
|
cmake --build .harness/build --config Debug
|
|
```
|
|
|
|
오류는 C++ 컴파일 전에 `ZERO_CHECK`의 `GetOutOfDateItems` 작업에서 발생했다.
|
|
|
|
```text
|
|
MSB4018: GetOutOfDateItems
|
|
System.TypeInitializationException: Microsoft.Build.Utilities.FileTracker
|
|
System.UnauthorizedAccessException: 0x80070005 (E_ACCESSDENIED)
|
|
Microsoft.Build.Framework.NativeMethods.GetLongFilePath
|
|
Microsoft.Build.Utilities.FileTracker..cctor()
|
|
```
|
|
|
|
같은 실행에서 configure는 성공했지만 manual Debug build는 exit 1이었다. 별도로 등록된 Stop의 build와 CTest는 성공했다. 따라서 자동 검증의 성공으로 native manual build 실패를 통과 처리하지 않았다.
|
|
|
|
확인된 범위는 MSBuild의 FileTracker 초기화에서 발생하는 접근 오류다. 어떤 Windows 접근 규칙과 정확한 내부 경로가 거부됐는지까지 확정한 것은 아니다.
|
|
|
|
## 앞선 조치와 구분해야 할 문제
|
|
|
|
1. 최초 configure의 `FESA_GTEST_SOURCE_DIR` 누락은 사용자 지정 `C:/git/googletest`와 설치된 MKL/TBB/HDF5 경로로 해결했다.
|
|
2. 긴 TEMP 경로에서 기존 pressure 테스트의 결과 잠금 파일 생성이 실패했다. 동일 binary의 TEMP 경로만 바꾼 비교에서 긴 경로는 실패하고 짧은 경로는 통과했다. 이후 TEMP/TMP는 새 `.harness/build/t-<8hex>`, pytest basetemp는 새 `.harness/build/p-<8hex>`를 사용하고 각각 80자 이하를 확인한다.
|
|
3. 짧은 TEMP/TMP를 build와 같은 native shell에 직접 설정해도 FileTracker 접근 오류가 재발했다. 따라서 TEMP 대입 누락이나 경로 길이 문제만으로 이 빌드 오류를 설명하지 않는다.
|
|
|
|
## 적용한 Ninja 구성
|
|
|
|
- 기존 `windows-msvc-ninja-debug` configure/build/test preset을 함께 사용한다.
|
|
- `.harness/config.example.json`의 설정을 ignored `.harness/config.json`으로 사용한다. 예상 밖 기존 설정은 덮어쓰지 않는다.
|
|
- 새 binary directory는 `.harness/build-ninja-msvc-debug`다. 기존 VS `.harness/build` cache와 실행 기록을 보존한다.
|
|
- Harness를 시작하는 부모 shell에서 설치된 `Launch-VsDevShell.ps1`로 MSVC host/target x64 환경을 설정하고 Ninja 및 승인된 dependency 경로를 적용한다. 이번 실행의 자식 tool shell에서는 해당 스크립트 호출이 PowerShell 실행 정책으로 거부됐다. 실행 정책을 우회하지 않고 부모에서 상속된 `VSINSTALLDIR`, `VSCMD_ARG_TGT_ARCH=x64`, `INCLUDE`, `LIB`, `cl.exe`, `ninja.exe`를 확인한 뒤 컴파일·링크를 진행했다.
|
|
- 기존 reference helper가 실제 library의 수정 시각을 확인할 수 있도록 `CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG`를 새 build의 `src/fesa/Debug`로 지정한다. Library를 복사하거나 수정 시각을 조작하지 않는다.
|
|
- 환경 변수는 해당 process에서만 설정하고 `finally`에서 복원한다. 정확한 설정·복원과 실행 순서는 [구현 환경 문서 E8](implementation-environment.md#e8-attempt3-후의-정상-backend-대안)에 있다.
|
|
|
|
환경을 적용한 shell에서 핵심 검증 명령은 다음과 같다.
|
|
|
|
```powershell
|
|
$mfeArchive = (Join-Path (Get-Location).Path '.harness/build-ninja-msvc-debug/src/fesa/Debug').Replace('\', '/')
|
|
cmake --preset windows-msvc-ninja-debug "-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG=$mfeArchive"
|
|
cmake --build --preset windows-msvc-ninja-debug
|
|
ctest --preset windows-msvc-ninja-debug --show-only=json-v1
|
|
ctest --preset windows-msvc-ninja-debug --output-on-failure
|
|
```
|
|
|
|
실제 실행에서는 각 명령의 종료 코드를 즉시 확인하고 실패 시 다음 검증으로 진행하지 않는다. Registered Stop도 같은 preset과 binary directory를 사용한다. Test selection, assertion, source, 수치 계약, reference 원본과 검증 기준은 이 환경 전환에서 변경하지 않는다.
|
|
|
|
## 검증 결과
|
|
|
|
| 확인 항목 | 결과 |
|
|
| --- | --- |
|
|
| 짧은 TEMP를 직접 적용한 기존 native MSBuild | configure exit 0, build exit 1 (`E_ACCESSDENIED`) |
|
|
| 위 실행의 별도 registered Stop/CTest | exit 0, 362/362 통과 |
|
|
| Root의 새 Ninja 준비 configure | exit 0, 7.446초; MSVC Hostx64/x64, Debug, Ninja 및 dependency 경로 확인 |
|
|
| Root configure 전후 보존 확인 | tracked 변경 0, 기존 VS cache 동일, Git clean |
|
|
| 새 Ninja native Debug build | 컴파일 경고 0개; 컴파일·링크 이후 integration GoogleTest discovery의 JSON parsing 오류로 exit 1 |
|
|
| 새 Ninja manual CTest/full pytest | 최초 manual build 실패 뒤 미실행 |
|
|
| 새 Ninja registered 검증의 CMake/CTest | build exit 0, CTest exit 0, 362/362 통과 |
|
|
| 위 registered 검증을 감싼 프로세스 | Python 두 프로세스 exit 0, 외부 PowerShell wrapper exit 1; 전체 Hook 성공으로 합치지 않음 |
|
|
| E8.2 Harness invocation | native PowerShell exit 1; manual build 실패를 보존 |
|
|
|
|
Root의 configure 성공이나 후속 CTest 통과는 최초 manual build 실패를 대체하지 않는다. 이 결과만으로 전체 준비 단계의 통과를 주장하지 않는다. 세부 구현 담당 보고서는 [implementation-prep-evidence.md](implementation-prep-evidence.md)를 참조한다.
|
|
|
|
## Ninja에서 추가로 발견된 검증 장애
|
|
|
|
새 Ninja 빌드에서는 기존 FileTracker 접근 오류 대신, 컴파일·링크 후 CMake의 GoogleTest 목록 생성에서 `ParseTestList.cmake:96` JSON parsing 오류가 발생했다. 현재 설치된 모듈 조합을 읽어 다음을 확인했다.
|
|
|
|
- `GoogleTestAddTests.cmake`는 `TEST_TARGET`의 SHA-256 앞 10자를 JSON 파일명으로 사용한다.
|
|
- `GoogleTest.cmake`와 실제 생성된 세 discovery 스크립트에는 `TEST_TARGET` 인수가 없다.
|
|
- 세 스크립트가 같은 디렉터리의 `cmake_test_discovery_e3b0c44298.json`을 삭제·생성·읽는 구조다.
|
|
- 동일 integration binary의 단독 목록 생성은 34개 테스트를 반환했고, 생성된 discovery 스크립트도 단독 실행에서는 통과했다.
|
|
|
|
이 관찰은 병렬 POST_BUILD discovery의 공유 파일 경쟁을 뒷받침한다. 정확한 최초 경쟁 순서를 재현한 것은 아니며, 단독 진단의 성공으로 최초 전체 빌드 실패를 통과 처리하지 않았다. 설치된 모듈·생성된 JSON·테스트 소스를 고치거나 discovery를 끄지 않고 정상적인 빌드 병렬도 설정을 후속 환경 조치로 검토한다.
|
|
|
|
## 근거 기록
|
|
|
|
- [동일 native build shell의 TEMP/TMP 설정과 FileTracker 실패](../../.harness/build/mitc4-eigen-evidence/prep/attempt3/root-manual-build-environment-observation.json)
|
|
- [새 Ninja 환경 준비 결과](../../.harness/build/mitc4-eigen-evidence/prep/attempt3/e8-root-setup/result.json), [실제 선택된 compiler·dependency·archive 경로](../../.harness/build/mitc4-eigen-evidence/prep/attempt3/e8-root-setup/configuration-observation.json)
|
|
- [최초 Ninja manual build 원시 로그](../../.harness/build/mitc4-eigen-evidence/prep/attempt4/manual-cmake-d2d41bcf6bb242f4b484ea02850d762e/build.log): UTF-16LE, SHA-256 `47484e659a73977626c549fb56783ad5416ff14260e48e559b37b6b93f358f96`
|
|
- [설치된 CMake 모듈과 생성된 discovery 경로의 읽기 전용 감사](../../.harness/build/mitc4-eigen-evidence/prep/attempt4/root-gtest-discovery-path-observation.json): SHA-256 `9d383f04a347df95b742403ceca4732b331ddf4ec96437993f0ceffaa060bf59`
|
|
- [실제 프로세스 종료 관찰](../../.harness/build/mitc4-eigen-evidence/prep/attempt4/root-process-observations.json): CMake PID `1916`, CTest `21912`, Python `3492`/`24968`, 외부 wrapper `23560`, Harness 부모 `21996`을 command·parent와 함께 대조했다. 파일의 `role`은 탐색용 분류다. `rg` 소스 조회 shell인 PID `10528`은 Hook 실행에서 제외한다.
|
|
|
|
이 원시 로그는 해당 workspace의 ignored 검증 artifact다. 장기 workflow 상태와 후속 실행 판정은 [coordination.md](coordination.md)를 기준으로 한다.
|
|
|
|
## 설정 수명
|
|
|
|
이 환경은 process 단위다. Root의 준비 명령이 종료돼도 다른 shell에 dependency 환경이 지속된다고 가정할 수 없다. 이후 개발 shell에는 같은 MSVC/dependency 환경을 적용해야 하며, feature 종료 때 local 설정의 유지·원상복구와 Root outer Stop 환경을 별도로 확인한다.
|