2017-01-01 8 views
-1

CMakeプロジェクトでは、バージョン番号にgitタグを使用しています。 https://github.com/iPenguin/version_gitのアプローチを使用して、私はソースコードにバージョン番号を取得できます(つまり、CMakeは、C++ソースコードで使用できるバージョン番号を含むconst文字列を含むversion.cppファイルを作成します)。問題は、私がCPackを使ってソースパッケージを作成するときに、.gitディレクトリを除外し、パッケージから抽出されたソースをコンパイルするとき、バージョン番号が利用できないということです。バージョン番号をgitタグからCPack生成ソースパッケージに転送するには?

CPackにバージョン番号をソースパッケージに入れる方法を教えてください。

私は、次の要件があります

  1. 私はビルドディレクトリは、私のソースパッケージに含まれたくないし。私がプロジェクトのルートの下のディレクトリからソース外のビルドを行うことに注意することは重要です。つまり、トップレベルのCMakeLists.txtがディレクトリmy_projectにある場合は、ディレクトリmy_project/buildに "cmake .."と "make"を実行します。

  2. ソースパッケージに.gitディレクトリを含めたくありません。

  3. cmakeによって生成されたすべてのファイルと "make package_source"がビルドディレクトリ内に存在するようにします。さらに、私はcmakeがビルドディレクトリの外にあるファイルを変更または削除しないようにします。

  4. 私はcmakeとcpackの文書化されていない動作、特にcpackで使用されているパスを使用したくありません。

これまでのところ、すべての要件を満たす解決策を見つけることができませんでした。ここで私が試したことは次のとおりです:

私はcmakeにファイルversionForSourcePackage.cmakeを作成させました。このファイルは後でcmakeによってインクルードされ、VERSION変数が設定されます。次に、このファイルをソースパッケージに入れて、抽出されたパッケージでcmakeを実行すると、VERSION変数が設定されるようにします。このファイルはビルドディレクトリの下に作成されますが、CPackがソースパッケージにコピーするようにする方法はわかりません。

最初の可能性https://github.com/iPenguin/version_gitのわずかな変更であるが、それは私の要件番号4.全例がhttps://github.com/josefcibulka/version_gitである満足していません。

リポジトリからビルドするとき、gitからバージョン番号を取得し、$ {PROJECT_BINARY_DIR} /versionForSourcePackage.cmakeに保存します。次にCPACK_INSTALL_COMMANDSを使用して、このファイルを$ {PROJECT_BINARY_DIR}/_ CPack_Packages/Linux-Source/$ {CPACK_SOURCE_GENERATOR}/$ {CPACK_SOURCE_PACKAGE_FILE_NAME} /にコピーして、パッケージに含めます。これは要件番号4に違反し、さらに将来的にTGZパッケージとZIPパッケージの両方を作成したい場合は、いくつかの変更を加える必要があります。 CPackがパッケージの内容を準備しているディレクトリへのパスを取得するためにCPACK_INSTALL_COMMANDS内で使用できる変数がありますか?

cmake_minimum_required(VERSION 2.8) 

project("version_from_git") 

# Appends the cmake/modules path to MAKE_MODULE_PATH variable. 
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH}) 

# When in the extracted package, use the previously generated file, otherwise get the current version from git. 
if(EXISTS "${PROJECT_SOURCE_DIR}/versionForSourcePackage.cmake") 
    include("${PROJECT_SOURCE_DIR}/versionForSourcePackage.cmake") 
else() 
    include(GetGitRevisionDescription) 
    git_describe(VERSION --tags --dirty=-dirty) 
endif() 

# Parse the version information into pieces. 
string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${VERSION}") 
string(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${VERSION}") 
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${VERSION}") 
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.[0-9]+(.*)" "\\1" VERSION_SHA1 "${VERSION}") 
set(VERSION_SHORT "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") 

set(CPACK_SOURCE_GENERATOR "TGZ") 
set(CPACK_PACKAGE_VERSION_MAJOR "${VERSION_MAJOR}") 
set(CPACK_PACKAGE_VERSION_MINOR "${VERSION_MINOR}") 
set(CPACK_PACKAGE_VERSION_PATCH "${VERSION_PATCH}") 
# The following will copy the version file to the source package. 
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_SHORT}-Source") 
set(CPACK_INSTALL_COMMANDS "${CMAKE_COMMAND} -E make_directory \ 
    ${PROJECT_BINARY_DIR}/_CPack_Packages/Linux-Source/${CPACK_SOURCE_GENERATOR}/${CPACK_SOURCE_PACKAGE_FILE_NAME}/" 
    "${CMAKE_COMMAND} -E copy \ 
    ${PROJECT_BINARY_DIR}/versionForSourcePackage.cmake \ 
    ${PROJECT_BINARY_DIR}/_CPack_Packages/Linux-Source/${CPACK_SOURCE_GENERATOR}/${CPACK_SOURCE_PACKAGE_FILE_NAME}/") 
# Exclude the build and .git directory from the source package. 
set(CPACK_SOURCE_IGNORE_FILES "${PROJECT_SOURCE_DIR}/.git/;${PROJECT_BINARY_DIR}/;${CPACK_SOURCE_IGNORE_FILES}") 

include (CPack) 

configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/version.cpp.in 
       ${CMAKE_CURRENT_BINARY_DIR}/version.cpp) 
# Prepare the versionForSourcePackage.cmake file that will be included in the source package. 
configure_file(
    ${PROJECT_SOURCE_DIR}/versionForSourcePackage.cmake.in 
    ${PROJECT_BINARY_DIR}/versionForSourcePackage.cmake @ONLY) 
set(version_file "${CMAKE_CURRENT_BINARY_DIR}/version.cpp") 

set(source_files "${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp") 

#Add the version_file to the project build. 
add_executable(${PROJECT_NAME} ${source_files} ${version_file}) 

ファイルversionForSourcePackage.cmake:

CMakeLists.txtは次のようになります。で:

set(VERSION "[email protected][email protected]") 

第二の可能性https://github.com/lcw/cmake_git_versionに使用されるアプローチです。完全な例は、https://github.com/josefcibulka/version_gitのsecond_possibilityブランチにあります。 versionForSourcePackage.cmakeファイルは、buildディレクトリのversion_fileというサブディレクトリに置かれ、このディレクトリはCPACK_SOURCE_INSTALLED_DIRECTORIESに追加されます。これは、プロジェクトとビルドディレクトリが同じレベルにある場合にうまく機能します。 問題は、ビルドディレクトリがプロジェクトディレクトリの下にある場合、要件1を満たすためにビルドディレクトリをCPACK_SOURCE_IGNORE_FILESに追加します。次に、version_fileディレクトリをインクルードするようにCPACK_SOURCE_INSTALLED_DIRECTORIESを設定しても無視されます。ビルドディレクトリ内のversion_fileディレクトリ以外のすべてを無視するようにすることができます。ソースパッケージ内のビルドディレクトリには、ビルドディレクトリ全体よりも優れていても、完全ではないversion_fileディレクトリのみが含まれています。

更新:それは私がthe CMake documentationでCPACK_SOURCE_INSTALLED_DIRECTORIESを見つけることができないため、要件4は、どちらか満たされていないようです。

第一の可能性との違いはCMakeLists.txtに、以下のとおりです。

# The following will transfer the version from git to the source package. 
set(CPACK_SOURCE_INSTALLED_DIRECTORIES "${PROJECT_SOURCE_DIR};/;${PROJECT_BINARY_DIR}/version_file;/") 
# Exclude the build and .git directory from the source package. 
set(CPACK_SOURCE_IGNORE_FILES "${PROJECT_SOURCE_DIR}/.git/;${PROJECT_BINARY_DIR}/([^v].*|v[^e].*|ve[^r].*|ver[^s].*|vers[^i].*|vers[^i].*|versi[^o].*|versio[^n].*|version[^_].*|version_[^f].*|version_f[^i].*|version_fi[^l].*|version_fil[^e].*);${CPACK_SOURCE_IGNORE_FILES}") 

include (CPack) 

configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/version.cpp.in 
       ${CMAKE_CURRENT_BINARY_DIR}/version.cpp) 
configure_file(
    ${PROJECT_SOURCE_DIR}/versionForSourcePackage.cmake.in 
    ${PROJECT_BINARY_DIR}/version_file/versionForSourcePackage.cmake @ONLY) 
+0

ときの包装、それはによって作成されたファイルを読み込むことができるようにCPackは、*の.cmakeスクリプトを実行することができますbuild(そしてバージョン変数を設定する)。私は今日、私のソースを持っていないが、あまりにも難しくありませんでした。 – Velkan

+0

@Velkan CPackにバージョン番号を知らせることができました。私がしたいのは、バージョン番号のファイルをソースパッケージに入れて、それを適切な方法で実行したいということを明確にするために質問を改めました。 – pepan

+0

@Velkan cpackからcmakeスクリプトを実行する可能性を指摘してくれてありがとう。これは、私がやっていたときにシェルコマンドを実行するよりも優れています。今は私が必要としていることをほぼ正確に行うことができます。私はすぐに完全な答えを書くでしょう。 – pepan

答えて

0

終わりに、私は最初の可能性の修正を使用していますが、問題は部分的にしか解決されます。

代わりのCPACK_INSTALL_COMMANDS、私はCPACK_INSTALL_SCRIPTとCMakeのスクリプトを使用します。このスクリプトは、作成されているすべてのパッケージに対して実行されます。このスクリプトの内部では、CMAKE_CURRENT_BINARY_DIRは、パッケージの内容が収集されているディレクトリを指しています。つまり、そのディレクトリにコピーしたものがパッケージの中に入ります。

ただし、これは文書化されていない動作のようです。CMAKE_CURRENT_BINARY_DIRたとえば、CMAKE_BINARY_DIRPROJECT_BINARY_DIRは、CPackによって実行されるCMakeスクリプトで使用されると空になります。したがって、CMakeの他のバージョンでは、CMAKE_CURRENT_BINARY_DIRは、CPackによって実行されると空になることがあります。

別の問題は、バージョンファイルをソースパッケージのみにコピーし、バイナリパッケージにはコピーしないことです。私がどのように区別するかは、CMAKE_CURRENT_BINARY_DIRが "Source"で終わる場合、ソースパッケージの準備中にスクリプトが実行されていることを前提としています。

例はusing_cpack_install_scriptブランチhttps://github.com/josefcibulka/version_gitです。 CMakeLists.txtの変更部品:

# The following will transfer the version from git to the source package. 
set(CPACK_INSTALL_SCRIPT "${CMAKE_BINARY_DIR}/versionNumberToPackage.cmake") 

configure_file(${CMAKE_SOURCE_DIR}/versionNumberToPackage.cmake.in 
       ${CMAKE_BINARY_DIR}/versionNumberToPackage.cmake @ONLY) 

versionNumberToPackage.cmake.inの内容は次のとおりです。

# Copies VersionForSourcePackage.cmake to the source package (it should not be copied to binary package). 
# Detection if this is the source package is that the path ends with "Source" and an optional slash. 
if("${CMAKE_CURRENT_BINARY_DIR}" MATCHES "Source/?$") 
    file(COPY @[email protected]/versionForSourcePackage.cmake DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) 
endif() 
関連する問題