4

アップデート

Windows の cpack バージョンのバグのようです。Linux (Ubuntu) では、cpack コマンドで不足しているファイルが表示されます。時間があるときに、さらに調査を行い、結果を投稿します。


注: この質問を単純化して新しい短い例を作成することができたので、この質問を完全に変更しました。しかし、コアの問題は少しも変わりませんでした。

問題の説明

私はライブラリ プロジェクトを持っています。それを Foo と呼びましょうcpack。コマンドを使用してパックします。このパッケージにはFooConfig.cmakeFooTargets.cmakeファイル (cmake メカニズムによってエクスポートされた 2 番目のファイル) が含まれています。問題は、cmake がそれを使用するのに十分ではないということです。find_package()で見つけたのですが、でリンクするfooNo rule to make target foo-NOTFOUND', needed by bar.exe'. Stop.エラーが出ます。

しかし、でインストールするとmake install DESTDIR=./out_dir、動作し、もう 1 つのファイルが含まれます: FooTargets-noconfig.cmake. このファイルには、foo ライブラリ ファイルへのパスが含まれています。

それで、これを修正するために私は何をする必要がありますか?この動作を説明するドキュメントはありますか?

おまけの質問:*-noconfig*ファイルにはライブラリへのパスが含まれていますが、ヘッダー ディレクトリへのパスは含まれていません。この生成されたファイルにも自動的に含まれるようにライブラリ プロジェクトを構成する方法はありますか?

詳細情報、メモ:

  • 私の OS: Windows 7、64 ビット。
  • コンパイラ: MinGW 4.4.0 (32 ビット)。(注: はい、代わりにコマンドmakeを使用しますmingw32-make。)
  • CMake バージョン: cmake 2.8.12.2。
  • の結果を使用しようとするmake installと、No rule to make target xyz-NOTFOUND', needed by Index.exe'. Stop.エラーが消え、すべてがコンパイルされ、結果のexeが期待どおりに機能しました。必要なものは noconfig ファイルだけのようです。

ワークフロー / 再現手順:

  • コードを作成した後 (以下を参照):
  • cmake-guiビルド ディレクトリ (ライブラリ プロジェクト) を作成する (構成、次に生成)
  • mingw32-makeビルドディレクトリに
  • バリアント a)mingw32-make install DESTDIR=./out_dirライブラリをインストールする
  • バリアント b)cpack -C CpackConfig.cmake -G ZIPライブラリでパッケージを取得する
  • 前のステップのファイルを使用し、環境変数にある特別なディレクトリに移動してCMAKE_PREFIX_PATH、cmake がそれを見つけられるようにします (元のファイルが削除されるように、「コピー」ではなく「移動」に注意してください)。
  • cmake-gui実行可能プロジェクトの場合 (再度、構成、次に生成)
  • mingw32-makeビルドディレクトリに

最後のステップは、バリアント a) と b) で異なります。a) の場合、期待どおり、ビルドが終了し、実行可能ファイルが正常に動作します。b) の場合、エラーNo rule to make target xyz-NOTFOUND', needed by Index.exe'. Stop.が表示され、それ以上の情報はありません。

私のコード例:

- Foo/                          (Experimental library)
  - CMakeLists.txt              (XyzLib configuration)
  - foo.cpp                     (Function implementation - just prints something)
  - foo.h                       (Contains just single function)
  - FooConfig.cmake             (Configuration so the find_package find the
                                 library)
- Bar/                          (Testing executable)
  - CMakeLists.txt              (Executable configuration)
  - bar.cpp                     (Main function printing something and
                                 calling the Foo library function)

Foo/CMakeLists.txt:

cmake_minimum_required(VERSION 2.6.3)
project("Foo")

add_library(foo STATIC foo.h foo.cpp)

set_target_properties(foo PROPERTIES PUBLIC_HEADER foo.h)

install(TARGETS foo EXPORT fooTargets
        RUNTIME DESTINATION bin
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib
        PUBLIC_HEADER DESTINATION include
        INCLUDES DESTINATION include)

install(FILES FooConfig.cmake DESTINATION lib/foo)

install(EXPORT fooTargets FILE "FooTargets.cmake" DESTINATION lib/foo)

include(CPack)

フー/foo.cpp:

#include <iostream>

#include "foo.h"

void FooCall()
{
    ::std::cout << "Hello from Foo!" << ::std::endl;
}

フー/フー.h:

#ifndef FOO_H
#define FOO_H

void FooCall();

#endif // FOO_H

Foo/FooConfig.cmake :

# - Config file for the Foo library package
# This module defines the following variables:
#  Foo_FOUND         - true if this module was found, false otherwise
#  Foo_INCLUDE_DIRS  - include directories
#  Foo_LIBRARIES     - libraries to link against

get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)

# Import targets
include("${SELF_DIR}/FooTargets.cmake")

# Foo_INCLUDE_DIRS
get_filename_component(Foo_INCLUDE_DIRS "${SELF_DIR}/../../include" ABSOLUTE)

# Foo_LIBRARIES
set(Foo_LIBRARIES foo)

バー/CMakeLists.txt:

cmake_minimum_required(VERSION 2.6.3)
project("Bar")

add_executable(bar bar.cpp)

find_package(Foo REQUIRED)
include_directories(${Foo_INCLUDE_DIRS})
target_link_libraries(bar ${Foo_LIBRARIES})

バー/bar.cpp

#include <iostream>

#include "foo.h"

int main(int argc, char *argv[])
{
    ::std::cout << "Hello from bar!" << ::std::endl;
    FooCall();
    return 0;
}

いくつかの生成されたファイル:

興味がある場合のために、生成されたファイルはいくつかあります。

lib/foo/FooTargets-noconfig.cmake

#----------------------------------------------------------------
# Generated CMake target import file for configuration "".
#----------------------------------------------------------------

# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)

# Import target "foo" for configuration ""
set_property(TARGET foo APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
set_target_properties(foo PROPERTIES
  IMPORTED_LINK_INTERFACE_LANGUAGES_NOCONFIG "CXX"
  IMPORTED_LOCATION_NOCONFIG "${_IMPORT_PREFIX}/lib/libfoo.a"
  )

list(APPEND _IMPORT_CHECK_TARGETS foo )
list(APPEND _IMPORT_CHECK_FILES_FOR_foo "${_IMPORT_PREFIX}/lib/libfoo.a" )

# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)

lib/foo/FooTargets.cmake

# Generated by CMake 2.8.12.2

if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
   message(FATAL_ERROR "CMake >= 2.6.0 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.6)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------

# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)

# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_targetsDefined)
set(_targetsNotDefined)
set(_expectedTargets)
foreach(_expectedTarget foo)
  list(APPEND _expectedTargets ${_expectedTarget})
  if(NOT TARGET ${_expectedTarget})
    list(APPEND _targetsNotDefined ${_expectedTarget})
  endif()
  if(TARGET ${_expectedTarget})
    list(APPEND _targetsDefined ${_expectedTarget})
  endif()
endforeach()
if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
  set(CMAKE_IMPORT_FILE_VERSION)
  cmake_policy(POP)
  return()
endif()
if(NOT "${_targetsDefined}" STREQUAL "")
  message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
endif()
unset(_targetsDefined)
unset(_targetsNotDefined)
unset(_expectedTargets)


# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)

# Create imported target foo
add_library(foo STATIC IMPORTED)

set_target_properties(foo PROPERTIES
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)

# Load information for each installed configuration.
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB CONFIG_FILES "${_DIR}/FooTargets-*.cmake")
foreach(f ${CONFIG_FILES})
  include(${f})
endforeach()

# Cleanup temporary variables.
set(_IMPORT_PREFIX)

# Loop over all imported files and verify that they actually exist
foreach(target ${_IMPORT_CHECK_TARGETS} )
  foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
    if(NOT EXISTS "${file}" )
      message(FATAL_ERROR "The imported target \"${target}\" references the file
   \"${file}\"
but this file does not exist.  Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
   \"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
    endif()
  endforeach()
  unset(_IMPORT_CHECK_FILES_FOR_${target})
endforeach()
unset(_IMPORT_CHECK_TARGETS)

# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.

# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
4

1 に答える 1

1

export コマンドを使用して、ビルド ディレクトリから使用するエクスポート ターゲットを作成します。

http://www.cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html#creating-packages

CMake 2.8.12 は export(EXPORT) をサポートしていませんが、export(TARGETS) をサポートしています。

于 2014-05-15T13:23:29.807 に答える