1

JSON ファイルを取り込み.h、ターゲットの 1 つが依存するファイルを出力するシェル スクリプトがあります。これを達成するために必要なのはCMakeのadd_custom_commandようですが、ヘッダーファイルを生成できません。この投稿この投稿の情報を使用して、考えられるほぼすべての組み合わせを試しました。

以下は、私が遭遇した問題を再現するために作成できる最も簡単なものです。

私のプロジェクト構造は次のとおりです。

.
├── CMakeLists.txt
├──main.c
└──レス
    ├──generate.sh
    └──input.json

CMakeLists.txt


cmake_minimum_required(VERSION 2.8)
project(test)

set(TEST_DATA_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test_data.h)
add_custom_command(
    OUTPUT ${TEST_DATA_OUTPUT}
    COMMAND res/generate.sh h res/input.json ${TEST_DATA_OUTPUT}
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    COMMENT "Generates the header file containing the JSON data."
)

# add the binary tree to the search path for include files so we
# will fine the generated files
include_directories(${CMAKE_CURRENT_BINARY_DIR})

set(SRCS main.c)
add_executable(test ${SRCS})

main.c


#include <stdio.h>

#include "test_data.h"

int main(int argc, char** argv)
{
    printf("%s\n", TEST_DATA);
    return 0;
}

res/generate.sh


#!/bin/sh
#
# Converts the JSON to a C header file to be used as a resource file.

print_usage()
{
cat << EOF
USAGE:
    $0 h INPUT

DESCRIPTION:
    Outputs JSON data to another format.

EOF
}

to_h()
{
cat << EOF
#ifndef TEST_DATA_H
#define TEST_DATA_H

static const char* TEST_DATA =
"$(cat "$1" | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/"\n"/g')";

#endif // TEST_DATA_H
EOF
}

case "$1" in
h)
    if [ $# -eq 3 ] ; then
        to_h "$2" > "$3"
    elif [ $# -eq 2 ] ; then
        to_h "$2"
    else
        echo "no input file specified" 1>&2
    fi
    ;;
*)
    print_usage
    ;;
esac

exit 0

res/input.json


{
    "1": {
        "attr1": "value1",
        "attr2": "value2"
    },
    "2": {
        "attr1": "value1",
        "attr2": "value2"
    }
}
4

2 に答える 2

0

CMake でより多くの経験を積んだので、これを機能させることができるかどうかを確認するために戻ってきました。以下は、変更が必要な 2 行を示しています。

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6aa2ac6..5d80124 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,8 +2,7 @@ cmake_minimum_required(VERSION 2.8)
 project(test)

 set(TEST_DATA_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/test_data.h)
-add_custom_command(
-    OUTPUT ${TEST_DATA_OUTPUT}
+add_custom_target(generate
     COMMAND res/generate.sh h res/input.json ${TEST_DATA_OUTPUT}
     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
     COMMENT "Generates the header file containing the JSON data."
@@ -15,3 +14,4 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})

 set(SRCS main.c)
 add_executable(test ${SRCS})
+add_dependencies(test generate)
于 2014-08-14T01:51:46.387 に答える
0

Ragelを使用して入力ファイルを読み取り ( nstrip.rl)、出力ファイルを生成し ( nstrip.c)、出力ファイルをバイナリにコンパイル/リンクするCMakeLists.txt の例を次に示します。

set(RAGEL_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/nstrip.c)

add_executable(
  nstrip
    ${RAGEL_OUTPUT}
  )
set_target_properties(
  nstrip
  PROPERTIES
    COMPILE_FLAGS -std=c99
  )

find_program(RAGEL ragel)
add_custom_command(
  OUTPUT             ${RAGEL_OUTPUT}
  COMMAND            ${RAGEL} -G2 -o ${RAGEL_OUTPUT} nstrip.rl
  DEPENDS            nstrip.rl
  WORKING_DIRECTORY  ${CMAKE_CURRENT_SOURCE_DIR}
  COMMENT            "Ragel: Generating Statemachine"
  VERBATIM
  )

ノート:

  • コマンドをDEPENDS使用すると、依存関係が実際に変更されたときにのみ実行されます。
  • これは、生成されたファイルをCMAKE_CURRENT_BINARY_DIR(つまり、ソースツリー内の上記の CMakeLists.txt の場所に対応するビルドツリー内のディレクトリ) に配置し、それを実行可能。
  • WORKING_DIRECTORY同様に、上記の CMakeLists.txt が存在する場所に設定されたコマンドも実行されるため、ソース ファイル (ここではnstrip.rl) を相対パスで参照できます (その逆も可能です)。

あなたの場合、ヘッダーを見つける場所を CMake に伝える必要があります。

# assuming you generate into the build tree
include_directories("${CMAKE_CURRENT_BINARY_DIR}")`

また、生成する実行可能ファイルが ではなくソース ツリーに存在するスクリプトである場合は、 を省略し$PATHfind_programスクリプトを に追加しますDEPENDS。CMake は、入力ファイル (json)またはスクリプト自体を変更するたびに、ヘッダーの再構築を自動的にトリガーします。

于 2013-02-11T12:38:45.773 に答える