c++ boost cmake

c++ - ¿Existe una versión actualizada y basada en CMake para Boost?



(2)

Sería bueno construir las bibliotecas de Boost usando CMake. Aquí hay varios proyectos que han intentado o intentan hacerlo:

  1. El proyecto Boost.CMake que no se ha actualizado desde v1.41.0.
  2. El proyecto Ryppl ( http://ryppl.org/ ), pero el sitio web ahora está muerto. La mayoría de los repositorios de Ryppl Github no se han actualizado desde 2013. El grupo de Google Ryppl no ha tenido mucho tráfico desde 2013.
  3. La página wiki de CMakeModularizationStatus indica que está desactualizada y redirige a la lista de correo de ryppl-dev.
  4. https://github.com/boost-cmake parece mantenerse activamente (a principios de 2017). Su página de documentación es muy liviana; no está claro si tiene que descargar o clonar las bibliotecas de Boost por separado. Muestra un logotipo "Propuesto para bibliotecas de C ++", por lo que podemos suponer que todavía no es un componente oficial de la biblioteca Boost.

La pregunta es: ¿hay una versión actualizada y basada en CMake para Boost que funcione actualmente?

[De la pregunta original, fechada en agosto de 2013]

No encontré el "mejor" método para hacerlo. Pero 2 buenas maneras:

  1. solo incluya las fuentes que necesita si esto no es un gran problema para usted ni demasiadas fuentes. Entonces no te olvides de definir como "-DBOOST_XXXXX_SOURCE" que dice a las fuentes de impulso que no deben vincular una biblioteca. (Aparecerán advertencias ya que esta macro se redefine en las fuentes alguna vez, luego puede ignorar C4005 en esos archivos en MSVC, en CLang lamentablemente no se puede silenciar esta advertencia)
  2. use la función de proyecto externo de CMake y use el sistema de refuerzo bjam build (esto tiene el gran inconveniente de un largo tiempo de compilación, por eso debería ir solo si usa muchas bibliotecas de boost)

Gracias a todos por su ayuda


Considero que la respuesta de Fraser anterior es un buen punto de partida, pero encontré algunos problemas al utilizar Boost 1.55.0 en nuestro sistema.

Primero queríamos tener un paquete de código fuente autónomo para nuestras aplicaciones, por lo que preferimos no usar el CMake ExternalProject. Solo utilizábamos las bibliotecas thread y date_time de Boost, por lo que utilizamos bcp para crear un subconjunto de Boost con las herramientas de compilación, el hilo y otras bibliotecas dependientes:

$ bcp tools/build thread system date_time ../boost_1_55_0_threads_only

y comprobado esto en nuestro repositorio svn.

Luego, pude adaptar el archivo CMake de Fraser para construir en Linux, pero tuve problemas para ejecutar el archivo bootstrap.bat en Windows con el comando execute_process de CMake. Para ejecutar bootstrap.bat, primero necesitábamos ejecutar el guión de Visual Studio vcvarsall.bat relevante para establecer las variables de entorno (probablemente podríamos averiguar qué variables individuales deben establecerse, pero fue más fácil ejecutar todo el guión). Para ejecutar dos archivos .bat en el mismo shell usando execult_process, usamos cmd /c y enumeramos los archivos separados por un & como el argumento.

Además, bootstrap.bat no configuró el código de salida en un valor distinto de cero en caso de error, por lo que el proceso execute_process RESULT_VARIABLE para verificar el éxito no funcionó. En cambio, verificamos que el ejecutable b2.exe haya sido creado después de ejecutar el comando.

Un último problema: bootstrap.sh admite la opción --prefix= , que bootstrap.bat no tiene. También encontré que especificar la opción --prefix para b2.exe en Windows funcionaba, pero el uso de la opción --prefix para b2 en Linux, sin especificarlo para bootstrap.sh dio errores. (No he entendido por qué todavía).

Entonces, la parte relevante de nuestro archivo CMake se ve así:

# # run bootstrap # if(WIN32) if(MSVC10) set(VCVARS_CMD "C://Program^ Files^ ^(x86^)//Microsoft^ Visual^ Studio^ 10.0//VC//vcvarsall.bat") elseif(MSVC11) set(VCVARS_CMD "C://Program^ Files^ ^(x86^)//Microsoft^ Visual^ Studio^ 11.0//VC//vcvarsall.bat") elseif(MSVC12) set(VCVARS_CMD "C://Program^ Files^ ^(x86^)//Microsoft^ Visual^ Studio^ 12.0//VC//vcvarsall.bat") # elseif(...) # add more options here endif(MSVC10) set(BOOTSTRAP_CMD "${VCVARS_CMD} & bootstrap.bat") message("Executing command: ${BOOTSTRAP_CMD}") execute_process(COMMAND cmd /c "${BOOTSTRAP_CMD}" WORKING_DIRECTORY ${APT_BOOST_SRC} RESULT_VARIABLE BS_RESULT OUTPUT_VARIABLE BS_OUTPUT ERROR_VARIABLE BS_ERROR) if(NOT EXISTS ${APT_BOOST_SRC}/b2.exe) message(FATAL_ERROR "Failed running cmd /c ${BOOTSTRAP_CMD} in ${APT_BOOST_SRC}:/n${BS_OUTPUT}/n${BS_ERROR}/n") else(NOT EXISTS ${APT_BOOST_SRC}/b2.exe) message("bootstrap output:/n${BS_OUTPUT}") endif(NOT EXISTS ${APT_BOOST_SRC}/b2.exe) else(WIN32) set(BOOTSTRAP_CMD "./bootstrap.sh") set(BOOTSTRAP_ARGS "--prefix=${APT_BOOST_BIN}") message("Executing command: ${BOOTSTRAP_CMD} ${BOOTSTRAP_ARGS}") execute_process(COMMAND "${BOOTSTRAP_CMD}" ${BOOTSTRAP_ARGS} WORKING_DIRECTORY ${APT_BOOST_SRC} RESULT_VARIABLE BS_RESULT OUTPUT_VARIABLE BS_OUTPUT ERROR_VARIABLE BS_ERROR) if(NOT BS_RESULT EQUAL 0) message(FATAL_ERROR "Failed running ${BOOTSTRAP_CMD} ${BOOTSTRAP_ARGS} in ${APT_BOOST_SRC}:/n${BS_OUTPUT}/n${BS_ERROR}/n") endif() endif(WIN32) # # run b2 # set(B2_ARGS "link=static" "threading=multi" "runtime-link=static" "variant=release") foreach(COMP IN LISTS APT_BOOST_COMPONENTS) set(B2_ARGS "--with-${COMP}" ${B2_ARGS}) endforeach(COMP IN LISTS APT_BOOST_COMPONENTS) if(WIN32) if(MSVC11) set(B2_ARGS "--toolset=msvc-11.0" ${B2_ARGS}) elseif(MSVC12) set(B2_ARGS "--toolset=msvc-12.0" ${B2_ARGS}) endif(MSVC11) file(TO_NATIVE_PATH ${APT_BOOST_BIN} APT_BOOST_BIN_WIN) set(B2_ARGS "--prefix=${APT_BOOST_BIN_WIN}" ${B2_ARGS} "architecture=x86" "address-model=64") endif(WIN32) set(B2_ARGS ${B2_ARGS} install) set(B2_CMD "./b2") message("Executing command: ${B2_CMD} ${B2_ARGS}") execute_process(COMMAND ${B2_CMD} ${B2_ARGS} WORKING_DIRECTORY ${APT_BOOST_SRC} RESULT_VARIABLE B2_RESULT OUTPUT_VARIABLE B2_OUTPUT ERROR_VARIABLE B2_ERROR) if(NOT B2_RESULT EQUAL 0) message(FATAL_ERROR "Failed running ${B2_CMD} in ${APT_BOOST_SRC}:/n${B2_OUTPUT}/n${B2_ERROR}/n") endif()

En lo anterior, APT_BOOST_SRC es la ubicación del subdirectorio de Boost en nuestro directorio de origen, APT_BOOST_BIN es la ubicación que utilizamos para almacenar las bibliotecas en nuestro directorio de compilación CMake, y APT_BOOST_COMPONENTS es una lista de las bibliotecas de Boost que estamos utilizando.


También hemos tenido problemas con esto en mi lugar de trabajo. Si bien no puedo afirmar que conozco la "mejor" manera, puedo ofrecer las siguientes reflexiones sobre mis experiencias.

Inicialmente solo solicitamos a los desarrolladores que instalaran la mejora por separado y que CMake hiciera sus comprobaciones normales en forma de una find_package(Boost...) a find_package(Boost...) . Esto fue fácil, pero no automatizado, y causó problemas a los desarrolladores con versiones anteriores de boost ya instaladas.

Luego cambiamos de rumbo y añadimos una copia de las fuentes de impulso que clonamos de uno de los proyectos que mencionaste anteriormente. No recuerdo los detalles, pero creo que fue un precursor del que se está trabajando actualmente en el proyecto Ryppl. El punto principal era que ya tenía soporte para CMake; las bibliotecas de impulso fueron objetivos reales de CMake agregados a través de llamadas add_library , lo que hizo que trabajar con ellos fuera más fácil en el código CMake.

Si bien esto resolvió los problemas anteriores mediante la automatización del uso de impulso en nuestro proyecto, finalmente se convirtió en una pesadilla de mantenimiento. El proyecto de impulso que habíamos clonado cambió radicalmente y ahora es muy dependiente de las funciones CMake específicas de Ryppl. No queríamos agregar Ryppl como una dependencia, ¡así que volvimos a cambiar de táctica!

Observamos los proyectos que mencionó en su pregunta, y tampoco encontramos que ninguno de ellos sea utilizable.

Nuestra configuración actual utiliza el módulo ExternalProject de CMake. Esto nos permite descargar y construir impulso a nuestro árbol de compilación.

Ventajas:

  • Bajo mantenimiento
  • Automatizado, por lo que todos los desarrolladores utilizan la misma versión construida con las mismas banderas
  • Mantiene nuestro propio árbol fuente libre de código de terceros
  • Varias copias de boost pueden coexistir felizmente (por lo que no hay posibilidad de vincular accidentalmente una copia creada con una combinación de compilador / stdlib diferente)

Desventajas

  • Eliminar su árbol de compilación significa tener que descargar y crear un impulso desde cero. Esto podría mejorarse, por ejemplo, descargando a una ubicación fija (por ejemplo, dir de sistema temporal), por lo que el paso de descarga / descomprimir podría omitirse si se encuentra una copia existente de las fuentes de impulso.
  • Las bibliotecas de refuerzo no son adecuadas para los objetivos de CMake (es decir, no se han agregado mediante llamadas a add_library )

Aquí hay un enlace a nuestro código CMake . Hay algunas maneras en que esto necesita mejorar, pero actualmente funciona razonablemente bien para nosotros.

Espero que pronto esta respuesta se desactualice y una solución decente, modular y compatible con CMake esté disponible.