관리-도구
편집 파일: copy_boost_headers
#!/usr/bin/env ruby # Phusion Passenger - https://www.phusionpassenger.com/ # Copyright (c) 2010-2017 Phusion Holding B.V. # # "Passenger", "Phusion Passenger" and "Union Station" are registered # trademarks of Phusion Holding B.V. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. ESSENTIALS = [ "boost/*regex*", "boost/algorithm/string", "boost/asio*", "boost/atomic", "boost/bind", "boost/chrono*", "boost/config*", "boost/container", "boost/core", "boost/cstdint.hpp", "boost/date_time", "boost/date_time/date_formatting_limited.hpp", "boost/date_time/gregorian/formatters_limited.hpp", "boost/detail/fenv.hpp", "boost/detail/reference_content.hpp", "boost/foreach.hpp", "boost/function", "boost/integer*", "boost/intrusive", "boost/move", "boost/mpl", "boost/non_type.hpp", "boost/none*", "boost/optional", "boost/optional.hpp", "boost/parameter", "boost/pool", "boost/predef", "boost/predef/other/endian.h", "boost/preprocessor", "boost/preprocessor/stringize.hpp", "boost/random*", "boost/ratio*", "boost/smart_ptr/detail/atomic_count*", "boost/smart_ptr/detail/sp_counted_*", "boost/smart_ptr/detail/spinlock*", "boost/system/config.hpp", "boost/system/detail/error_code.ipp", "boost/thread", "boost/type_traits", "boost/type_traits/detail/*", "boost/type_traits/make_signed.hpp", "boost/typeof", "boost/unordered*", "boost/utility", "libs/chrono/src", "libs/random/src", "libs/regex/src", "libs/system/src", "libs/thread/src", ] EXCLUDE = [ "libs/thread/src/win32/*", "libs/regex/src/w32_regex_traits.cpp", "libs/regex/src/fileiter.cpp", "libs/regex/src/icu.cpp", "libs/regex/src/usinstances.cpp", "boost/atomic/detail/windows.hpp", "boost/regex/icu.hpp", "boost/asio/detail/win*", "boost/asio/detail/impl/win*" ] PROGRAM_SOURCE = %q{ #include <boost/aligned_storage.hpp> #include <boost/asio.hpp> #include <boost/asio/ssl.hpp> #include <boost/asio/steady_timer.hpp> #include <boost/atomic.hpp> #include <boost/bind/bind.hpp> #include <boost/chrono.hpp> #include <boost/circular_buffer.hpp> #include <boost/config.hpp> #include <boost/container/small_vector.hpp> #include <boost/container/vector.hpp> #include <boost/core/noncopyable.hpp> #include <boost/cstdint.hpp> #include <boost/current_function.hpp> #include <boost/date_time/posix_time/posix_time.hpp> #include <boost/date_time/posix_time/posix_time_types.hpp> #include <boost/enable_shared_from_this.hpp> #include <boost/foreach.hpp> #include <boost/function.hpp> #include <boost/intrusive_ptr.hpp> #include <boost/make_shared.hpp> #include <boost/move/core.hpp> #include <boost/move/move.hpp> #include <boost/move/utility.hpp> #include <boost/noncopyable.hpp> #include <boost/nondet_random.hpp> #include <boost/pointer_cast.hpp> #include <boost/pool/object_pool.hpp> #include <boost/predef.h> #include <boost/predef/other/endian.h> #include <boost/random/random_device.hpp> #include <boost/random/uniform_int_distribution.hpp> #include <boost/ref.hpp> #include <boost/regex.hpp> #include <boost/scoped_array.hpp> #include <boost/scoped_ptr.hpp> #include <boost/shared_array.hpp> #include <boost/shared_ptr.hpp> #include <boost/smart_ptr/intrusive_ref_counter.hpp> #include <boost/static_assert.hpp> #include <boost/system/error_code.hpp> #include <boost/system/system_error.hpp> #include <boost/thread.hpp> #include <boost/thread/condition_variable.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/once.hpp> #include <boost/thread/tss.hpp> #include <boost/typeof/typeof.hpp> #include <boost/unordered_map.hpp> #include <boost/version.hpp> #include <boost/weak_ptr.hpp> // Included despite not used in Passenger #include <boost/thread/thread_time.hpp> #include <boost/cregex.hpp> #include <boost/pointer_cast.hpp> #include <boost/asio.hpp> } require 'fileutils' BOOST_DIR = ARGV[0] Dir.chdir(File.dirname(__FILE__) + "/../src/cxx_supportlib/vendor-modified") # Run the given command, and abort on error. def sh(*command) puts command.join(" ") if !system(*command) puts "*** ERROR" exit 1 end end def install(source_filename, target_filename) dir = File.dirname(target_filename) if !File.exist?(dir) sh "mkdir", "-p", dir end command = ["install", "-m", "u+rw,g+r,o+r", source_filename, target_filename] sh(*command) end def copy_boost_files(patterns, exclude = nil) patterns.each do |pattern| files = Dir["#{BOOST_DIR}/#{pattern}"] files -= exclude if exclude files.each do |source| if File.directory?(source) source.slice!(0 .. BOOST_DIR.size) copy_boost_files(["#{source}/*"], exclude) else target = source.slice(BOOST_DIR.size + 1 .. source.size - 1) if target =~ /^libs\// target = "boost/#{target}" end if !File.exist?(target) install(source, target) end end end end end def copy_essential_files exclude = [] EXCLUDE.each do |pattern| exclude.concat(Dir["#{BOOST_DIR}/#{pattern}"]) end copy_boost_files(ESSENTIALS, exclude) end def prepare File.open("test.cpp", "w") do |f| f.write(PROGRAM_SOURCE) end end def cleanup FileUtils.rm_rf("boost/asio/detail/old_win_sdk_compat.hpp") FileUtils.rm_rf("boost/asio/win32") FileUtils.rm_rf("boost/asio/windows") FileUtils.rm_rf("boost/atomic/detail/caps_windows.hpp") FileUtils.rm_rf("boost/atomic/detail/core_ops_windows.hpp") FileUtils.rm_rf("boost/atomic/detail/fence_ops_windows.hpp") FileUtils.rm_rf("boost/atomic/detail/ops_windows.hpp") FileUtils.rm_rf("boost/atomic/detail/wait_caps_windows.hpp") FileUtils.rm_rf("boost/atomic/detail/wait_ops_windows.hpp") FileUtils.rm_rf("boost/chrono/detail/inlined/win") FileUtils.rm_rf("boost/config/platform/cygwin.hpp") FileUtils.rm_rf("boost/config/platform/win32.hpp") FileUtils.rm_rf("boost/core/detail/sp_win32_sleep.hpp") FileUtils.rm_rf("boost/smart_ptr/detail/atomic_count_win32.hpp") FileUtils.rm_rf("boost/smart_ptr/detail/sp_counted_base_w32.hpp") FileUtils.rm_rf("boost/smart_ptr/detail/spinlock_w32.hpp") FileUtils.rm_rf("boost/src/win32") FileUtils.rm_rf("boost/thread/win32") File.unlink("test.cpp") rescue nil end # Compile PROGRAM_SOURCE and copy whatever missing header files the compiler needs. def copy_dependencies(cflags) if RUBY_PLATFORM =~ /darwin/ openssl_path = `brew --prefix openssl`.strip else openssl_path = '/usr/include/openssl' end done = false while !done compiler_output = `c++ test.cpp -c -I#{openssl_path}/include -I. -I.. #{cflags.join(" ")} 2>&1` File.unlink('test.o') if File.exist?('test.o') missing_headers = compiler_output. split("\n"). grep(/(error: .*: No such file|fatal error: '.*' file not found)/). reject{|s| s =~ /\/usr\/include\// }. map do |line| if line =~ /error: (.*): No such file/ file = $1 elsif line =~ /fatal error: '(.*)' file not found/ file = $1 else abort "Bug" end if file =~ /^boost\// file else line =~ /(.*?):/ source = $1 File.dirname(source) + "/" + file end end missing_headers.each do |header| install("#{BOOST_DIR}/#{header}", header) end done = missing_headers.empty? end end def start if BOOST_DIR.nil? || BOOST_DIR.empty? || BOOST_DIR == "--help" puts "Usage:" puts "Remove the src/cxx_supportlib/vendor-modified/boost directory," puts "then call: copy_boost_headers <boost source directory>" puts "then reapply patches to boost source files," puts "they are kept in dev/boost-patches and can be applied by:" puts "patch -p1 < dev/boost-patches/000*-Patch-Name.patch" exit 1 end begin prepare copy_essential_files [ "-std=c++98", "-std=c++03", "-std=gnu++98", "-std=gnu++03", "-std=c++11", "-std=gnu++11", "-std=c++14", "-std=gnu++14", "-std=c++17", "-std=gnu++17", "-std=c++20", "-std=gnu++20", "-std=c++0x", "-std=gnu++0x", "" ].product(["-m32","-m64",""]).each do |flags| copy_dependencies(flags) end ensure cleanup end end start