Handle multiple input files correctly

by invoking the generator multiple times
This commit is contained in:
Martchus 2017-10-25 17:32:03 +02:00
parent 3008e3ad6e
commit 3889031247
4 changed files with 39 additions and 40 deletions

View File

@ -21,36 +21,37 @@ include(CMakeParseArguments)
function(add_reflection_generator_invocation)
# parse arguments
set(OPTIONAL_ARGS)
set(ONE_VALUE_ARGS OUTPUT_FILE OUTPUT_NAME)
set(ONE_VALUE_ARGS OUTPUT_DIRECTORY)
set(MULTI_VALUE_ARGS INPUT_FILES GENERATORS OUTPUT_LISTS)
cmake_parse_arguments(ARGS "${OPTIONAL_ARGS}" "${ONE_VALUE_ARGS}" "${MULTI_VALUE_ARGS}" ${ARGN})
# determine file name or file path if none specified
if(OUTPUT_FILE AND OUTPUT_NAME)
message(FATAL_ERROR "Specify either OUTPUT_NAME or OUTPUT_FILE but not both.")
if(NOT ARGS_OUTPUT_DIRECTORY)
set(ARGS_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/reflection")
file(MAKE_DIRECTORY "${ARGS_OUTPUT_DIRECTORY}")
endif()
if(NOT ARGS_OUTPUT_FILE)
if(NOT ARGS_OUTPUT_NAME)
set(ARGS_OUTPUT_NAME "reflection.h")
foreach(INPUT_FILE ${ARGS_INPUT_FILES})
get_filename_component(OUTPUT_NAME "${INPUT_FILE}" NAME_WE)
set(OUTPUT_FILE "${ARGS_OUTPUT_DIRECTORY}/${OUTPUT_NAME}.h")
message(STATUS "Adding generator command for ${INPUT_FILE} producing ${OUTPUT_FILE}")
add_custom_command(
OUTPUT "${OUTPUT_FILE}"
COMMAND "${REFLECTION_GENERATOR_EXECUTABLE}"
-o "${OUTPUT_FILE}"
-i "${INPUT_FILE}"
-g ${ARGS_GENERATORS}
DEPENDS "${INPUT_FILE}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Generating reflection code for ${INPUT_FILE}"
)
# append the output file to lists specified via OUTPUT_LISTS
if(ARGS_OUTPUT_LISTS)
foreach(OUTPUT_LIST ${ARGS_OUTPUT_LISTS})
list(APPEND "${OUTPUT_LIST}" "${OUTPUT_FILE}")
set("${OUTPUT_LIST}" "${${OUTPUT_LIST}}" PARENT_SCOPE)
endforeach()
endif()
set(ARGS_OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${ARGS_OUTPUT_NAME}")
endif()
add_custom_command(
OUTPUT "${ARGS_OUTPUT_FILE}"
COMMAND "${REFLECTION_GENERATOR_EXECUTABLE}"
-o "${ARGS_OUTPUT_FILE}"
-i ${ARGS_INPUT_FILES}
-g ${ARGS_GENERATORS}
DEPENDS "${ARGS_INPUT_FILES}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Generating reflection code"
)
# append the output file to lists specified via OUTPUT_LISTS
if(ARGS_OUTPUT_LISTS)
foreach(OUTPUT_LIST ${ARGS_OUTPUT_LISTS})
set("${OUTPUT_LIST}" "${${OUTPUT_LIST}};${ARGS_OUTPUT_FILE}" PARENT_SCOPE)
endforeach()
endif()
endforeach()
endfunction()

View File

@ -44,9 +44,9 @@ list(APPEND PRIVATE_LIBRARIES reflective_rapidjson)
# trigger code generator for tests
include(ReflectionGenerator)
add_reflection_generator_invocation(
INPUT_FILES tests/overall.cpp
INPUT_FILES tests/overall.cpp tests/cppunit.cpp
GENERATORS json
OUTPUT_LISTS TEST_SRC_FILES
OUTPUT_LISTS TEST_HEADER_FILES
)
# include modules to apply configuration

View File

@ -26,9 +26,8 @@ int main(int argc, char *argv[])
// setup argument parser
ArgumentParser parser;
Argument inputFilesArg("input-files", 'i', "specifies the input files");
inputFilesArg.setValueNames({ "path" });
inputFilesArg.setRequiredValueCount(Argument::varValueCount);
ConfigValueArgument inputFileArg("input-file", 'i', "specifies the input file", { "path" });
inputFileArg.setRequired(true);
ConfigValueArgument outputFileArg("output-file", 'o', "specifies the output file", { "path" });
Argument generatorsArg("generators", 'g', "specifies the generators (by default all generators are enabled)");
generatorsArg.setValueNames({ "json" });
@ -38,17 +37,13 @@ int main(int argc, char *argv[])
ConfigValueArgument clangOptionsArg("clang-opt", 'c', "specifies an argument to be passed to Clang", { "option" });
HelpArgument helpArg(parser);
NoColorArgument noColorArg;
parser.setMainArguments({ &inputFilesArg, &outputFileArg, &generatorsArg, &clangOptionsArg, &noColorArg, &helpArg });
parser.setMainArguments({ &inputFileArg, &outputFileArg, &generatorsArg, &clangOptionsArg, &noColorArg, &helpArg });
// parse arguments
parser.parseArgsOrExit(argc, argv);
if (helpArg.isPresent()) {
return 0;
}
if (!inputFilesArg.isPresent()) {
cerr << Phrases::Error << "No input file specified." << Phrases::EndFlush;
return -1;
}
// setup output stream
ostream *os = nullptr;
@ -65,7 +60,7 @@ int main(int argc, char *argv[])
// configure code generator
vector<const char *> defaultClangOptions;
CodeFactory factory(
parser.executable(), inputFilesArg.values(0), clangOptionsArg.isPresent() ? clangOptionsArg.values(0) : defaultClangOptions, *os);
parser.executable(), inputFileArg.values(0), clangOptionsArg.isPresent() ? clangOptionsArg.values(0) : defaultClangOptions, *os);
// add only specified generators if the --generator argument is present
if (generatorsArg.isPresent()) {
// find and construct generators by name
@ -84,7 +79,7 @@ int main(int argc, char *argv[])
// read AST elements from input files
if (!factory.readAST()) {
cerr << Phrases::Error << "Errors occured when parsing the input files." << Phrases::EndFlush;
cerr << Phrases::Error << "Errors occured when parsing the input file." << Phrases::EndFlush;
return -2;
}

View File

@ -240,6 +240,9 @@ void OverallTests::testMultipleInheritence()
CPPUNIT_ASSERT_EQUAL(test.arrayOfStrings, parsedTest.arrayOfStrings);
}
// include file required for reflection of TestStruct; generation of this header is triggered using
// include file required for reflection of TestStruct and other structs; generation of this header is triggered using
// the CMake function add_reflection_generator_invocation()
#include "reflection.h"
#include "reflection/overall.h"
// this file should also be generated and hence includeable, but empty because it doesn't contain relevant classes
#include "reflection/cppunit.h"