2

私はCMakeを初めて使用し、プロジェクトをコンパイルしようとしています。プロジェクトは、いくつかの静的ライブラリといくつかの実行可能ファイルを作成します。

以下は私が持っているファイル構造の例です。

事業

  • SRC

    1. subProject_1
      .cpp(すべてのソースファイル)およびこのフォルダーのCMakeLists.txt 1(静的ライブラリの作成)
    2. subproject_2
      .cpp(すべてのソースファイル)およびこのフォルダーのCMakeLists.txt 2(静的ライブラリの作成)
    3. subproject_3
      .cpp(すべてのソースファイル)およびこのフォルダーのCMakeLists.txt 3(実行可能ファイルの作成)
  • 含む

    1. subProject_1
      .h(すべてのヘッダーファイル)
    2. subProject_2
      .h(すべてのヘッダーファイル)
    3. subProject_3
      .h(すべてのヘッダーファイル)
  • ビルド/Linux

    1. CMakeLists.txt(メインCMakelistファイル)

メインCMakeLists.txt

cmake_minimum_required(VERSION 2.6)
SET(CMAKE_CXX_COMPILER "g++")
Project(ort)
SET (CMAKE_CXX_FLAGS " -g -Wall -pThread")

#set the source and header directories location
set(ORT_HEADER_DIRECTORY "../../include") #include folder structure explained above
set(ORT_SOURCE_DIRECTORY "../../src")
set(ORT_BINARY_DIRECTORY "../../lib")  # lib folder to contain all the libraries

set (CMAKE_CURRENT_BINARY_DIR ".")

#Include the library packages
include_directories("/usr/include/wx-2.8")
include_directories("/usr/local/cuda/include") and so on


#set the names of all the projects (for creating the libraries)
SET(PROJECT_NAMES "log" "data" "cc")

foreach(PROJECT_NAME ${PROJECT_NAMES})
     # Create the cmake related files in the out folder so that the libraries can be
     # copied to the lib folder
     add_subdirectory( "{ORT_SOURCE_DIRECTORY}/${PROJECT_NAME}" "${CMAKE_CURRENT_BINARY_DIR}/out/${PROJECT_NAME}"

endforeach(PROJECT_NAME ${PROJECT_NAMES})

#set the names of all the projects (for creating the libraries)
SET(EXECUATALE_PROJECTS "metadata" )

foreach(EXECUATALE_PROJECT ${EXECUATALE_PROJECTS})
     # Create the cmake related files in the out folder so that the libraries can be
     # copied to the lib folder
     add_subdirectory( "{ORT_SOURCE_DIRECTORY}/${EXECUATALE_PROJECT}" "${CMAKE_CURRENT_BINARY_DIR}/out/${EXECUATALE_PROJECT}"

endforeach(EXECUATALE_PROJECT ${EXECUATALE_PROJECTS})

ログディレクトリ用のCMakeLists.txtファイル(ccおよびデータプロジェクトに使用したのと同じロジック)

include_directories(${ORT_HEADER_DIRECTORY})
SET(LOG_SOURCE a.cpp b.cpp c.cpp)
ADD_LIBRARY(log_d ${LOG_SOURCE})
target_link)libraries(log_d cc_d data_d)

メタデータCMakeLists.txtファイル(実行可能プロジェクトの作成)

FIND_PACKAGE(wxWidgets)
IF(wxWidgets_FOUND)
        INCLUDE(${wxWidgets_USE_FILE})
ENDIF(wxWidgets_FOUND)

Include_Directories(${wxWidgets_INCLUDE_DIRS})
include_directories(${ORT_HEADER_DIRECTORY})
include_directories("/usr/ort/lib/unixODBC/include")

SET(META_SOURCE meta.cpp data.cpp)

ADD_EXECUTABLE(meta_d ${META_SOURCE })
TARGET_LINK_LIBRARIES(meta_d log_d data_d)

実行可能ファイルを作成せずにプロジェクトを作成するだけで、静的ファイルが生成されます。しかし、プロジェクト全体を作成すると(つまり、subProject_3ディレクトリを含めると)、a.cppa::Stringの関数である未定義の参照が取得されます。

注:3つのプロジェクトはすべて相互に依存しています。たとえば、a.cppにはが#include "b.h"あり、b.cppにはがあり#include "a2.h"ます。

だから、私はいくつかの質問があります:

a)未定義の参照の問題を解決するにはどうすればよいですか?プロジェクト1と2のライブラリを生成したら、これらを実行可能ファイルにリンクするにはどうすればよいですか?

b)静的ライブラリを作成するときに依存関係を提供または追加する必要がありますか?これは静的ライブラリを作成する正しい方法ですか(プロジェクトは相互に依存しているため)?つまりtarget_link_libraries(project1 project2 ...)、プロジェクト1とtarget_link_libraries(project2 project1 ...)プロジェクト2です。

c)すべてのプロジェクトは、独自のコンパイル設定でコンパイルする必要があります。個々のプロジェクトごとに同じものを指定するにはどうすればよいですか?

エラーの詳細:

CXX実行可能ファイルのメタデータが好きです../log/liblog_d.a:ファイルが認識されません:ファイルが切り捨てられましたcollect2:ldが1つの終了ステータスを返しました

また、未定義の参照エラー/home...../metadata/data.cpp 172:xmlSerahNsへの未定義の参照などが発生します。collect2:ldが1つの終了ステータスを返しました

助けてくれてありがとう。

4

1 に答える 1

7

未定義の参照の問題を解決するにはどうすればよいですか?プロジェクト1と2のライブラリを生成しているので、これらを実行可能ファイルにリンクするにはどうすればよいですか。

target_link_libraries今回はsubProject3のCMakeLists.txtでもう一度使用してください。

target_link_libraries(subProject3 subProject2 subProject1)

これは静的ライブラリを作成する正しい方法ですか(プロジェクトは相互に依存しているため)

はい。のドキュメントからtarget_link_libraries

ライブラリ依存関係グラフは通常非循環(DAG)ですが、相互に依存するSTATICライブラリの場合、CMakeではグラフにサイクル(強連結成分)を含めることができます。別のターゲットがライブラリの1つにリンクすると、CMakeは接続されたコンポーネント全体を繰り返します。たとえば、コード

add_library(A STATIC a.c)
add_library(B STATIC b.c)
target_link_libraries(A B)
target_link_libraries(B A)
add_executable(main main.c)
target_link_libraries(main A)

「main」を「ABAB」にリンクします。(通常は1回の繰り返しで十分ですが、病理学的オブジェクトファイルとシンボルの配置にはさらに多くの時間が必要になる場合があります。最後のtarget_link_libraries呼び出しでコンポーネントを手動で繰り返すことで、このような場合に対処できます。ただし、2つのアーカイブが実際に相互依存している場合は、それらを組み合わせて単一のアーカイブ。)


すべてのプロジェクトは、独自のコンパイル設定でコンパイルする必要があります。個々のプロジェクトごとに同じものを指定するにはどうすればよいですか?

トップレベルのCMakeLists.txtでは、サブディレクトリを追加する前に、そこに必要なすべてのフラグを設定できます。(例を参照add_definitionsProperties on Targetsサブプロジェクト用に特別に変更されない限り、すべてのサブプロジェクトで採用されます。

于 2012-11-01T19:29:10.177 に答える