diff options
| author | Carl Hetherington <cth@carlh.net> | 2025-09-14 22:16:01 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2025-09-15 14:27:21 +0200 |
| commit | 7cd1d82e33d074050b132dba8c4ae4e0d4804310 (patch) | |
| tree | be8a4e4e630450736b4cba12a518e1219a688c71 | |
| parent | de3466fa0e6b8fa39fda86d39c2d4792ec69ecbf (diff) | |
Allow building with boost::process v2 (added in Ubuntu 25.10).
| -rw-r--r-- | src/tools/dcpomatic_disk.cc | 9 | ||||
| -rw-r--r-- | src/tools/wscript | 2 | ||||
| -rw-r--r-- | test/disk_writer_test.cc | 63 | ||||
| -rw-r--r-- | test/mpeg2_dcp_test.cc | 46 | ||||
| -rw-r--r-- | test/wscript | 2 | ||||
| -rw-r--r-- | wscript | 22 |
6 files changed, 132 insertions, 12 deletions
diff --git a/src/tools/dcpomatic_disk.cc b/src/tools/dcpomatic_disk.cc index 287efb901..176fbd208 100644 --- a/src/tools/dcpomatic_disk.cc +++ b/src/tools/dcpomatic_disk.cc @@ -211,7 +211,11 @@ public: LOG_DISK_NC("Not starting writer process as DCPOMATIC_NO_START_WRITER is set"); } else { LOG_DISK("Starting writer process {}", disk_writer_path().string()); +#ifdef DCPOMATIC_BOOST_PROCESS_V1 _writer = new boost::process::child (disk_writer_path()); +#else + _writer = new boost::process::v2::process(_context, disk_writer_path(), {}); +#endif } #endif @@ -428,7 +432,12 @@ private: std::vector<boost::filesystem::path> _dcp_paths; std::vector<Drive> _drives; #ifndef DCPOMATIC_OSX +#ifdef DCPOMATIC_BOOST_PROCESS_V1 boost::process::child* _writer; +#else + boost::process::v2::process* _writer; + boost::asio::io_context _context; +#endif #endif Nanomsg _nanomsg; wxSizer* _sizer; diff --git a/src/tools/wscript b/src/tools/wscript index 45ce81533..3128486f5 100644 --- a/src/tools/wscript +++ b/src/tools/wscript @@ -98,7 +98,7 @@ def configure(conf): def build(bld): uselib = 'BOOST_THREAD BOOST_DATETIME DCP XMLSEC CXML XMLPP AVFORMAT AVFILTER AVCODEC ' uselib += 'AVUTIL SWSCALE SWRESAMPLE POSTPROC CURL BOOST_FILESYSTEM SSH ZIP CAIROMM FONTCONFIG PANGOMM SUB ' - uselib += 'SNDFILE SAMPLERATE BOOST_REGEX ICU NETTLE RTAUDIO PNG JPEG LEQM_NRT SQLITE3 ' + uselib += 'SNDFILE SAMPLERATE BOOST_REGEX ICU NETTLE RTAUDIO PNG JPEG LEQM_NRT SQLITE3 BOOST_PROCESS ' if bld.env.ENABLE_DISK: if bld.env.TARGET_LINUX: diff --git a/test/disk_writer_test.cc b/test/disk_writer_test.cc index 5004df4d5..04ac6fe4e 100644 --- a/test/disk_writer_test.cc +++ b/test/disk_writer_test.cc @@ -23,6 +23,7 @@ #include "lib/ext.h" #include "lib/io_context.h" #include "test.h" +#include <fmt/format.h> #include <boost/algorithm/string.hpp> #include <boost/asio.hpp> #include <boost/filesystem.hpp> @@ -41,6 +42,8 @@ using std::string; using std::vector; +#ifdef DCPOMATIC_BOOST_PROCESS_V1 + vector<string> ext2_ls (vector<string> arguments) { @@ -58,6 +61,45 @@ ext2_ls (vector<string> arguments) return parts; } +#else + +static +string +collect_from_pipe(boost::asio::readable_pipe& pipe) +{ + std::string output; + + while (true) { + string block; + boost::system::error_code ec; + boost::asio::read(pipe, boost::asio::dynamic_buffer(block), ec); + output += block; + if (ec && ec == boost::asio::error::eof) { + break; + } + } + + return output; +} + +vector<string> +ext2_ls(vector<string> arguments) +{ + using namespace boost::process::v2; + + dcpomatic::io_context ios; + boost::asio::readable_pipe out{ios}; + process ch(ios, environment::find_executable("e2ls"), arguments, process_stdio{ {}, out, {}}); + std::string output = collect_from_pipe(out); + + boost::trim(output); + vector<string> parts; + boost::split(parts, output, boost::is_any_of("\t "), boost::token_compress_on); + return parts; +} + +#endif + static void @@ -80,7 +122,11 @@ make_empty_file(boost::filesystem::path file, off_t size) BOOST_AUTO_TEST_CASE (disk_writer_test1) { using namespace boost::filesystem; +#ifdef DCPOMATIC_BOOST_PROCESS_V1 using namespace boost::process; +#else + using namespace boost::process::v2; +#endif Cleanup cl; @@ -107,11 +153,17 @@ BOOST_AUTO_TEST_CASE (disk_writer_test1) { dcpomatic::io_context ios; +#ifdef DCPOMATIC_BOOST_PROCESS_V1 future<string> data; child ch ("/sbin/tune2fs", args({"-l", partition.string()}), std_in.close(), std_out > data, ios); ios.run(); - string output = data.get(); +#else + boost::asio::readable_pipe out{ios}; + process ch(ios, "/sbin/tune2fs", {"-l", partition.string()}, process_stdio{ {}, out, {}}); + string output = collect_from_pipe(out); +#endif + std::smatch matches; std::regex reg("Inode size:\\s*(.*)"); BOOST_REQUIRE (std::regex_search(output, matches, reg)); @@ -136,7 +188,8 @@ BOOST_AUTO_TEST_CASE (disk_writer_test1) BOOST_REQUIRE (details.size() >= 6); BOOST_CHECK (details[5] != unset_date); - system ("e2cp " + partition.string() + ":disk_writer_test1/foo build/test/disk_writer_test1_foo_back"); + int const r = system(fmt::format("e2cp {}:disk_writer_test1/foo build/test/disk_writer_test1_foo_back", partition.string()).c_str()); + BOOST_CHECK_EQUAL(r, 0); check_file ("build/test/disk_writer_test1/foo", "build/test/disk_writer_test1_foo_back"); cl.run(); @@ -176,7 +229,8 @@ BOOST_AUTO_TEST_CASE (disk_writer_test2) for (auto original: directory_iterator(dcp)) { auto path_in_copy = path("xm") / original.path().filename(); auto path_in_check = check / original.path().filename(); - system("e2cp " + partition.string() + ":" + path_in_copy.string() + " " + path_in_check.string()); + int const r = system(fmt::format("e2cp {}:{} {}", partition.string(), path_in_copy.string(), path_in_check.string()).c_str()); + BOOST_CHECK_EQUAL(r, 0); check_file(original.path(), path_in_check); } @@ -222,7 +276,8 @@ BOOST_AUTO_TEST_CASE (disk_writer_test3) for (auto original: directory_iterator(dcp)) { auto path_in_copy = dcp.filename() / original.path().filename(); auto path_in_check = check / original.path().filename(); - system("e2cp " + partition.string() + ":" + path_in_copy.string() + " " + path_in_check.string()); + int const r = system(fmt::format("e2cp {}:{} {}", partition.string(), path_in_copy.string(), path_in_check.string()).c_str()); + BOOST_CHECK_EQUAL(r, 0); check_file(original.path(), path_in_check); } } diff --git a/test/mpeg2_dcp_test.cc b/test/mpeg2_dcp_test.cc index dd439eac6..0a4d4512e 100644 --- a/test/mpeg2_dcp_test.cc +++ b/test/mpeg2_dcp_test.cc @@ -33,6 +33,7 @@ using std::make_shared; using std::shared_ptr; using std::string; +using std::vector; static @@ -47,6 +48,8 @@ mbits_per_second(shared_ptr<const Film> film) #ifdef DCPOMATIC_LINUX + +#ifdef DCPOMATIC_BOOST_PROCESS_V1 static string bitrate_in_header(shared_ptr<const Film> film) @@ -71,6 +74,49 @@ bitrate_in_header(shared_ptr<const Film> film) return rate; } + +#else + +static +string +bitrate_in_header(shared_ptr<const Film> film) +{ + namespace bp = boost::process::v2; + + boost::asio::io_context context; + boost::asio::readable_pipe out{context}; + bp::process child(context, bp::environment::find_executable("mediainfo"), { find_file(film->dir(film->dcp_name()), "mpeg2").string() }, bp::process_stdio{{}, out, {}}); + + string output; + boost::system::error_code ec; + while (child.running()) { + string block; + boost::asio::read(out, boost::asio::dynamic_buffer(block), ec); + output += block; + if (ec && ec == boost::asio::error::eof) { + break; + } + } + + vector<string> lines; + boost::algorithm::split(lines, output, boost::is_any_of("\n")); + + string rate; + for (auto const& line: lines) { + if (line.substr(0, 10) == "Bit rate ") { + auto colon = line.find(":"); + if (colon != string::npos) { + rate = line.substr(colon + 2); + } + } + } + + child.wait(); + + return rate; +} + +#endif #endif diff --git a/test/wscript b/test/wscript index 4bd2c8891..022f3f7d7 100644 --- a/test/wscript +++ b/test/wscript @@ -37,7 +37,7 @@ def build(bld): obj.name = 'unit-tests' obj.uselib = 'BOOST_TEST BOOST_THREAD BOOST_FILESYSTEM BOOST_DATETIME SNDFILE SAMPLERATE DCP FONTCONFIG CAIROMM PANGOMM XMLPP ' obj.uselib += 'AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE SWRESAMPLE POSTPROC CXML SUB GLIB CURL SSH XMLSEC BOOST_REGEX ICU NETTLE PNG JPEG ' - obj.uselib += 'LEQM_NRT ZIP SQLITE3 ' + obj.uselib += 'LEQM_NRT ZIP SQLITE3 BOOST_PROCESS ' if bld.env.TARGET_WINDOWS_64 or bld.env.TARGET_WINDOWS_32: obj.uselib += 'WINSOCK2 DBGHELP SHLWAPI MSWSOCK BOOST_LOCALE ' if bld.env.TARGET_LINUX: @@ -626,22 +626,32 @@ def configure(conf): lib=['boost_regex%s' % boost_lib_suffix], uselib_store='BOOST_REGEX') - # Really just checking for the header here (there's no associated library) but the test - # program has to link with boost_system so I'm doing it this way. if conf.options.enable_disk: deps = ['boost_system%s' % boost_lib_suffix] if conf.env.TARGET_WINDOWS_64 or conf.env.TARGET_WINDOWS_32: deps.append('ws2_32') deps.append('boost_filesystem%s' % boost_lib_suffix) - conf.check_cxx(fragment=""" + deps.append('boost_process%s' % boost_lib_suffix) + v1 = conf.check_cxx(fragment=""" #include <boost/process.hpp>\n int main() { new boost::process::child("foo"); }\n """, cxxflags='-Wno-unused-parameter', - msg='Checking for boost process library', + msg='Checking for boost process library v1', lib=deps, - uselib_store='BOOST_PROCESS') - + define_name='DCPOMATIC_BOOST_PROCESS_V1', + uselib_store='BOOST_PROCESS', + mandatory=False) + if v1 is None: + conf.check_cxx(fragment=""" + #include <boost/process.hpp>\n + int main() { boost::asio::io_context ctx; new boost::process::v2::process(ctx, "foo", {}); }\n + """, + cxxflags='-Wno-unused-parameter', + msg='Checking for boost process library v2', + lib=deps, + define_name='DCPOMATIC_BOOST_PROCESS_V2', + uselib_store='BOOST_PROCESS') conf.check_cxx(fragment=""" #include <boost/asio.hpp> int main() { boost::asio::io_context context; } |
