Est-il possible de construire Boost avec CMake?

Plutôt que d’inclure des bibliothèques statiques dans mon arbre source dans un projet compilé de manière croisée, j’aimerais append directement Boost dans cmake et le construire. Est-ce disponible?

Nous avons eu beaucoup de mal avec ça aussi sur mon lieu de travail. Bien que je ne puisse certainement pas prétendre connaître le «meilleur» moyen, je peux offrir les reflections suivantes sur mes expériences.

Au début, nous avions simplement demandé à devs d’installer boost séparément et CMake faisait ses vérifications normales sous la forme d’un find_package(Boost...) . Cela a été facile, mais pas automatisé, et a causé des problèmes aux développeurs avec d’anciennes versions de boost déjà installées.

Nous avons ensuite changé d’adresse et ajouté une copie des sources de boost que nous avons clonées à l’un des projets que vous avez mentionnés ci-dessus. Je ne me souviens pas des détails, mais je pense que c’était un précurseur à celui sur lequel on travaille actuellement dans le projet Ryppl. L’essentiel était qu’il avait déjà un support pour CMake; Les bibliothèques de boost étaient des cibles CMake réelles ajoutées via des appels add_library , ce qui les rendait plus faciles à add_library dans le code CMake.

Bien que cela ait résolu les problèmes précédents en automatisant l’utilisation du boost dans notre projet, il est finalement devenu un cauchemar de maintenance. Le projet boost que nous avions cloné a changé radicalement et est maintenant très dépendant des fonctions CMake spécifiques à Ryppl. Nous ne voulions pas append Ryppl comme dépendance, nous avons donc changé de tactique!

Nous avons examiné les projets que vous avez mentionnés dans votre question et nous n’avons trouvé aucun d’entre eux utilisables.

Notre configuration actuelle utilise le module ExternalProject de CMake. Cela nous permet de télécharger et de renforcer notre arbre de compilation.

Avantages:

  • Faible entretien
  • Automatisé, donc tous les développeurs utilisent la même version construite avec les mêmes indicateurs
  • Conserve notre propre arbre source sans code tiers
  • Plusieurs copies de boost peuvent coexister (donc aucune possibilité de liaison accidentelle à une copie construite avec une combinaison compilateur / stdlib différente)

Désavantages

  • La suppression de votre arborescence de construction signifie que vous devez télécharger et générer une impulsion à partir de zéro. Cela pourrait être amélioré en téléchargeant, par exemple, vers un emplacement fixe (par exemple, répertoire temporaire du système), de sorte que l’étape de téléchargement / décompression puisse être ignorée si une copie existante des sources de boost est trouvée.
  • Les bibliothèques de boost ne sont pas des cibles CMake correctes (c’est-à-dire qu’elles n’ont pas été ajoutées via les appels à add_library )

Voici un lien vers notre code CMake . Il y a plusieurs façons d’améliorer ce besoin, mais cela fonctionne assez bien pour nous.

J’espère que cette réponse deviendra rapidement obsolète et qu’une solution décente, modulaire et compatible CMake sera disponible.

J’ai trouvé la réponse de Fraser ci-dessus comme un bon sharepoint départ, mais j’ai rencontré quelques problèmes avec Boost 1.55.0 sur notre système.

Tout d’abord, nous voulions avoir un package de code source autonome pour nos applications, nous avons donc préféré ne pas utiliser CMake ExternalProject. Nous n’utilisions que les librairies thread et date_time de Boost, nous avons donc utilisé bcp pour créer un sous-ensemble de Boost avec les outils de construction, les threads et autres bibliothèques dépendantes:

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

et vérifié cela dans notre repository svn.

Ensuite, j’ai pu adapter le fichier CMake de Fraser à Linux, mais j’ai rencontré des problèmes lors de l’exécution du fichier bootstrap.bat sous Windows avec la commande execute_process de CMake. Pour exécuter bootstrap.bat, nous devions d’abord exécuter le script Visual Studio vcvarsall.bat pour définir les variables d’environnement (nous pourrions probablement déterminer quelles variables individuelles doivent être définies, mais il était plus facile d’exécuter l’ensemble du script). Pour exécuter deux fichiers .bat dans le même shell en utilisant execult_process, nous avons utilisé cmd /c et répertorié les fichiers séparés par un argument & as.

En outre, bootstrap.bat n’a pas défini le code de sortie sur zéro en cas d’échec. L’utilisation du processus execute_process RESULT_VARIABLE pour vérifier le succès n’a donc pas fonctionné. Au lieu de cela, nous avons vérifié que l’exécutable b2.exe avait été créé après l’exécution de la commande.

Un dernier problème: bootstrap.sh prend en charge l’option --prefix= , qui n’est pas bootstrap.bat . J’ai également trouvé que spécifier l’option --prefix pour b2.exe sur Windows fonctionnait, mais utiliser l’option --prefix pour b2 sous Linux sans le spécifier pour bootstrap.sh donnait des erreurs. (Je n’ai pas encore compris pourquoi).

Donc, la partie pertinente de notre fichier CMake ressemble à ceci:

  # # 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() 

APT_BOOST_SRC ci-dessus est l’emplacement du sous-répertoire Boost dans notre répertoire source, APT_BOOST_BIN est l’emplacement que nous utilisons pour stocker les bibliothèques dans notre répertoire de construction CMake, et APT_BOOST_COMPONENTS est une liste des bibliothèques Boost que nous utilisons.