ドキュメンテーションが不明確
CMake のドキュメントはここでは不明確です。CMake の Makefile ジェネレーターは、メインの Makefile には表示されないサブ Makefile にソース ファイルの make ルールを作成します。メインの Makefile には、CMake ターゲットのPHONYルールのみが含まれています。私が知っている唯一の例外は、Ninja
すべてのビルド規則を単一のファイルに入れる Makefiles ジェネレーターです。
後処理ステップを CMake に変換する
私の経験から-スクリプトの場合post_process
-CMakeスクリプトを使用して/内部で後処理手順を書き直すことを検討する必要があります。これは、CMakeが後処理に使用されるすべてのファイルの依存関係と変数について知っている必要があるためです(たとえば、すべてを処理します)必要な再構築またはクリーンアップの手順)。
ここに私がしていることの簡略化/修正版があります:
function(my_add_elf _target)
set(_source_list ${ARGN})
add_executable(${_target}_in ${_source_list})
set_target_properties(
${_target}_in
PROPERTIES
POSITION_INDEPENDENT_CODE 0
SUFFIX .elf
)
add_custom_command(
OUTPUT ${_target}_step1.elf
COMMAND some_conversion_cmd $<TARGET_FILE:${_target}_in> > ${_target}_step1.elf
DEPENDS ${_target}_in
)
add_custom_target(
${_target}_step1
DEPENDS
${_target}_step1.elf
)
add_custom_command(
OUTPUT ${_target}_out.elf
COMMAND final_post_process_cmd ${_target}_step1.elf > ${_target}_out.elf
DEPENDS ${_target}_step1
)
add_custom_target(
${_target}_out
DEPENDS
${_target}_out.elf
)
# alias / PHONY target
add_custom_target(${_target} DEPENDS ${_target}_out)
endfunction(my_add_elf)
そして電話する
my_add_elf(foo foo.c)
これは単なる例ですが、アイデアが得られることを願っています。make foo
最終的な ELF 出力、make foo_in
またはmake foo_step1
他のステップの 1 つを呼び出すことができます。そして、すべてのステップはユーザーと CMake にとって透過的だと思います。
ターゲットに出力の 1 つと同じ名前を付けることはできません
カスタム ターゲットに出力の 1 つと同じ名前を付けようとしている場合、たとえば次のようにします。
add_executable(foo_in foo.c)
add_custom_command(
OUTPUT foo_out
COMMAND post_process foo_in > foo_out
DEPENDS foo_in
)
add_custom_target(foo_out DEPENDS foo_out)
無効なメイク ファイルが作成されます。CMake自体を拡張することで解決できる可能性があることを期待して、これについて問題を提起し、次の返信を得ました。
CMake は、Makefile で特定のコンテンツを生成することを意図していません。add_custom_target によって作成された最上位のターゲット名は、常に論理 (偽) 名です。同じ名前のファイルを持つことは単に許可されていません。
考えられる回避策
したがって、いくつかの回避策がありますが、それらにはいずれも欠点があります。
1.最短バージョン:
macro(my_add_elf_we _target)
add_executable(${_target}_in ${ARGN})
add_custom_target(
${_target}_out
COMMAND post_process $<TARGET_FILE:${_target}_in> > ${_target}_out
DEPENDS ${_target}_in
)
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${_target}_out)
endmacro(my_add_elf_we)
OUTPUT
s自体を宣言することはできませんadd_custom_target()
が、この場合は宣言しません (命名の混乱を避けるため)。ただし、出力を宣言しない場合:
- ターゲットは常に期限切れと見なされます
- 「見えない」出力を
clean
ビルドルールに追加する必要があります
2.強制出力名バージョン
以下は、ターゲット名と出力名を特定の値に強制する上記のマクロのバージョンです。
macro(my_add_elf_in_out _target_in _target_out)
add_executable(${_target_in} ${ARGN})
set_target_properties(
${_target_in}
PROPERTIES
SUFFIX ""
OUTPUT_NAME "${_target_in}"
)
add_custom_target(
${_target_out}
COMMAND post_process ${_target_in} > ${_target_out}
DEPENDS ${_target_in}
)
set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${_target_out})
endmacro(my_add_elf_in_out)
次のように呼び出します。
my_add_elf_in_out(foo_in.elf foo_out.elf foo.c)
3.オブジェクト ライブラリのバージョン
次のバージョンはオブジェクト ライブラリを使用しますが、システムはfoo_in
ターゲット リンケージを再利用しません。
macro(my_add_elf_obj_in_out _target_in _target_out)
add_library(${_target_in}_obj OBJECT ${ARGN})
add_executable(${_target_in} $<TARGET_OBJECTS:${_target_in}_obj>)
set_target_properties(
${_target_in}
PROPERTIES
SUFFIX ""
OUTPUT_NAME "${_target_in}"
)
add_executable(${_target_out} $<TARGET_OBJECTS:${_target_in}_obj>)
set_target_properties(
${_target_out}
PROPERTIES
SUFFIX ""
OUTPUT_NAME "${_target_out}"
EXCLUDE_FROM_ALL 1
)
add_custom_command(
TARGET ${_target_out}
POST_BUILD
COMMAND post_process ${_target_in} > ${_target_out}
)
endmacro(my_add_elf_obj_in_out)
4.最終バージョン
そして、間違いなくMakefile ジェネレーターでのみ機能する1 つの最終バージョンで、CMake のバグ トラッカーに問題を投稿することになりました。
macro(my_add_elf_ext_in_out _target_in _target_out)
add_executable(${_target_in} ${ARGN})
set_target_properties(
${_target_in}
PROPERTIES
SUFFIX ""
OUTPUT_NAME "${_target_in}"
)
add_executable(${_target_out} NotExisting.c)
set_source_files_properties(
NotExisting.c
PROPERTIES
GENERATED 1
HEADER_FILE_ONLY 1
)
set_target_properties(
${_target_out}
PROPERTIES
SUFFIX ""
OUTPUT_NAME "${_target_out}"
RULE_LAUNCH_LINK "# "
)
add_custom_command(
TARGET ${_target_out}
POST_BUILD
COMMAND post_process ${_target_in} > ${_target_out}
)
add_dependencies(${_target_out} ${_target_in})
endmacro(my_add_elf_ext_in_out)
参考文献