ext/extconf.rb
require File.expand_path("../base.rb", __FILE__)
def local_build?
File.exist?(ext_path("appsignal-agent")) &&
File.exist?(ext_path("libappsignal.a")) &&
File.exist?(ext_path("appsignal.h"))
end
def install
library_type = "static"
report["language"]["implementation"] = "ruby"
report["build"]["library_type"] = library_type
return unless check_architecture
if local_build?
report["build"]["source"] = "local"
else
archive = download_archive(library_type)
return unless archive
return unless verify_archive(archive, library_type)
unarchive(archive)
end
is_linux_system = [
Appsignal::System::LINUX_TARGET,
Appsignal::System::MUSL_TARGET
].include?(AGENT_PLATFORM)
require "mkmf"
link_libraries if is_linux_system
if !have_library("appsignal", "appsignal_start", "appsignal.h")
abort_installation("Library libappsignal.a or appsignal.h not found")
elsif !find_executable("appsignal-agent", EXT_PATH)
abort_installation("File appsignal-agent not found")
else
if is_linux_system
# Statically link libgcc and libgcc_s libraries.
# Dependencies of the libappsignal extension library.
# If the gem is installed on a host with build tools installed, but is
# run on one that isn't the missing libraries will cause the extension
# to fail on start.
$LDFLAGS += " -static-libgcc" # rubocop:disable Style/GlobalVars
report["build"]["flags"]["LDFLAGS"] = $LDFLAGS # rubocop:disable Style/GlobalVars
end
create_makefile "appsignal_extension"
successful_installation
end
rescue => error
fail_installation_with_error(error)
ensure
create_dummy_makefile unless installation_succeeded?
write_report
end
# Ruby 2.6 requires us to statically link more libraries we use in our
# extension library than previous versions. Needed for normal Linux libc
# and musl builds.
def link_libraries
if RbConfig::CONFIG["THREAD_MODEL"] == "pthread"
# Link gem extension against pthread library
have_library "pthread"
have_required_function "pthread", "pthread_create"
end
# Links gem extension against the `dl` library. This is needed when Ruby is
# not linked against `dl` itself, so link it on the gem extension.
have_library "dl"
# Check if functions are available now from the linked library
%w[dlopen dlclose dlsym].each do |func|
have_required_function "dl", func
end
end
def have_required_function(library, func) # rubocop:disable Naming/PredicateName
if have_func(func)
report["build"]["dependencies"][library] = "linked"
return
end
report["build"]["dependencies"][library] = "not linked"
abort_installation("Missing function '#{func}'")
# Exit with true/0/success because the AppSignal installation should never
# break a build
exit
end
install