From c599fef7294df42c366e02bbc831c4f9e570deed Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 6 Jun 2024 21:55:36 -0400 Subject: [PATCH] dev: extconf supports --gumbo-dev for faster feedback loops --- CONTRIBUTING.md | 9 +++++ ext/nokogiri/extconf.rb | 88 +++++++++++++++++++++++------------------ 2 files changed, 59 insertions(+), 38 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3c0e94d1a10..fa9167559ed 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -251,6 +251,15 @@ git submodule update --init # test/html5lib-tests bundle exec rake compile test ``` +If you're actively working on the libgumbo source, you will probably want a faster feedback loop than `rake clean compile test` will give you. Here's how to get more immediate builds of libgumbo whenever you change a file: + +``` sh +bundle exec rake clean compile -- --gumbo-dev +# change a gumbo file +bundle exec rake compile # immediate compilation of changed file and relinking of nokogiri.so +``` + + ### Fuzzing your gumbo HTML5 parser changes When making changes or adding new features to `gumbo-parser`, it's recommended to run [libfuzzer](https://llvm.org/docs/LibFuzzer.html) against `gumbo-parser` using various [sanitizers](https://github.com/google/sanitizers/wiki). diff --git a/ext/nokogiri/extconf.rb b/ext/nokogiri/extconf.rb index 451ac48b1cf..8ea793d2a43 100644 --- a/ext/nokogiri/extconf.rb +++ b/ext/nokogiri/extconf.rb @@ -1044,55 +1044,67 @@ def configure ensure_func("exsltFuncRegister", "libexslt/exslt.h") end -libgumbo_recipe = process_recipe("libgumbo", "1.0.0-nokogiri", static_p, cross_build_p, false) do |recipe| - recipe.configure_options = [] +if arg_config("--gumbo-dev") + message("DEV MODE ENABLED: build libgumbo as packaged source") + ext_dir = File.dirname(__FILE__) + Dir.chdir(ext_dir) do + $srcs = Dir["*.c", "../../gumbo-parser/src/*.c"] + $hdrs = Dir["*.h", "../../gumbo-parser/src/*.h"] + end + $INCFLAGS << " -I$(srcdir)/../../gumbo-parser/src" + $VPATH << "$(srcdir)/../../gumbo-parser/src" + find_header("nokogiri_gumbo.h") || abort("nokogiri_gumbo.h not found") +else + libgumbo_recipe = process_recipe("libgumbo", "1.0.0-nokogiri", static_p, cross_build_p, false) do |recipe| + recipe.configure_options = [] - class << recipe - def downloaded? - true - end + class << recipe + def downloaded? + true + end - def extract - target = File.join(tmp_path, "gumbo-parser") - output("Copying gumbo-parser files into #{target}...") - FileUtils.mkdir_p(target) - FileUtils.cp(Dir.glob(File.join(PACKAGE_ROOT_DIR, "gumbo-parser/src/*")), target) - end + def extract + target = File.join(tmp_path, "gumbo-parser") + output("Copying gumbo-parser files into #{target}...") + FileUtils.mkdir_p(target) + FileUtils.cp(Dir.glob(File.join(PACKAGE_ROOT_DIR, "gumbo-parser/src/*")), target) + end - def configured? - true - end + def configured? + true + end - def install - lib_dir = File.join(port_path, "lib") - inc_dir = File.join(port_path, "include") - FileUtils.mkdir_p([lib_dir, inc_dir]) - FileUtils.cp(File.join(work_path, "libgumbo.a"), lib_dir) - FileUtils.cp(Dir.glob(File.join(work_path, "*.h")), inc_dir) - end + def install + lib_dir = File.join(port_path, "lib") + inc_dir = File.join(port_path, "include") + FileUtils.mkdir_p([lib_dir, inc_dir]) + FileUtils.cp(File.join(work_path, "libgumbo.a"), lib_dir) + FileUtils.cp(Dir.glob(File.join(work_path, "*.h")), inc_dir) + end - def compile - cflags = concat_flags(ENV["CFLAGS"], "-fPIC", "-O2", "-g") + def compile + cflags = concat_flags(ENV["CFLAGS"], "-fPIC", "-O2", "-g") - env = { "CC" => gcc_cmd, "CFLAGS" => cflags } - if config_cross_build? - if host.include?("darwin") - env["AR"] = "#{host}-libtool" - env["ARFLAGS"] = "-o" - else - env["AR"] = "#{host}-ar" + env = { "CC" => gcc_cmd, "CFLAGS" => cflags } + if config_cross_build? + if host.include?("darwin") + env["AR"] = "#{host}-libtool" + env["ARFLAGS"] = "-o" + else + env["AR"] = "#{host}-ar" + end + env["RANLIB"] = "#{host}-ranlib" end - env["RANLIB"] = "#{host}-ranlib" - end - execute("compile", make_cmd, { env: env }) + execute("compile", make_cmd, { env: env }) + end end end + append_cppflags("-I#{File.join(libgumbo_recipe.path, "include")}") + $libs = $libs + " " + File.join(libgumbo_recipe.path, "lib", "libgumbo.a") + $LIBPATH = $LIBPATH | [File.join(libgumbo_recipe.path, "lib")] + ensure_func("gumbo_parse_with_options", "nokogiri_gumbo.h") end -append_cppflags("-I#{File.join(libgumbo_recipe.path, "include")}") -$libs = $libs + " " + File.join(libgumbo_recipe.path, "lib", "libgumbo.a") -$LIBPATH = $LIBPATH | [File.join(libgumbo_recipe.path, "lib")] -ensure_func("gumbo_parse_with_options", "nokogiri_gumbo.h") have_func("xmlHasFeature") || abort("xmlHasFeature() is missing.") # introduced in libxml 2.6.21 have_func("xmlFirstElementChild") # introduced in libxml 2.7.3