Set Clang's resource dir and platform triple correctly
* The option `-resource-dir` must be specified to point to Clang's resource directory containing built-in header files. Then the massive warnings are gone. * Setting the platform triple seems to be the right way for cross-compilation. Note that the stdlib.h still needs to be worked around.
This commit is contained in:
parent
4ae20cf38b
commit
54d4a15d4f
19
README.md
19
README.md
|
@ -28,7 +28,6 @@ The basic functionality is implemented, tested and documented:
|
||||||
### TODOs
|
### TODOs
|
||||||
There are still things missing which would likely be very useful in practise. The following list contains the open TODOs which are supposed to be most relevant in practise:
|
There are still things missing which would likely be very useful in practise. The following list contains the open TODOs which are supposed to be most relevant in practise:
|
||||||
|
|
||||||
* [ ] Fix the massive number of warnings which are currently being created by the code generator
|
|
||||||
* [ ] Allow to specify which member variables should be considered
|
* [ ] Allow to specify which member variables should be considered
|
||||||
* This could work similar to Qt's Signals & Slots macros.
|
* This could work similar to Qt's Signals & Slots macros.
|
||||||
* but there should also be a way to do this for 3rdparty types.
|
* but there should also be a way to do this for 3rdparty types.
|
||||||
|
@ -157,13 +156,17 @@ from certain targets to the code generator. The targets can be specified using t
|
||||||
* Since the code generator is likely not required under the target platform, you should add `-DNO_GENERATOR:BOOL=ON` to the CMake
|
* Since the code generator is likely not required under the target platform, you should add `-DNO_GENERATOR:BOOL=ON` to the CMake
|
||||||
arguments when building Reflective RapidJSON for the target platform.
|
arguments when building Reflective RapidJSON for the target platform.
|
||||||
* When using the `add_reflection_generator_invocation` macro, you need to set the following CMake cache variables:
|
* When using the `add_reflection_generator_invocation` macro, you need to set the following CMake cache variables:
|
||||||
* `REFLECTION_GENERATOR_EXECUTABLE:FILEPATH=/path/to/executable`: path of the code generator executable built for the platform
|
* `REFLECTION_GENERATOR_EXECUTABLE:FILEPATH=/path/to/executable`
|
||||||
you're building on
|
* specifies the path of the code generator executable built for the platform you're building on
|
||||||
* `REFLECTION_GENERATOR_INCLUDE_DIRECTORIES:STRING=/custom/prefix/include`: directories containing header files for target
|
* only required if executable not in path anyways
|
||||||
platform (not required if you set `CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES` anyways since it defaults to that variable)
|
* `REFLECTION_GENERATOR_TRIPLE:STRING=machine-vendor-operatingsystem`
|
||||||
* It is likely required to pass additional options for the target platform. For example, to cross compile with MingGW, is is
|
* specifies the GNU platform triple for the target platform
|
||||||
required to add `-fdeclspec`, `-D_WIN32` and some more options (see `lib/cmake/modules/ReflectionGenerator.cmake`). The
|
* examples for cross compiling with mingw-w64 under GNU/Linux:
|
||||||
`add_reflection_generator_invocation` macro is supposed to take care of this, but currently only MingGW under GNU/Linux is supported.
|
`x86_64-w64-mingw32`, `i686-w64-mingw32`
|
||||||
|
* `REFLECTION_GENERATOR_INCLUDE_DIRECTORIES:STRING=/custom/prefix/include`
|
||||||
|
* directories containing header files for target platform
|
||||||
|
* example for cross compiling with mingw-w64 under GNU/Linux:
|
||||||
|
`/usr/lib/gcc/x86_64-w64-mingw32/7.2.1/include;/usr/x86_64-w64-mingw32/include/c++/7.2.1/x86_64-w64-mingw32;/usr/x86_64-w64-mingw32/include`
|
||||||
* The Arch Linux packages mentioned at the end of the README file also include `mingw-w64` variants which give a concrete example how
|
* The Arch Linux packages mentioned at the end of the README file also include `mingw-w64` variants which give a concrete example how
|
||||||
cross-compilation can be done.
|
cross-compilation can be done.
|
||||||
|
|
||||||
|
|
2
TODOs.md
2
TODOs.md
|
@ -10,7 +10,7 @@
|
||||||
explicitely
|
explicitely
|
||||||
- [x] Fix traits currently relying on `JsonSerializable` being base class
|
- [x] Fix traits currently relying on `JsonSerializable` being base class
|
||||||
- [x] Allow exporting symbols
|
- [x] Allow exporting symbols
|
||||||
- [ ] Fix the massive number of warnings which are currently being created by the code generator
|
- [x] Fix the massive number of warnings which are currently being created by the code generator (missing `-resource-dir` was the problem)
|
||||||
- [ ] Test with libc++ (currently only tested with libstdc++)
|
- [ ] Test with libc++ (currently only tested with libstdc++)
|
||||||
- [ ] Support templated classes
|
- [ ] Support templated classes
|
||||||
- [ ] Allow (de)serialization of static members (if that makes sense?)
|
- [ ] Allow (de)serialization of static members (if that makes sense?)
|
||||||
|
|
|
@ -91,6 +91,9 @@ if(RapidJSON_FOUND)
|
||||||
string(APPEND META_CUSTOM_CONFIG "#define RAPIDJSON_INCLUDE_DIRS \"${RAPIDJSON_INCLUDE_DIRS}\"\n")
|
string(APPEND META_CUSTOM_CONFIG "#define RAPIDJSON_INCLUDE_DIRS \"${RAPIDJSON_INCLUDE_DIRS}\"\n")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# add path of Clang's resource dir to config header so test cases can use it
|
||||||
|
string(APPEND META_CUSTOM_CONFIG "#define REFLECTION_GENERATOR_CLANG_RESOURCE_DIR \"${REFLECTION_GENERATOR_CLANG_RESOURCE_DIR}\"\n")
|
||||||
|
|
||||||
# make config header
|
# make config header
|
||||||
include(ConfigHeader)
|
include(ConfigHeader)
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,8 @@ void JsonGeneratorTests::testGeneratorItself()
|
||||||
{
|
{
|
||||||
const string inputFilePath(testFilePath("some_structs.h"));
|
const string inputFilePath(testFilePath("some_structs.h"));
|
||||||
const vector<const char *> inputFiles{ inputFilePath.data() };
|
const vector<const char *> inputFiles{ inputFilePath.data() };
|
||||||
const vector<string> clangOptions{ "-I" CPP_UTILITIES_INCLUDE_DIRS, "-I" RAPIDJSON_INCLUDE_DIRS };
|
const vector<string> clangOptions{ "-resource-dir", REFLECTION_GENERATOR_CLANG_RESOURCE_DIR, "-I", CPP_UTILITIES_INCLUDE_DIRS, "-I",
|
||||||
|
RAPIDJSON_INCLUDE_DIRS };
|
||||||
|
|
||||||
stringstream buffer;
|
stringstream buffer;
|
||||||
JsonSerializationCodeGenerator::Options jsonOptions;
|
JsonSerializationCodeGenerator::Options jsonOptions;
|
||||||
|
@ -90,8 +91,9 @@ void JsonGeneratorTests::testCLI()
|
||||||
string stdout, stderr;
|
string stdout, stderr;
|
||||||
|
|
||||||
const string inputFilePath(testFilePath("some_structs.h"));
|
const string inputFilePath(testFilePath("some_structs.h"));
|
||||||
const char *const args1[] = { PROJECT_NAME, "--input-file", inputFilePath.data(), "--json-classes", "TestNamespace2::ThirdPartyStruct", "--clang-opt",
|
const char *const args1[]
|
||||||
"-I" CPP_UTILITIES_INCLUDE_DIRS, "-I" RAPIDJSON_INCLUDE_DIRS, nullptr };
|
= { PROJECT_NAME, "--input-file", inputFilePath.data(), "--json-classes", "TestNamespace2::ThirdPartyStruct", "--clang-opt", "-resource-dir",
|
||||||
|
REFLECTION_GENERATOR_CLANG_RESOURCE_DIR, "-I", CPP_UTILITIES_INCLUDE_DIRS, "-I", RAPIDJSON_INCLUDE_DIRS, nullptr };
|
||||||
TESTUTILS_ASSERT_EXEC(args1);
|
TESTUTILS_ASSERT_EXEC(args1);
|
||||||
assertEqualityLinewise(m_expectedCode, toArrayOfLines(stdout));
|
assertEqualityLinewise(m_expectedCode, toArrayOfLines(stdout));
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,9 +28,30 @@ if(NOT REFLECTION_GENERATOR_EXECUTABLE)
|
||||||
message(FATAL_ERROR "Unable to find executable of generator for reflection code. Set REFLECTION_GENERATOR_EXECUTABLE to specify the path.")
|
message(FATAL_ERROR "Unable to find executable of generator for reflection code. Set REFLECTION_GENERATOR_EXECUTABLE to specify the path.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# allow to specify a custom include path and use first implicit include directory as default
|
# determine Clang's resource directory
|
||||||
# (useful for cross-compilation when header files are under custom prefix)
|
set(REFLECTION_GENERATOR_CLANG_RESOURCE_DIR "" CACHE PATH "directory containing Clang's builtin headers, usually /usr/lib/clang/version")
|
||||||
set(REFLECTION_GENERATOR_INCLUDE_DIRECTORIES "${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}" CACHE FILEPATH "include directories for code generator")
|
if(NOT REFLECTION_GENERATOR_CLANG_RESOURCE_DIR)
|
||||||
|
if(NOT REFLECTION_GENERATOR_CLANG_BIN)
|
||||||
|
find_program(REFLECTION_GENERATOR_CLANG_BIN clang
|
||||||
|
NAMES clang++
|
||||||
|
PATHS "/usr/bin" "/bin"
|
||||||
|
)
|
||||||
|
if(NOT REFLECTION_GENERATOR_CLANG_BIN)
|
||||||
|
message(FATAL_ERROR "Unable to find the clang executable to determine Clang's resource directory")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
exec_program(${REFLECTION_GENERATOR_CLANG_BIN} ARGS -print-resource-dir OUTPUT_VARIABLE REFLECTION_GENERATOR_CLANG_RESOURCE_DIR)
|
||||||
|
endif()
|
||||||
|
if(NOT REFLECTION_GENERATOR_CLANG_RESOURCE_DIR OR NOT IS_DIRECTORY "${REFLECTION_GENERATOR_CLANG_RESOURCE_DIR}")
|
||||||
|
message(FATAL_ERROR "Unable to find Clang's resource directory. Set REFLECTION_GENERATOR_CLANG_RESOURCE_DIR manually to the corresponding path (usually /usr/lib/clang/\$version).")
|
||||||
|
endif()
|
||||||
|
message(STATUS "Using ${REFLECTION_GENERATOR_CLANG_RESOURCE_DIR} as Clang's resource directory for Reflective RapidJSON")
|
||||||
|
|
||||||
|
# allow to specify a custom include paths (useful for cross-compilation when header files are under custom prefix)
|
||||||
|
set(REFLECTION_GENERATOR_INCLUDE_DIRECTORIES "" CACHE FILEPATH "include directories for code generator")
|
||||||
|
|
||||||
|
# allow to specify a custom platform tiple (useful for cross-compilation to specify the target platform)
|
||||||
|
set(REFLECTION_GENERATOR_TRIPLE "" CACHE STRING "platform triple for code generator")
|
||||||
|
|
||||||
# define helper function to add a reflection generator invocation for a specified list of source files
|
# define helper function to add a reflection generator invocation for a specified list of source files
|
||||||
include(CMakeParseArguments)
|
include(CMakeParseArguments)
|
||||||
|
@ -57,34 +78,38 @@ function(add_reflection_generator_invocation)
|
||||||
file(MAKE_DIRECTORY "${ARGS_OUTPUT_DIRECTORY}")
|
file(MAKE_DIRECTORY "${ARGS_OUTPUT_DIRECTORY}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# specify Clang's resource directory
|
||||||
|
list(APPEND ARGS_CLANG_OPTIONS -resource-dir "${REFLECTION_GENERATOR_CLANG_RESOURCE_DIR}")
|
||||||
|
|
||||||
|
# apply specified REFLECTION_GENERATOR_TRIPLET
|
||||||
|
if(REFLECTION_GENERATOR_TRIPLE)
|
||||||
|
list(APPEND ARGS_CLANG_OPTIONS
|
||||||
|
-Xclang -triple
|
||||||
|
-Xclang "${REFLECTION_GENERATOR_TRIPLE}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
# apply specified REFLECTION_GENERATOR_INCLUDE_DIRECTORIES
|
# apply specified REFLECTION_GENERATOR_INCLUDE_DIRECTORIES
|
||||||
foreach(INCLUDE_DIR ${REFLECTION_GENERATOR_INCLUDE_DIRECTORIES})
|
foreach(INCLUDE_DIR ${REFLECTION_GENERATOR_INCLUDE_DIRECTORIES})
|
||||||
list(APPEND ARGS_CLANG_OPTIONS "-isystem ${INCLUDE_DIR}")
|
list(APPEND ARGS_CLANG_OPTIONS -I "${INCLUDE_DIR}")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
# add options required for cross compiling with mingw-w64
|
# add workaround for cross compiling with mingw-w64 to prevent host stdlib.h being included
|
||||||
|
# (not sure why specifying REFLECTION_GENERATOR_INCLUDE_DIRECTORIES is not enough to let it find this particular header file)
|
||||||
if(MINGW)
|
if(MINGW)
|
||||||
# find MinGW version of stdlib.h to ensure that only this version is processed
|
# find MinGW version of stdlib.h
|
||||||
find_file(MINGW_W64_STDLIB_H stdlib.h ${REFLECTION_GENERATOR_INCLUDE_DIRECTORIES})
|
find_file(MINGW_W64_STDLIB_H stdlib.h ${REFLECTION_GENERATOR_INCLUDE_DIRECTORIES})
|
||||||
if(NOT EXISTS "${MINGW_W64_STDLIB_H}")
|
if(NOT EXISTS "${MINGW_W64_STDLIB_H}")
|
||||||
message(FATAL_ERROR "Unable to locate MinGW version of stdlib.h. Ensure it is in REFLECTION_GENERATOR_INCLUDE_DIRECTORIES.")
|
message(FATAL_ERROR "Unable to locate MinGW version of stdlib.h. Ensure it is in REFLECTION_GENERATOR_INCLUDE_DIRECTORIES.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# ensure libtooling includes the MinGW version of stdlib.h rather than the host version
|
||||||
list(APPEND ARGS_CLANG_OPTIONS
|
list(APPEND ARGS_CLANG_OPTIONS
|
||||||
# allow __declspec
|
-include "${MINGW_W64_STDLIB_H}"
|
||||||
"-fdeclspec"
|
-D_STDLIB_H # prevent processing of host stdlib.h
|
||||||
# make sure platform detection works as expected
|
|
||||||
"-D_WIN32"
|
|
||||||
# ensure libtooling processes the MinGW version of stdlib.h rather than the host version
|
|
||||||
# (not sure why specifying REFLECTION_GENERATOR_INCLUDE_DIRECTORIES is not enough to let it find the correct header file)
|
|
||||||
"-include ${MINGW_W64_STDLIB_H}"
|
|
||||||
# prevent processing of host stdlib.h
|
|
||||||
"-D_STDLIB_H"
|
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# TODO: add options for other targets
|
|
||||||
|
|
||||||
# add options to be passed to clang from the specified targets
|
# add options to be passed to clang from the specified targets
|
||||||
if(ARGS_CLANG_OPTIONS_FROM_TARGETS)
|
if(ARGS_CLANG_OPTIONS_FROM_TARGETS)
|
||||||
foreach(TARGET_NAME ${ARGS_CLANG_OPTIONS_FROM_TARGETS})
|
foreach(TARGET_NAME ${ARGS_CLANG_OPTIONS_FROM_TARGETS})
|
||||||
|
|
Loading…
Reference in New Issue