summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-09-14 22:16:01 +0200
committerCarl Hetherington <cth@carlh.net>2025-09-15 14:27:21 +0200
commit7cd1d82e33d074050b132dba8c4ae4e0d4804310 (patch)
treebe8a4e4e630450736b4cba12a518e1219a688c71
parentde3466fa0e6b8fa39fda86d39c2d4792ec69ecbf (diff)
Allow building with boost::process v2 (added in Ubuntu 25.10).
-rw-r--r--src/tools/dcpomatic_disk.cc9
-rw-r--r--src/tools/wscript2
-rw-r--r--test/disk_writer_test.cc63
-rw-r--r--test/mpeg2_dcp_test.cc46
-rw-r--r--test/wscript2
-rw-r--r--wscript22
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:
diff --git a/wscript b/wscript
index 97bd54a3e..d6abb428f 100644
--- a/wscript
+++ b/wscript
@@ -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; }