Prerrequisitos y Entorno de Ejecución Requerido¶
Para compilar y verificar las soluciones de este módulo bajo el estándar C11 estricto de cátedra, se requiere:
Compilador C11: GCC 9+ o Clang 11+ configurado con flags
-Wall -Wextra -Werror -pedantic -std=c11.Entorno POSIX: Linux o WSL con utilidades estándar (
make,ar,diff,bash).Herramientas de Automatización: GNU Make 4.0+ y soporte para compilación modular multiobjeto.
Conocimientos Previos: Etapas de compilación (preprocesado, compilación, ensamblado, enlazado), archivos objeto (
.o), bibliotecas estáticas (.a) y reglas con targets/dependencias.
Objetivos Pedagógicos y Competencias (Taxonomía de Bloom)¶
Nivel 2 (Comprensión): Analizar el flujo de traducción de código fuente a binario ejecutable y la separación en cabeceras e implementaciones.
Nivel 3 (Aplicación): Construir Makefiles modulares con variables automáticas (
$@,$<,$^), reglas implícitas y targets phony (all,clean,test).Nivel 4 (Análisis): Diagnosticar errores de enlazado (undefined reference vs multiple definition) y optimizar tiempos de compilación incremental.
Andamiaje Progresivo: Ejercicios andamiados con contratos formales (precondiciones/postcondiciones), tablas de vectores de prueba y suites ejecutables con
assert().
Capítulos de Apunte Correspondientes¶
Proyecto Multi-archivo Manual¶
Ejercicio 1.08.01 - Separar un programa en módulos ⭐⭐☆☆☆¶
(ej_b1_c08_02)=
### Ejercicio 1.08.02 - Compilación manual ⭐⭐☆☆☆
**Tarea**: Usando la terminal, compilá y enlazá los archivos del ejercicio
anterior sin usar un Makefile.
:::{hint} Lógica y Consideraciones
1. **Compilar los archivos objeto (`.o`)**: Se usa la opción `-c` de `gcc` para
compilar cada archivo fuente por separado.
```bash
gcc -c main.c -o main.o
gcc -c calculadora.c -o calculadora.o
```
2. **Enlazar los objetos**: Se combinan los archivos objeto para crear el
ejecutable final.
```bash
gcc main.o calculadora.o -o mi_calculadora
```
errores de E/S con `ferror` y `feof`.
archivo en todos los caminos de ejecución.Automatización con Makefile¶
Ejercicio 1.08.03 - Makefile básico ⭐☆☆☆☆¶
Tarea: Crear un Makefile para el proyecto del ejercicio anterior. El
Makefile debe tener los siguientes objetivos (targets):
all: El objetivo por defecto, que debe compilar y enlazar todo el programa para crear el ejecutablemi_calculadora.clean: Un objetivo “phony” que elimina todos los archivos generados por la compilación (.oy el ejecutable).
Compilación Condicional¶
Ejercicio 1.08.04 - Mensajes de depuración ⭐⭐☆☆☆¶
(ej_b1_c08_05)=
## Ejercicio 1.08.05 - Compilación Básica ⭐☆☆☆☆
Compilá un programa simple desde línea de comandos.
**Orientación:**
:::{hint} Lógica y Consideraciones
definición interna oculta en el archivo `.c`.
para copiar la estructura de forma segura.gcc -o programa programa.c
./programa-oespecifica nombre del ejecutableSin
-o, creaa.outpor defecto
Ejercicio 1.08.06 - Warnings Habilitados ⭐☆☆☆☆¶
Compilá con warnings completos y corregí los problemas.
Orientación:
gcc -Wall -Wextra -std=c99 -pedantic programa.c -o programa-Wall: warnings comunes-Wextra: warnings adicionales-std=c99: estándar C99-pedantic: estricto con estándar
Ejercicio 1.08.07 - Verificación de Arquitectura en Tiempo de Compilación con _Static_assert ⭐⭐☆☆☆¶
---
(ej_b1_c08_08)=
## Ejercicio 1.08.08 - Include Guards ⭐⭐☆☆☆
Explicá por qué se necesitan include guards y implementalos.
**Orientación:**
:::{hint} Lógica y Consideraciones
valores fuera de rango o tipos inválidos.
un lazo hasta que el usuario elija finalizar.#ifndef MI_HEADER_H
#define MI_HEADER_H
// Contenido del header
#endif // MI_HEADER_HPreviene inclusión múltiple
Evita errores de redefinición
Ejercicio 1.08.09 - Makefile Básico ⭐⭐⭐☆☆¶
Creá Makefile para compilar proyecto de ejercicio 3.
Makefile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14CC = gcc CFLAGS = -Wall -Wextra -std=c99 programa: main.o funciones.o $(CC) main.o funciones.o -o programa main.o: main.c funciones.h $(CC) $(CFLAGS) -c main.c funciones.o: funciones.c funciones.h $(CC) $(CFLAGS) -c funciones.c clean: rm -f *.o programa
Uso:
make # Compila
make clean # LimpiaEjercicio 1.08.10 - Biblioteca Matemática ⭐⭐⭐☆☆¶
Creá biblioteca con funciones matemáticas: factorial, potencia, fibonacci.
Estructura:
proyecto/
├── matematica.h
├── matematica.c
├── test.c
└── MakefileOrientación:
matematica.h: declaracionesmatematica.c: implementacionestest.c: programa que usa la biblioteca
Ejercicio 1.08.11 - Flags de Optimización ⭐⭐⭐☆☆¶
Compilá con diferentes niveles de optimización y medí diferencia.
Orientación:
gcc -O0 programa.c -o prog_O0 # Sin optimización
gcc -O1 programa.c -o prog_O1 # Básica
gcc -O2 programa.c -o prog_O2 # Recomendada
gcc -O3 programa.c -o prog_O3 # AgresivaMedí tiempo de ejecución:
time ./prog_O2-O0útil para debugging-O2balance entre velocidad y tamaño-O3máxima optimización
Ejercicio 1.08.12 - Compilación Condicional ⭐⭐⭐☆☆¶
Usá directivas de preprocesador para debug opcional.
Orientación:
#ifdef DEBUG
printf("Debug: valor = %d\n", valor);
#endifCompilación:
gcc -DDEBUG programa.c -o programa # Con debug
gcc programa.c -o programa # Sin debugEjercicio 1.08.13 - Módulo de Utilidades ⭐⭐⭐⭐☆¶
Creá módulo utils con funciones de uso general: intercambio, mínimo, máximo.
Estructura:
1 2 3 4 5 6 7 8 9 10 11 12 13// utils.h #ifndef UTILS_H #define UTILS_H void intercambiar(int *a, int *b); int minimo(int a, int b); int maximo(int a, int b); #endif // utils.c #include "utils.h" // Implementaciones... // main.c #include "utils.h" // Uso...
Ejercicio 1.08.14 - Makefile con Variables ⭐⭐⭐⭐☆¶
Mejorá Makefile usando variables y patrones.
Makefile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18CC = gcc CFLAGS = -Wall -Wextra -std=c99 -O2 LDFLAGS = -lm SRCS = main.c utils.c matematica.c OBJS = $(SRCS:.c=.o) TARGET = programa $(TARGET): $(OBJS) $(CC) $(OBJS) $(LDFLAGS) -o $(TARGET) %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ clean: rm -f $(OBJS) $(TARGET) .PHONY: clean
Ejercicio 1.08.15 - Dependencias Automáticas ⭐⭐⭐⭐☆¶
Generá dependencias automáticamente con gcc.
Orientación:
DEPS = $(OBJS:.o=.d)
-include $(DEPS)
%.o: %.c
$(CC) $(CFLAGS) -MMD -MP -c $< -o $@-MMD: genera archivo .d con dependencias-MP: crea targets phony para headers
Ejercicio 1.08.16 - Biblioteca Estática ⭐⭐⭐⭐⭐¶
Creá biblioteca estática (.a) y usala en programa.
Orientación:
1 2 3 4 5 6 7 8# Compilar objetos gcc -c modulo1.c modulo2.c # Crear biblioteca estática ar rcs libmibiblioteca.a modulo1.o modulo2.o # Usar biblioteca gcc main.c -L. -lmibiblioteca -o programa
ar: archiver, crea bibliotecas-L.: buscar bibliotecas en directorio actual-lmibiblioteca: enlazar con libmibiblioteca.a
Ejercicio 1.08.17 - Biblioteca Compartida ⭐⭐⭐⭐⭐¶
Creá biblioteca compartida (.so) y usala.
Orientación:
1 2 3 4 5 6 7 8 9 10 11 12# Compilar con PIC (Position Independent Code) gcc -fPIC -c modulo.c # Crear biblioteca compartida gcc -shared modulo.o -o libmodulo.so # Compilar programa gcc main.c -L. -lmodulo -o programa # Ejecutar (necesita encontrar .so) export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ./programa
Ejercicio 1.08.18 - Proyecto Multi-Directorio ⭐⭐⭐⭐⭐¶
Organizá proyecto en directorios: src/, include/, obj/, bin/.
Estructura:
proyecto/
├── src/
│ ├── main.c
│ └── modulo.c
├── include/
│ └── modulo.h
├── obj/ (generado)
├── bin/ (generado)
└── MakefileMakefile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18SRCDIR = src INCDIR = include OBJDIR = obj BINDIR = bin CFLAGS = -I$(INCDIR) -Wall -Wextra SRCS = $(wildcard $(SRCDIR)/*.c) OBJS = $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SRCS)) $(BINDIR)/programa: $(OBJS) | $(BINDIR) $(CC) $^ -o $@ $(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR) $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR) $(BINDIR): mkdir -p $@
Ejercicio 1.08.19 - Targets Adicionales ⭐⭐⭐⭐☆¶
Agregá targets útiles: run, test, install, uninstall.
Makefile:
1 2 3 4 5 6 7 8 9 10 11 12 13run: $(TARGET) ./$(TARGET) test: $(TARGET) ./$(TARGET) test_input.txt install: $(TARGET) install -m 755 $(TARGET) /usr/local/bin/ uninstall: rm -f /usr/local/bin/$(TARGET) .PHONY: run test install uninstall
Ejercicio 1.08.20 - Compilación Debug/Release ⭐⭐⭐⭐⭐¶
Makefile con modo debug y release.
Makefile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16MODE ?= release ifeq ($(MODE),debug) CFLAGS += -g -O0 -DDEBUG TARGET = programa_debug else CFLAGS += -O2 -DNDEBUG TARGET = programa endif all: $(TARGET) @echo "Compiled in $(MODE) mode" # Uso: # make # Release # make MODE=debug # Debug
Ejercicio 1.08.21 - Análisis Estático ⭐⭐⭐⭐☆¶
Integrá herramientas de análisis en Makefile.
Makefile:
1 2 3 4 5 6 7 8 9 10check: $(SRCS) cppcheck --enable=all $(SRCS) format: $(SRCS) clang-format -i $(SRCS) valgrind: $(TARGET) valgrind --leak-check=full ./$(TARGET) .PHONY: check format valgrind
Ejercicio 1.08.22 - Cross-Compilation ⭐⭐⭐⭐⭐¶
Configurá cross-compilation para diferentes arquitecturas.
Makefile:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15# Compilación nativa CC_NATIVE = gcc TARGET_NATIVE = programa # Cross-compilation para ARM CC_ARM = arm-linux-gnueabi-gcc TARGET_ARM = programa_arm arm: CC = $(CC_ARM) arm: TARGET = $(TARGET_ARM) arm: $(TARGET) native: CC = $(CC_NATIVE) native: TARGET = $(TARGET_NATIVE) native: $(TARGET)
Ejercicio 1.08.23 - Sistema de Build Completo ⭐⭐⭐⭐⭐¶
Proyecto completo con múltiples bibliotecas y tests.
Estructura:
proyecto/
├── lib/
│ ├── util/
│ │ ├── util.h
│ │ └── util.c
│ └── math/
│ ├── math.h
│ └── math.c
├── src/
│ └── main.c
├── tests/
│ ├── test_util.c
│ └── test_math.c
└── MakefileOrientación:
Compilar bibliotecas separadamente
Enlazar con main
Target para tests
Target para todo (all)
Ejercicio 1.08.24 - CMake Básico ⭐⭐⭐⭐⭐¶
Convertí proyecto a usar CMake en lugar de Makefile.
CMakeLists.txt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19cmake_minimum_required(VERSION 3.10) project(MiProyecto C) set(CMAKE_C_STANDARD 99) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra") include_directories(include) add_executable(programa src/main.c src/modulo.c ) target_link_libraries(programa m) # Tests enable_testing() add_executable(tests tests/test_main.c) add_test(NAME tests COMMAND tests)
Uso:
mkdir build
cd build
cmake ..
make
./programaNotas Finales¶
Estas consignas cubren compilación desde comandos básicos hasta proyectos complejos multi-archivo con automatización profesional.