Skip to content

Commit

Permalink
dev: extconf supports --gumbo-dev (#3220)
Browse files Browse the repository at this point in the history
**What problem is this PR intended to solve?**

Enable a faster development feedback loop when working on libgumbo. See
notes in CONTRIBUTING.md for how to use it.

Closes #2718
  • Loading branch information
flavorjones authored Jun 7, 2024
2 parents 4cceeac + c599fef commit f306126
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 38 deletions.
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
88 changes: 50 additions & 38 deletions ext/nokogiri/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit f306126

Please sign in to comment.