web-dev-qa-db-fra.com

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 ajouter un boost directement dans cmake et le construire. Est-ce disponible?

47
dzada

Nous avons également eu beaucoup de mal avec cela sur mon lieu de travail. Bien que je ne puisse certainement pas prétendre connaître la "meilleure" façon, je peux offrir les réflexions suivantes sur mes expériences.

Au début, nous avions juste besoin que les développeurs installent boost séparément et nous avons demandé à CMake de faire ses vérifications normales sous la forme d'un appel find_package(Boost...) . Cela a été facile, mais pas automatisé, et a causé des problèmes aux développeurs avec les anciennes versions de boost déjà installées.

Nous avons ensuite changé de tactique et ajouté une copie des sources de boost que nous avons clonées à partir de 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 de celui en cours d'élaboration dans le projet Ryppl. Le point principal était qu'il avait déjà un soutien pour CMake; les bibliothèques boost étaient des cibles CMake réelles ajoutées via add_library appels, ce qui a facilité leur utilisation dans le code CMake.

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

Nous avons examiné les projets que vous avez mentionnés dans votre question et nous avons également constaté qu'aucun d'entre eux n'était utilisable.

Notre configuration actuelle utilise le module ExternalProject de CMake. Cela nous permet de télécharger et de booster notre build build tree.

Avantages:

  • Faible entretien
  • Automatisé, donc tous les développeurs utilisent la même version construite avec les mêmes drapeaux
  • Maintient notre propre arbre source sans code tiers
  • Plusieurs copies de boost peuvent coexister avec bonheur (donc aucune chance de se lier accidentellement à 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 augmenter la création à partir de zéro. Cela pourrait être amélioré par ex. le téléchargement vers un emplacement fixe (par exemple, le répertoire temp du système), de sorte que l'étape de téléchargement/décompression pourrait être ignorée si une copie existante des sources de boost est trouvée.
  • Les bibliothèques boost ne sont pas des cibles CMake appropriées (c'est-à-dire qu'elles n'ont pas été ajoutées via add_library appels)

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

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

40
Fraser

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

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

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

et vérifié cela dans notre référentiel svn.

Ensuite, j'ai pu adapter le fichier CMake de Fraser pour construire sur Linux, mais j'ai rencontré des problèmes lors de l'exécution de bootstrap.bat fichier sous Windows avec la commande execute_process de CMake. Pour exécuter bootstrap.bat, nous devions d'abord exécuter Visual Studio vcvarsall.bat script 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 & comme argument.

Aussi bootstrap.bat n'a pas défini le code de sortie sur zéro en cas d'échec, donc l'utilisation de execute_process RESULT_VARIABLE pour vérifier la réussite n'a 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 numéro: bootstrap.sh prend en charge le --prefix= option, qui bootstrap.bat ne fait pas. J'ai également constaté que la spécification du --prefix option pour b2.exe sur Windows fonctionnait, mais en utilisant le --prefix option pour b2 sous Linux, sans le spécifier pour bootstrap.sh a donné des erreurs. (Je n'ai pas encore compris pourquoi).

Ainsi, la partie pertinente de notre fichier CMake ressemble à:

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

Au dessus APT_BOOST_SRC 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.

5
user1735629