¿Por qué CMake compila objetos con diferentes tamaños?
Estoy intentando utilizar CMake para un proyecto heredado y he notado que los binarios (CMake vs originales) tienen diferentes tamaños. Encontré una razón por la que el mismo código se convierte en archivos de objeto compilados (.o) con diferentes tamaños. Aquí hay un ejemplo mínimo y reproducible para demostrar el problema (usando Ubuntu 18.04):
Archivo main.cpp:
#include <iostream>
using namespace std; // esta línea cambia el tamaño del archivo .o
int main() {
std::cout << "¡Hola mundo!" << std::endl;
return 0;
}
Archivo CMakeList.txt:
cmake_minimum_required(VERSION 3.10)
project(hola_mundo)
add_library(app SHARED main.cpp)
Luego, en el directorio build
, ejecuta:
$ cmake -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo ../fuente
$ make
Gracias al archivo makefile extendido, podemos copiar el comando exacto enviado al compilador. Entonces, crea nuevos directorios mybuild/CMakeFiles/app.dir
(solo para coincidir con el comando) y desde el directorio mybuild
, ejecuta:
$ /usr/bin/c++ -Dapp_EXPORTS -O2 -g -DNDEBUG -fPIC -o CMakeFiles/app.dir/main.cpp.o -c /home/EjemploCMake/fuente/main.cpp
Comprobando el tamaño de ambos archivos de objeto, obtenemos:
Archivo | Tamaño |
---|---|
build/main.cpp.o |
42408 |
mybuild/main.cpp.o |
42416 |
Preguntas:
1. ¿Por qué hay una diferencia en el tamaño si el compilador está recibiendo el mismo comando?
2. ¿Cómo solucionarlo (es decir, tener el mismo tamaño desde CMake)?
davy.ai
Respuesta
¿Por qué hay una diferencia en el tamaño si el compilador recibe el mismo comando?
La diferencia de tamaño se debe al uso de
using namespace std
en el archivomain.cpp
. Cuando utilizamosusing namespace std
, importa todas las funciones y tipos de la biblioteca estándar en el espacio de nombres actual, lo que puede resultar en la inclusión de más símbolos en el archivo binario compilado. Como el archivoCMakeList.txt
no especifica ningún indicador del compilador para el nombre de objeto o la visibilidad de los símbolos, los símbolos se incluyen en el binario como visibilidad por defecto, lo que puede resultar en un archivo binario más grande.¿Cómo solucionarlo (es decir, tener el mismo tamaño desde CMake)?
Para solucionarlo, podemos establecer el indicador
-fvisibility=hidden
del compilador para ocultar los símbolos y reducir el tamaño del archivo binario. Esto se puede agregar al archivoCMakeList.txt
de la siguiente manera:Después de hacer este cambio y volver a compilar el proyecto, ambos archivos objeto deberían tener el mismo tamaño.