From 67230ac8e761d45560ef5611ea3aa8d8152ccb29 Mon Sep 17 00:00:00 2001 From: Niki Guldbrand Date: Fri, 26 Aug 2016 22:54:48 +0200 Subject: [PATCH] Keep Source tree clean * Move all generated files to the build tree during build so the source tree is kept clean. Signed-off-by: Niki Guldbrand --- .gitignore | 40 +----------------------- CMakeLists.txt | 1 + common/CMakeLists.txt | 59 ++++++++++++++++++----------------- eeschema/CMakeLists.txt | 34 ++++++++++---------- pcb_calculator/CMakeLists.txt | 32 ++++++++++--------- pcbnew/CMakeLists.txt | 10 +++--- 6 files changed, 74 insertions(+), 102 deletions(-) diff --git a/.gitignore b/.gitignore index de78aa985e..14969d12ac 100644 --- a/.gitignore +++ b/.gitignore @@ -2,53 +2,15 @@ boost_root .downloads-by-cmake Build build -common/netlist_keywords.* -common/netlist_lexer.h -common/pcb_plot_params_lexer.h -common/page_layout/page_layout_reader_keywords.cpp -common/fp_lib_table_keywords.* -common/gal/opengl/shader_src.h -include/fp_lib_table_lexer.h -include/netlist_lexer.h -include/page_layout_reader_lexer.h -eeschema/cmp_library_lexer.h -eeschema/cmp_library_keywords.* -eeschema/dialogs/dialog_bom_cfg_keywords.cpp -eeschema/dialogs/dialog_bom_cfg_lexer.h -eeschema/dialogs/dialog_bom_help_html.h -eeschema/template_fieldnames_keywords.* -eeschema/template_fieldnames_lexer.h -pcbnew/dialogs/dialog_freeroute_exchange_help_html.h -pcbnew/pcb_plot_params_keywords.cpp -pcbnew/pcb_plot_params_lexer.h -pcb_calculator/attenuators/bridget_tee_formula.h -pcb_calculator/attenuators/pi_formula.h -pcb_calculator/attenuators/splitter_formula.h -pcb_calculator/attenuators/tee_formula.h -Makefile -CMakeCache.txt auto_renamed_to_cpp Testing -version.h -config.h install_manifest.txt Documentation/doxygen Documentation/development/doxygen *.bak .*.swp *.~* -common/pcb_plot_params_keywords.cpp -include/pcb_plot_params_lexer.h -pcbnew/specctra_keywords.cpp -pcbnew/specctra_lexer.h -pcb_calculator/pcb_calculator_datafile_keywords.cpp -pcb_calculator/pcb_calculator_datafile_lexer.h new/html -new/sch_lib_table_keywords.cpp -new/sch_lib_table_lexer.h -new/sweet_keywords.cpp -new/sweet_lexer.h bitmaps_png/png* bitmaps_png/tmp -common/pcb_keywords.cpp -include/pcb_lexer.h + diff --git a/CMakeLists.txt b/CMakeLists.txt index 6b4b2741ea..484a365840 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -519,6 +519,7 @@ endif() set( INC_BEFORE . ${CMAKE_SOURCE_DIR}/include + ${PROJECT_BINARY_DIR}/include ) set( INC_AFTER diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 612c817bed..53d6069a2b 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -1,5 +1,7 @@ include_directories( BEFORE ${INC_BEFORE} ) include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/gal/opengl/ ./dialogs ./widgets ./dialog_about @@ -8,6 +10,7 @@ include_directories( ${GLM_INCLUDE_DIR} ${CURL_INCLUDE_DIRS} ../3d-viewer + ${PROJECT_BINARY_DIR}/pcbnew ../pcbnew ../polygon ${INC_AFTER} @@ -22,18 +25,18 @@ endif() # Generate header files containing shader programs # Order of input files is significant add_custom_command( - OUTPUT gal/opengl/shader_src.h + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/gal/opengl/shader_src.h COMMAND ${CMAKE_COMMAND} -DinputFiles="${PROJECT_SOURCE_DIR}/common/gal/opengl/shader.vert\\;${PROJECT_SOURCE_DIR}/common/gal/opengl/shader.frag" - -DoutputFile="shader_src.h" + -DoutputFile="${CMAKE_CURRENT_BINARY_DIR}/gal/opengl/shader_src.h" -P ${CMAKE_MODULE_PATH}/Shaders.cmake - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/common/gal/opengl + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} COMMENT "Generating headers containing GLSL source code" ) add_custom_target( shader_headers ALL - DEPENDS gal/opengl/shader_src.h + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/gal/opengl/shader_src.h ) set( GAL_SRCS @@ -384,8 +387,8 @@ add_dependencies( pcbcommon lib-dependencies ) # auto-generate specctra_lexer.h and specctra_keywords.cpp make_lexer( ${PROJECT_SOURCE_DIR}/pcbnew/specctra.keywords - ${PROJECT_SOURCE_DIR}/pcbnew/specctra_lexer.h - ${PROJECT_SOURCE_DIR}/pcbnew/specctra_keywords.cpp + ${PROJECT_BINARY_DIR}/pcbnew/specctra_lexer.h + ${PROJECT_BINARY_DIR}/pcbnew/specctra_keywords.cpp DSN # Pass header file with dependency on *_lexer.h as extra_arg @@ -395,8 +398,8 @@ make_lexer( add_custom_target( specctra_lexer_source_files ALL DEPENDS - ${PROJECT_SOURCE_DIR}/pcbnew/specctra_lexer.h - ${PROJECT_SOURCE_DIR}/pcbnew/specctra_keywords.cpp + ${PROJECT_BINARY_DIR}/pcbnew/specctra_lexer.h + ${PROJECT_BINARY_DIR}/pcbnew/specctra_keywords.cpp ) add_dependencies( pcbcommon specctra_lexer_source_files ) @@ -404,8 +407,8 @@ add_dependencies( pcbcommon specctra_lexer_source_files ) # auto-generate netlist_lexer.h and netlist_keywords.cpp make_lexer( ${CMAKE_CURRENT_SOURCE_DIR}/netlist.keywords - ${PROJECT_SOURCE_DIR}/include/netlist_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/netlist_keywords.cpp + ${PROJECT_BINARY_DIR}/include/netlist_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/netlist_keywords.cpp NL_T # Pass header file with dependency on *_lexer.h as extra_arg @@ -415,8 +418,8 @@ make_lexer( add_custom_target( netlist_lexer_source_files ALL DEPENDS - ${PROJECT_SOURCE_DIR}/include/netlist_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/netlist_keywords.cpp + ${PROJECT_BINARY_DIR}/include/netlist_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/netlist_keywords.cpp ) add_dependencies( common netlist_lexer_source_files ) @@ -425,8 +428,8 @@ add_dependencies( pcbcommon netlist_lexer_source_files ) # auto-generate pcb_plot_params_lexer.h and pcb_plot_params_keywords.cpp make_lexer( ${CMAKE_CURRENT_SOURCE_DIR}/pcb_plot_params.keywords - ${PROJECT_SOURCE_DIR}/include/pcb_plot_params_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/pcb_plot_params_keywords.cpp + ${PROJECT_BINARY_DIR}/include/pcb_plot_params_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/pcb_plot_params_keywords.cpp PCBPLOTPARAMS_T # Pass header file with dependencies on *_lexer.h as extra_arg @@ -436,8 +439,8 @@ make_lexer( add_custom_target( pcb_plot_lexer_source_files ALL DEPENDS - ${PROJECT_SOURCE_DIR}/include/pcb_plot_params_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/pcb_plot_params_keywords.cpp + ${PROJECT_BINARY_DIR}/include/pcb_plot_params_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/pcb_plot_params_keywords.cpp ) add_dependencies( pcbcommon pcb_plot_lexer_source_files ) @@ -445,8 +448,8 @@ add_dependencies( pcbcommon pcb_plot_lexer_source_files ) # auto-generate pcbnew_sexpr.h and pcbnew_sexpr.cpp make_lexer( ${CMAKE_CURRENT_SOURCE_DIR}/pcb.keywords - ${PROJECT_SOURCE_DIR}/include/pcb_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/pcb_keywords.cpp + ${PROJECT_BINARY_DIR}/include/pcb_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/pcb_keywords.cpp PCB_KEYS_T # Pass header file with dependency on *_lexer.h as extra_arg @@ -456,8 +459,8 @@ make_lexer( add_custom_target( pcb_lexer_source_files ALL DEPENDS - ${PROJECT_SOURCE_DIR}/include/pcb_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/pcb_keywords.cpp + ${PROJECT_BINARY_DIR}/include/pcb_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/pcb_keywords.cpp ) add_dependencies( pcbcommon pcb_lexer_source_files ) @@ -465,16 +468,16 @@ add_dependencies( pcbcommon pcb_lexer_source_files ) # auto-generate pcbnew s-expression footprint library table code. make_lexer( ${CMAKE_CURRENT_SOURCE_DIR}/fp_lib_table.keywords - ${PROJECT_SOURCE_DIR}/include/fp_lib_table_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/fp_lib_table_keywords.cpp + ${PROJECT_BINARY_DIR}/include/fp_lib_table_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/fp_lib_table_keywords.cpp FP_LIB_TABLE_T ) add_custom_target( fp_lib_table_lexer_source_files ALL DEPENDS - ${PROJECT_SOURCE_DIR}/include/fp_lib_table_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/fp_lib_table_keywords.cpp + ${PROJECT_BINARY_DIR}/include/fp_lib_table_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/fp_lib_table_keywords.cpp ) add_dependencies( pcbcommon fp_lib_table_lexer_source_files ) @@ -483,16 +486,16 @@ add_dependencies( pcbcommon fp_lib_table_lexer_source_files ) # and title_block_reader_keywords.cpp. make_lexer( ${CMAKE_CURRENT_SOURCE_DIR}/page_layout/page_layout_reader.keywords - ${PROJECT_SOURCE_DIR}/include/page_layout_reader_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/page_layout/page_layout_reader_keywords.cpp + ${PROJECT_BINARY_DIR}/include/page_layout_reader_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/page_layout/page_layout_reader_keywords.cpp TB_READER_T ) add_custom_target( page_layout_lexer_source_files ALL DEPENDS - ${PROJECT_SOURCE_DIR}/include/page_layout_reader_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/page_layout/page_layout_reader_keywords.cpp + ${PROJECT_BINARY_DIR}/include/page_layout_reader_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/page_layout/page_layout_reader_keywords.cpp ) add_dependencies( common page_layout_lexer_source_files ) diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 59e714e68c..4279d302ab 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -6,6 +6,8 @@ endif() include_directories( BEFORE ${INC_BEFORE} ) include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_BINARY_DIR}/dialogs ./dialogs ./netlist_exporters ./widgets @@ -230,19 +232,19 @@ endif() # Create a C++ compilable string initializer containing html text into a *.h file: add_custom_command( - OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help_html.h + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dialogs/dialog_bom_help_html.h COMMAND ${CMAKE_COMMAND} -DinputFile=${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help.html - -DoutputFile=${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help_html.h + -DoutputFile=${CMAKE_CURRENT_BINARY_DIR}/dialogs/dialog_bom_help_html.h -P ${CMAKE_MODULE_PATH}/Html2C.cmake DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help.html - COMMENT "creating ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help_html.h + COMMENT "creating ${CMAKE_BINARY_SOURCE_DIR}/dialogs/dialog_bom_help_html.h from ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help.html" ) set_source_files_properties( dialogs/dialog_bom.cpp PROPERTIES - OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_help_html.h + OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/dialogs/dialog_bom_help_html.h ) if( APPLE ) @@ -362,24 +364,24 @@ endif() # library format. make_lexer( ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library.keywords - ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library_keywords.cpp + ${CMAKE_CURRENT_BINARY_DIR}/cmp_library_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/cmp_library_keywords.cpp TLIB_T ) add_custom_target( cmp_library_lexer_source_files ALL DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/cmp_library_keywords.cpp + ${CMAKE_CURRENT_BINARY_DIR}/cmp_library_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/cmp_library_keywords.cpp ) add_dependencies( eeschema_kiface cmp_library_lexer_source_files ) make_lexer( ${CMAKE_CURRENT_SOURCE_DIR}/template_fieldnames.keywords - ${CMAKE_CURRENT_SOURCE_DIR}/template_fieldnames_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/template_fieldnames_keywords.cpp + ${CMAKE_CURRENT_BINARY_DIR}/template_fieldnames_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/template_fieldnames_keywords.cpp TFIELD_T # Pass header file with dependency on *_lexer.h as extra_arg @@ -389,16 +391,16 @@ make_lexer( add_custom_target( field_template_lexer_source_files ALL DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/template_fieldnames_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/template_fieldnames_keywords.cpp + ${CMAKE_CURRENT_BINARY_DIR}/template_fieldnames_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/template_fieldnames_keywords.cpp ) add_dependencies( eeschema_kiface field_template_lexer_source_files ) make_lexer( ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg.keywords - ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg_keywords.cpp + ${CMAKE_CURRENT_BINARY_DIR}/dialogs/dialog_bom_cfg_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/dialogs/dialog_bom_cfg_keywords.cpp T_BOMCFG_T # Pass header file with dependency on *_lexer.h as extra_arg @@ -408,8 +410,8 @@ make_lexer( add_custom_target( dialog_bom_cfg_lexer_source_files ALL DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_bom_cfg_keywords.cpp + ${CMAKE_CURRENT_BINARY_DIR}/dialogs/dialog_bom_cfg_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/dialogs/dialog_bom_cfg_keywords.cpp ) add_dependencies( eeschema_kiface dialog_bom_cfg_lexer_source_files ) diff --git a/pcb_calculator/CMakeLists.txt b/pcb_calculator/CMakeLists.txt index 292308c4e5..ff8cf17b57 100644 --- a/pcb_calculator/CMakeLists.txt +++ b/pcb_calculator/CMakeLists.txt @@ -1,9 +1,11 @@ include_directories( BEFORE ${INC_BEFORE} ) include_directories( + ${CMAKE_CURRENT_BINARY_DIR} bitmaps dialogs transline + ${CMAKE_CURRENT_BINARY_DIR}/attenuators attenuators ../polygon ../common @@ -149,8 +151,8 @@ endif() # for the storage data file format. make_lexer( ${CMAKE_CURRENT_SOURCE_DIR}/pcb_calculator_datafile.keywords - ${CMAKE_CURRENT_SOURCE_DIR}/pcb_calculator_datafile_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/pcb_calculator_datafile_keywords.cpp + ${CMAKE_CURRENT_BINARY_DIR}/pcb_calculator_datafile_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/pcb_calculator_datafile_keywords.cpp PCBCALC_DATA_T # Pass header file with dependency on *_lexer.h as extra_arg @@ -160,8 +162,8 @@ make_lexer( add_custom_target( pcb_calculator_lexer_source_files ALL DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/pcb_calculator_datafile_lexer.h - ${CMAKE_CURRENT_SOURCE_DIR}/pcb_calculator_datafile_keywords.cpp + ${CMAKE_CURRENT_BINARY_DIR}/pcb_calculator_datafile_lexer.h + ${CMAKE_CURRENT_BINARY_DIR}/pcb_calculator_datafile_keywords.cpp ) # @@ -170,25 +172,25 @@ add_custom_target( # Function html_doc2h : converts a single *.html text file to a *.h header function( html_doc2h inputFile ) add_custom_command( - OUTPUT ${inputFile}.h + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${inputFile}.h - COMMAND ${CMAKE_COMMAND} -DinputFile=${inputFile}.html -DoutputFile=${inputFile}.h + COMMAND ${CMAKE_COMMAND} -DinputFile=${CMAKE_CURRENT_SOURCE_DIR}/${inputFile}.html -DoutputFile=${CMAKE_CURRENT_BINARY_DIR}/${inputFile}.h -P ${CMAKE_MODULE_PATH}/Html2C.cmake DEPENDS ${inputFile}.html ${CMAKE_MODULE_PATH}/Html2C.cmake - COMMENT "creating ${inputFile}.h from ${inputFile}.html" + COMMENT "creating ${CMAKE_CURRENT_BINARY_DIR}/${inputFile}.h from ${CMAKE_CURRENT_SOURCE_DIR}/${inputFile}.html" ) endfunction() - html_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/bridget_tee_formula ) - html_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/splitter_formula ) - html_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/pi_formula ) - html_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/tee_formula ) + html_doc2h( attenuators/bridget_tee_formula ) + html_doc2h( attenuators/splitter_formula ) + html_doc2h( attenuators/pi_formula ) + html_doc2h( attenuators/tee_formula ) set( DOCS_LIST - ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/pi_formula.h - ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/tee_formula.h - ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/bridget_tee_formula.h - ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/splitter_formula.h + ${CMAKE_CURRENT_BINARY_DIR}/attenuators/pi_formula.h + ${CMAKE_CURRENT_BINARY_DIR}/attenuators/tee_formula.h + ${CMAKE_CURRENT_BINARY_DIR}/attenuators/bridget_tee_formula.h + ${CMAKE_CURRENT_BINARY_DIR}/attenuators/splitter_formula.h ) set_source_files_properties( attenuators/attenuator_classes.cpp diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index c4aff5177a..21eaec9ee0 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -28,6 +28,8 @@ endif() include_directories( BEFORE ${INC_BEFORE} ) include_directories( + ${PROJECT_BINARY_DIR}/pcbnew + ${PROJECT_BINARY_DIR}/pcbnew/dialogs ./dialogs ./autorouter ../3d-viewer @@ -518,18 +520,18 @@ endif() # Create a C++ compilable string initializer containing html text into a *.h file: add_custom_command( - OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help_html.h + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dialogs/dialog_freeroute_exchange_help_html.h COMMAND ${CMAKE_COMMAND} -DinputFile=${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help.html - -DoutputFile=${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help_html.h + -DoutputFile=${CMAKE_CURRENT_BINARY_DIR}/dialogs/dialog_freeroute_exchange_help_html.h -P ${CMAKE_MODULE_PATH}/Html2C.cmake DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help.html - COMMENT "creating ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help_html.h + COMMENT "creating ${CMAKE_CURRENT_BINARY_DIR}/dialogs/dialog_freeroute_exchange_help_html.h from ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help.html" ) set_source_files_properties( dialogs/dialog_freeroute_exchange.cpp PROPERTIES - OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/dialog_freeroute_exchange_help_html.h + OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/dialogs/dialog_freeroute_exchange_help_html.h ) add_subdirectory( pcad2kicadpcb_plugin )