BUILD_TROUBLESHOOTING_PHILOSOPHY.md
╔══════════════════════════════════════════════════════════╗ ║ 🔍 TROUBLESHOOTING: LA ARQUEOLOGÍA DE ERRORES ║ ╚══════════════════════════════════════════════════════════╝
═══════════════════════════════════════════════════════════ 🧠 CAPÍTULO 1: TAXONOMÍA DE ERRORES DE BUILD ═══════════════════════════════════════════════════════════
🔷 LA JERARQUÍA TEMPORAL DE FALLOS
Los errores de build no son monolíticos. Ocurren en diferentes fases del proceso de construcción, cada una con características únicas, causas típicas, y estrategias de diagnóstico específicas.
Comprender EN QUÉ FASE ocurre un error es el primer paso crítico para resolverlo eficientemente.
⏰ BUILD PIPELINE - PUNTOS DE FALLO
┌─────────────────────────────────────────────────────────┐ │ │ │ USER INVOKES BUILD │ │ │ │ │ ├─────────────────────────────────┐ │ │ │ │ │ │ ▼ │ │ │ ┌──────────────────────┐ │ │ │ │ 🔴 PHASE 1 │ │ │ │ │ CONFIGURATION TIME │ │ │ │ │ │ │ │ │ │ CMake reads and │ ← 15% errors │ │ │ │ processes all │ │ │ │ │ CMakeLists.txt files │ │ │ │ └──────────────────────┘ │ │ │ │ │ │ │ │ Success? │ │ │ ├─ NO ──────────────────────────┐ │ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌──────────────────────┐ ❌ BUILD FAILED │ │ │ 🟡 PHASE 2 │ │ │ │ GENERATION TIME │ │ │ │ │ │ │ │ CMake creates native │ ← 5% errors │ │ │ build files │ │ │ │ (Makefiles, .sln, │ │ │ │ build.ninja) │ │ │ └──────────────────────┘ │ │ │ │ │ │ Success? │ │ ├─ NO ──────────────────────────┐ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────────────────┐ ❌ BUILD FAILED │ │ │ 🟠 PHASE 3 │ │ │ │ COMPILE TIME │ │ │ │ │ │ │ │ Compiler transforms │ ← 45% errors │ │ │ source code (.cpp) │ (MOST COMMON) │ │ │ into object files │ │ │ │ (.o, .obj) │ │ │ └──────────────────────┘ │ │ │ │ │ │ Success? │ │ ├─ NO ──────────────────────────┐ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────────────────┐ ❌ BUILD FAILED │ │ │ 🔴 PHASE 4 │ │ │ │ LINK TIME │ │ │ │ │ │ │ │ Linker combines │ ← 30% errors │ │ │ object files into │ (VERY COMMON) │ │ │ executables/libs │ │ │ └──────────────────────┘ │ │ │ │ │ │ Success? │ │ ├─ NO ──────────────────────────┐ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────────────────┐ ❌ BUILD FAILED │ │ │ 🟣 PHASE 5 │ │ │ │ POST-BUILD │ │ │ │ │ │ │ │ Code signing, │ ← 5% errors │ │ │ packaging, │ │ │ │ deployment prep │ │ │ └──────────────────────┘ │ │ │ │ │ ▼ │ │ ✅ BUILD SUCCESS │ │ │ └─────────────────────────────────────────────────────────┘
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 📊 ERROR FREQUENCY DISTRIBUTION ║ ║ ║ ║ Based on empirical data from large C++ projects: ║ ║ ║ ║ Configuration ████░░░░░░░░░░░░░░░░░░ 15% ║ ║ Usually environment/setup issues ║ ║ ║ ║ Generation ██░░░░░░░░░░░░░░░░░░░░ 5% ║ ║ Rare, often platform-specific ║ ║ ║ ║ Compilation █████████████████░░░░░ 45% ║ ║ MOST COMMON - code errors ║ ║ ║ ║ Linking ███████████░░░░░░░░░░░ 30% ║ ║ Second most common, trickier ║ ║ ║ ║ Post-build ██░░░░░░░░░░░░░░░░░░░░ 5% ║ ║ Platform/tooling specific ║ ║ ║ ║ 🎯 KEY INSIGHT: ║ ║ 75% of errors occur in Compilation + Linking phases ║ ║ These are where troubleshooting skills matter most ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
🔷 PHASE 1: CONFIGURATION TIME ERRORS
CMake procesa CMakeLists.txt, detecta toolchain, busca dependencias.
CARACTERÍSTICAS: • Ocurren ANTES de cualquier compilación • Típicamente mensajes claros de CMake • Bloquean completamente el build • Generalmente problemas de setup/environment • Relativamente fáciles de diagnosticar
ERRORES TÍPICOS:
┌─────────────────────────────────────────────────────────┐ │ ❌ ERROR: CMake version too old │ │ │ │ Manifestación: │ │ CMake 3.10 or higher is required. You are running │ │ version 3.5 │ │ │ │ Causa raíz: │ │ cmake_minimum_required() especifica versión mayor │ │ que la instalada en sistema │ │ │ │ Conceptos involucrados: │ │ • Version detection │ │ • Feature compatibility │ │ • Toolchain requirements │ │ │ │ Solución conceptual: │ │ Actualizar CMake o reducir minimum required │ │ (si features usadas lo permiten) │ │ │ └─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐ │ ❌ ERROR: Compiler not found │ │ │ │ Manifestación: │ │ Could not find compiler for CXX │ │ CMAKE_CXX_COMPILER not set │ │ │ │ Causa raíz: │ │ CMake no puede detectar compilador C++ en PATH │ │ o no está instalado │ │ │ │ Conceptos involucrados: │ │ • Toolchain detection │ │ • Environment variables │ │ • PATH resolution │ │ • Cross-compilation setup │ │ │ │ Solución conceptual: │ │ Instalar compiler o especificar explícitamente: │ │ -DCMAKE_CXX_COMPILER=/path/to/compiler │ │ O usar toolchain file para cross-compilation │ │ │ └─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐ │ ❌ ERROR: Dependency not found │ │ │ │ Manifestación: │ │ Could not find package JUCE (required) │ │ find_package(JUCE) failed │ │ │ │ Causa raíz: │ │ Library no está instalada o CMake no la encuentra │ │ en sus search paths │ │ │ │ Conceptos involucrados: │ │ • Package discovery mechanism │ │ • CMAKE_PREFIX_PATH │ │ • Find modules vs Config files │ │ • Package manager integration │ │ │ │ Solución conceptual: │ │ Instalar dependency vía vcpkg/conan │ │ O especificar donde buscar: │ │ -DCMAKE_PREFIX_PATH=/path/to/library │ │ O usar FetchContent como fallback │ │ │ └─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐ │ ❌ ERROR: Invalid option value │ │ │ │ Manifestación: │ │ AUDIOLAB_BUILD_TYPE must be VST3 or AU, got INVALID │ │ │ │ Causa raíz: │ │ User provided invalid value for CMake option │ │ Validation logic detected inconsistency │ │ │ │ Conceptos involucrados: │ │ • CMake cache variables │ │ • Option validation │ │ • User input sanitization │ │ • Configuration constraints │ │ │ │ Solución conceptual: │ │ Corregir valor de opción │ │ Consultar documentación de opciones válidas │ │ Usar CMake presets para evitar errores manuales │ │ │ └─────────────────────────────────────────────────────────┘
DIAGNOSTIC STRATEGY FOR CONFIGURATION ERRORS:
┌─────────────────────────────────────────────────────────┐ │ │ │ 🔍 CONFIGURATION ERROR DIAGNOSTIC WORKFLOW │ │ │ │ 1️⃣ READ COMPLETE CMAKE OUTPUT │ │ CMake es verboso pero informativo │ │ El error suele estar claro │ │ │ │ 2️⃣ CHECK CMakeError.log │ │ Located in build/CMakeFiles/ │ │ Contains detailed failure information │ │ │ │ 3️⃣ VERIFY ENVIRONMENT │ │ • CMake version (cmake --version) │ │ • Compiler available (which g++/clang/cl) │ │ • Dependencies installed │ │ • Environment variables set │ │ │ │ 4️⃣ TEST IN ISOLATION │ │ • Fresh build directory │ │ • Minimal CMakeLists.txt │ │ • One dependency at a time │ │ │ │ 5️⃣ CONSULT DOCUMENTATION │ │ • CMake module docs │ │ • Package installation guide │ │ • Platform-specific requirements │ │ │ └─────────────────────────────────────────────────────────┘
🔷 PHASE 2: GENERATION TIME ERRORS
CMake transforma su representación interna en archivos de build nativos.
CARACTERÍSTICAS: • Configuration exitosa, pero generation falla • Menos comunes (~5% de errores) • A menudo platform-specific • Pueden ser transient (permissions, filesystem) • Difíciles de debuggear (menos visible)
ERRORES TÍPICOS:
┌─────────────────────────────────────────────────────────┐ │ ❌ ERROR: Generator not available │ │ │ │ Manifestación: │ │ CMake Error: Could not create named generator Ninja │ │ │ │ Causa raíz: │ │ Generator especificado no está instalado │ │ │ │ Solución conceptual: │ │ Instalar Ninja o cambiar a generator disponible │ │ cmake -G "Unix Makefiles" (lista: cmake --help) │ │ │ └─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐ │ ❌ ERROR: Path too long (Windows) │ │ │ │ Manifestación: │ │ Error writing output file │ │ Filename too long │ │ │ │ Causa raíz: │ │ Windows 260 character path limit │ │ Deep nesting de directorios │ │ │ │ Conceptos involucrados: │ │ • Windows MAX_PATH limitation │ │ • Path resolution │ │ • Build directory structure │ │ │ │ Solución conceptual: │ │ Usar build directory más cerca de root: │ │ C:/build/ en lugar de C:/very/deep/path/build/ │ │ O enable long paths en Windows registry │ │ O usar junction points │ │ │ └─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐ │ ❌ ERROR: Permission denied │ │ │ │ Manifestación: │ │ Cannot write to output directory │ │ Permission denied │ │ │ │ Causa raíz: │ │ Output directory no es writable │ │ Antivirus bloqueando writes │ │ Proceso anterior aún tiene lock │ │ │ │ Solución conceptual: │ │ Verificar permissions del directorio │ │ Cerrar procesos que tengan archivos abiertos │ │ Añadir excepción a antivirus │ │ │ └─────────────────────────────────────────────────────────┘
🔷 PHASE 3: COMPILE TIME ERRORS
El compilador transforma código fuente en object files.
CARACTERÍSTICAS: • 45% de todos los errores (MÁS COMÚN) • Típicamente problemas en código C++ • Mensajes de error pueden ser largos (templates!) • Line numbers apuntan a problema • Requieren entendimiento de C++
CATEGORÍAS DE ERRORES DE COMPILACIÓN:
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🎨 COMPILE ERROR TAXONOMY ║ ║ ║ ║ 🔸 SYNTAX ERRORS ║ ║ ══════════════ ║ ║ ║ ║ Violaciones gramaticales del lenguaje ║ ║ ║ ║ Ejemplos: ║ ║ • Missing semicolon ║ ║ • Mismatched braces/parentheses ║ ║ • Invalid token ║ ║ • Typo in keyword ║ ║ ║ ║ Características: ║ ║ • Compilador apunta exactamente al error ║ ║ • Mensaje claro: "expected ; before }" ║ ║ • Fácil de corregir una vez encontrado ║ ║ ║ ║ Diagnostic approach: ║ ║ → Leer mensaje de error ║ ║ → Ir a línea indicada ║ ║ → Buscar problema obvio ║ ║ ║ ║ 🔸 SEMANTIC ERRORS ║ ║ ═══════════════ ║ ║ ║ ║ Código sintácticamente correcto pero semánticamente ║ ║ inválido ║ ║ ║ ║ Ejemplos: ║ ║ • Type mismatch (int vs float*) ║ ║ • Undefined symbol ║ ║ • Const correctness violation ║ ║ • Template substitution failure ║ ║ • Overload resolution ambiguity ║ ║ ║ ║ Características: ║ ║ • Compilador explica QUÉ está mal ║ ║ • Puede requerir entender tipos ║ ║ • A veces mensajes largos (templates) ║ ║ ║ ║ Diagnostic approach: ║ ║ → Entender tipos involucrados ║ ║ → Verificar declaraciones ║ ║ → Simplificar expresión compleja ║ ║ ║ ║ 🔸 INCLUDE ERRORS ║ ║ ══════════════ ║ ║ ║ ║ Problemas con headers y includes ║ ║ ║ ║ Ejemplos: ║ ║ • Header not found ║ ║ • Circular include ║ ║ • Include order dependency ║ ║ • Macro conflict entre headers ║ ║ • Missing include guard ║ ║ ║ ║ Características: ║ ║ • Puede causar cascade de errores ║ ║ • Path issues confunden mensaje ║ ║ • Platform differences (case sensitivity) ║ ║ ║ ║ Diagnostic approach: ║ ║ → Verificar include paths (-I flags) ║ ║ → Check file existence y case ║ ║ → Preprocessor output para debug ║ ║ → Dependency graph de includes ║ ║ ║ ║ 🔸 TEMPLATE ERRORS ║ ║ ═══════════════ ║ ║ ║ ║ Errores en template instantiation/deduction ║ ║ ║ ║ Ejemplos: ║ ║ • SFINAE failure ║ ║ • Concept not satisfied (C++20) ║ ║ • Infinite template recursion ║ ║ • Missing typename/template keyword ║ ║ • Dependent name not resolved ║ ║ ║ ║ Características: ║ ║ • MENSAJES MUY LARGOS (páginas) ║ ║ • Backtrace de instantiation stack ║ ║ • Difícil encontrar causa raíz ║ ║ • Compilador C++ differences grandes ║ ║ ║ ║ Diagnostic approach: ║ ║ → Buscar ERROR primero en output ║ ║ → Ignorar instantiation noise ║ ║ → Simplificar template para aislar ║ ║ → Usar concepts (C++20) para mejor errors ║ ║ → Compiler explorer para comparar ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
EJEMPLO DE ERROR CASCADE:
Un error puede causar múltiples mensajes:
┌─────────────────────────────────────────────────────────┐
│ REAL ERROR (línea 10): │
│ Missing #include
🔷 PHASE 4: LINK TIME ERRORS
El linker combina object files en executable/library.
CARACTERÍSTICAS: • 30% de todos los errores (MUY COMÚN) • Más difíciles de diagnosticar que compile errors • Síntomas similares, causas muy diferentes • Requieren entender linking model • Platform/toolchain specific
ANATOMÍA DEL LINKING:
┌─────────────────────────────────────────────────────────┐ │ │ │ WHAT THE LINKER DOES │ │ │ │ Input: Collection of object files (.o, .obj) │ │ │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ main.o │ │ foo.o │ │ bar.o │ │ │ │ │ │ │ │ │ │ │ │ symbols:│ │ symbols:│ │ symbols:│ │ │ │ • main │ │ • foo() │ │ • bar() │ │ │ │ → foo() │ │ → bar() │ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ │ │ │ │ │ │ │ └────────────┴────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────┐ │ │ │ LINKER │ │ │ │ │ │ │ │ Tasks: │ │ │ │ 1. Resolve symbols │ │ │ 2. Combine sections │ │ │ 3. Relocate addresses │ │ │ 4. Generate executable │ │ └──────────┘ │ │ │ │ │ ▼ │ │ ┌──────────┐ │ │ │ myapp │ │ │ │ │ │ │ │ Complete │ │ │ │ binary │ │ │ └──────────┘ │ │ │ │ LINKER MUST: │ │ ✅ Find definition for every symbol referenced │ │ ✅ Ensure each symbol defined exactly once │ │ ✅ Resolve dependencies between objects │ │ ✅ Create final memory layout │ │ │ └─────────────────────────────────────────────────────────┘
ERRORES DE LINKING MÁS COMUNES:
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ ❌ ERROR ARCHETYPE #1: UNDEFINED REFERENCE ║ ║ ║ ║ Manifestación: ║ ║ ┌───────────────────────────────────────────────────┐ ║ ║ │ undefined reference to `Oscillator::process()' │ ║ ║ └───────────────────────────────────────────────────┘ ║ ║ ║ ║ ¿Qué significa? ║ ║ Código usa un símbolo (función/variable) que el linker ║ ║ no puede encontrar definido en ningún object file. ║ ║ ║ ║ Árbol de causas posibles: ║ ║ ║ ║ Undefined Reference ║ ║ │ ║ ║ ├─ 🔸 CAUSA A: Missing source file ║ ║ │ │ ║ ║ │ ├─ Función declarada en header ║ ║ │ ├─ Pero .cpp con implementación ║ ║ │ │ no agregado a CMake target ║ ║ │ │ ║ ║ │ └─ Solución conceptual: ║ ║ │ Add source to target_sources() ║ ║ │ ║ ║ ├─ 🔸 CAUSA B: Missing library ║ ║ │ │ ║ ║ │ ├─ Símbolo está en library externa ║ ║ │ ├─ Pero library no linkeada ║ ║ │ │ ║ ║ │ └─ Solución conceptual: ║ ║ │ Add to target_link_libraries() ║ ║ │ ║ ║ ├─ 🔸 CAUSA C: Wrong library order ║ ║ │ │ ║ ║ │ ├─ Libraries con circular deps ║ ║ │ ├─ Order matters en static linking ║ ║ │ │ ║ ║ │ └─ Solución conceptual: ║ ║ │ Reorder libs o link twice ║ ║ │ O usar shared libs (no order) ║ ║ │ ║ ║ ├─ 🔸 CAUSA D: Name mangling mismatch ║ ║ │ │ ║ ║ │ ├─ C++ mangle names ║ ║ │ ├─ extern "C" { } para C code ║ ║ │ ├─ Mismatch causa undefined ref ║ ║ │ │ ║ ║ │ └─ Solución conceptual: ║ ║ │ Consistent linkage specification ║ ║ │ Check with nm/objdump ║ ║ │ ║ ║ ├─ 🔸 CAUSA E: Inline function not inlined ║ ║ │ │ ║ ║ │ ├─ Función marcada inline ║ ║ │ ├─ Compiler decidió no inline ║ ║ │ ├─ No definition available ║ ║ │ │ ║ ║ │ └─ Solución conceptual: ║ ║ │ Define inline en header ║ ║ │ O remove inline keyword ║ ║ │ ║ ║ ├─ 🔸 CAUSA F: Template not instantiated ║ ║ │ │ ║ ║ │ ├─ Template definition en .cpp ║ ║ │ ├─ Usado desde otro TU ║ ║ │ ├─ No implicit instantiation ║ ║ │ │ ║ ║ │ └─ Solución conceptual: ║ ║ │ Move template to header ║ ║ │ O explicit instantiation ║ ║ │ ║ ║ └─ 🔸 CAUSA G: ABI mismatch ║ ║ │ ║ ║ ├─ Library built with different ║ ║ │ compiler/stdlib/flags ║ ║ ├─ Symbols exist but incompatible ║ ║ │ ║ ║ └─ Solución conceptual: ║ ║ Rebuild library with same toolchain║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
DIAGNOSTIC STRATEGY FOR UNDEFINED REFERENCE:
┌─────────────────────────────────────────────────────────┐ │ │ │ 🔍 STEP-BY-STEP DIAGNOSIS │ │ │ │ 1️⃣ DEMANGLE THE SYMBOL NAME │ │ │ │ Linux/macOS: │ │ c++filt '_ZN10Oscillator7processEv' │ │ → Oscillator::process() │ │ │ │ Windows MSVC: │ │ undname ?process@Oscillator@@QEAAXXZ │ │ → Oscillator::process(void) │ │ │ │ 2️⃣ VERIFY DECLARATION EXISTS │ │ │ │ Buscar en headers: │ │ grep -r "void process()" include/ │ │ │ │ Si NO existe → Typo o wrong class │ │ Si SÍ existe → Continue │ │ │ │ 3️⃣ VERIFY DEFINITION EXISTS │ │ │ │ Buscar en sources: │ │ grep -r "Oscillator::process()" src/ │ │ │ │ Si NO existe → Missing implementation │ │ Si SÍ existe → Continue │ │ │ │ 4️⃣ VERIFY FILE IN BUILD │ │ │ │ Check CMakeLists.txt: │ │ target_sources incluye oscillator.cpp? │ │ │ │ Si NO → Add to build │ │ Si SÍ → Continue │ │ │ │ 5️⃣ CHECK COMPILED OBJECT │ │ │ │ Verify symbol in .o file: │ │ nm oscillator.o | grep process │ │ objdump -t oscillator.o | grep process │ │ │ │ Si NO está → Compilation issue │ │ Si SÍ está → Linking issue │ │ │ │ 6️⃣ VERIFY LINK COMMAND │ │ │ │ Check linker includes oscillator.o: │ │ cmake --build . -- VERBOSE=1 │ │ │ │ Si NO incluye → CMake target issue │ │ Si SÍ incluye → ABI/mangling issue │ │ │ └─────────────────────────────────────────────────────────┘
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ ❌ ERROR ARCHETYPE #2: MULTIPLE DEFINITION ║ ║ ║ ║ Manifestación: ║ ║ ┌───────────────────────────────────────────────────┐ ║ ║ │ multiple definition of `globalConfig' │ ║ ║ │ first defined here │ ║ ║ └───────────────────────────────────────────────────┘ ║ ║ ║ ║ ¿Qué significa? ║ ║ Símbolo definido en múltiples object files. ║ ║ Linker no sabe cuál usar. ║ ║ ║ ║ One Definition Rule (ODR) violation ║ ║ ║ ║ Árbol de causas: ║ ║ ║ ║ Multiple Definition ║ ║ │ ║ ║ ├─ 🔸 CAUSA A: Missing inline/static ║ ║ │ │ ║ ║ │ ├─ Function defined in header ║ ║ │ ├─ Header included by multiple TUs ║ ║ │ ├─ Each TU gets copy ║ ║ │ ├─ Linker sees multiple definitions ║ ║ │ │ ║ ║ │ └─ Solución conceptual: ║ ║ │ Mark inline or static ║ ║ │ O move to single .cpp ║ ║ │ ║ ║ ├─ 🔸 CAUSA B: Variable in header ║ ║ │ │ ║ ║ │ ├─ Global variable in header ║ ║ │ ├─ Should be extern declaration ║ ║ │ ├─ Definition in one .cpp ║ ║ │ │ ║ ║ │ └─ Solución conceptual: ║ ║ │ Header: extern int myVar; ║ ║ │ One .cpp: int myVar = 0; ║ ║ │ ║ ║ ├─ 🔸 CAUSA C: Duplicate source in build ║ ║ │ │ ║ ║ │ ├─ Same .cpp added twice ║ ║ │ ├─ In different targets ║ ║ │ ├─ Both linked to final binary ║ ║ │ │ ║ ║ │ └─ Solución conceptual: ║ ║ │ Remove duplicate from CMake ║ ║ │ O make symbol static/anonymous ns ║ ║ │ ║ ║ └─ 🔸 CAUSA D: Library linked twice ║ ║ │ ║ ║ ├─ Same static library linked multiple ║ ║ ├─ Via different dependency paths ║ ║ │ ║ ║ └─ Solución conceptual: ║ ║ Check link dependencies ║ ║ Remove duplicate links ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
═══════════════════════════════════════════════════════════ 🎯 CAPÍTULO 2: METODOLOGÍA DE DIAGNÓSTICO SISTEMÁTICO ═══════════════════════════════════════════════════════════
🔷 EL PROCESO CIENTÍFICO APLICADO A BUILD ERRORS
Troubleshooting efectivo NO es trial-and-error aleatorio. Es un proceso sistemático, científico, reproducible.
🔬 THE DIAGNOSTIC WORKFLOW
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 📋 PHASE 1: OBSERVATION ║ ║ ══════════════════ ║ ║ ║ ║ "Gather ALL information before acting" ║ ║ ║ ║ ✅ Full error message ║ ║ • Don't just read first line ║ ║ • Read ENTIRE error output ║ ║ • Note all file names and line numbers ║ ║ • Look for patterns in multiple errors ║ ║ ║ ║ ✅ Context ║ ║ • What were you doing when error occurred? ║ ║ • What changed since last successful build? ║ ║ • Is error reproducible? ║ ║ • Does it occur on other machines? ║ ║ ║ ║ ✅ Build configuration ║ ║ • Build type (Debug/Release) ║ ║ • Platform (Windows/macOS/Linux) ║ ║ • Compiler version ║ ║ • CMake version ║ ║ • Dependencies versions ║ ║ ║ ║ ✅ Environment ║ ║ • Working directory ║ ║ • Environment variables ║ ║ • PATH contents ║ ║ • Disk space available ║ ║ ║ ║ 🎯 GOLDEN RULE: ║ ║ NEVER ASSUME ║ ║ Assumptions are the enemy of diagnosis ║ ║ Verify everything ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🎯 PHASE 2: CLASSIFICATION ║ ║ ═══════════════════ ║ ║ ║ ║ "Correctly identifying error type = 50% solved" ║ ║ ║ ║ Decision Tree: ║ ║ ║ ║ ¿Error output from CMake or compiler? ║ ║ │ ║ ║ ├─ CMake → Configuration/Generation error ║ ║ │ └─ Strategy: Fix environment/dependencies ║ ║ │ ║ ║ └─ Compiler/Linker ↓ ║ ║ ║ ║ ¿Compilation or linking phase? ║ ║ │ ║ ║ ├─ Compilation (.cpp → .o) ║ ║ │ ├─ File and line number shown ║ ║ │ ├─ Source code error ║ ║ │ └─ Strategy: Fix code at location ║ ║ │ ║ ║ └─ Linking (.o → exe) ↓ ║ ║ ├─ No line numbers ║ ║ ├─ Symbol-related ║ ║ └─ Strategy: Fix build configuration ║ ║ ║ ║ ¿Is it a known pattern? ║ ║ ├─ "undefined reference" → Missing link/source ║ ║ ├─ "multiple definition" → Duplicate symbol ║ ║ ├─ "cannot find -l" → Missing library ║ ║ ├─ "No such file" → Missing header/path ║ ║ └─ Unknown → Deep investigation needed ║ ║ ║ ║ 📊 PATTERN RECOGNITION: ║ ║ Build troubleshooting skill = library of patterns ║ ║ Each error you solve adds to your pattern database ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🔍 PHASE 3: ISOLATION ║ ║ ══════════════════ ║ ║ ║ ║ "Minimize problem to essential elements" ║ ║ ║ ║ BINARY SEARCH APPROACH: ║ ║ ║ ║ If error is in large codebase: ║ ║ ║ ║ ┌─────────────────────────────────────────┐ ║ ║ │ Full project │ ║ ║ │ ├─ 100 source files │ ║ ║ │ └─ Error occurs │ ║ ║ │ │ ║ ║ │ Step 1: Disable half │ ║ ║ │ ├─ Comment out 50 files from build │ ║ ║ │ └─ Does error still occur? │ ║ ║ │ │ │ ║ ║ │ ├─ YES → Problem in other half │ ║ ║ │ └─ NO → Problem in disabled half │ ║ ║ │ │ ║ ║ │ Step 2: Repeat until isolated │ ║ ║ │ Eventually: Single file causing issue │ ║ ║ └─────────────────────────────────────────┘ ║ ║ ║ ║ ISOLATION TECHNIQUES: ║ ║ ║ ║ ✂️ Comment out code ║ ║ Start from error location ║ ║ Remove code until error disappears ║ ║ What was last removed = likely cause ║ ║ ║ ║ 🎯 Disable targets ║ ║ CMake: comment add_subdirectory() ║ ║ Narrow down which component has issue ║ ║ ║ ║ 📦 Simplify dependencies ║ ║ Remove external libraries one by one ║ ║ Find if dependency causes issue ║ ║ ║ ║ 🆕 Fresh build directory ║ ║ rm -rf build/ && mkdir build ║ ║ Eliminates stale state issues ║ ║ ║ ║ 🧪 Minimal reproduction ║ ║ Create new tiny project ║ ║ Add only code that triggers error ║ ║ Share-able, debuggable ║ ║ ║ ║ 🎯 GOAL: ║ ║ Smallest change that makes error appear/disappear ║ ║ = Deep understanding of root cause ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════╗
║ ║
║ 🧪 PHASE 4: HYPOTHESIS ║
║ ═══════════════════ ║
║ ║
║ "Form testable theory based on observations" ║
║ ║
║ SCIENTIFIC METHOD: ║
║ ║
║ Based on symptoms, form hypothesis: ║
║ "If X is the cause, then Y should fix it" ║
║ ║
║ EXAMPLE 1: ║
║ ┌─────────────────────────────────────────┐ ║
║ │ Symptom: │ ║
║ │ undefined reference to JUCE::Audio' │ ║
║ │ │ ║
║ │ Observations: │ ║
║ │ • JUCE headers compile fine │ ║
║ │ • Only linking fails │ ║
║ │ • Symbol is from JUCE library │ ║
║ │ │ ║
║ │ Hypothesis: │ ║
║ │ "JUCE library not linked to target" │ ║
║ │ │ ║
║ │ Testable prediction: │ ║
║ │ "Adding JUCE::juce_audio to │ ║
║ │ target_link_libraries should fix" │ ║
║ │ │ ║
║ │ Test: Make that single change │ ║
║ └─────────────────────────────────────────┘ ║
║ ║
║ EXAMPLE 2: ║
║ ┌─────────────────────────────────────────┐ ║
║ │ Symptom: │ ║
║ │ multiple definition ofconfig' │ ║
║ │ │ ║
║ │ Observations: │ ║
║ │ • Global variable in header │ ║
║ │ • Header included by multiple .cpp │ ║
║ │ • Each TU gets copy │ ║
║ │ │ ║
║ │ Hypothesis: │ ║
║ │ "Variable defined in header without │ ║
║ │ inline/extern, causing ODR violation"│ ║
║ │ │ ║
║ │ Testable prediction: │ ║
║ │ "Making variable extern or inline │ ║
║ │ should resolve" │ ║
║ │ │ ║
║ │ Test: Try inline first │ ║
║ └─────────────────────────────────────────┘ ║
║ ║
║ 🎯 GOOD HYPOTHESIS: ║
║ • Based on evidence, not guessing ║
║ • Specific and testable ║
║ • Falsifiable (can prove wrong) ║
║ • Leads to concrete action ║
║ ║
╚═══════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ ⚗️ PHASE 5: EXPERIMENTATION ║ ║ ════════════════════ ║ ║ ║ ║ "Test hypothesis systematically" ║ ║ ║ ║ ⚠️ CRITICAL RULE: ║ ║ ONE CHANGE AT A TIME ║ ║ ║ ║ ❌ ANTI-PATTERN (Shotgun Debugging): ║ ║ • Change 5 things ║ ║ • Rebuild ║ ║ • Error gone ║ ║ • Which change fixed it? UNKNOWN ║ ║ • Learned nothing ║ ║ • Cannot explain to colleague ║ ║ • May have introduced new bugs ║ ║ ║ ║ ✅ CORRECT PATTERN (Systematic): ║ ║ 1. Make ONE change ║ ║ 2. Rebuild ║ ║ 3. Observe result ║ ║ 4. Document outcome ║ ║ 5. If not fixed, revert and try next ║ ║ ║ ║ EXPERIMENTAL WORKFLOW: ║ ║ ║ ║ ┌─────────────────────────────────────────┐ ║ ║ │ 1. Establish baseline │ ║ ║ │ Build and confirm error exists │ ║ ║ │ │ ║ ║ │ 2. Make single change │ ║ ║ │ Edit one file, one line if possible │ ║ ║ │ │ ║ ║ │ 3. Clean build │ ║ ║ │ Sometimes: rm -rf build/ │ ║ ║ │ Usually: ninja clean && ninja │ ║ ║ │ │ ║ ║ │ 4. Observe outcome │ ║ ║ │ ├─ Error gone? → Fixed! │ ║ ║ │ ├─ Error changed? → Progress │ ║ ║ │ ├─ Error same? → No effect │ ║ ║ │ └─ New error? → Broke something │ ║ ║ │ │ ║ ║ │ 5. Document │ ║ ║ │ Note what changed and result │ ║ ║ │ │ ║ ║ │ 6. Decide next step │ ║ ║ │ ├─ Fixed → Done, understand why │ ║ ║ │ ├─ Progress → Continue direction │ ║ ║ │ ├─ No effect → Revert, try different │ ║ ║ │ └─ Broke → Revert immediately │ ║ ║ └─────────────────────────────────────────┘ ║ ║ ║ ║ 💡 PRO TIP: ║ ║ Use version control for experiments ║ ║ git stash / git checkout -- file ║ ║ Easy to revert failed attempts ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 📝 PHASE 6: DOCUMENTATION ║ ║ ══════════════════════ ║ ║ ║ ║ "Learn from every error" ║ ║ ║ ║ When you solve an error, WRITE IT DOWN: ║ ║ ║ ║ 📋 ERROR LOG TEMPLATE: ║ ║ ║ ║ ┌─────────────────────────────────────────┐ ║ ║ │ Date: 2025-10-03 │ ║ ║ │ │ ║ ║ │ Error Message: │ ║ ║ │ undefined reference to │ ║ ║ │ `Oscillator::setFrequency(float)' │ ║ ║ │ │ ║ ║ │ Context: │ ║ ║ │ Adding new DSP module to project │ ║ ║ │ After merging feature branch │ ║ ║ │ │ ║ ║ │ Root Cause: │ ║ ║ │ oscillator.cpp not added to │ ║ ║ │ CMakeLists.txt target_sources() │ ║ ║ │ │ ║ ║ │ Solution: │ ║ ║ │ Added oscillator.cpp to │ ║ ║ │ audiolab_dsp target in │ ║ ║ │ src/dsp/CMakeLists.txt line 15 │ ║ ║ │ │ ║ ║ │ Prevention: │ ║ ║ │ • Check CMakeLists when adding .cpp │ ║ ║ │ • Consider using GLOB (with caveats) │ ║ ║ │ • Add to checklist in PR template │ ║ ║ │ │ ║ ║ │ Time to Solve: 15 minutes │ ║ ║ │ │ ║ ║ │ Lessons Learned: │ ║ ║ │ CMake doesn't auto-detect new files │ ║ ║ │ Always update build configuration │ ║ ║ └─────────────────────────────────────────┘ ║ ║ ║ ║ 💡 BENEFITS: ║ ║ • Future you will thank past you ║ ║ • Team learns from your experience ║ ║ • Builds organizational knowledge ║ ║ • Faster resolution next time ║ ║ • Can contribute to FAQs/docs ║ ║ ║ ║ 📚 BUILD KNOWLEDGE BASE: ║ ║ Over time, create searchable database ║ ║ of errors and solutions specific to ║ ║ your project (AudioLab) ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
═══════════════════════════════════════════════════════════ 🎭 CAPÍTULO 3: ATLAS DE PATRONES DE ERRORES ═══════════════════════════════════════════════════════════
🔷 TOP 15 BUILD ERROR ARCHETYPES
Cada error es único, pero patrones emergen. Este atlas documenta los arquetipos más comunes.
╔═══════════════════════════════════════════════════════════╗
║ ║
║ 🏆 ARCHETYPE #1: HEADER NOT FOUND ║
║ ║
║ Manifestación: ║
║ ┌───────────────────────────────────────────────────┐ ║
║ │ fatal error: AudioProcessor.h: No such file or │ ║
║ │ directory │ ║
║ └───────────────────────────────────────────────────┘ ║
║ ║
║ Frecuencia: ████████░░ (Very Common) ║
║ Phase: Compilation ║
║ Difficulty: ⭐⭐ (Easy to Moderate) ║
║ ║
║ Causas raíz (6 variants): ║
║ ║
║ 🔸 Variant A: Include path not configured ║
║ CMake no sabe dónde buscar headers ║
║ → target_include_directories() missing ║
║ ║
║ 🔸 Variant B: Dependency not found ║
║ find_package() failed (silently o no) ║
║ → Check CMake output for warnings ║
║ ║
║ 🔸 Variant C: Wrong include syntax ║
║ #include
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🏆 ARCHETYPE #2: UNDEFINED REFERENCE ║ ║ ║ ║ (Already covered in detail in Chapter 1) ║ ║ ║ ║ Frecuencia: ██████████ (Extremely Common) ║ ║ Phase: Linking ║ ║ Difficulty: ⭐⭐⭐ (Moderate to Hard) ║ ║ ║ ║ Key diagnostic: ║ ║ 1. Demangle symbol ║ ║ 2. Find declaration ║ ║ 3. Find definition ║ ║ 4. Verify in build ║ ║ 5. Check link libraries ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🏆 ARCHETYPE #3: MULTIPLE DEFINITION ║ ║ ║ ║ (Already covered in detail in Chapter 1) ║ ║ ║ ║ Frecuencia: ██████░░░░ (Common) ║ ║ Phase: Linking ║ ║ Difficulty: ⭐⭐ (Easy to Moderate) ║ ║ ║ ║ Key diagnostic: ║ ║ 1. Find all definitions of symbol ║ ║ 2. Check for header definitions ║ ║ 3. Verify inline/static/extern ║ ║ 4. Check for duplicate sources ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🏆 ARCHETYPE #4: CANNOT FIND LIBRARY ║ ║ ║ ║ Manifestación: ║ ║ ┌───────────────────────────────────────────────────┐ ║ ║ │ cannot find -ljuce_core │ ║ ║ │ ld: library not found for -ljuce_core │ ║ ║ └───────────────────────────────────────────────────┘ ║ ║ ║ ║ Frecuencia: ████████░░ (Very Common) ║ ║ Phase: Linking ║ ║ Difficulty: ⭐⭐ (Easy to Moderate) ║ ║ ║ ║ ¿Qué significa? ║ ║ Linker no puede encontrar archivo de library ║ ║ especificado en link command ║ ║ ║ ║ Causas posibles: ║ ║ ║ ║ 🔸 Library no está compilada ║ ║ Dependency no se buildó ║ ║ → Build dependency first ║ ║ ║ ║ 🔸 Library path incorrecto ║ ║ Linker no sabe dónde buscar ║ ║ → Add to link_directories() (old way) ║ ║ → Better: Use full path via target ║ ║ ║ ║ 🔸 Wrong library name ║ ║ Typo en nombre ║ ║ → Verify exact library file name ║ ║ ║ ║ 🔸 Wrong architecture ║ ║ 32-bit vs 64-bit mismatch ║ ║ → Rebuild for correct architecture ║ ║ ║ ║ 🔸 Wrong configuration ║ ║ Looking for Debug lib in Release build ║ ║ → Match configurations ║ ║ ║ ║ Diagnostic Steps: ║ ║ 1. Verify library file exists ║ ║ 2. Check library search paths ║ ║ 3. Verify architecture matches ║ ║ 4. Check configuration (Debug/Release) ║ ║ 5. Test with absolute path ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🏆 ARCHETYPE #5: ABI INCOMPATIBILITY ║ ║ ║ ║ Manifestación: ║ ║ ┌───────────────────────────────────────────────────┐ ║ ║ │ Varies: Sometimes no error, just crashes │ ║ ║ │ Sometimes: undefined reference despite lib linked │ ║ ║ │ Sometimes: symbol version mismatch │ ║ ║ └───────────────────────────────────────────────────┘ ║ ║ ║ ║ Frecuencia: ████░░░░░░ (Moderate) ║ ║ Phase: Linking or Runtime ║ ║ Difficulty: ⭐⭐⭐⭐ (Hard) ║ ║ ║ ║ ¿Qué es ABI? ║ ║ Application Binary Interface ║ ║ • Layout of data structures ║ ║ • Calling conventions ║ ║ • Name mangling ║ ║ • Exception handling ║ ║ ║ ║ Causas de incompatibilidad: ║ ║ ║ ║ 🔸 Mixed Debug/Release ║ ║ Some components Debug, others Release ║ ║ → Rebuild all with same configuration ║ ║ ║ ║ 🔸 Different compilers ║ ║ MSVC vs GCC, different versions ║ ║ → Use same compiler for all ║ ║ ║ ║ 🔸 Different C++ standard libraries ║ ║ libstdc++ vs libc++ ║ ║ → Consistent stdlib ║ ║ ║ ║ 🔸 Different compiler flags ║ ║ -fno-rtti, -fno-exceptions ║ ║ → Match flags across components ║ ║ ║ ║ 🔸 Different C runtime (Windows) ║ ║ /MD vs /MT vs /MDd vs /MTd ║ ║ → Use same CRT for all ║ ║ ║ ║ Prevention: ║ ║ • Build all components together ║ ║ • Use same toolchain ║ ║ • Use same configuration ║ ║ • Document ABI requirements ║ ║ ║ ║ 🎯 GOLDEN RULE: ║ ║ NEVER MIX ABIs ║ ║ Rebuild everything together with same settings ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════╗
║ ║
║ 🏆 ARCHETYPE #6: TEMPLATE ERROR AVALANCHE ║
║ ║
║ Manifestación: ║
║ ┌───────────────────────────────────────────────────┐ ║
║ │ [3000 lines of error output] │ ║
║ │ In instantiation of 'template
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🏆 ARCHETYPE #7: PATH TOO LONG (Windows) ║ ║ ║ ║ Manifestación: ║ ║ ┌───────────────────────────────────────────────────┐ ║ ║ │ Cannot create file │ ║ ║ │ The filename or extension is too long │ ║ ║ └───────────────────────────────────────────────────┘ ║ ║ ║ ║ Frecuencia: ████░░░░░░ (Common on Windows) ║ ║ Phase: Generation or Compilation ║ ║ Difficulty: ⭐⭐ (Easy once identified) ║ ║ ║ ║ ¿Por qué ocurre? ║ ║ Windows MAX_PATH = 260 characters (legacy) ║ ║ Build systems create deep paths ║ ║ C:/very/deep/path/build/CMakeFiles/target.dir/... ║ ║ ║ ║ Soluciones: ║ ║ ║ ║ 🔧 Short build path ║ ║ Use C:/b/ instead of C:/Users/Name/Projects/... ║ ║ Closer to drive root ║ ║ ║ ║ 🔧 Enable long paths ║ ║ Windows 10+: Registry setting ║ ║ HKLM\SYSTEM\CurrentControlSet\Control\FileSystem ║ ║ LongPathsEnabled = 1 ║ ║ ║ ║ 🔧 Junction points ║ ║ mklink /J C:\b C:\very\long\path ║ ║ Use short junction for build ║ ║ ║ ║ 🔧 Shorten target names ║ ║ audiolab_very_long_descriptive_name ║ ║ → audiolab_vldn ║ ║ ║ ║ Prevention: ║ ║ • Plan build paths early ║ ║ • Enable long paths on Windows ║ ║ • Keep target names reasonable ║ ║ • Use junction for deep projects ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🏆 ARCHETYPE #8: OUT OF MEMORY ║ ║ ║ ║ Manifestación: ║ ║ ┌───────────────────────────────────────────────────┐ ║ ║ │ Compiler/Linker crashed │ ║ ║ │ c++: internal compiler error: Killed │ ║ ║ │ ld: out of memory │ ║ ║ └───────────────────────────────────────────────────┘ ║ ║ ║ ║ Frecuencia: ███░░░░░░░ (Occasional) ║ ║ Phase: Compilation or Linking ║ ║ Difficulty: ⭐⭐⭐ (Moderate) ║ ║ ║ ║ Causas: ║ ║ ║ ║ 🔸 Template metaprogramming ║ ║ Complex templates consume memory ║ ║ Recursive instantiations ║ ║ ║ ║ 🔸 Too many parallel builds ║ ║ make -j16 on 8GB system ║ ║ Each compiler process uses GB ║ ║ ║ ║ 🔸 32-bit toolchain limit ║ ║ 32-bit linker has 2-4GB limit ║ ║ Large projects exceed ║ ║ ║ ║ 🔸 Unity builds too large ║ ║ Single TU with too much code ║ ║ ║ ║ Soluciones: ║ ║ ║ ║ 🔧 Reduce parallelism ║ ║ make -j4 instead of -j16 ║ ║ Balance build time vs memory ║ ║ ║ ║ 🔧 Use 64-bit toolchain ║ ║ More address space ║ ║ Essential for large projects ║ ║ ║ ║ 🔧 Simplify templates ║ ║ Reduce template depth ║ ║ Explicit instantiations ║ ║ ║ ║ 🔧 Split unity builds ║ ║ Smaller chunks ║ ║ Multiple smaller TUs ║ ║ ║ ║ 🔧 Add more RAM ║ ║ Modern C++ needs memory ║ ║ 16GB minimum, 32GB better ║ ║ ║ ║ 🔧 Use precompiled headers ║ ║ Reduce redundant parsing ║ ║ Save memory per TU ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🏆 ARCHETYPE #9: PERMISSION DENIED ║ ║ ║ ║ Manifestación: ║ ║ ┌───────────────────────────────────────────────────┐ ║ ║ │ Cannot write to output file │ ║ ║ │ Permission denied │ ║ ║ │ Access is denied │ ║ ║ └───────────────────────────────────────────────────┘ ║ ║ ║ ║ Frecuencia: ████░░░░░░ (Moderate, frustrating) ║ ║ Phase: Any ║ ║ Difficulty: ⭐⭐ (Easy once identified) ║ ║ ║ ║ Causas: ║ ║ ║ ║ 🔸 File still in use ║ ║ Previous build process still running ║ ║ IDE has file open ║ ║ Debugger attached to executable ║ ║ ║ ║ 🔸 Antivirus interference ║ ║ AV scanning files ║ ║ Blocking write access ║ ║ Common with Windows Defender ║ ║ ║ ║ 🔸 Folder permissions ║ ║ No write access to build dir ║ ║ System-protected location ║ ║ ║ ║ 🔸 Admin rights required ║ ║ Installing to Program Files ║ ║ System directories ║ ║ ║ ║ Soluciones: ║ ║ ║ ║ 🔧 Close all processes ║ ║ Task manager: kill lingering builds ║ ║ Close IDE if has file open ║ ║ ║ ║ 🔧 Add AV exception ║ ║ Exclude build directory ║ ║ Exclude compiler/linker ║ ║ ║ ║ 🔧 Use user-writable directory ║ ║ Not Program Files ║ ║ Not C:\Windows ║ ║ ║ ║ 🔧 Check folder permissions ║ ║ Right-click → Properties → Security ║ ║ Ensure write access ║ ║ ║ ║ Prevention: ║ ║ • Build in user directories ║ ║ • Configure AV exclusions early ║ ║ • Close IDE before command-line builds ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🏆 ARCHETYPE #10: CIRCULAR DEPENDENCY ║ ║ ║ ║ Manifestación: ║ ║ ┌───────────────────────────────────────────────────┐ ║ ║ │ Circular dependency between targets │ ║ ║ │ A depends on B depends on A │ ║ ║ └───────────────────────────────────────────────────┘ ║ ║ ║ ║ Frecuencia: ███░░░░░░░ (Occasional) ║ ║ Phase: Configuration or Linking ║ ║ Difficulty: ⭐⭐⭐⭐ (Hard - design issue) ║ ║ ║ ║ ¿Por qué ocurre? ║ ║ Architectural problem in code ║ ║ Two modules depend on each other ║ ║ ║ ║ Ejemplo: ║ ║ ┌───────────────────────────────────┐ ║ ║ │ AudioEngine │ ║ ║ │ ├─ uses PluginHost │ ║ ║ │ │ ║ ║ │ PluginHost │ ║ ║ │ ├─ uses AudioEngine │ ║ ║ │ │ ║ ║ │ → Circular! │ ║ ║ └───────────────────────────────────┘ ║ ║ ║ ║ Soluciones arquitecturales: ║ ║ ║ ║ 🔧 Extract interface ║ ║ Create common interface library ║ ║ Both depend on interface ║ ║ No circular dependency ║ ║ ║ ║ 🔧 Dependency inversion ║ ║ Use callbacks/observers ║ ║ Remove direct dependency ║ ║ ║ ║ 🔧 Merge modules ║ ║ If truly interdependent ║ ║ Should be one module ║ ║ ║ ║ 🔧 Reorder dependencies ║ ║ Identify which is higher level ║ ║ Lower level shouldn't know higher ║ ║ ║ ║ Prevention: ║ ║ • Design clear module hierarchy ║ ║ • Use dependency diagrams ║ ║ • Follow dependency inversion principle ║ ║ • Regular architecture review ║ ║ ║ ║ 🎯 This is a DESIGN ERROR, not just build error ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
═══════════════════════════════════════════════════════════ 🛠️ CAPÍTULO 4: ARSENAL DE HERRAMIENTAS DE DIAGNÓSTICO ═══════════════════════════════════════════════════════════
🔷 LA CAJA DE HERRAMIENTAS DEL TROUBLESHOOTER
Troubleshooting efectivo requiere herramientas adecuadas. No todas son obvias. Aquí está el arsenal completo.
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🔧 TIER 1: COMPILER/LINKER OUTPUT ANALYSIS ║ ║ ═══════════════════════════════════════ ║ ║ ║ ║ Tu primera línea de información ║ ║ ║ ║ 📝 VERBOSE COMPILATION ║ ║ ═══════════════════ ║ ║ ║ ║ See exact commands executed: ║ ║ ║ ║ make VERBOSE=1 ║ ║ ninja -v ║ ║ cmake --build . --verbose ║ ║ ║ ║ Output shows: ║ ║ • Exact compiler invocation ║ ║ • All flags passed ║ ║ • Include paths (-I) ║ ║ • Defines (-D) ║ ║ • Link libraries ║ ║ ║ ║ Use to verify: ║ ║ ✓ Correct compiler being used ║ ║ ✓ Flags as expected ║ ║ ✓ Include paths correct ║ ║ ✓ Libraries linked ║ ║ ║ ║ 🔍 PREPROCESSOR OUTPUT ║ ║ ══════════════════ ║ ║ ║ ║ See code after macro expansion: ║ ║ ║ ║ g++ -E file.cpp > file.i ║ ║ clang++ -E file.cpp > file.i ║ ║ cl /E file.cpp > file.i ║ ║ ║ ║ Reveals: ║ ║ • What headers actually included ║ ║ • Macro expansions ║ ║ • Conditional compilation results ║ ║ • Include order ║ ║ ║ ║ Use to debug: ║ ║ • Macro conflicts ║ ║ • Include errors ║ ║ • Platform-specific code ║ ║ ║ ║ 📊 DEPENDENCY FILE ║ ║ ═══════════════ ║ ║ ║ ║ See what headers a file includes: ║ ║ ║ ║ g++ -MM file.cpp ║ ║ Shows: file.o: file.cpp header1.h header2.h ... ║ ║ ║ ║ Use to: ║ ║ • Understand include dependencies ║ ║ • Find circular includes ║ ║ • Optimize include structure ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🔬 TIER 2: BINARY ANALYSIS TOOLS ║ ║ ══════════════════════════ ║ ║ ║ ║ Inspección profunda de binarios compilados ║ ║ ║ ║ 🔍 nm (Unix) / dumpbin (Windows) ║ ║ ═══════════════════════════════ ║ ║ ║ ║ List symbols in object file/library: ║ ║ ║ ║ nm libfoo.a ║ ║ nm -C libfoo.a (demangle C++) ║ ║ dumpbin /SYMBOLS foo.lib ║ ║ ║ ║ Output shows: ║ ║ T = defined in text section ║ ║ U = undefined (needs linking) ║ ║ W = weak symbol ║ ║ D = defined in data section ║ ║ ║ ║ Use to: ║ ║ ✓ Verify symbol exists in library ║ ║ ✓ Check mangling ║ ║ ✓ Find duplicate symbols ║ ║ ✓ Debug undefined references ║ ║ ║ ║ Example workflow: ║ ║ 1. Error: undefined reference to Foo::bar() ║ ║ 2. nm libfoo.a | grep bar ║ ║ 3. Check if bar is defined (T) or missing ║ ║ 4. Check mangling matches ║ ║ ║ ║ 📐 objdump / otool ║ ║ ═══════════════════ ║ ║ ║ ║ Disassemble and inspect binaries: ║ ║ ║ ║ objdump -t libfoo.a (symbol table) ║ ║ objdump -d libfoo.a (disassembly) ║ ║ objdump -h libfoo.a (section headers) ║ ║ otool -L myapp (macOS dependencies) ║ ║ ║ ║ Use to: ║ ║ • Verify what compiler generated ║ ║ • Check optimizations applied ║ ║ • Verify instructions (SIMD) ║ ║ • Debug performance issues ║ ║ ║ ║ 🔗 ldd / otool -L / dumpbin /DEPENDENTS ║ ║ ═══════════════════════════════════════ ║ ║ ║ ║ Show runtime library dependencies: ║ ║ ║ ║ ldd myapp (Linux) ║ ║ otool -L myapp (macOS) ║ ║ dumpbin /DEPENDENTS myapp.exe (Windows) ║ ║ ║ ║ Output shows: ║ ║ • What shared libraries needed ║ ║ • Where they're located ║ ║ • If they're found ║ ║ ║ ║ Use to debug: ║ ║ • "Library not found" runtime errors ║ ║ • Verify dependencies packaged ║ ║ • Check rpath/runpath ║ ║ ║ ║ 🎯 c++filt / undname ║ ║ ══════════════════ ║ ║ ║ ║ Demangle C++ symbols: ║ ║ ║ ║ c++filt _ZN10Oscillator7processEv ║ ║ → Oscillator::process() ║ ║ ║ ║ undname ?process@Oscillator@@QEAAXXZ ║ ║ → public: void Oscillator::process(void) ║ ║ ║ ║ Essential for: ║ ║ • Understanding linker errors ║ ║ • Debugging symbol mismatches ║ ║ • Reading nm/objdump output ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🎯 TIER 3: CMAKE INTROSPECTION ║ ║ ════════════════════════ ║ ║ ║ ║ Entender qué CMake decidió ║ ║ ║ ║ 📄 CMakeCache.txt ║ ║ ══════════════ ║ ║ ║ ║ Located: build/CMakeCache.txt ║ ║ ║ ║ Contains: ║ ║ • All cached variables ║ ║ • Detected compiler paths ║ ║ • Found package locations ║ ║ • User-set options ║ ║ ║ ║ Use to: ║ ║ • Verify detected toolchain ║ ║ • Check option values ║ ║ • See where dependencies found ║ ║ • Debug cache issues ║ ║ ║ ║ 📋 CMakeFiles/ directory ║ ║ ═══════════════════ ║ ║ ║ ║ Located: build/CMakeFiles/ ║ ║ ║ ║ Contains: ║ ║ • CMakeError.log (errors during configure) ║ ║ • CMakeOutput.log (successful checks) ║ ║ • Feature test results ║ ║ • Intermediate files ║ ║ ║ ║ Use to: ║ ║ • Debug configuration failures ║ ║ • See why find_package failed ║ ║ • Check feature detection results ║ ║ ║ ║ 🔍 cmake --trace ║ ║ ═════════════ ║ ║ ║ ║ See every CMake command executed: ║ ║ ║ ║ cmake -trace .. 2>&1 | tee trace.log ║ ║ cmake --trace-expand .. 2>&1 | tee trace.log ║ ║ ║ ║ Output shows: ║ ║ • Every CMake command ║ ║ • File and line number ║ ║ • Variable values (with --trace-expand) ║ ║ ║ ║ Use to: ║ ║ • Debug complex CMake logic ║ ║ • Find where variable set ║ ║ • Understand include() flow ║ ║ ║ ║ WARNING: Very verbose! ║ ║ Redirect to file and search ║ ║ ║ ║ 🎨 cmake --system-information ║ ║ ══════════════════════════ ║ ║ ║ ║ Dump complete system info: ║ ║ ║ ║ cmake --system-information info.txt ║ ║ ║ ║ Shows: ║ ║ • CMake version ║ ║ • Detected compilers ║ ║ • Platform information ║ ║ • All CMake variables ║ ║ ║ ║ Use for: ║ ║ • Environment documentation ║ ║ • Bug reports ║ ║ • Comparing configurations ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🚀 TIER 4: ADVANCED DEBUGGING ║ ║ ═══════════════════ ║ ║ ║ ║ Cuando todo lo demás falla ║ ║ ║ ║ 🔬 Compiler Explorer (godbolt.org) ║ ║ ════════════════════════════════ ║ ║ ║ ║ Online compiler with: ║ ║ • Multiple compilers ║ ║ • Different versions ║ ║ • Assembly output ║ ║ • Side-by-side comparison ║ ║ ║ ║ Use to: ║ ║ • Test minimal reproduction ║ ║ • Compare compiler behavior ║ ║ • Share with community ║ ║ • Understand code generation ║ ║ ║ ║ 🧪 Minimal Reproduction ║ ║ ════════════════════ ║ ║ ║ ║ Create smallest project that shows error: ║ ║ ║ ║ my_repro/ ║ ║ ├─ CMakeLists.txt (minimal) ║ ║ ├─ main.cpp (only relevant code) ║ ║ └─ README.md (repro steps) ║ ║ ║ ║ Benefits: ║ ║ • Forces understanding ║ ║ • Isolates root cause ║ ║ • Shareable with others ║ ║ • Often solves itself during creation ║ ║ ║ ║ 📊 Build Timing Analysis ║ ║ ═══════════════════ ║ ║ ║ ║ Identify slow parts: ║ ║ ║ ║ ninja -d stats ║ ║ cmake --build . -- -d stats ║ ║ ║ ║ time ninja -v 2>&1 | grep "some_file" ║ ║ ║ ║ Use to: ║ ║ • Find bottlenecks ║ ║ • Optimize build time ║ ║ • Justify build improvements ║ ║ ║ ║ 👥 Community Resources ║ ║ ═══════════════════ ║ ║ ║ ║ When stuck, ask for help: ║ ║ ║ ║ • Stack Overflow ║ ║ • Reddit (r/cpp, r/cmake) ║ ║ • Discord servers (C++, JUCE) ║ ║ • GitHub Discussions ║ ║ ║ ║ CRITICAL: Provide MCVE ║ ║ (Minimal Complete Verifiable Example) ║ ║ ║ ║ Good question includes: ║ ║ ✓ Complete error message ║ ║ ✓ Minimal code to reproduce ║ ║ ✓ Environment details ║ ║ ✓ What you've tried ║ ║ ✓ Specific question ║ ║ ║ ║ ❌ BAD: "My code doesn't build, help!" ║ ║ ✅ GOOD: "Getting undefined reference to X when ║ ║ linking Y. Here's minimal CMakeLists..." ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
═══════════════════════════════════════════════════════════ 💡 CAPÍTULO 5: PREVENCIÓN - BUILD HYGIENE ═══════════════════════════════════════════════════════════
🔷 MEJOR PREVENIR QUE CURAR
La mayoría de errores de build son prevenibles con buenas prácticas.
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🛡️ AUDIOLAB BUILD HYGIENE CHECKLIST ║ ║ ║ ║ ✅ CONFIGURATION HYGIENE ║ ║ ════════════════════ ║ ║ ║ ║ □ Use CMake Presets (CMakePresets.json) ║ ║ → Standardized configurations ║ ║ → Developer = CI = Production ║ ║ ║ ║ □ Version lock dependencies (vcpkg.json) ║ ║ → Exact versions, not "latest" ║ ║ → Reproducible builds ║ ║ ║ ║ □ Document toolchain requirements ║ ║ → CMake version ║ ║ → Compiler versions ║ ║ → Platform requirements ║ ║ ║ ║ □ Consistent ABI ║ ║ → Same compiler for all ║ ║ → Same configuration (Debug/Release) ║ ║ → Same stdlib ║ ║ ║ ║ ✅ PROJECT STRUCTURE ║ ║ ═══════════════════ ║ ║ ║ ║ □ Out-of-source builds enforced ║ ║ if(SOURCE_DIR STREQUAL BINARY_DIR) ║ ║ error("No in-source builds!") ║ ║ endif() ║ ║ ║ ║ □ Separate build dir per config ║ ║ build/debug/ ║ ║ build/release/ ║ ║ build/sanitizers/ ║ ║ ║ ║ □ Modular CMakeLists structure ║ ║ → One target per CMakeLists ║ ║ → Clear hierarchy ║ ║ → No global variables ║ ║ ║ ║ □ Clean .gitignore ║ ║ build/ ║ ║ .vs/ ║ ║ *.user ║ ║ CMakeUserPresets.json ║ ║ ║ ║ ✅ CODE PRACTICES ║ ║ ════════════ ║ ║ ║ ║ □ Include guards in all headers ║ ║ #pragma once (modern) ║ ║ Or #ifndef HEADER_H guards ║ ║ ║ ║ □ Forward declarations where possible ║ ║ → Reduce compile dependencies ║ ║ → Faster builds ║ ║ → Break circular includes ║ ║ ║ ║ □ Inline only in headers ║ ║ → Or mark static ║ ║ → Avoid multiple definition ║ ║ ║ ║ □ Explicit template instantiations ║ ║ → For frequently used types ║ ║ → Reduce compile time ║ ║ → Avoid link errors ║ ║ ║ ║ □ Consistent naming conventions ║ ║ → PascalCase for types ║ ║ → camelCase for functions ║ ║ → Clear, searchable names ║ ║ ║ ║ ✅ CONTINUOUS INTEGRATION ║ ║ ═════════════════════ ║ ║ ║ ║ □ Build on every commit ║ ║ → Catch errors immediately ║ ║ → No "works on my machine" ║ ║ ║ ║ □ Test multiple platforms ║ ║ → Windows (MSVC) ║ ║ → macOS (Clang) ║ ║ → Linux (GCC) ║ ║ ║ ║ □ Fresh environment each time ║ ║ → Docker containers ║ ║ → Clean VMs ║ ║ → No state accumulation ║ ║ ║ ║ □ Warnings as errors in CI ║ ║ -Werror, /WX ║ ║ → Force addressing warnings ║ ║ ║ ║ □ Static analysis integrated ║ ║ → clang-tidy ║ ║ → cppcheck ║ ║ → Catch issues early ║ ║ ║ ║ ✅ MONITORING & METRICS ║ ║ ═══════════════════ ║ ║ ║ ║ □ Track build times ║ ║ → Detect regressions ║ ║ → Justify optimizations ║ ║ ║ ║ □ Monitor binary sizes ║ ║ → Catch bloat ║ ║ → Optimize for size ║ ║ ║ ║ □ Log configuration changes ║ ║ → CMake options history ║ ║ → Dependency updates ║ ║ ║ ║ □ Alert on new warnings ║ ║ → Don't let them accumulate ║ ║ → Fix immediately ║ ║ ║ ║ ✅ DOCUMENTATION ║ ║ ══════════════ ║ ║ ║ ║ □ BUILD.md with instructions ║ ║ → Prerequisites ║ ║ → Step-by-step build ║ ║ → Common issues ║ ║ ║ ║ □ Troubleshooting guide ║ ║ → Project-specific errors ║ ║ → Known issues ║ ║ → Workarounds ║ ║ ║ ║ □ Platform-specific notes ║ ║ → Windows quirks ║ ║ → macOS code signing ║ ║ → Linux dependencies ║ ║ ║ ║ □ CHANGELOG for breaking changes ║ ║ → Build system changes ║ ║ → Dependency updates ║ ║ → Migration guides ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
🔷 ERROR PREVENTION MATRIX
┌─────────────────────────────────────────────────────────┐ │ │ │ ERROR TYPE → PREVENTION STRATEGY │ │ ═══════════════════════════════════════════════ │ │ │ │ Header not found → Consistent include paths │ │ CMake target properties │ │ Verify dependencies │ │ │ │ Undefined ref → Add sources to CMake │ │ Link required libraries │ │ Check library order │ │ │ │ Multiple def → Inline in headers │ │ Extern for globals │ │ Avoid duplicate sources │ │ │ │ ABI mismatch → Same toolchain for all │ │ Same configuration │ │ Document requirements │ │ │ │ Template errors → Use concepts (C++20) │ │ Static asserts │ │ Simplify when possible │ │ │ │ Path too long → Short build paths │ │ Enable long paths │ │ Junction points │ │ │ │ Out of memory → Limit parallelism │ │ 64-bit toolchain │ │ Adequate RAM │ │ │ │ Permission denied → User-writable dirs │ │ AV exceptions │ │ Close processes │ │ │ │ Circular deps → Clear architecture │ │ Dependency inversion │ │ Interface libraries │ │ │ └─────────────────────────────────────────────────────────┘
═══════════════════════════════════════════════════════════ 🎯 CONCLUSIÓN: TROUBLESHOOTING COMO DISCIPLINA ═══════════════════════════════════════════════════════════
💡 LOS PRINCIPIOS MAESTROS
╔═══════════════════════════════════════════════════════════╗ ║ ║ ║ 🧠 THE TROUBLESHOOTER'S MINDSET ║ ║ ║ ║ 1️⃣ READ ERROR MESSAGES COMPLETELY ║ ║ ════════════════════════════ ║ ║ • Don't just skim first line ║ ║ • Read ENTIRE error output ║ ║ • Look for patterns ║ ║ • First error often most important ║ ║ ║ ║ 2️⃣ REPRODUCE CONSISTENTLY ║ ║ ══════════════════════ ║ ║ • Cannot fix what you can't reproduce ║ ║ • Find minimal repro ║ ║ • Document reproduction steps ║ ║ • Test in clean environment ║ ║ ║ ║ 3️⃣ ISOLATE MINIMALLY ║ ║ ═════════════════ ║ ║ • Binary search approach ║ ║ • Remove until error disappears ║ ║ • Smallest change that triggers ║ ║ • Understand, don't just fix ║ ║ ║ ║ 4️⃣ CHANGE ONE THING AT A TIME ║ ║ ═══════════════════════════ ║ ║ • No shotgun debugging ║ ║ • Test each change ║ ║ • Document what worked ║ ║ • Revert what didn't ║ ║ ║ ║ 5️⃣ DOCUMENT EVERYTHING ║ ║ ═══════════════════ ║ ║ • Error and solution ║ ║ • Root cause analysis ║ ║ • Prevention strategy ║ ║ • Share with team ║ ║ ║ ║ 6️⃣ BUILD HYGIENE > FIREFIGHTING ║ ║ ═════════════════════════ ║ ║ • Prevent 80% of errors ║ ║ • Consistent configuration ║ ║ • CI catches issues early ║ ║ • Document requirements ║ ║ ║ ║ 7️⃣ COMMUNITY IS YOUR ALLY ║ ║ ══════════════════════ ║ ║ • Don't struggle alone ║ ║ • Prepare good questions ║ ║ • Provide MCVE ║ ║ • Give back when you can ║ ║ ║ ║ 8️⃣ LEARN FROM EVERY ERROR ║ ║ ══════════════════════ ║ ║ • Each error teaches something ║ ║ • Build pattern library ║ ║ • Get faster over time ║ ║ • Expertise = experience ║ ║ ║ ╚═══════════════════════════════════════════════════════════╝
🎓 TROUBLESHOOTING MATURITY LEVELS
┌─────────────────────────────────────────────────────────┐ │ │ │ NOVICE │ │ ══════ │ │ • Panics at errors │ │ • Random changes hoping for fix │ │ • Doesn't read full error message │ │ • Asks "doesn't work, help!" │ │ │ │ INTERMEDIATE │ │ ═════════════ │ │ • Reads error messages │ │ • Googles errors │ │ • Tries systematic changes │ │ • Sometimes finds solution │ │ │ │ ADVANCED │ │ ════════ │ │ • Categorizes errors immediately │ │ • Knows common patterns │ │ • Uses diagnostic tools │ │ • Solves most errors quickly │ │ │ │ EXPERT │ │ ══════ │ │ • Prevents errors proactively │ │ • Debugs unfamiliar systems │ │ • Contributes to community │ │ • Teaches others │ │ │ │ GOAL: Move up this ladder with every error solved │ │ │ └─────────────────────────────────────────────────────────┘
🌟 FINAL WISDOM
Build errors are not obstacles, they are teachers.
Every error you debug: • Deepens your understanding of C++ • Improves your mental model of build systems • Builds your pattern recognition library • Makes you a better engineer
The path to expertise is paved with solved errors.
Embrace the debugging journey.
═══════════════════════════════════════════════════════════
📚 ESTE DOCUMENTO CONECTA CON
• CMAKE_ARCHITECTURE_DEEP_DIVE.md → CMake concepts • Compiler documentation → Error messages • Linker documentation → Symbol resolution • C++ standard → Language rules • Platform ABIs → Compatibility
═══════════════════════════════════════════════════════════
🔗 PRÓXIMOS PASOS
Para dominar troubleshooting: 1. Solve errors methodically 2. Document each solution 3. Build personal knowledge base 4. Share with team 5. Contribute to community 6. Teach others
═══════════════════════════════════════════════════════════