Make JNI-bindings package-agnostic.

GitOrigin-RevId: a3a66de7561cf0ea9a3faf0b26bda1c34de7d317
This commit is contained in:
levlam 2018-01-21 14:45:24 +03:00
parent 92c03c4b9a
commit d8f13abb2c
8 changed files with 67 additions and 51 deletions

View File

@ -189,10 +189,10 @@ else()
endif()
message (STATUS ${IOS_ARCH})
set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string "Build architecture for iOS")
set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE STRING "Build architecture for iOS")
# Set the find root to the iOS developer roots and to user defined paths
set (CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE string "iOS find search path root")
set (CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE STRING "iOS find search path root")
# default to searching for frameworks first
set (CMAKE_FIND_FRAMEWORK FIRST)

View File

@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
project(TDLib VERSION 1.0.4 LANGUAGES CXX C)
option(TD_ENABLE_JNI "Use \"ON\" to enable JNI-compatible TDLib API.")
if (NOT DEFINED CMAKE_MODULE_PATH)
set(CMAKE_MODULE_PATH "")
endif()
@ -240,7 +242,7 @@ endif()
#SOURCE SETS
set_source_files_properties(${TL_TD_AUTO} PROPERTIES GENERATED TRUE)
if (TD_API_JAVA_PACKAGE)
if (TD_ENABLE_JNI)
set(TL_JNI_OBJECT
td/tl/tl_jni_object.cpp
td/tl/tl_jni_object.h
@ -547,7 +549,7 @@ target_include_directories(tdcore PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURC
target_include_directories(tdcore SYSTEM PRIVATE ${OPENSSL_INCLUDE_DIR})
target_link_libraries(tdcore PUBLIC tdactor tdutils tdnet tddb PRIVATE ${OPENSSL_CRYPTO_LIBRARY})
if (TD_API_JAVA_PACKAGE AND NOT ANDROID) # jni is available by default on Android
if (TD_ENABLE_JNI AND NOT ANDROID) # jni is available by default on Android
if (NOT JNI_FOUND)
find_package(JNI REQUIRED)
endif()
@ -558,6 +560,9 @@ endif()
if (NOT CMAKE_CROSSCOMPILING)
add_dependencies(tdcore tl_generate_common)
if (TD_ENABLE_JNI)
add_dependencies(tdcore generate_java)
endif()
endif()
add_library(tdclient td/telegram/Client.cpp td/telegram/Client.h td/telegram/Log.cpp td/telegram/Log.h)
@ -567,7 +572,7 @@ target_include_directories(tdclient PUBLIC
)
target_link_libraries(tdclient PRIVATE tdcore)
if (TD_API_JAVA_PACKAGE AND NOT ANDROID) # jni is available by default on Android
if (TD_ENABLE_JNI AND NOT ANDROID) # jni is available by default on Android
target_include_directories(tdclient PUBLIC ${JAVA_INCLUDE_PATH} ${JAVA_INCLUDE_PATH2})
target_link_libraries(tdclient PUBLIC ${JAVA_JVM_LIBRARY})
endif()
@ -665,7 +670,7 @@ add_library(Td::TdStatic ALIAS TdStatic)
add_library(Td::TdJson ALIAS TdJson)
add_library(Td::TdJsonStatic ALIAS TdJsonStatic)
install(TARGETS tdjson TdJson tdjson_static tdjson_private tdclient tdcore TdJsonStatic TdStatic EXPORT TdTargets
install(TARGETS tdjson TdJson tdjson_static TdJsonStatic tdjson_private tdclient tdcore TdStatic EXPORT TdTargets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
@ -682,7 +687,7 @@ install(FILES ${TD_JSON_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/td/telegram/tdjson_
install(FILES td/telegram/Client.h td/telegram/Log.h DESTINATION include/td/telegram)
install(FILES td/tl/TlObject.h DESTINATION include/td/tl)
install(FILES ${TL_TD_AUTO_INCLUDES}/td/telegram/td_api.h ${TL_TD_AUTO_INCLUDES}/td/telegram/td_api.hpp DESTINATION include/td/telegram)
if (TD_API_JAVA_PACKAGE)
if (TD_ENABLE_JNI)
install(FILES td/tl/tl_jni_object.h DESTINATION include/td/tl)
endif()

View File

@ -79,7 +79,7 @@ set(TL_GENERATE_JSON_SOURCE
if (NOT CMAKE_CROSSCOMPILING)
find_program(PHP_EXECUTABLE php)
if (PHP_EXECUTABLE AND NOT TD_API_JAVA_PACKAGE)
if (PHP_EXECUTABLE AND NOT TD_ENABLE_JNI)
set(GENERATE_COMMON_CMD generate_common && ${PHP_EXECUTABLE} DoxygenTlDocumentationGenerator.php scheme/td_api.tl auto/td/telegram/td_api.h)
else()
set(GENERATE_COMMON_CMD generate_common)
@ -93,8 +93,8 @@ if (NOT CMAKE_CROSSCOMPILING)
COMMENT "Generate common tl source files"
DEPENDS generate_common scheme/mtproto_api.tlo scheme/telegram_api.tlo scheme/secret_api.tlo scheme/td_api.tlo
)
if (TD_API_JAVA_PACKAGE)
target_compile_definitions(generate_common PRIVATE TD_API_JAVA_PACKAGE=\"${TD_API_JAVA_PACKAGE}\")
if (TD_ENABLE_JNI)
target_compile_definitions(generate_common PRIVATE TD_ENABLE_JNI=1)
endif()
add_executable(generate_c ${TL_GENERATE_C_SOURCE})
@ -117,4 +117,10 @@ if (NOT CMAKE_CROSSCOMPILING)
COMMENT "Generate JSON tl source files"
DEPENDS generate_json scheme/td_api.tlo
)
if (TD_ENABLE_JNI)
install(TARGETS generate_java RUNTIME DESTINATION bin)
install(FILES JavadocTlDocumentationGenerator.php TlDocumentationGenerator.php DESTINATION bin/td/generate)
install(FILES scheme/td_api.tlo scheme/td_api.tl DESTINATION bin/td/generate/scheme)
endif()
endif()

View File

@ -17,39 +17,32 @@
#include <string>
#include <vector>
template <class WriterCpp = td::TD_TL_writer_cpp, class WriterH = td::TD_TL_writer_h,
class WriterHpp = td::TD_TL_writer_hpp>
static void generate_cpp(const std::string &directory, const std::string &tl_name, const std::string &string_type,
const std::string &bytes_type, const std::vector<std::string> &ext_cpp_includes,
const std::vector<std::string> &ext_h_includes) {
std::string path = directory + "/" + tl_name;
td::tl::tl_config config = td::tl::read_tl_config_from_file("scheme/" + tl_name + ".tlo");
td::tl::write_tl_to_file(config, path + ".cpp",
td::TD_TL_writer_cpp(tl_name, string_type, bytes_type, ext_cpp_includes));
td::tl::write_tl_to_file(config, path + ".h", td::TD_TL_writer_h(tl_name, string_type, bytes_type, ext_h_includes));
td::tl::write_tl_to_file(config, path + ".hpp", td::TD_TL_writer_hpp(tl_name, string_type, bytes_type));
td::tl::write_tl_to_file(config, path + ".cpp", WriterCpp(tl_name, string_type, bytes_type, ext_cpp_includes));
td::tl::write_tl_to_file(config, path + ".h", WriterH(tl_name, string_type, bytes_type, ext_h_includes));
td::tl::write_tl_to_file(config, path + ".hpp", WriterHpp(tl_name, string_type, bytes_type));
}
int main() {
generate_cpp("auto/td/telegram", "telegram_api", "std::string", "BufferSlice",
{"\"td/tl/tl_object_parse.h\"", "\"td/tl/tl_object_store.h\""}, {"\"td/utils/buffer.h\""});
generate_cpp<>("auto/td/telegram", "telegram_api", "std::string", "BufferSlice",
{"\"td/tl/tl_object_parse.h\"", "\"td/tl/tl_object_store.h\""}, {"\"td/utils/buffer.h\""});
generate_cpp("auto/td/telegram", "secret_api", "std::string", "BufferSlice",
{"\"td/tl/tl_object_parse.h\"", "\"td/tl/tl_object_store.h\""}, {"\"td/utils/buffer.h\""});
generate_cpp<>("auto/td/telegram", "secret_api", "std::string", "BufferSlice",
{"\"td/tl/tl_object_parse.h\"", "\"td/tl/tl_object_store.h\""}, {"\"td/utils/buffer.h\""});
generate_cpp("auto/td/mtproto", "mtproto_api", "Slice", "Slice",
{"\"td/tl/tl_object_parse.h\"", "\"td/tl/tl_object_store.h\""}, {"\"td/utils/Slice.h\""});
generate_cpp<>("auto/td/mtproto", "mtproto_api", "Slice", "Slice",
{"\"td/tl/tl_object_parse.h\"", "\"td/tl/tl_object_store.h\""}, {"\"td/utils/Slice.h\""});
#ifdef TD_API_JAVA_PACKAGE
td::tl::tl_config config = td::tl::read_tl_config_from_file("scheme/td_api.tlo");
std::string path = "auto/td/telegram/td_api";
std::string package = TD_API_JAVA_PACKAGE;
std::replace(package.begin(), package.end(), '/', '.');
td::tl::write_tl_to_file(
config, path + ".cpp",
td::TD_TL_writer_jni_cpp("td_api", "std::string", "std::string", {"\"td/tl/tl_jni_object.h\""}, package));
td::tl::write_tl_to_file(config, path + ".h",
td::TD_TL_writer_jni_h("td_api", "std::string", "std::string", {"<string>"}));
td::tl::write_tl_to_file(config, path + ".hpp", td::TD_TL_writer_hpp("td_api", "std::string", "std::string"));
#ifdef TD_ENABLE_JNI
generate_cpp<td::TD_TL_writer_jni_cpp, td::TD_TL_writer_jni_h>(
"auto/td/telegram", "td_api", "std::string", "std::string", {"\"td/tl/tl_jni_object.h\""}, {"<string>"});
#else
generate_cpp("auto/td/telegram", "td_api", "std::string", "std::string", {}, {"<string>"});
generate_cpp<>("auto/td/telegram", "td_api", "std::string", "std::string", {}, {"<string>"});
#endif
}

View File

@ -518,7 +518,7 @@ std::string TD_TL_writer_jni_cpp::gen_basic_java_class_name(std::string name) co
}
std::string TD_TL_writer_jni_cpp::gen_java_class_name(std::string name) const {
return package_name + "/" + "TdApi" + "$" + gen_basic_java_class_name(name);
return "(PSLICE() << package_name << \"/TdApi$" + gen_basic_java_class_name(name) + "\").c_str()";
}
std::string TD_TL_writer_jni_cpp::gen_type_signature(const tl::tl_tree_type *tree_type) const {
@ -543,7 +543,7 @@ std::string TD_TL_writer_jni_cpp::gen_type_signature(const tl::tl_tree_type *tre
const tl::tl_tree_type *child = static_cast<const tl::tl_tree_type *>(tree_type->children[0]);
return "[" + gen_type_signature(child);
} else {
return "L" + gen_java_class_name(gen_main_class_name(t)) + ";";
return "L%PACKAGE_NAME%/TdApi$" + gen_basic_java_class_name(gen_main_class_name(t)) + ";";
}
assert(false);
return "";
@ -558,9 +558,9 @@ std::string TD_TL_writer_jni_cpp::gen_additional_function(const std::string &fun
"\n"
"void " +
class_name + "::" + function_name +
"(JNIEnv *env) {\n"
"(JNIEnv *env, const char *package_name) {\n"
" " +
class_name_class + " = jni::get_jclass(env, \"" + gen_java_class_name(gen_class_name(t->name)) + "\");\n";
class_name_class + " = jni::get_jclass(env, " + gen_java_class_name(gen_class_name(t->name)) + ");\n";
if (t->args.size()) {
res +=
@ -577,8 +577,24 @@ std::string TD_TL_writer_jni_cpp::gen_additional_function(const std::string &fun
assert(field_name.size());
std::string java_field_name = gen_java_field_name(std::string(field_name, 0, field_name.size() - 1));
std::string type_signature = gen_type_signature(tree_type);
if (type_signature.find("%PACKAGE_NAME%") == std::string::npos) {
type_signature = '"' + type_signature + '"';
} else {
std::string new_type_signature = "(PSLICE()";
std::size_t pos = type_signature.find("%PACKAGE_NAME%");
while (pos != std::string::npos) {
new_type_signature += " << \"" + type_signature.substr(0, pos) + "\" << package_name";
type_signature = type_signature.substr(pos + 14);
pos = type_signature.find("%PACKAGE_NAME%");
}
if (!type_signature.empty()) {
new_type_signature += " << \"" + type_signature + "\"";
}
type_signature = new_type_signature + ").c_str()";
}
res += " " + field_name + "fieldID = jni::get_field_id(env, " + class_name_class + ", \"" + java_field_name +
"\", \"" + gen_type_signature(tree_type) + "\");\n";
"\", " + type_signature + ");\n";
}
res += " }\n";
@ -596,9 +612,9 @@ std::string TD_TL_writer_jni_cpp::gen_additional_proxy_function_begin(const std:
return "\n"
"void " +
class_name + "::" + function_name +
"(JNIEnv *env) {\n"
" Class = jni::get_jclass(env, \"" +
gen_java_class_name(class_name) + "\");\n";
"(JNIEnv *env, const char *package_name) {\n"
" Class = jni::get_jclass(env, " +
gen_java_class_name(class_name) + ");\n";
}
std::string TD_TL_writer_jni_cpp::gen_additional_proxy_function_case(const std::string &function_name,
@ -606,7 +622,7 @@ std::string TD_TL_writer_jni_cpp::gen_additional_proxy_function_case(const std::
const std::string &class_name, int arity) const {
assert(function_name == "init_jni_vars");
assert(arity == 0);
return " " + class_name + "::" + function_name + "(env);\n";
return " " + class_name + "::" + function_name + "(env, package_name);\n";
}
std::string TD_TL_writer_jni_cpp::gen_additional_proxy_function_case(const std::string &function_name,
@ -615,7 +631,7 @@ std::string TD_TL_writer_jni_cpp::gen_additional_proxy_function_case(const std::
bool is_function) const {
assert(function_name == "init_jni_vars");
assert(arity == 0);
return " " + gen_class_name(t->name) + "::" + function_name + "(env);\n";
return " " + gen_class_name(t->name) + "::" + function_name + "(env, package_name);\n";
}
std::string TD_TL_writer_jni_cpp::gen_additional_proxy_function_end(const std::string &function_name,

View File

@ -38,13 +38,8 @@ class TD_TL_writer_jni_cpp : public TD_TL_writer_cpp {
public:
TD_TL_writer_jni_cpp(const std::string &tl_name, const std::string &string_type, const std::string &bytes_type,
const std::vector<std::string> &ext_include, const std::string &package_name_)
: TD_TL_writer_cpp(tl_name, string_type, bytes_type, ext_include), package_name(package_name_) {
for (std::size_t i = 0; i < package_name.size(); i++) {
if (package_name[i] == '.') {
package_name[i] = '/';
}
}
const std::vector<std::string> &ext_include)
: TD_TL_writer_cpp(tl_name, string_type, bytes_type, ext_include) {
}
bool is_built_in_simple_type(const std::string &name) const override;

View File

@ -141,7 +141,7 @@ std::string TD_TL_writer_jni_h::gen_additional_function(const std::string &funct
if (function_name == "init_jni_vars") {
return "\n"
" static void " +
function_name + "(JNIEnv *env);\n";
function_name + "(JNIEnv *env, const char *package_name);\n";
}
return TD_TL_writer_h::gen_additional_function(function_name, t, is_function);
@ -154,7 +154,7 @@ std::string TD_TL_writer_jni_h::gen_additional_proxy_function_begin(const std::s
if (function_name == "init_jni_vars") {
return "\n"
" static void " +
function_name + "(JNIEnv *env);\n";
function_name + "(JNIEnv *env, const char *package_name);\n";
}
return TD_TL_writer_h::gen_additional_proxy_function_begin(function_name, type, class_name, arity, is_function);

View File

@ -236,6 +236,7 @@ class Variant {
int32 get_offset() const {
return offset_;
}
private:
union {
int64 align_;