Skip to content

Updating boost process rebased #1346

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 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
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
8 changes: 1 addition & 7 deletions .github/workflows/CI-macos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,14 @@ jobs:
gnuplot
- name: Installation of pandoc
uses: r-lib/actions/setup-pandoc@v2
- name: Installation of latex
uses: teatimeguest/setup-texlive-action@v3
with:
packages: |
scheme-full
bibtex
- name: Checkout of source code
uses: actions/checkout@v3
- name: Preparation
run: |
echo "$(brew --prefix qt6)/bin" >> $GITHUB_PATH
mkdir ./_build
- name: Configuration
run: cmake .. -DCMAKE_PREFIX_PATH=$(brew --prefix qt6)/lib/cmake
run: cmake .. -DCMAKE_PREFIX_PATH=$(brew --prefix qt6)/lib/cmake -DOFBUILD_ENABLE_DOCS=OFF
working-directory: ./_build
- name: Build
run: make -j 2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/CI-windows.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
release: false
install: >-
mingw-w64-x86_64-toolchain mingw-w64-x86_64-gcc mingw-w64-x86_64-gcc-fortran
mingw-w64-x86_64-cmake mingw-w64-x86_64-doxygen
mingw-w64-x86_64-cmake mingw-w64-x86_64-doxygen make
mingw-w64-x86_64-boost mingw-w64-x86_64-gdal mingw-w64-x86_64-curl-winssl
mingw-w64-x86_64-qt5 mingw-w64-x86_64-openssl
git p7zip mingw-w64-x86_64-gnuplot mingw-w64-x86_64-graphviz
Expand Down
5 changes: 3 additions & 2 deletions CMake.in.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#
# Configuration file for CMakeLists.txt files
#
# Author : Jean-Christophe FABRE <[email protected]>
# Authors : Jean-Christophe FABRE <[email protected]>
# Armel THÖNI <[email protected]>
#
# This file is included by the main CMakeLists.txt file, and defines variables
# to configure the build and install
Expand All @@ -23,7 +24,7 @@ SET(OFBUILD_CUSTOM_CMAKE_VERSION "${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.
SET(OPENFLUID_VERSION_MAJOR 2)
SET(OPENFLUID_VERSION_MINOR 2)
SET(OPENFLUID_VERSION_PATCH 1)
SET(OPENFLUID_VERSION_STATUS "alpha5") # example: SET(OPENFLUID_VERSION_STATUS "rc1")
SET(OPENFLUID_VERSION_STATUS "alpha6") # example: SET(OPENFLUID_VERSION_STATUS "rc1")

SET(OPENFLUID_VERSION_FULL "${OPENFLUID_VERSION_MAJOR}.${OPENFLUID_VERSION_MINOR}.${OPENFLUID_VERSION_PATCH}")

Expand Down
21 changes: 16 additions & 5 deletions src/openfluid/utils/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@

INCLUDE_DIRECTORIES(${GDAL_INCLUDE_DIR} ${CURL_INCLUDE_DIRS})

# Hack for boost::process on Windows/MinGW only
SET(BOOST_COMPONENTS )
SET(BOOST_LINK_LIBRARIES Boost::boost)
IF(Boost_VERSION_MINOR GREATER 85)
SET(BOOST_COMPONENTS ${BOOST_COMPONENTS} process)
SET(BOOST_LINK_LIBRARIES ${BOOST_LINK_LIBRARIES} Boost::process)
ENDIF()


IF(MINGW)
FIND_PACKAGE(Boost REQUIRED filesystem)
SET(BOOST_COMPONENTS ${BOOST_COMPONENTS} filesystem system thread)
# Hack for boost::process on Windows/MinGW only
IF(Boost_VERSION GREATER 107000)
ADD_DEFINITIONS(-DBOOST_USE_WINDOWS_H -DWIN32_LEAN_AND_MEAN)
ENDIF()
IF(Boost_VERSION_MINOR GREATER 85)
SET(BOOST_LINK_LIBRARIES ${BOOST_LINK_LIBRARIES} bcrypt)
ENDIF()
ENDIF()

FIND_PACKAGE(Boost REQUIRED ${BOOST_COMPONENTS})
ADD_COMPILE_DEFINITIONS(Boost_VERSION_MINOR=${Boost_VERSION_MINOR})

SET(OPENFLUID_UTILS_CPP GDALHelpers.cpp
Process.cpp
Expand Down Expand Up @@ -46,12 +58,11 @@ TARGET_LINK_LIBRARIES(openfluid-utils
openfluid-tools
${GDAL_LIBRARIES}
${CURL_LIBRARIES}
Boost::boost
${BOOST_LINK_LIBRARIES}
$<$<BOOL:${MINGW}>:Boost::filesystem> $<$<BOOL:${MINGW}>:ws2_32> # MinGW hack
)



INSTALL(TARGETS openfluid-utils
RUNTIME DESTINATION ${OFBUILD_BIN_INSTALL_PATH}
LIBRARY DESTINATION ${OFBUILD_LIB_INSTALL_PATH}
Expand Down
159 changes: 151 additions & 8 deletions src/openfluid/utils/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,21 @@
#include <sstream>
#include <iterator>

#if (Boost_VERSION_MINOR > 85) && defined(OPENFLUID_OS_WINDOWS)
#include <winsock2.h> // FIXME check if useful or necessary, theorically useful to respect include order
#endif
#if (Boost_VERSION_MINOR > 85)
#include <unordered_map>
#include <boost/asio/io_context.hpp>
#include <boost/asio/readable_pipe.hpp>
#include <boost/asio/read.hpp>
#include <boost/process/v2/process.hpp>
#include <boost/process/v2/environment.hpp>
#include <boost/process/v2/stdio.hpp>
#include <boost/process/v2/start_dir.hpp>
#else
#include <boost/process.hpp>
#endif

#include <openfluid/tools/FilesystemPath.hpp>
#include <openfluid/tools/StringHelpers.hpp>
Expand Down Expand Up @@ -136,6 +150,107 @@ bool Process::run()

try
{
#if (Boost_VERSION_MINOR > 85)
std::ofstream StdOutFile;
std::ofstream StdErrFile;
std::string LineOut;
std::string LineErr;
std::unordered_map<std::string, std::string> ProcessEnv;
boost::asio::io_context Ctx;
boost::asio::readable_pipe PipeOut{Ctx};
boost::asio::readable_pipe PipeErr{Ctx};

bool SinkOutToFile = !m_Cmd.OutFile.empty();
bool SinkErrToFile = !m_Cmd.ErrFile.empty();

// prepare environment
if (m_Env.Inherits)
{
for(const auto& InheritedVar : boost::process::v2::environment::current())
{
ProcessEnv[InheritedVar.key().string()] = InheritedVar.value().string();
}
}

for (const auto& Var : m_Env.Vars)
{
ProcessEnv[Var.first] = Var.second;
}
// Hotfix for windows bug when work dir is empty
std::string WorkDir;
if (m_Cmd.WorkDir.empty())
{
WorkDir = "."; // warning boost : If your path is relative, it may fail on posix,
//because the directory is changed before a call to execve.
}
else
{
WorkDir = m_Cmd.WorkDir;
}

// boost::process::shell, <- not relevant in new system?
boost::process::v2::process Proc(Ctx, m_Cmd.Program, m_Cmd.Args,
boost::process::v2::process_stdio{nullptr, PipeOut, PipeErr},
boost::process::v2::process_start_dir(WorkDir),
boost::process::v2::process_environment(ProcessEnv));

// if out is redirected, create out file
if (SinkOutToFile)
{
openfluid::tools::Path(openfluid::tools::Path(m_Cmd.OutFile).dirname()).makeDirectory();
StdOutFile.open(m_Cmd.OutFile,std::ios::out);
}

// if error is redirected, create error file
if (SinkErrToFile)
{
openfluid::tools::Path(openfluid::tools::Path(m_Cmd.ErrFile).dirname()).makeDirectory();
StdErrFile.open(m_Cmd.ErrFile,std::ios::out);
}

boost::system::error_code Ec;
boost::asio::read(PipeOut, boost::asio::dynamic_buffer(LineOut), Ec);
if (!Ec || (Ec == boost::asio::error::eof))
{
std::cout << "Boost process reading error in out stream: " << Ec.message() << std::endl;
openfluid::utils::log::error("Process", "Boost process reading error in out stream");
}
boost::asio::read(PipeErr, boost::asio::dynamic_buffer(LineErr), Ec);
if (!Ec || (Ec == boost::asio::error::eof))
{
std::cout << "Boost process reading error in err stream: " << Ec.message() << std::endl;
openfluid::utils::log::error("Process", "Boost process reading error in err stream");
}

Proc.wait();
for (const auto& L : openfluid::tools::split(LineOut, "\n"))
{
if (SinkOutToFile)
{
// if out is redirected, sink out lines in file
StdOutFile << L << "\n";
}
else
{
m_OutLines.push_back(L);
}
}

for (const auto& L : openfluid::tools::split(LineErr, "\n"))
{
if (SinkErrToFile)
{
// if out is redirected, sink out lines in file
StdErrFile << L << "\n";
}
else
{
m_ErrLines.push_back(L);
}
}

m_ExitCode = Proc.exit_code();
#else
boost::process::environment ProcessEnv;
boost::process::ipstream StdOutStr;
boost::process::ipstream StdErrStr;
Expand Down Expand Up @@ -229,17 +344,12 @@ bool Process::run()

BPC.wait();
m_ExitCode = BPC.exit_code();
#endif
}
catch(const boost::process::process_error& E)
catch(const std::exception& E)
{
m_ErrorMsg = std::string(E.what());
openfluid::utils::log::error("Process", std::string("Boost process error: ")+E.what());
return false;
}
catch(...)
{
// TODO for logging purposes
openfluid::utils::log::error("Process", "Boost process error");
openfluid::utils::log::error("Process", std::string("Boost process error: ")+m_ErrorMsg);
return false;
}

Expand Down Expand Up @@ -291,6 +401,38 @@ int Process::system(const std::string& Program, const std::vector<std::string>&

int Process::system(const Command& Cmd, const Environment& Env)
{
#if (Boost_VERSION_MINOR > 85)
boost::asio::io_context Ctx;
std::unordered_map<std::string, std::string> ProcessEnv;
// prepare environment
if (Env.Inherits)
{
for(const auto& InheritedVar : boost::process::v2::environment::current())
{
ProcessEnv[InheritedVar.key().string()] = InheritedVar.value().string();
}
}

for (const auto& Var : Env.Vars)
{
ProcessEnv[Var.first] = Var.second;
}
// Hotfix for windows bug when work dir is empty
std::string WorkDir;
if (Cmd.WorkDir.empty())
{
WorkDir = "."; // warning boost : If your path is relative, it may fail on posix,
//because the directory is changed before a call to execve.
}
else
{
WorkDir = Cmd.WorkDir;
}
boost::process::v2::process Proc(Ctx, Cmd.Program, Cmd.Args,
boost::process::v2::process_start_dir(WorkDir),
boost::process::v2::process_environment(ProcessEnv));
return Proc.wait();
#else
boost::process::environment ProcessEnv;

// prepare environment
Expand Down Expand Up @@ -321,6 +463,7 @@ int Process::system(const Command& Cmd, const Environment& Env)
boost::process::args = Cmd.Args,
boost::process::start_dir = WorkDir,
ProcessEnv);
#endif
}


Expand Down
Loading