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
|
||||
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
|
||||
* This could work similar to Qt's Signals & Slots macros.
|
||||
* 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
|
||||
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:
|
||||
* `REFLECTION_GENERATOR_EXECUTABLE:FILEPATH=/path/to/executable`: 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
|
||||
platform (not required if you set `CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES` anyways since it defaults to that variable)
|
||||
* It is likely required to pass additional options for the target platform. For example, to cross compile with MingGW, is is
|
||||
required to add `-fdeclspec`, `-D_WIN32` and some more options (see `lib/cmake/modules/ReflectionGenerator.cmake`). The
|
||||
`add_reflection_generator_invocation` macro is supposed to take care of this, but currently only MingGW under GNU/Linux is supported.
|
||||
* `REFLECTION_GENERATOR_EXECUTABLE:FILEPATH=/path/to/executable`
|
||||
* specifies the path of the code generator executable built for the platform you're building on
|
||||
* only required if executable not in path anyways
|
||||
* `REFLECTION_GENERATOR_TRIPLE:STRING=machine-vendor-operatingsystem`
|
||||
* specifies the GNU platform triple for the target platform
|
||||
* examples for cross compiling with mingw-w64 under GNU/Linux:
|
||||
`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
|
||||
cross-compilation can be done.
|
||||
|
||||
|
|
2
TODOs.md
2
TODOs.md
|
@ -10,7 +10,7 @@
|
|||
explicitely
|
||||
- [x] Fix traits currently relying on `JsonSerializable` being base class
|
||||
- [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++)
|
||||
- [ ] Support templated classes
|
||||
- [ ] 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")
|
||||
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
|
||||
include(ConfigHeader)
|
||||
|
||||
|
|
|
@ -67,7 +67,8 @@ void JsonGeneratorTests::testGeneratorItself()
|
|||
{
|
||||
const string inputFilePath(testFilePath("some_structs.h"));
|
||||
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;
|
||||
JsonSerializationCodeGenerator::Options jsonOptions;
|
||||
|
@ -90,8 +91,9 @@ void JsonGeneratorTests::testCLI()
|
|||
string stdout, stderr;
|
||||
|
||||
const string inputFilePath(testFilePath("some_structs.h"));
|
||||
const char *const args1[] = { PROJECT_NAME, "--input-file", inputFilePath.data(), "--json-classes", "TestNamespace2::ThirdPartyStruct", "--clang-opt",
|
||||
"-I" CPP_UTILITIES_INCLUDE_DIRS, "-I" RAPIDJSON_INCLUDE_DIRS, nullptr };
|
||||
const char *const args1[]
|
||||
= { 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);
|
||||
assertEqualityLinewise(m_expectedCode, toArrayOfLines(stdout));
|
||||
#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.")
|
||||
endif()
|
||||
|
||||
# allow to specify a custom include path and use first implicit include directory as default
|
||||
# (useful for cross-compilation when header files are under custom prefix)
|
||||
set(REFLECTION_GENERATOR_INCLUDE_DIRECTORIES "${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}" CACHE FILEPATH "include directories for code generator")
|
||||
# determine Clang's resource directory
|
||||
set(REFLECTION_GENERATOR_CLANG_RESOURCE_DIR "" CACHE PATH "directory containing Clang's builtin headers, usually /usr/lib/clang/version")
|
||||
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
|
||||
include(CMakeParseArguments)
|
||||
|
@ -57,34 +78,38 @@ function(add_reflection_generator_invocation)
|
|||
file(MAKE_DIRECTORY "${ARGS_OUTPUT_DIRECTORY}")
|
||||
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
|
||||
foreach(INCLUDE_DIR ${REFLECTION_GENERATOR_INCLUDE_DIRECTORIES})
|
||||
list(APPEND ARGS_CLANG_OPTIONS "-isystem ${INCLUDE_DIR}")
|
||||
list(APPEND ARGS_CLANG_OPTIONS -I "${INCLUDE_DIR}")
|
||||
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)
|
||||
# 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})
|
||||
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.")
|
||||
endif()
|
||||
|
||||
# ensure libtooling includes the MinGW version of stdlib.h rather than the host version
|
||||
list(APPEND ARGS_CLANG_OPTIONS
|
||||
# allow __declspec
|
||||
"-fdeclspec"
|
||||
# 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"
|
||||
-include "${MINGW_W64_STDLIB_H}"
|
||||
-D_STDLIB_H # prevent processing of host stdlib.h
|
||||
)
|
||||
endif()
|
||||
|
||||
# TODO: add options for other targets
|
||||
|
||||
# add options to be passed to clang from the specified targets
|
||||
if(ARGS_CLANG_OPTIONS_FROM_TARGETS)
|
||||
foreach(TARGET_NAME ${ARGS_CLANG_OPTIONS_FROM_TARGETS})
|
||||
|
|
Loading…
Reference in New Issue