rb-sys
rb-sys copied to clipboard
Generated Makefiles use GNU make specific syntax
Ruby's mkmf is designed to support both GNU make and BSD make (and Ruby itself can be built with both GNU make and BSD make), and it would be nice if the Makefiles produced by create_rust_makefile worked with both.
Example (using commonmarker gem, attempting to build on OpenBSD):
$ cat extconf.rb
require "mkmf"
require "rb_sys/mkmf"
create_rust_makefile("commonmarker/commonmarker")
$ ruby extconf.rb
checking for cc... yes
checking for c++... yes
checking for ar... yes
$ make
*** Parse error in /usr/obj/ports/commonmarker-1.0.3-ruby32/gem-tmp/.gem/ruby/3.2/gems/commonmarker-1.0.3/ext/commonmarker: Missing dependency operator (Makefile:8)
*** Parse error: Need an operator in 'endif' (Makefile:10)
*** Parse error: Missing dependency operator (Makefile:20)
*** Parse error: Need an operator in 'else' (Makefile:22)
*** Parse error: Need an operator in 'endif' (Makefile:24)
*** Parse error: Missing dependency operator (Makefile:31)
*** Parse error: Need an operator in 'else' (Makefile:33)
*** Parse error: Need an operator in 'endif' (Makefile:35)
*** Parse error: Missing dependency operator (Makefile:265)
*** Parse error: Need an operator in 'endif' (Makefile:267)
*** Parse error: Missing dependency operator (Makefile:523)
*** Parse error: Missing dependency operator (Makefile:528)
*** Parse error: Need an operator in 'endif' (Makefile:530)
*** Parse error: Missing dependency operator (Makefile:534)
*** Parse error: Need an operator in 'else' (Makefile:536)
*** Parse error: Need an operator in 'endif' (Makefile:538)
*** Parse error: Need an operator in 'endif' (Makefile:557)
$ gmake
generating target/release/libcommonmarker.so (release)
cargo rustc --manifest-path ./Cargo.toml --target-dir target --lib --profile release -- -C linker=cc -L native=/usr/local/lib -L native=/usr/local/lib -C link-arg=-lm -C link-arg=-pthread
...
As far as I can tell, Ruby's mkmf doesn't generate Makefiles with conditional expressions, which seems to be the main source of issues above.
I think Ruby also uses autotools to generate the Makefile, which is why it works both on GNU and BSD make.
If we added support for BSD make, I think mkmf.rb would have to:
- Detect whether BSD make was being used. As far as I can tell, there's no
-vor--versionargument that makes it obvious that BSD make is used:
# gmake -v
GNU Make 4.3
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
# bmake -h
usage: bmake [-BeikNnqrstWwX]
[-C directory] [-D variable] [-d flags] [-f makefile]
[-I directory] [-J private] [-j max_jobs] [-m directory] [-T file]
[-V variable] [-v variable] [variable=value] [target ...]
- Update the conditional expressions for BSD make.
I'm not sure it's worth it to do this. It might be better just to document that MAKE=gmake can be set in the environment.
Maybe something similar to this can be used: https://github.com/redis/hiredis-rb/blob/master/ext/hiredis_ext/extconf.rb#L19-L27
That could work. I submitted https://github.com/rubygems/rubygems/pull/7348.
I think the ultimate solution will be to compile to a generic-enough Make syntax to not break... tedious change though. Maybe in the meantime we can add a warning / better error message @stanhu