Skip to content

more rigorous compiler checks #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
286 changes: 178 additions & 108 deletions ext/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,129 +2,199 @@

# add check for member function, does need default constructor for class
def have_member_func(klass,member,header)
if have_func("#{klass}().#{member}()",header)
$defs[-1] = "-DHAVE_#{klass.tr_cpp}_#{member.tr_cpp}"
end
if have_func("#{klass}().#{member}()",header)
$defs[-1] = "-DHAVE_#{klass.tr_cpp}_#{member.tr_cpp}"
end
end

def have_std_header(header, preheaders = nil, opt = "", &b)
checking_for header do
if try_header(cpp_include(preheaders)+cpp_include(header), opt, &b)
$defs.push(format("-DHAVE_STD_%s", header.tr_cpp))
true
else
false
end
end
end

def pkg_conf(pkg)
if (pkglibs = pkg_config(pkg,"libs")) then
if (pkgcinc = pkg_config(pkg,"cflags-only-I")) then
pkgcflags = pkg_config(pkg,"cflags-only-other")
else
pkgcflags = pkg_config(pkg,"cflags")
end
pkglibsonly = pkg_config(pkg,"libs-only-l")
pkgldflags = (Shellwords.shellwords(pkglibs) - Shellwords.shellwords(pkglibsonly)).quote.join(" ")
$CFLAGS += " " << pkgcflags
$CFLAGS = $CFLAGS.split.uniq.join(" ")
$CXXFLAGS += " " << pkgcflags
$CXXFLAGS = $CXXFLAGS.split.uniq.join(" ")
$INCFLAGS += " " << pkgcinc
$INCFLAGS = $INCFLAGS.split.uniq.join(" ")
$libs += " " << pkglibsonly
$libs = $libs.split.uniq.join(" ")
else
abort("package configuration for %s is missing\n" % [pkg])
end
end

unless have_macro("HAVE_RB_DATA_TYPE_T_PARENT")
abort("rb_data_type_t needs parent attribute!")
abort("rb_data_type_t needs parent attribute!")
end


dir_config "rwx"

if(wx_config = find_executable('wx-config'))

if `#{wx_config} --version`.chomp < "3.0.0"
abort("wx version outdated, please update to 3.0.0 or newer")
end

ruby_cc = CONFIG["CC"]
ruby_cxx = CONFIG["CXX"]
# An ruby extension does need to be build against
# the same compiler as ruby was
unless ruby_cc && find_executable(ruby_cc)
abort("C compiler not found!")
end
unless ruby_cxx && find_executable(ruby_cxx)
abort("C++ compiler not found!")
end

cc = `#{wx_config} --cc`.chomp
unless cc == ruby_cc
abort("CC compiler missmatch %s == %s" % [cc, ruby_cc])
end

cxx = `#{wx_config} --cxx`.chomp
unless cxx == ruby_cxx
abort("CXX compiler missmatch %s == %s" % [cxx, ruby_cxx])
end

#earlier versions of ruby does not have that constant
$CXXFLAGS = CONFIG["CXXFLAGS"] unless defined?($CXXFLAGS)

#for some function add the base classes
extra_libs = []
case `#{wx_config} --basename`
when /gtk2/
extra_libs << "gtk+-x11-2.0" << "gdk-x11-2.0"
when /gtk3/
extra_libs << "gtk+-x11-3.0" << "gdk-x11-3.0"
end

extra_libs.each {|l|
pkg = pkg_config(l)
#because pkg forgot to add the include paths to cxx flags
$CXXFLAGS << " " << pkg[0] if pkg && !$CXXFLAGS[pkg[0]]
}

all = " -fvisibility-inlines-hidden"
$CFLAGS << all << " -x c++ -g -Wall "
$CXXFLAGS << all << " -g -Wall "
$CPPFLAGS << all << " -g "
$LDFLAGS << all << " "

# add the wx-config flags
$CFLAGS << `#{wx_config} --cflags`.chomp
$CXXFLAGS << `#{wx_config} --cxxflags`.chomp
$CPPFLAGS << `#{wx_config} --cppflags`.chomp
$LDFLAGS << `#{wx_config} --libs all`.chomp

# TODO add extra check if a lib of wx is missing

with_cflags(" -x c++ ") {
# need c++ for some of the tests
RbConfig::CONFIG["CC"] = CONFIG["CXX"]

have_header("wx/preferences.h")

#check for better Bind commmand
unless have_macro("wxHAS_EVENT_BIND","wx/wx.h")
abort("need wxHAS_EVENT_BIND, update your compiler!")
end

#check for Default-Constructors
have_func("wxContextHelpButton()","wx/cshelp.h")
have_func("wxNumberEntryDialog()","wx/numdlg.h")
have_func("wxPasswordEntryDialog()","wx/textdlg.h")
have_func("wxProgressDialog()","wx/progdlg.h")
have_func("wxMessageDialog()","wx/msgdlg.h")
have_func("wxGenericMessageDialog()","wx/generic/msgdlgg.h")
have_func("wxRichMessageDialog()","wx/richmsgdlg.h")
have_func("wxBusyInfoFlags()","wx/busyinfo.h")

#check for instance methods, that classes need to have default constuctor
have_member_func("wxFontPickerCtrl","GetSelectedColour","wx/fontpicker.h")
have_member_func("wxInfoBar","GetButtonCount","wx/infobar.h")

have_member_func("wxOwnerDrawnComboBox","IsListEmpty","wx/odcombo.h")

#check for enum flags
have_const("wxFD_NO_FOLLOW","wx/filedlg.h")
have_const("wxDIRCTRL_DEFAULT_STYLE",["wx/wx.h", "wx/dirctrl.h"])
have_func("wxDirCtrl()",["wx/wx.h", "wx/dirctrl.h"])
have_const("wxSTC_LEX_DMAP",["wx/wx.h", "wx/stc/stc.h"])
if(wxversion = pkg_config("wx","version"))

if wxversion.chomp < "3.0.0"
abort("wx version outdated, please update to 3.0.0 or newer")
end
# ruby compilers
ruby_cc = find_executable CONFIG["CC"]
ruby_cxx = find_executable CONFIG["CXX"]
# An ruby extension does need to be build against
# the same compiler as ruby was
unless ruby_cc && find_executable(ruby_cc)
abort("C compiler %s not found!"%ruby_cc)
end
unless ruby_cxx && find_executable(ruby_cxx)
abort("C++ compiler not found!")
end
# wx compilers
cc = find_executable Shellwords.shellwords(pkg_config("wx","cc"))[0]
cxx = find_executable Shellwords.shellwords(pkg_config("wx","cxx"))[0]
# check if cc compilers are matched
unless (cc == ruby_cc)
unless RbConfig::CONFIG["host_os"].include?("darwin")
abort("CC compiler missmatch %s == %s" % [cc, ruby_cc])
else # Apple Mac OS X
optwx = IO.popen(["#{cc}","--version"],:err=>[:child,:out],&:read)
optrwx = IO.popen(["#{ruby_cc}","--version"],:err=>[:child,:out],&:read)
unless optrwx.include?(optwx)
# good to go
else
# good to go
end
end
end
# check if cxx compilers are matched
unless (cxx == ruby_cxx)
unless RbConfig::CONFIG["host_os"].include?("darwin")
abort("CXX compiler missmatch1 %s == %s" % [cxx, ruby_cxx])
else # Apple Mac OS X
optwx = IO.popen(["#{cxx}","--version"],:err=>[:child,:out],&:read)
optrwx = IO.popen(["#{ruby_cxx}","--version"],:err=>[:child,:out],&:read)
unless optrwx.include?(optwx)
# need to tell clang to be compatible
abort("Apple CXX compiler missmatch %s == %s" % [cxx, ruby_cxx]) # clang needs $CFLAGS += " -std=c++11 -stdlib=libc++ -nostdinc++"
else
# good to go
end
end
end

#earlier versions of ruby does not have that constant
#remove bad paths in flags
$CPPFLAGS=CONFIG["CPPFLAGS"]
$CFLAGS=CONFIG["CFLAGS"]
$CFLAGS=$CFLAGS.split.delete_if {|x| x[0,2]=="-I" && !File.exist?(x[2,x.length-2])}.join(" ")
$CXXFLAGS=CONFIG["CXXFLAGS"]
$LDFLAGS=CONFIG["LDFLAGS"]
$LDFLAGS=$LDFLAGS.split.delete_if {|x| x[0,2]=="-L" && !File.exist?(x[2,x.length-2])}.join(" ")

have_const("wxALIGN_CENTER_VERTICAL","wx/sizer.h")
have_member_func("wxSizerFlags","CenterVertical","wx/sizer.h")
}
else
abort("wx-config executable not found!")

wxpkg = pkg_config("wx","basename")
case wxpkg
when /gtk2/
pkg_conf("gdk-x11-2.0")
pkg_conf("gtk+-x11-2.0")
when /gtk3/
pkg_conf("gdk-x11-3.0")
pkg_conf("gtk+-x11-3.0")
end
wxcppflags=pkg_config("wx","cppflags")
$CPPFLAGS += " " << wxcppflags
wxcflags=pkg_config("wx","cflags")
$CFLAGS += " " << wxcflags
wxcxxflags=pkg_config("wx","cxxflags")
$CXXFLAGS += " " << wxcxxflags
wxlibs=pkg_config("wx","libs all")
$libs += " " << wxlibs
wxldflags=pkg_config("wx","linkdeps")
$LDFLAGS << " " << wxldflags
#for some function add the base classes
all = " -fvisibility-inlines-hidden"
$CFLAGS << all << " -x c++ -g -Wall "
$CXXFLAGS << all << " -g -Wall "
$CPPFLAGS << all << " -g -x c++ "
$LDFLAGS << all << " "
# add the wx-config flags
# TODO add extra check if a lib of wx is missing
#set up special flags for testing
olddefs = $defs
$defs.clear
with_cflags(" -x c++ ") {
have_header("type_traits")
have_header("tr1/type_traits")
have_std_header("unordered_map")
have_header("tr1/unordered_map")
have_std_header("unordered_set")
have_header("tr1/unordered_set")
}
moreflags = $defs.join(" ")
$defs = olddefs + $defs
with_cflags(" -x c++ " + moreflags) {
# need c++ for some of the tests
CONFIG["CC"] = CONFIG["CXX"]
#C++03tr1 c++11 differences
have_header("wx/preferences.h","wx/defs.h")
#check for better Bind commmand
unless have_macro("wxHAS_EVENT_BIND","wx/wx.h")
abort("need wxHAS_EVENT_BIND, update your compiler!")
end

#check for Default-Constructors
have_func("wxContextHelpButton()","wx/cshelp.h")
have_func("wxNumberEntryDialog()","wx/numdlg.h")
have_func("wxPasswordEntryDialog()","wx/textdlg.h")
have_func("wxProgressDialog()","wx/progdlg.h")
have_func("wxMessageDialog()","wx/msgdlg.h")
have_func("wxGenericMessageDialog()","wx/generic/msgdlgg.h")
have_func("wxRichMessageDialog()","wx/richmsgdlg.h")
have_func("wxBusyInfoFlags()","wx/busyinfo.h")

#check for instance methods, that classes need to have default constuctor
have_member_func("wxFontPickerCtrl","GetSelectedColour","wx/fontpicker.h")
have_member_func("wxInfoBar","GetButtonCount","wx/infobar.h")
have_member_func("wxOwnerDrawnComboBox","IsListEmpty","wx/odcombo.h")

#check for enum flags
have_const("wxFD_NO_FOLLOW","wx/filedlg.h")
have_const("wxDIRCTRL_DEFAULT_STYLE",["wx/wx.h", "wx/dirctrl.h"])
have_func("wxDirCtrl()",["wx/wx.h", "wx/dirctrl.h"])
have_const("wxSTC_LEX_DMAP",["wx/wx.h", "wx/stc/stc.h"])

have_const("wxALIGN_CENTER_VERTICAL","wx/sizer.h")
have_member_func("wxSizerFlags","CenterVertical","wx/sizer.h")
}
else
abort("wx-config executable not found!\n for MSWindows see https://sites.google.com/site/wxconfig/")

end

$defs.push("-DRUBY_UNTYPED_DATA_WARNING=1")

#drop some of the warn flags because they are not valid for C++
CONFIG["warnflags"].gsub!(
Regexp.union(
"-Wdeclaration-after-statement",
"-Wimplicit-function-declaration",
"-Wextra" #wxAUI is a bit buggy
), "")

Regexp.union(
"-Wdeclaration-after-statement",
"-Wimplicit-function-declaration",
"-Wextra" #wxAUI is a bit buggy
), "")
#with_cppflags("-std=c++11") {
create_header
create_makefile "rwx"
create_header
create_makefile "rwx"
#}