質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CMake

CMakeはクロスプラットフォームで作動するオープンソースのビルドシステムです。コマンドライン又は組み込まれた開発環境で使うことができる元のmakefileとプロジェクトファイルを生成します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

313閲覧

cmakeで動的ライブラリの動的リンク方法について

id9m4i2l67

総合スコア7

CMake

CMakeはクロスプラットフォームで作動するオープンソースのビルドシステムです。コマンドライン又は組み込まれた開発環境で使うことができる元のmakefileとプロジェクトファイルを生成します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2024/02/10 05:54

編集2024/02/10 07:27

実現したいこと

cmakeで自作の動的ライブラリを動的リンクでプロジェクトに組み込んで実行したいのですが、実行時にエラーが出てしまい、上手くいきません。CMakeLists.txtの書き方に誤りがあればご指摘いただけますでしょうか

前提

VisualStudio2019を利用して以下3プロジェクトを作成いたしました。
■プロジェクト⓵:DynamicLibrarySample
動的ライブラリのプロジェクトでint piyopiyo(int a, int b)というメソッドが定義されており、
戻り値にはa + bの値を返すメソッドが1つだけ定義されている。

■プロジェクト②:LibraryCallSample
C++のコンソールアプリで⓵を動的リンクして呼び出すアプリ

■プロジェクト③:CMakeSample(★今回の問題が起きてるプロジェクト)
プロジェクトファイルを作らずCMakeを使って⓵を動的リンクして呼び出すアプリ

下記記載のソースとライブラリは全て同じディレクトリに配置
・CMakeSample.cpp
・CMakeLists.txt
・DynamicLibrarySample.h
・DynamicLibrarySample.lib
・DynamicLibrarySample.dll

発生している問題・エラーメッセージ

重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態 エラー 'MyLibrary-NOTFOUND', needed by 'CMakeSample/CMakeSample.exe', missing and no known rule to make it

該当のソースコード

CMakeSample.cpp

1 2#include "CMakeSample.h" 3#include "DynamicLibrarySample.h" 4 5#pragma comment (lib, "DynamicLibrarySample.lib") 6 7using namespace std; 8 9int main() 10{ 11 int a = 1; 12 int b = 2; 13 14 int ret = piyopiyo(a, b); 15 16 printf("%d", ret); 17 18 return 0; 19} 20

CMakeLists.txt

1cmake_minimum_required (VERSION 3.8) 2 3add_executable (CMakeSample "CMakeSample.cpp" "CMakeSample.h" "DynamicLibrarySample.h") 4 5# ライブラリを追加 6add_library(MyLibrary SHARED IMPORTED) 7set_target_properties(MyLibrary PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/DynamicLibrarySample.lib) 8 9# ターゲットとライブラリをリンク 10target_link_libraries(CMakeSample PRIVATE MyLibrary) 11

試したこと

プロジェクト2で同一ライブラリをプロジェクトとして組み込んだアプリではライブラリが動作することを確認いたしました。
また、ここには記載しておりませんが、プロジェクト3と同様の手法で静的ライブラリを組み込んだアプリが動作することは確認いたしました。
(但し、CMakeLists.txtのSHAREDの箇所はSTATICと記述して確認)

試したこと(追記:2024/02/10 16:20)

IMPORTED_LOCATIONにはdllを指定するべきとQiitaのノートを見つけたので以下2パターンを試しましたが、エラーが変わりましたが正常には動作しませんでした。

CMakeLists.txt

1# ライブラリを追加 2add_library(MyLibrary SHARED IMPORTED) 3set_target_properties(MyLibrary PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/DynamicLibrarySample.dll)

→エラーの内容は変わりませんでした。

CMakeLists.txt

1# ライブラリを追加 2add_library(MyLibrary SHARED IMPORTED) 3set_target_properties(MyLibrary PROPERTIES IMPORTED_IMPLIB ${CMAKE_SOURCE_DIR}/DynamicLibrarySample.lib) 4set_target_properties(MyLibrary PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/DynamicLibrarySample.dll)

→エラーの内容が変わりましたがやはり正常には実行できませんでした。
重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態
エラー '../../../DynamicLibrarySample.lib', needed by 'CMakeSample/CMakeSample.exe', missing and no known rule to make it

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dameo

2024/02/10 19:45

add_libraryは(ビルド)ターゲットとしての追加なので、それを意図してるのでなければ不要かと思います。 正しい方法を知らないので、回答はしかねますが、VS2019で ・CMakeプロジェクトをCMakeProject1という名前でソリューションに追加する形(意味あるか不明)で作成 ・そのソリューションに元から追加されていたVC++のDLL用プロジェクトDll1の成果物をリンク ・アーキテクチャをx64にして同じビルドタイプ・アーキテクチャでDll1がビルドしてある 前提なら、CMakeProject1プロジェクトの直下にあるCMakeLists.txtを以下のように記述することでビルドだけは出来るようでした。 cmake_minimum_required (VERSION 3.8) add_executable (CMakeProject1 "CMakeProject1.cpp" "CMakeProject1.h") find_path(DLL1_INCLUDE_DIR dll1.h PATHS ../Dll1 REQUIRED) find_library(DLL1_LIBRARY dll1 PATHS ../x64/${CMAKE_BUILD_TYPE} REQUIRED) include_directories(${DLL1_INCLUDE_DIR}) target_link_libraries(CMakeProject1 ${DLL1_LIBRARY}) ※ビルドできてもDLLはコピーされないので、そのままでは実行できません。
id9m4i2l67

2024/02/11 06:17

ご回答ありがとうございます。 ご指摘通り、add_libraryの使い道の根本を間違えているようでした。 動的リンクについてはtarget_link_librariesでlibファイルを指定するだけでビルドが上手くいきました。 その後、dllファイルをビルド先にコピーするカスタムコマンドを追加することで目的の動作を果たすことが出来ました。折角なので動作版を下記コメントに残すことにいたしました。 前回のご質問に続き、今回も詳細なご説明までしていただき、重ね重ね本当にありがとうございます。
guest

回答1

0

自己解決

下記記述で解決したのでクローズいたします。
根本原因はadd_libraryがライブラリをビルドするための命令であるのに、ビルド時にライブラリを追加するための命令だと勘違いしている点と、${CMAKE_SOURCE_DIR}の変数が"現在の"CMakeLists.txtの場所を指している変数と勘違いしている点でした(${CMAKE_SOURCE_DIR}は大元のCMakeLists.txtでサブファイルの場合は${CMAKE_CURRENT_SOURCE_DIR})
また、ビルド後にdllファイルをexeファイルの出力先にコピーするコマンドを追加することで本問題は全て解決いたしました。

CMakeLists.txt

1cmake_minimum_required (VERSION 3.8) 2 3add_executable (CMakeSample "CMakeSample.cpp" "CMakeSample.h" "DynamicLibrarySample.h") 4 5target_link_libraries(CMakeSample PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/DynamicLibrarySample.lib) 6 7add_custom_command( 8 TARGET CMakeSample POST_BUILD 9 COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/DynamicLibrarySample.dll "${CMAKE_BINARY_DIR}/CMakeSample" 10)

投稿2024/02/11 06:23

id9m4i2l67

総合スコア7

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問