Triggering rebuild after changing a *.json file

Alexander Neundorf neundorf at kde.org
Mon Nov 24 19:55:28 GMT 2014


On Sunday, November 23, 2014 23:37:45 Kevin Funk wrote:
> On Sunday 23 November 2014 17:54:21 Milian Wolff wrote:
> > On Sunday 23 November 2014 10:39:02 Andreas Pakulat wrote:
> > > Hi,
> > > 
> > > On Sun, Nov 23, 2014 at 4:36 AM, Milian Wolff <mail at milianw.de> wrote:
> > > > Hey all,
> > > > 
> > > > in my quest for better *.json support in KF5 based applications, I
> > > > noticed
> > > > that we currently do not rebuild properly on changes to the *.desktop
> > > > or
> > > > *.json files.
> > > > 
> > > > For KDevelop, I'm thus playing around with something like this
> > > > currently:
> > > > 
> > > > ~~~~~~~~~~~~~~~+
> > > > function(kdevplatform_add_plugin plugin)
> > > > 
> > > >     set(options )
> > > >     set(oneValueArgs JSON)
> > > >     set(multiValueArgs SOURCES)
> > > >     cmake_parse_arguments(KDEV_ADD_PLUGIN "${options}"
> > > >     "${oneValueArgs}"
> > > > 
> > > > "${multiValueArgs}" ${ARGN})
> > > > 
> > > >     string(REGEX REPLACE "\\.cmake$" "" json_out
> > > >     ${KDEV_ADD_PLUGIN_JSON})
> > > >     configure_file(${KDEV_ADD_PLUGIN_JSON}
> > > > 
> > > > ${CMAKE_CURRENT_BINARY_DIR}/${json_out})
> > > > 
> > > >     # ensure we recompile the corresponding object files when the json
> > > >     file
> > > > 
> > > > changes
> > > > 
> > > >     set(dependent_sources )
> > > >     foreach(header ${KDEV_ADD_PLUGIN_SOURCES})
> > > >     
> > > >         file(STRINGS "${header}" match REGEX
> > > >         "K_PLUGIN_FACTORY_WITH_JSON")
> > > >         if(match)
> > > >         
> > > >             list(APPEND dependent_sources "${header}")
> > > >         
> > > >         endif()
> > > >     
> > > >     endforeach()
> > > >     if(NOT dependent_sources)
> > > >     
> > > >         # fallback to all sources - better safe than sorry...
> > > >         set(dependent_sources ${KDEV_ADD_PLUGIN_SOURCES})
> > > >     
> > > >     endif()
> > > >     set_property(SOURCE ${dependent_sources} APPEND PROPERTY
> > > >     OBJECT_DEPENDS
> > > > 
> > > > ${CMAKE_CURRENT_BINARY_DIR}/${json_out})
> > > > 
> > > >     add_library(${plugin} MODULE ${KDEV_ADD_PLUGIN_SOURCES})
> > > >     set_property(TARGET ${plugin} APPEND PROPERTY
> > > >     AUTOGEN_TARGET_DEPENDS
> > > > 
> > > > ${CMAKE_CURRENT_BINARY_DIR}/${json_out})
> > > > endfunction()
> > > > ~~~~~~~~~~~~~~~+
> > > > 
> > > > 
> > > > To be used like this:
> > > > 
> > > > kdevplatform_add_plugin(kdevgit JSON kdevgit.json.cmake SOURCES
> > > > ${kdevgit_PART_SRCS})
> > > > 
> > > > This does trigger a rebuild, but the strings are still not updated
> > > > properly.
> > > > I'm quite confused actually, does anyone know where the code comes
> > > > from
> > > > that
> > > > is embedded into the *.o that uses Q_PLUGIN_METADATA? I suspect CMake
> > > > AUTOGEN?
> > > > But where does that put its generated binary JSON representation? How
> > > > can
> > > > I
> > > > make sure that it gets updated properly when the source file changes?
> > > > 
> > > > To reproduce this, you can just change any *.desktop file that is
> > > > piped
> > > > through desktop_to_json. The change will be picked up by CMake and a
> > > > reconfigure is triggered, which is pretty slow as well. But nothing is
> > > > rebuilt. With the macro above, I trigger the build but still, the *.o
> > > > file
> > > > that uses K_PLUGIN_FACTORY_WITH_JSON is still containing the "old"
> > > > strings...
> > > > I'm at loss - can someone help me please? <http://milianw.de>
> > > 
> > > Is there a particular reason why you run the to-json part during cmake
> > > time? If you setup a simple cmake script you could easily switch the
> > > generation to be a custom target and then have the plugin depend on that
> > > custom target (or rather its json output file).
> > 
> > That was apparently a side-effect of KDevelop using configure_file to
> > embed
> > the version number in the *.desktop file. This is not required anymore
> > with
> > the JSON-based plugin loading mechanism, as we install plugins into a
> > versioned directory path. I've changed this now and the CMake configure
> > step when changing a file is gone. Note that desktop_to_json already uses
> > a custom target internally.
> > 
> > > I also think you're misunderstanding the AUTOGEN_TARGET_DEPENDS
> > > property,
> > > according to the documentation it is to be set on an auto-generator
> > > target
> > > and not on a 'standard' one like the library. As far as I can see you
> > > know
> > > the input and output files of the desktop-to-json conversion so a custom
> > > target should be easily doable (unlike automoc).
> > 
> > This might be true, yes. Note that I just copied that line from
> > desktop_to_json. But note that in the ideal case, we wouldn't have any
> > desktop-to-json. Rather, we just have a *.json file, a *.cpp file that
> > uses
> > K_PLUGIN_FACTORY_WITH_JSON. Currently, when the *.json file is changed,
> > the
> > *.cpp.o is not updated, nor the plugin *.so rebuilt and thus the new
> > strings are not available at runtime.
> > 
> > This is what we need to fix somehow, and I still don't know how. Will we
> > have to fix this inside CMake?
> 
> Seems like a job for OBJECT_DEPENDS... That would require you to explicitly
> name the .cpp containing the K_PLUGIN_FACTORY_WITH_JSON(...) use, though.
> 
> Something along:
>   SET_SOURCE_FILES_PROPERTIES(myplugin.cpp
>     PROPERTIES OBJECT_DEPENDS myplugin.json)

without looking at any details (and without remembering the exact details), 
the OBJECT_DEPENDS property has issues, and if possible, an alternative 
solution should be used.

Alex





More information about the kde-core-devel mailing list