Programar en C++ desde un Mac no requiere instalar un entorno pesado ni recurrir necesariamente a GNU GCC. macOS dispone de Apple Clang, el compilador incluido en las herramientas de desarrollo de Apple, junto con libc++ como biblioteca estándar de C++. Con las Command Line Tools instaladas es posible escribir, compilar, depurar y ejecutar programas C++ directamente desde Terminal tanto en Mac Intel como en equipos Apple Silicon con procesadores M1, M2, M3, M4 y generaciones posteriores.
Las claves para programar C++ en macOS en 20 segundos
- Apple utiliza Clang como compilador C y C++, acompañado de
libc++como biblioteca estándar. - Las Command Line Tools pueden instalarse sin descargar el entorno completo de Xcode.
clang++ programa.cpp -o programabasta para compilar un ejemplo sencillo.- Los Mac Apple Silicon generan normalmente código ARM64 de forma nativa.
- CMake, Homebrew, VS Code, Xcode y LLDB permiten ampliar el entorno para proyectos más grandes.
Para alguien acostumbrado a Linux, la experiencia resulta bastante familiar. El cambio principal está en el toolchain: muchos desarrolladores esperan encontrar GNU GCC y descubren que el entorno de Apple gira alrededor de Clang, LLVM, los SDK de macOS y herramientas como xcrun.
Hay además algunos detalles que conviene conocer desde el principio, especialmente si el código procede de Linux, utiliza bibliotecas externas o tiene que funcionar tanto en Intel x86-64 como en Apple Silicon ARM64.
Instalar el compilador C++ en macOS
La forma más sencilla de empezar es instalar las Command Line Tools for Xcode.
Desde Terminal:
xcode-select --install
macOS mostrará el diálogo correspondiente para descargar e instalar las herramientas.
Apple ofrece este paquete precisamente para quienes necesitan trabajar desde Terminal o compilar proyectos UNIX y multiplataforma sin instalar necesariamente la aplicación completa de Xcode. Incluye el SDK de macOS, páginas de manual y los binarios principales del toolchain.
Una vez terminado el proceso puede comprobarse dónde se encuentra el entorno activo:
xcode-select -p
Si solo están instaladas las Command Line Tools, una ubicación habitual es:
/Library/Developer/CommandLineTools
También puede verificarse la versión instalada:
pkgutil --pkg-info=com.apple.pkg.CLTools_Executables
Y comprobar el compilador:
clang++ --version
En un Mac Apple Silicon la salida debería indicar un objetivo similar a:
Target: arm64-apple-darwin...
Mientras que un Mac Intel utilizará normalmente:
Target: x86_64-apple-darwin...
Esto permite comprobar rápidamente para qué arquitectura se está generando el código.
¿Clang o GCC en macOS?
Aquí aparece una confusión bastante habitual.
En muchos sistemas Linux, C++ se compila mediante:
g++
En macOS la herramienta estándar es:
clang++
Apple soporta oficialmente C++ mediante Apple Clang y libc++. Ambos forman parte de su plataforma de desarrollo.
Clang es el frontend del proyecto LLVM y soporta múltiples versiones del estándar C++. El grado exacto de compatibilidad depende de la versión instalada: C++17 dispone de soporte completo desde hace años, mientras que C++20, C++23 y las características previstas para C++26 deben comprobarse individualmente porque no todas están necesariamente disponibles en cada versión de Clang o Apple Clang.
Por eso es mejor no asumir que instalar la última versión de macOS proporciona automáticamente soporte completo para todas las características del estándar más reciente.
Para conocer el compilador disponible:
clang++ --version
Y para localizarlo:
which clang++
También puede utilizarse xcrun, que resulta especialmente útil cuando existen varios SDK o instalaciones de Xcode:
xcrun --find clang++
Para consultar el SDK activo:
xcrun --show-sdk-path
Esto ayuda a entender una diferencia importante respecto a muchos entornos Linux: en macOS, compilador, SDK y versión objetivo del sistema operativo están estrechamente relacionados.
Crear, compilar y ejecutar el primer programa C++
El primer programa puede guardarse como hello.cpp:
#include <iostream>
#include <string>
int main()
{
std::string name;
int age;
std::cout << "Enter your name: ";
std::getline(std::cin, name);
std::cout << "Enter your age: ";
std::cin >> age;
std::cout << "Hello " << name
<< ", you are " << age
<< " years old!\n";
return 0;
}
Se ha utilizado std::getline() para el nombre en lugar de:
std::cin >> name;
porque esta segunda opción se detiene en el primer espacio. Con std::getline() pueden introducirse nombres completos.
Para compilar:
clang++ hello.cpp -o hello
Si no aparecen errores, se habrá generado un ejecutable:
hello
Puede comprobarse con:
ls -lh hello
Y ejecutarlo:
./hello
El prefijo ./ es necesario porque, por motivos de seguridad y funcionamiento tradicional de los sistemas Unix, el directorio actual no suele formar parte de la variable $PATH.
Si no se especifica el nombre:
clang++ hello.cpp
el compilador genera normalmente:
a.out
que puede ejecutarse con:
./a.out
Para aprender y mantener los proyectos organizados suele ser preferible utilizar siempre -o.
Elegir C++17, C++20 o C++23
Es recomendable declarar explícitamente el estándar utilizado por el proyecto.
Por ejemplo:
clang++ -std=c++17 hello.cpp -o hello
Para C++20:
clang++ -std=c++20 hello.cpp -o hello
Y para C++23:
clang++ -std=c++23 hello.cpp -o hello
La disponibilidad de una bandera no significa necesariamente que absolutamente todas las características de ese estándar estén implementadas. LLVM mantiene una tabla detallada con el estado de compatibilidad de Clang, mientras Apple publica además información específica sobre las características soportadas en sus plataformas.
Para un proyecto nuevo que no necesite características muy recientes, C++20 puede ser una elección razonable:
clang++ -std=c++20 hello.cpp -o hello
Compilar mejor: warnings, optimización y depuración
Para aprender C++ o trabajar en un proyecto real no conviene limitarse a:
clang++ hello.cpp
Los warnings del compilador pueden detectar errores antes de ejecutar el programa.
Una configuración sencilla para desarrollo sería:
clang++ -std=c++20 -Wall -Wextra -Wpedantic hello.cpp -o hello
Estas opciones activan diferentes grupos de advertencias.
También puede añadirse:
-Werror
para convertir warnings en errores:
clang++ -std=c++20 -Wall -Wextra -Wpedantic -Werror hello.cpp -o hello
Es una política útil en algunos proyectos y sistemas de integración continua, aunque durante el desarrollo puede resultar demasiado estricta dependiendo del código y las bibliotecas utilizadas.
Compilar para depuración
Para generar información útil para un debugger:
clang++ -std=c++20 -Wall -Wextra -g hello.cpp -o hello
La opción:
-g
incluye información de depuración.
macOS incluye LLDB, el debugger del proyecto LLVM.
Puede iniciarse con:
lldb ./hello
Dentro de LLDB:
run
ejecuta el programa.
También pueden colocarse breakpoints:
breakpoint set --name main
o utilizando su forma abreviada:
b main
Después:
run
El programa se detendrá al llegar a main().
Compilar una versión optimizada
Clang dispone de diferentes niveles de optimización:
-O0
-O1
-O2
-O3
-Os
Para desarrollo suele utilizarse -O0 o una optimización moderada.
Para una versión optimizada:
clang++ -std=c++20 -O2 hello.cpp -o hello
-O3 aplica optimizaciones más agresivas:
clang++ -std=c++20 -O3 hello.cpp -o hello
Más optimización no significa automáticamente que cualquier programa vaya a ser más rápido. La decisión debe tomarse según el proyecto y, cuando el rendimiento sea importante, mediante benchmarks.
Una configuración práctica durante el desarrollo
Un comando bastante razonable sería:
clang++ -std=c++20 -Wall -Wextra -Wpedantic -g hello.cpp -o hello
Mientras que para una compilación optimizada podría utilizarse:
clang++ -std=c++20 -Wall -Wextra -Wpedantic -O2 hello.cpp -o hello
Apple Silicon cambia algunas cosas que conviene conocer
Los Mac modernos utilizan procesadores Apple Silicon basados en ARM64.
Para comprobar la arquitectura:
uname -m
En Apple Silicon:
arm64
En un Mac Intel:
x86_64
También puede analizarse un ejecutable recién compilado:
file ./hello
En Apple Silicon debería aparecer una descripción similar a:
Mach-O 64-bit executable arm64
En Intel:
Mach-O 64-bit executable x86_64
Esto se vuelve especialmente importante cuando se incorporan bibliotecas externas.
Un programa ARM64 no puede enlazar directamente con una biblioteca disponible únicamente para x86-64.
Ese es uno de los motivos por los que algunos proyectos antiguos presentan errores de compilación o linking después de migrarlos desde un Mac Intel a Apple Silicon.
Compilar explícitamente para ARM64
Puede indicarse la arquitectura:
clang++ -arch arm64 hello.cpp -o hello
Para Intel:
clang++ -arch x86_64 hello.cpp -o hello
La segunda opción solo funcionará correctamente cuando las bibliotecas y SDK necesarios estén disponibles para esa arquitectura.
macOS también permite crear Universal Binaries que contienen código para más de una arquitectura.
Conceptualmente pueden compilarse ambas versiones:
clang++ -arch arm64 hello.cpp -o hello-arm64
clang++ -arch x86_64 hello.cpp -o hello-x86_64
Y combinarse mediante:
lipo -create hello-arm64 hello-x86_64 -output hello-universal
Después:
file hello-universal
permite comprobar las arquitecturas incluidas.
Para un programa personal ejecutado únicamente en un Mac Apple Silicon normalmente no hace falta hacer nada de esto. Clang seleccionará automáticamente la arquitectura nativa.
Por qué bits/stdc++.h falla en macOS
Una de las sorpresas más frecuentes al copiar ejemplos C++ procedentes de Internet es encontrar:
#include <bits/stdc++.h>
y recibir un error parecido a:
fatal error: 'bits/stdc++.h' file not found
El problema no es C++ ni macOS.
bits/stdc++.h no forma parte del estándar C++. Es una cabecera asociada habitualmente a implementaciones de GNU libstdc++ y se utiliza mucho en programación competitiva porque incluye una gran cantidad de cabeceras de una sola vez.
Apple utiliza Clang con libc++, por lo que no debería dependerse de esa cabecera.
En su lugar hay que incluir exactamente lo que utiliza el programa:
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
Esto tiene además una ventaja de portabilidad: el código deja de depender de una característica específica de una implementación.
Un programa que utilice:
std::vector
std::sort
std::string
std::cout
debería declarar:
#include <vector>
#include <algorithm>
#include <string>
#include <iostream>
La regla práctica es sencilla: si se pretende escribir C++ portable entre macOS, Linux y Windows, conviene utilizar cabeceras estándar.
Instalar bibliotecas C++ externas en macOS
Los programas reales suelen necesitar algo más que la biblioteca estándar.
Aquí aparece Homebrew como una opción habitual para instalar dependencias.
Por ejemplo, si un proyecto necesita Boost:
brew install boost
Para OpenSSL:
brew install openssl
Para CMake:
brew install cmake
Sin embargo, instalar una biblioteca no significa que Clang vaya a encontrarla automáticamente.
Puede ser necesario indicar rutas de cabeceras y bibliotecas:
clang++ main.cpp \
-I/ruta/include \
-L/ruta/lib \
-lmi_biblioteca \
-o programa
Las opciones principales son:
| Opción | Función |
|---|---|
-I | Añade una ruta de cabeceras |
-L | Añade una ruta de bibliotecas |
-l | Indica una biblioteca que debe enlazarse |
-std= | Selecciona el estándar C++ |
-o | Define el nombre del ejecutable |
-g | Añade información de depuración |
-O2 | Activa optimizaciones |
-Wall | Activa warnings habituales |
En proyectos grandes escribir manualmente todos estos parámetros deja de ser práctico. Ahí entra CMake.
Pasar de un archivo a un proyecto con CMake
Para un único hello.cpp, Clang es suficiente.
Cuando aparecen diez, cien o miles de archivos, bibliotecas y configuraciones diferentes, interesa utilizar un sistema de build.
CMake es una de las opciones más extendidas en proyectos C++ multiplataforma.
Una estructura sencilla podría ser:
myproject/
├── CMakeLists.txt
└── src/
└── main.cpp
El archivo CMakeLists.txt:
cmake_minimum_required(VERSION 3.20)
project(MyProject LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(myapp src/main.cpp)
Después:
mkdir build
cd build
cmake ..
cmake --build .
O utilizando el enfoque moderno:
cmake -S . -B build
cmake --build build
El ejecutable aparecerá dentro del directorio de compilación.
Este modelo tiene una ventaja importante si se trabaja simultáneamente con macOS y Linux: el proyecto deja de depender de una colección de comandos manuales específicos de cada ordenador.
Clang, Xcode, VS Code o solo Terminal
No es obligatorio instalar Xcode completo para programar C++.
| Entorno | Cuándo puede interesar |
|---|---|
| Terminal + Clang | Aprendizaje, scripts, pequeños proyectos |
| VS Code + Clang | Desarrollo general y multiplataforma |
| Xcode | Software especialmente integrado con plataformas Apple |
| CLion | Proyectos C++ grandes y CMake |
| Vim/Neovim + Clang | Entornos centrados en Terminal |
Las Command Line Tools son suficientes para numerosos proyectos C++.
Xcode completo empieza a ser necesario cuando se utilizan determinadas herramientas que Apple distribuye únicamente con el IDE. Por ejemplo, Apple indica que xcodebuild y otras utilidades específicas no forman parte del paquete independiente de Command Line Tools.
Errores habituales al compilar C++ en macOS
clang++: command not found
Conviene comprobar primero:
xcode-select -p
Si las herramientas no están instaladas:
xcode-select --install
'bits/stdc++.h' file not found
Hay que sustituir esa cabecera no estándar por las cabeceras C++ que realmente utilice el programa.
Undefined symbols for architecture arm64
Este error suele indicar un problema durante el enlazado.
Puede existir una biblioteca que no se está enlazando correctamente o una dependencia compilada para una arquitectura diferente.
Conviene comprobarla con:
file /ruta/a/libbiblioteca.dylib
o:
lipo -info /ruta/a/libbiblioteca.dylib
El programa compila en Linux pero no en macOS
No todo lo disponible en Linux forma parte de C++ estándar.
El programa puede depender de:
- GNU-specific headers;
- APIs propias de Linux;
- llamadas al sistema;
- bibliotecas que no están instaladas;
- rutas de filesystem específicas;
- o extensiones particulares de GCC.
En ese caso el problema no es necesariamente Clang. Puede ser simplemente que el código no sea portable.
library not found
Hay que comprobar dónde está instalada la biblioteca y pasar la ruta correspondiente mediante -L, además de enlazarla mediante -l.
header file not found
El equivalente para las cabeceras suele solucionarse indicando su ubicación:
clang++ main.cpp -I/ruta/include -o programa
Un pequeño entorno C++ completo en menos de cinco minutos
Para alguien que acaba de recibir un Mac y simplemente quiere empezar:
xcode-select --install
Comprobar:
clang++ --version
Crear:
nano hello.cpp
Introducir:
#include <iostream>
int main()
{
std::cout << "Hello from C++ on macOS!\n";
return 0;
}
Compilar:
clang++ -std=c++20 -Wall -Wextra -Wpedantic hello.cpp -o hello
Ejecutar:
./hello
Comprobar qué se ha generado:
file ./hello
Y si hay que depurarlo:
clang++ -std=c++20 -g hello.cpp -o hello
lldb ./hello
Con estos pasos ya existe un entorno C++ completamente funcional sin necesidad de abrir un IDE.
Para proyectos más grandes el siguiente paso razonable es incorporar CMake, Git, un editor con soporte para clangd y un gestor de dependencias adecuado al proyecto.
macOS no intenta reproducir exactamente el entorno GNU habitual de muchas distribuciones Linux. Su toolchain gira alrededor de Apple Clang, LLVM, libc++, LLDB y los SDK de Apple. Entender esa diferencia evita buena parte de los problemas que aparecen al trasladar código C++ entre ambos sistemas.
Preguntas frecuentes
¿Qué compilador C++ utiliza macOS?
Apple utiliza Apple Clang como compilador C++ oficial de sus herramientas de desarrollo y libc++ como implementación de la biblioteca estándar. Ambos están disponibles mediante Xcode y las Command Line Tools.
¿Es necesario instalar Xcode completo para programar C++ en Mac?
No. Para compilar programas C++ desde Terminal suele ser suficiente instalar las Command Line Tools con xcode-select --install. Xcode completo resulta útil o necesario para determinadas herramientas y proyectos específicos de las plataformas Apple.
¿Cómo se compila un archivo C++ en macOS?
Un ejemplo sencillo puede compilarse con clang++ hello.cpp -o hello y ejecutarse posteriormente con ./hello. Puede añadirse -std=c++20 o el estándar que necesite el proyecto.
¿Por qué bits/stdc++.h no funciona en macOS?
Porque no es una cabecera estándar de C++. Está asociada principalmente al entorno GNU libstdc++ y no forma parte de libc++, utilizada por Apple. Para escribir código portable deben incluirse las cabeceras estándar necesarias individualmente.
Fuentes:
- Apple Developer Documentation, Installing the Command Line Tools for Xcode.
- Apple Developer, C++ Language Support.
- Apple Developer Documentation, Xcode Command-Line Tools.
- LLVM Project, C++ Support in Clang.








