From 3b590e7bfb01d3447fd762cb02937e38c77c59b1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 4 Aug 2026 16:04:35 +0200 Subject: [PATCH 1/3] MDEV-40608 MariaDB-devel is incomplete for plugins create and install mariadb-plugin-config.cmake --- .gitignore | 1 + CMakeLists.txt | 13 +++++++- cmake/plugin.cmake | 22 +++++-------- support-files/CMakeLists.txt | 6 ++++ support-files/mariadb-plugin-config.cmake.in | 33 ++++++++++++++++++++ 5 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 support-files/mariadb-plugin-config.cmake.in diff --git a/.gitignore b/.gitignore index 11a6c4600d711..551a2e8fa7d79 100644 --- a/.gitignore +++ b/.gitignore @@ -264,6 +264,7 @@ support-files/mariadb-extra.socket support-files/mariadb@.service support-files/mariadb@.socket support-files/mariadb-extra@.socket +support-files/mariadb-plugin-config.cmake support-files/mini-benchmark support-files/my-huge.cnf support-files/my-innodb-heavy-4G.cnf diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f68ec93a13ae..6e151f1e4851c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -493,7 +493,18 @@ SET(PYTHON_SHEBANG "/usr/bin/env python3" CACHE STRING "python shebang") MARK_AS_ADVANCED(PYTHON_SHEBANG) # Add storage engines and plugins. -CONFIGURE_PLUGINS() +IF(NOT WITHOUT_SERVER) + FILE(GLOB dirs_storage ${CMAKE_SOURCE_DIR}/storage/*) +ENDIF() + +FILE(GLOB dirs_plugin ${CMAKE_SOURCE_DIR}/plugin/*) +FOREACH(dir ${dirs_storage} ${dirs_plugin}) + IF (EXISTS ${dir}/CMakeLists.txt) + ADD_SUBDIRECTORY(${dir}) + ENDIF() +ENDFOREACH() + +VERIFY_PLUGINS() ADD_SUBDIRECTORY(include) ADD_SUBDIRECTORY(dbug) diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake index a0deacbcb578b..8a99b999dd1d1 100644 --- a/cmake/plugin.cmake +++ b/cmake/plugin.cmake @@ -17,7 +17,7 @@ INCLUDE(CMakeParseArguments) -# MYSQL_ADD_PLUGIN(plugin_name source1...sourceN +# MARIADB_ADD_PLUGIN(plugin_name source1...sourceN # [STORAGE_ENGINE] # [STATIC_ONLY|MODULE_ONLY] # [MANDATORY|DEFAULT] @@ -32,7 +32,7 @@ INCLUDE(CMakeParseArguments) # [LINK_LIBRARIES lib1...libN] # [DEPENDS target1...targetN] -MACRO(MYSQL_ADD_PLUGIN) +MACRO(MARIADB_ADD_PLUGIN) CMAKE_PARSE_ARGUMENTS(ARG "STORAGE_ENGINE;STATIC_ONLY;MODULE_ONLY;MANDATORY;DEFAULT;DISABLED;NOT_EMBEDDED;RECOMPILE_FOR_EMBEDDED;CLIENT" "MODULE_OUTPUT_NAME;STATIC_OUTPUT_NAME;COMPONENT;CONFIG;VERSION" @@ -326,20 +326,12 @@ MACRO(MYSQL_ADD_PLUGIN) ENDMACRO() -# Add all CMake projects under storage and plugin -# subdirectories, configure sql_builtins.cc -MACRO(CONFIGURE_PLUGINS) - IF(NOT WITHOUT_SERVER) - FILE(GLOB dirs_storage ${CMAKE_SOURCE_DIR}/storage/*) - ENDIF() - - FILE(GLOB dirs_plugin ${CMAKE_SOURCE_DIR}/plugin/*) - FOREACH(dir ${dirs_storage} ${dirs_plugin}) - IF (EXISTS ${dir}/CMakeLists.txt) - ADD_SUBDIRECTORY(${dir}) - ENDIF() - ENDFOREACH() +MACRO(MYSQL_ADD_PLUGIN) + MARIADB_ADD_PLUGIN(${ARGV}) +ENDMACRO() +# verify that all -DPLUGIN_xxx=YES plugins are being built +MACRO(VERIFY_PLUGINS) GET_CMAKE_PROPERTY(ALL_VARS VARIABLES) FOREACH (V ${ALL_VARS}) IF (V MATCHES "^PLUGIN_") diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index 1e2b5ef37c332..542b9743444d2 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -256,4 +256,10 @@ IF(UNIX AND NOT WITHOUT_SERVER) WORKING_DIRECTORY \$ENV{DESTDIR}${prefix})" COMPONENT SupportFiles) ENDIF(INSTALL_SYSCONFDIR) + + FILE(READ ${CMAKE_SOURCE_DIR}/cmake/install_layout.cmake install_layout.cmake) + FILE(READ ${CMAKE_SOURCE_DIR}/cmake/plugin.cmake plugin.cmake) + CONFIGURE_FILE(mariadb-plugin-config.cmake.in mariadb-plugin-config.cmake @ONLY) + INSTALL(FILES mariadb-plugin-config.cmake DESTINATION ${INSTALL_SHAREDIR}/cmake/mariadb-plugin/ + COMPONENT Development) ENDIF() diff --git a/support-files/mariadb-plugin-config.cmake.in b/support-files/mariadb-plugin-config.cmake.in new file mode 100644 index 0000000000000..e9e8226242cfa --- /dev/null +++ b/support-files/mariadb-plugin-config.cmake.in @@ -0,0 +1,33 @@ +# Copyright (c) 2026, MariaDB plc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA + +MACRO(DTRACE_INSTRUMENT) +ENDMACRO() +MACRO(ADD_VERSION_INFO) +ENDMACRO() +MACRO(MYSQL_INSTALL_TARGETS) + INSTALL(TARGETS ${ARGV}) +ENDMACRO() +ADD_CUSTOM_TARGET(GenError) + +INCLUDE(FeatureSummary) + +GET_FILENAME_COMPONENT(prefix "${CMAKE_CURRENT_LIST_DIR}/../../.." ABSOLUTE) +INCLUDE_DIRECTORIES(${prefix}/@INSTALL_INCLUDEDIR@/server ${prefix}/@INSTALL_INCLUDEDIR@/server/private) + +@install_layout.cmake@ + +@plugin.cmake@ + From 7bf109aa72ffb270b142d61876d785a697eaac2e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 4 Aug 2026 17:35:29 +0200 Subject: [PATCH 2/3] don't put WITH_WSREP into my_config.h it confuses plugins, when installed --- cmake/wsrep.cmake | 1 + config.h.cmake | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake index 91f040bcdb6ef..748ed705e3751 100644 --- a/cmake/wsrep.cmake +++ b/cmake/wsrep.cmake @@ -35,6 +35,7 @@ IF(WITH_WSREP) # Set the patch version SET(WSREP_PATCH_VERSION "22") + ADD_DEFINITIONS(-DWITH_WSREP) ADD_SUBMODULE(wsrep-lib) # Obtain wsrep API version diff --git a/config.h.cmake b/config.h.cmake index e0c65c3e3a73c..86d0d9ef07fbc 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -543,7 +543,6 @@ #ifndef EMBEDDED_LIBRARY #cmakedefine WSREP_INTERFACE_VERSION "@WSREP_INTERFACE_VERSION@" -#cmakedefine WITH_WSREP 1 #endif #if !defined(__STDC_FORMAT_MACROS) From 667da4a47d1453bf975b59b8fdc778088a03fb5b Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 7 Aug 2026 10:56:10 +0200 Subject: [PATCH 3/3] rename plugin.cmake -> mariadb-plugin-config.cmake to make it possible for the same plugin to compile inside and outside the server source tree. switch example plugins to use that. --- CMakeLists.txt | 5 +-- ...ugin.cmake => mariadb-plugin-config.cmake} | 34 +++++++++---------- plugin/auth_examples/CMakeLists.txt | 23 +++++++------ plugin/daemon_example/CMakeLists.txt | 4 ++- plugin/example_key_management/CMakeLists.txt | 5 +-- sql/sql_builtin.cc.in | 2 +- storage/example/CMakeLists.txt | 4 ++- support-files/CMakeLists.txt | 4 +-- 8 files changed, 45 insertions(+), 36 deletions(-) rename cmake/{plugin.cmake => mariadb-plugin-config.cmake} (94%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e151f1e4851c..2f56c6e8c65f5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (c) 2006, 2017, Oracle and/or its affiliates. -# Copyright (c) 2008, 2022, MariaDB Corporation. +# Copyright (c) 2008, 2026, MariaDB Corporation. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -43,6 +43,7 @@ MESSAGE(STATUS "Running cmake version ${CMAKE_VERSION}") SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_SOURCE_DIR}/cmake/Internal/CPack) +SET(mariadb-plugin_DIR ${CMAKE_SOURCE_DIR}/cmake) # Use a default manufacturer if no manufacturer was identified. IF(NOT DEFINED MANUFACTURER) @@ -167,7 +168,7 @@ INCLUDE(dtrace) INCLUDE(pcre) INCLUDE(libfmt) INCLUDE(ctest) -INCLUDE(plugin) +INCLUDE(mariadb-plugin-config) INCLUDE(install_macros) INCLUDE(systemd) INCLUDE(mysql_add_executable) diff --git a/cmake/plugin.cmake b/cmake/mariadb-plugin-config.cmake similarity index 94% rename from cmake/plugin.cmake rename to cmake/mariadb-plugin-config.cmake index 8a99b999dd1d1..a3e09fbdf134b 100644 --- a/cmake/plugin.cmake +++ b/cmake/mariadb-plugin-config.cmake @@ -42,7 +42,7 @@ MACRO(MARIADB_ADD_PLUGIN) IF(NOT WITHOUT_SERVER OR ARG_CLIENT) # Add common include directories - INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include + INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql ${PCRE_INCLUDE_DIRS} ${SSL_INCLUDE_DIRS} @@ -133,7 +133,7 @@ MACRO(MARIADB_ADD_PLUGIN) IF(ARG_VERSION) SET(version_string ";PLUGIN_${plugin}_VERSION=\"${ARG_VERSION}\"") ENDIF() - + IF(NOT ARG_MODULE_OUTPUT_NAME) IF(ARG_STORAGE_ENGINE) SET(ARG_MODULE_OUTPUT_NAME "ha_${target}") @@ -148,10 +148,10 @@ MACRO(MARIADB_ADD_PLUGIN) IF(CMAKE_GENERATOR MATCHES "Makefiles|Ninja") # If there is a shared library from previous shared build, - # remove it. This is done just for mysql-test-run.pl - # so it does not try to use stale shared lib as plugin + # remove it. This is done just for mysql-test-run.pl + # so it does not try to use stale shared lib as plugin # in test. - FILE(REMOVE + FILE(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${ARG_MODULE_OUTPUT_NAME}${CMAKE_SHARED_MODULE_SUFFIX}) ENDIF() @@ -166,9 +166,9 @@ MACRO(MARIADB_ADD_PLUGIN) # Recompile some plugins for embedded ADD_CONVENIENCE_LIBRARY(${target}_embedded ${SOURCES}) RESTRICT_SYMBOL_EXPORTS(${target}_embedded) - DTRACE_INSTRUMENT(${target}_embedded) + DTRACE_INSTRUMENT(${target}_embedded) IF(ARG_RECOMPILE_FOR_EMBEDDED) - SET_TARGET_PROPERTIES(${target}_embedded + SET_TARGET_PROPERTIES(${target}_embedded PROPERTIES COMPILE_DEFINITIONS "EMBEDDED_LIBRARY${version_string}") ENDIF() ADD_DEPENDENCIES(${target}_embedded GenError ${ARG_DEPENDS}) @@ -179,7 +179,7 @@ MACRO(MARIADB_ADD_PLUGIN) ENDIF() IF(ARG_STATIC_OUTPUT_NAME) - SET_TARGET_PROPERTIES(${target} PROPERTIES + SET_TARGET_PROPERTIES(${target} PROPERTIES OUTPUT_NAME ${ARG_STATIC_OUTPUT_NAME}) ENDIF() @@ -190,7 +190,7 @@ MACRO(MARIADB_ADD_PLUGIN) SET(${with_var} ON CACHE INTERNAL "Link ${plugin} statically to the server" FORCE) # Update mysqld dependencies - SET (MYSQLD_STATIC_PLUGIN_LIBS ${MYSQLD_STATIC_PLUGIN_LIBS} + SET (MYSQLD_STATIC_PLUGIN_LIBS ${MYSQLD_STATIC_PLUGIN_LIBS} ${target} ${ARG_LINK_LIBRARIES} CACHE INTERNAL "" FORCE) IF(WITH_EMBEDDED_SERVER AND (NOT ARG_NOT_EMBEDDED)) @@ -205,11 +205,11 @@ MACRO(MARIADB_ADD_PLUGIN) ENDIF() IF(ARG_MANDATORY) - SET (mysql_mandatory_plugins + SET (mysql_mandatory_plugins "${mysql_mandatory_plugins}${builtin_entry}\n") SET (mysql_mandatory_plugins ${mysql_mandatory_plugins} PARENT_SCOPE) ELSE() - SET (mysql_optional_plugins + SET (mysql_optional_plugins "${mysql_optional_plugins}${builtin_entry}\n") SET (mysql_optional_plugins ${mysql_optional_plugins} PARENT_SCOPE) ENDIF() @@ -217,7 +217,7 @@ MACRO(MARIADB_ADD_PLUGIN) AND NOT ARG_STATIC_ONLY AND NOT WITHOUT_DYNAMIC_PLUGINS) ADD_VERSION_INFO(${target} MODULE SOURCES) - ADD_LIBRARY(${target} MODULE ${SOURCES}) + ADD_LIBRARY(${target} MODULE ${SOURCES}) DTRACE_INSTRUMENT(${target}) SET_TARGET_PROPERTIES (${target} PROPERTIES PREFIX "") @@ -238,10 +238,10 @@ MACRO(MARIADB_ADD_PLUGIN) ENDIF() # Server plugins use symbols defined in mysqld executable. - # Some operating systems like Windows and OSX and are pretty strict about + # Some operating systems like Windows and OSX and are pretty strict about # unresolved symbols. Others are less strict and allow unresolved symbols - # in shared libraries. On Linux for example, CMake does not even add - # executable to the linker command line (it would result into link error). + # in shared libraries. On Linux for example, CMake does not even add + # executable to the linker command line (it would result into link error). # Thus we skip TARGET_LINK_LIBRARIES on Linux, as it would only generate # an additional dependency. IF(ARG_RECOMPILE_FOR_EMBEDDED OR ARG_STORAGE_ENGINE) @@ -256,8 +256,8 @@ MACRO(MARIADB_ADD_PLUGIN) ADD_DEPENDENCIES(${target} GenError ${ARG_DEPENDS}) - SET_TARGET_PROPERTIES(${target} PROPERTIES - OUTPUT_NAME "${ARG_MODULE_OUTPUT_NAME}") + SET_TARGET_PROPERTIES(${target} PROPERTIES + OUTPUT_NAME "${ARG_MODULE_OUTPUT_NAME}") # Install dynamic library IF(ARG_COMPONENT) IF(CPACK_COMPONENTS_ALL AND diff --git a/plugin/auth_examples/CMakeLists.txt b/plugin/auth_examples/CMakeLists.txt index 0efd8348ab443..1e94668d9f053 100644 --- a/plugin/auth_examples/CMakeLists.txt +++ b/plugin/auth_examples/CMakeLists.txt @@ -1,36 +1,39 @@ # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. -# +# Copyright (c) 2026, MariaDB plc +# # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; version 2 of the # License. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA -MYSQL_ADD_PLUGIN(dialog_examples dialog_examples.c +FIND_PACKAGE(mariadb-plugin REQUIRED) + +MARIADB_ADD_PLUGIN(dialog_examples dialog_examples.c MODULE_ONLY COMPONENT Test) -MYSQL_ADD_PLUGIN(auth_test_plugin test_plugin.c +MARIADB_ADD_PLUGIN(auth_test_plugin test_plugin.c MODULE_ONLY COMPONENT Test) -MYSQL_ADD_PLUGIN(qa_auth_interface qa_auth_interface.c +MARIADB_ADD_PLUGIN(qa_auth_interface qa_auth_interface.c MODULE_ONLY COMPONENT Test) -MYSQL_ADD_PLUGIN(qa_auth_server qa_auth_server.c +MARIADB_ADD_PLUGIN(qa_auth_server qa_auth_server.c MODULE_ONLY COMPONENT Test) -MYSQL_ADD_PLUGIN(qa_auth_client qa_auth_client.c +MARIADB_ADD_PLUGIN(qa_auth_client qa_auth_client.c MODULE_ONLY COMPONENT Test) -MYSQL_ADD_PLUGIN(auth_0x0100 auth_0x0100.c MODULE_ONLY COMPONENT Test) +MARIADB_ADD_PLUGIN(auth_0x0100 auth_0x0100.c MODULE_ONLY COMPONENT Test) # disabled in favor of # libmariadb/plugins/auth/mariadb_cleartext.c # -#MYSQL_ADD_PLUGIN(mysql_clear_password clear_password_client.c +#MARIADB_ADD_PLUGIN(mysql_clear_password clear_password_client.c # MODULE_ONLY CLIENT COMPONENT ClientPlugins) diff --git a/plugin/daemon_example/CMakeLists.txt b/plugin/daemon_example/CMakeLists.txt index 57a1135e69550..fe370cc83d338 100644 --- a/plugin/daemon_example/CMakeLists.txt +++ b/plugin/daemon_example/CMakeLists.txt @@ -1,4 +1,5 @@ # Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2026, MariaDB plc # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -13,7 +14,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA -MYSQL_ADD_PLUGIN(daemon_example daemon_example.cc RECOMPILE_FOR_EMBEDDED +FIND_PACKAGE(mariadb-plugin REQUIRED) +MARIADB_ADD_PLUGIN(daemon_example daemon_example.cc RECOMPILE_FOR_EMBEDDED MODULE_ONLY MODULE_OUTPUT_NAME "libdaemon_example" COMPONENT Test) INSTALL(FILES daemon_example.ini DESTINATION ${INSTALL_PLUGINDIR} diff --git a/plugin/example_key_management/CMakeLists.txt b/plugin/example_key_management/CMakeLists.txt index fe893e5368eae..da38effacdf7f 100644 --- a/plugin/example_key_management/CMakeLists.txt +++ b/plugin/example_key_management/CMakeLists.txt @@ -1,2 +1,3 @@ -MYSQL_ADD_PLUGIN(EXAMPLE_KEY_MANAGEMENT example_key_management_plugin.cc - MODULE_ONLY COMPONENT Test) +FIND_PACKAGE(mariadb-plugin REQUIRED) +MARIADB_ADD_PLUGIN(EXAMPLE_KEY_MANAGEMENT example_key_management_plugin.cc + MODULE_ONLY COMPONENT Test) diff --git a/sql/sql_builtin.cc.in b/sql/sql_builtin.cc.in index 810f98a876c3b..bab97ad992d15 100644 --- a/sql/sql_builtin.cc.in +++ b/sql/sql_builtin.cc.in @@ -16,7 +16,7 @@ /* Note that sql_builtin.cc is automatically built by sql_bultin.cc.in - and cmake/plugin.cmake + and cmake/mariadb-plugin-config.cmake */ #include diff --git a/storage/example/CMakeLists.txt b/storage/example/CMakeLists.txt index 5b59d1b1118db..36418daf24b0f 100644 --- a/storage/example/CMakeLists.txt +++ b/storage/example/CMakeLists.txt @@ -1,4 +1,5 @@ # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2026, MariaDB plc # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -13,5 +14,6 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA +FIND_PACKAGE(mariadb-plugin REQUIRED) SET(EXAMPLE_SOURCES ha_example.cc) -MYSQL_ADD_PLUGIN(example ${EXAMPLE_SOURCES} STORAGE_ENGINE MODULE_ONLY COMPONENT Test) +MARIADB_ADD_PLUGIN(example ${EXAMPLE_SOURCES} STORAGE_ENGINE MODULE_ONLY COMPONENT Test) diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt index 542b9743444d2..7a7d90815da9a 100644 --- a/support-files/CMakeLists.txt +++ b/support-files/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (c) 2006, 2016, Oracle and/or its affiliates. -# Copyright (c) 2012, 2022, MariaDB +# Copyright (c) 2012, 2026, MariaDB plc # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -258,7 +258,7 @@ IF(UNIX AND NOT WITHOUT_SERVER) ENDIF(INSTALL_SYSCONFDIR) FILE(READ ${CMAKE_SOURCE_DIR}/cmake/install_layout.cmake install_layout.cmake) - FILE(READ ${CMAKE_SOURCE_DIR}/cmake/plugin.cmake plugin.cmake) + FILE(READ ${CMAKE_SOURCE_DIR}/cmake/mariadb-plugin-config.cmake plugin.cmake) CONFIGURE_FILE(mariadb-plugin-config.cmake.in mariadb-plugin-config.cmake @ONLY) INSTALL(FILES mariadb-plugin-config.cmake DESTINATION ${INSTALL_SHAREDIR}/cmake/mariadb-plugin/ COMPONENT Development)