lib/autobuild/packages/cmake.rb in autobuild-1.5.43 vs lib/autobuild/packages/cmake.rb in autobuild-1.5.45

- old
+ new

@@ -63,16 +63,135 @@ if @doc_dir File.expand_path(@doc_dir, builddir) end end + DOXYGEN_ACCEPTED_VARIABLES = { + '@CMAKE_SOURCE_DIR@' => lambda { |pkg| pkg.srcdir }, + '@PROJECT_SOURCE_DIR@' => lambda { |pkg| pkg.srcdir }, + '@CMAKE_BINARY_DIR@' => lambda { |pkg| pkg.builddir }, + '@PROJECT_BINARY_DIR@' => lambda { |pkg| pkg.builddir }, + '@PROJECT_NAME@' => lambda { |pkg| pkg.name } + } + + class << self + # Flag controlling whether autobuild should run doxygen itself or + # use the "doc" target generated by CMake + # + # This is experimental and OFF by default. See CMake#run_doxygen for + # more details + # + # See also CMake#always_use_doc_target= and CMake#always_use_doc_target? + # for a per-package control of that feature + attr_writer :always_use_doc_target + + # Flag controlling whether autobuild should run doxygen itself or + # use the "doc" target generated by CMake + # + # This is experimental and OFF by default. See CMake#run_doxygen for + # more details + # + # See also CMake#always_use_doc_target= and CMake#always_use_doc_target? + # for a per-package control of that feature + def always_use_doc_target? + @always_use_doc_target + end + end + @always_use_doc_target = true + + # Flag controlling whether autobuild should run doxygen itself or + # use the "doc" target generated by CMake + # + # This is experimental and OFF by default. See CMake#run_doxygen for + # more details + # + # See also CMake.always_use_doc_target= and CMake.always_use_doc_target? + # for a global control of that feature + attr_reader :always_use_doc_target + + # Flag controlling whether autobuild should run doxygen itself or + # use the "doc" target generated by CMake + # + # This is experimental and OFF by default. See CMake#run_doxygen for + # more details + # + # See also CMake.always_use_doc_target= and CMake.always_use_doc_target? + # for a global control of that feature + def always_use_doc_target? + if @always_use_doc_target.nil? + return CMake.always_use_doc_target? + else + @always_use_doc_target + end + end + + # To avoid having to build packages to run the documentation target, we + # try to autodetect whether (1) the package is using doxygen and (2) + # whether the cmake variables in the doxyfile can be provided by + # autobuild itself. + # + # This can be disabled globally by setting + # Autobuild::CMake.always_use_doc_target= or on a per-package basis with + # #always_use_doc_target= + # + # This method returns true if the package can use the internal doxygen + # mode and false otherwise + def internal_doxygen_mode? + if always_use_doc_target? + return false + end + + doxyfile_in = File.join(srcdir, "Doxyfile.in") + if !File.file?(doxyfile_in) + puts "NO INTERNAL: #{name}" + return false + end + File.readlines(doxyfile_in).each do |line| + matches = line.scan(/@[^@]+@/) + if matches.any? { |str| !DOXYGEN_ACCEPTED_VARIABLES.has_key?(str) } + return false + end + end + end + + # To avoid having to build packages to run the documentation target, we + # try to autodetect whether (1) the package is using doxygen and (2) + # whether the cmake variables in the doxyfile can be provided by + # autobuild itself. + # + # This can be disabled globally by setting + # Autobuild::CMake.always_use_doc_target or on a per-package basis with + # #always_use_doc_target + # + # This method generates the corresponding doxygen file in + # <builddir>/Doxygen and runs doxygen. It raises if the internal doxygen + # support cannot be used on this package + def run_doxygen + doxyfile_in = File.join(srcdir, "Doxyfile.in") + if !File.file?(doxyfile_in) + raise RuntimeError, "no Doxyfile.in in this package, cannot use the internal doxygen support" + end + doxyfile_data = File.readlines(doxyfile_in).map do |line| + line.gsub(/@[^@]+@/) { |match| DOXYGEN_ACCEPTED_VARIABLES[match].call(self) } + end + doxyfile = File.join(builddir, "Doxyfile") + File.open(doxyfile, 'w') do |io| + io.write(doxyfile_data) + end + Subprocess.run(self, 'doc', Autobuild.tool(:doxygen), doxyfile) + end + # Declare that the given target can be used to generate documentation def with_doc(target = 'doc') doc_task do Dir.chdir(builddir) do progress "generating documentation for %s" - Subprocess.run(self, 'doc', Autobuild.tool(:make), "-j#{parallel_build_level}", target) + if internal_doxygen_mode? + run_doxygen + else + Subprocess.run(self, 'doc', Autobuild.tool(:make), "-j#{parallel_build_level}", target) + end yield if block_given? end end end @@ -104,9 +223,13 @@ provides "pkgconfig/#{file}" end end def prepare + if !internal_doxygen_mode? && has_doc? + task "#{name}-doc" => configurestamp + end + # A failed initial CMake configuration leaves a CMakeCache.txt file, # but no Makefile. # # Delete the CMakeCache to force reconfiguration if !File.exists?( File.join(builddir, 'Makefile') )