静的ライブラリをReleaseビルドとDebugビルドで共用したい。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
YUKI_DAYO
記事: 16
登録日時: 2年前

静的ライブラリをReleaseビルドとDebugビルドで共用したい。

#1

投稿記事 by YUKI_DAYO » 2年前

はじめましてこんにちは。

一般的に配布されている(?)静的ライブラリはリリースビルドとデバッグビルドで共通のものが使用されていると思っています。例えば libvulkan-1.a や d3d12.lib など

そのため、自分で .lib もしくは lib.a ファイルを作成するときにも共用できるタイプで作成したいと思いました。しかし、.obj もしくは .o ファイルを作成する際に、-D_DEBUG や -DNDEBUG などのデバッグ用とリリース用で異なるプリプロセッサフラグを指定する場合があります。
そうすると .obj ファイルから .lib ファイルを作成するときにデバッグもしくはリリース用で固定されてしまいます。

そこで質問なのですが、これを回避し、デバッグビルドとリリースビルドで共通して使える .lib ファイルは作成できるのでしょうか?


↓自分の予想↓
vulkan-1.lib と d3d12.lib には対応するランタイム dll(vulkan-1.dll, d3d12.dll)が OS に入っていることや、c++ - Debug版とRelease版で同じLibファイルにする方法 - スタック・オーバーフロー を見た感じ、 .lib ファイル単体では共通して使用できず、共通して利用するには .dll または lib.so ファイルが必要なのかな。と思いました。
ただ、.dll に関して完全に無知なのでよく分かりません。教えてください。

環境
Windows 10 64bit
MSYS2 MinGW x64 - GCC 11.2.0

アバター
あたっしゅ
記事: 663
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: 静的ライブラリをReleaseビルドとDebugビルドで共用したい。

#2

投稿記事 by あたっしゅ » 2年前

東上☆海美☆「
静的にリンクされるライブラリなら .exe と一体になっていて .dll は、用いないのでは ?
別の話をしているのかみみ ?
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。

アバター
usao
記事: 1887
登録日時: 11年前

Re: 静的ライブラリをReleaseビルドとDebugビルドで共用したい。

#3

投稿記事 by usao » 2年前

マルチポスト.ちゃんと対応してね.

YUKI_DAYO
記事: 16
登録日時: 2年前

Re: 静的ライブラリをReleaseビルドとDebugビルドで共用したい。

#4

投稿記事 by YUKI_DAYO » 2年前

マルチポストはよくなかったですね。
反省してます。

https://teratail.com/questions/376791

こちらで同様の質問をしてますので、返信してくださる方、同じ疑問を持った方はこちらを参照してください。

アバター
あたっしゅ
記事: 663
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: 静的ライブラリをReleaseビルドとDebugビルドで共用したい。

#5

投稿記事 by あたっしゅ » 2年前

東上☆海美☆「
『Release 時と Debug 時で同じ .dll をリンクしたい』という本筋から離れた話だから、
他サイトでは触れられていないようだが、


(1)DirectX のランタイム(今なら d3d12.dll か ?)なら、Debug 時の .dll は、Release 時の .dll と違って、
引数をチェックするコードが入っていて遅い、という話を聞いたことがあるみみ。


(2)「静的リンク」か「動的リンク」か、については、下記を参考のこと。

https://qiita.com/argama147/items/2f636a2f4fd76f6ce130
ライブラリのリンク方法をきっちり区別しよう - Qiita(ja)</a>
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。

アバター
usao
記事: 1887
登録日時: 11年前

Re: 静的ライブラリをReleaseビルドとDebugビルドで共用したい。

#6

投稿記事 by usao » 2年前

> 『Release 時と Debug 時で同じ .dll をリンクしたい』という本筋

そもそもそんなこと言ってないように見える.
共用したいのは「静的ライブラリ」であり dll の話はしてない.

Debug,Releaseで共用できる「スタティックライブラリが作りたい」って話でしょ.
質問文の末尾側にある

> ↓自分の予想↓

のところに書いてある話は,
「スタックオーバーフローの話を見た感じだと,インポートライブラリならば共用できるっぽいけど,そうじゃない場合(実装が詰まったlib)ではできないっぽい」
という調査結果を述べているだけであろう.

アバター
tk-xleader
記事: 158
登録日時: 13年前
連絡を取る:

Re: 静的ライブラリをReleaseビルドとDebugビルドで共用したい。

#7

投稿記事 by tk-xleader » 2年前

解決していたら申し訳ないんですが…

msvcのlibcはちょっとややこしいので、基本的なことから説明します。以下はmsvcを念頭に置いています。

1 そもそも.libファイルには何が記録されているか。
libファイルには大別すると、静的ライブラリとインポートライブラリの2つの種類があります。
それで、静的ライブラリは、ソースファイルをコンパイルすると、ソースファイルごとに、コンパイル後のバイナリとして.objファイルが出力されますが、この.objファイルを一つのファイルにアーカイブしたものです。要するに、リンク前のコンパイル済みバイナリの集積体です。
そのため、静的ライブラリの内容は、主にコンパイル済みバイナリコード(関数の実体)を集積したものです。デバッグ情報とかも記録されてはいるのですが、主な存在意義は、関数の実体の集積です。
そのため、リンク時にリンカーの入力ファイルにすることで、libファイル内に実体がある関数を引っ張ってきてexeなどに書き込めるというわけです(静的リンク)。
一方、dllと同名(理論的にはそうではないものも作れるんですが、普通は同名です)のlibファイルは、インポートライブラリと呼ばれる種類のライブラリで、大雑把に言えば、関数の実体ではなく、dll内の関数の情報リストを記録しているものです。
ですので、インポートライブラリをリンカーの入力ファイルにした場合、リンカーは、関数の実体が記録されているdllと、そのdll内での関数の場所の識別情報をexeに書き込みます。そして、exeは、実行時に自身に書き込まれたその情報を基に、dllから関数を呼び出せる(動的リンク)というわけです。
つまり、同じ.libファイルでも、静的ライブラリとインポートライブラリでは、記録されている内容が全く異なるということになります。vulkan-1.lib や d3d12.lib は、vulkan-1.dllやd3d12.dllのためのインポートライブラリです。

2 msvc で静的ライブラリを作成するとどうなるか?(libc問題)
msvcの.objファイルは、ライブラリなどのリンク情報を保持できる( #pragma comment(lib, "shlwapi.lib") はこの情報を.objファイルに書き込むためのもの)のですが、デフォルトでは、コンパイル時にC/C++ランタイムライブラリ(libc)のリンク情報を、.objファイルに書き込みます。
そのうえで、msvcのC/C++ランタイムライブラリ(libc)は、Release/Debugの別でABIが大きく異なっている(バイナリの内容が異なる)ため、例えば、.obj側がDebugの状態だと、Releaseのlibcとリンクできる保証がありません(リンカーがDebugモードで使われるlibc関数を探しているのに、Releaseモードのlibc関数しかないためにリンクすべき関数が見つからないとかがざらです)。
そのため、.objファイルの集積体となる.libも、Debug/Releaseのどちらかに固定されてしまうというわけです
ちなみにですが、msvcのlibcは、Debug/Releaseの別以外にも、libc自身のリンクについて、静的/動的のどちらにするかというのでもバイナリが分かれており、これも一致させる必要があります。

3 Release/Debugで共用できる静的ライブラリとは?
それでは、msvcで、Release/Debugで共用できる静的ライブラリとはどのような内容なのかということですが、要するに、「libcのリンク情報を一切含まず、かつ、libcへの依存が全く存在しないライブラリ」ということになります。そのためには、C/C++の標準ライブラリを一切呼ばず、C/C++の言語機能のうち、ランタイムサポートを要するもの(例外とか実行時型情報とか)を全く使わずにコードを書き、コンパイルオプションとして"/Zl"を指定すればそうなります。
そして、YUKI_DAYOさんが引用されている、「Debug版とRelease版で同じLibファイルにする方法」の egtraさんの回答がまさにその内容となっているわけです。
ただし、面倒な割にデメリットが大きいですね。

返信

“C言語何でも質問掲示板” へ戻る