CJentzsch
10 years ago
389 changed files with 12180 additions and 29202 deletions
@ -0,0 +1,4 @@ |
|||||
|
[submodule "evmjit"] |
||||
|
path = evmjit |
||||
|
url = https://github.com/ethereum/evmjit |
||||
|
branch = develop |
@ -1,101 +1,53 @@ |
|||||
|
cmake_policy(SET CMP0015 NEW) |
||||
|
# let cmake autolink dependencies on windows |
||||
|
cmake_policy(SET CMP0020 NEW) |
||||
|
# this policy was introduced in cmake 3.0 |
||||
|
# remove if, once 3.0 will be used on unix |
||||
|
if (${CMAKE_MAJOR_VERSION} GREATER 2) |
||||
|
cmake_policy(SET CMP0043 OLD) |
||||
|
endif() |
||||
|
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON) |
set(CMAKE_INCLUDE_CURRENT_DIR ON) |
||||
aux_source_directory(. SRC_LIST) |
aux_source_directory(. SRC_LIST) |
||||
include_directories(..) |
|
||||
|
|
||||
if (APPLE) |
include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) |
||||
# Add homebrew path for qt5 |
include_directories(..) |
||||
set(CMAKE_PREFIX_PATH /usr/local/opt/qt5) |
|
||||
include_directories(/usr/local/opt/qt5/include /usr/local/include) |
|
||||
elseif ("${TARGET_PLATFORM}" STREQUAL "w64") |
|
||||
set(SRC_LIST ${SRC_LIST} ../windows/qt_plugin_import.cpp) |
|
||||
include_directories(/usr/x86_64-w64-mingw32/include /usr/x86_64-w64-mingw32/include/QtCore /usr/x86_64-w64-mingw32/include/QtGui /usr/x86_64-w64-mingw32/include/QtQuick /usr/x86_64-w64-mingw32/include/QtQml /usr/x86_64-w64-mingw32/include/QtNetwork /usr/x86_64-w64-mingw32/include/QtWidgets /usr/x86_64-w64-mingw32/include/QtWebKit /usr/x86_64-w64-mingw32/include/QtWebKitWidgets) |
|
||||
elseif (UNIX) |
|
||||
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake") |
|
||||
endif () |
|
||||
|
|
||||
find_package(Qt5Core REQUIRED) |
|
||||
find_package(Qt5Gui REQUIRED) |
|
||||
find_package(Qt5Quick REQUIRED) |
|
||||
find_package(Qt5Qml REQUIRED) |
|
||||
find_package(Qt5Network REQUIRED) |
|
||||
find_package(Qt5Widgets REQUIRED) |
|
||||
find_package(Qt5WebKit REQUIRED) |
|
||||
find_package(Qt5WebKitWidgets REQUIRED) |
|
||||
|
|
||||
qt5_wrap_ui(ui_Main.h Main.ui) |
qt5_wrap_ui(ui_Main.h Main.ui) |
||||
|
|
||||
# Set name of binary and add_executable() |
|
||||
file(GLOB HEADERS "*.h") |
file(GLOB HEADERS "*.h") |
||||
if (APPLE) |
|
||||
set(EXECUTEABLE AlethZero) |
|
||||
set(BIN_INSTALL_DIR ".") |
|
||||
set(DOC_INSTALL_DIR ".") |
|
||||
|
|
||||
set(PROJECT_VERSION "${ETH_VERSION}") |
|
||||
set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") |
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}") |
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") |
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") |
|
||||
set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") |
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") |
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTEABLE}) |
|
||||
set(MACOSX_BUNDLE_ICON_FILE alethzero) |
|
||||
include(BundleUtilities) |
|
||||
|
|
||||
add_executable(${EXECUTEABLE} MACOSX_BUNDLE alethzero.icns Main.ui ${SRC_LIST} ${HEADERS}) |
|
||||
set_target_properties(${EXECUTEABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") |
|
||||
SET_SOURCE_FILES_PROPERTIES(${EXECUTEABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) |
|
||||
SET_SOURCE_FILES_PROPERTIES(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") |
|
||||
|
|
||||
else () |
|
||||
set(EXECUTEABLE alethzero) |
|
||||
add_executable(${EXECUTEABLE} Main.ui ${SRC_LIST} ${HEADERS}) |
|
||||
endif () |
|
||||
|
|
||||
qt5_use_modules(${EXECUTEABLE} Core)# Gui Widgets Network WebKit WebKitWidgets) |
|
||||
target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 gmp ${CRYPTOPP_LS} serpent lll solidity evmcore devcore web3jsonrpc jsqrc) |
|
||||
|
|
||||
if (APPLE) |
if (APPLE) |
||||
# First have qt5 install plugins and frameworks |
set(EXECUTABLE AlethZero) |
||||
add_custom_command(TARGET ${EXECUTEABLE} POST_BUILD |
|
||||
COMMAND /usr/local/opt/qt5/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTEABLE}.app |
|
||||
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) |
|
||||
|
|
||||
# This tool and next will inspect linked libraries in order to determine which dependencies are required |
|
||||
if (${CMAKE_CFG_INTDIR} STREQUAL ".") |
|
||||
set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTEABLE}.app") |
|
||||
else () |
|
||||
set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTEABLE}.app") |
|
||||
endif () |
|
||||
install(CODE " |
|
||||
include(BundleUtilities) |
|
||||
set(BU_CHMOD_BUNDLE_ITEMS 1) |
|
||||
fixup_bundle(\"${APP_BUNDLE_PATH}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\") |
|
||||
" COMPONENT RUNTIME ) |
|
||||
# Cleanup duplicate libs from macdeployqt |
|
||||
install(CODE " |
|
||||
file(GLOB LINGER_RM \"${APP_BUNDLE_PATH}/Contents/Frameworks/*.dylib\") |
|
||||
if (LINGER_RM) |
|
||||
file(REMOVE \${LINGER_RM}) |
|
||||
endif () |
|
||||
") |
|
||||
elseif ("${TARGET_PLATFORM}" STREQUAL "w64") |
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -static-libgcc -static-libstdc++ -static") |
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s -Wl,-subsystem,windows -mthreads -L/usr/x86_64-w64-mingw32/plugins/platforms") |
|
||||
target_link_libraries(${EXECUTEABLE} gcc) |
|
||||
target_link_libraries(${EXECUTEABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport opengl32 gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32) |
|
||||
target_link_libraries(${EXECUTEABLE} boost_system-mt-s) |
|
||||
target_link_libraries(${EXECUTEABLE} boost_filesystem-mt-s) |
|
||||
target_link_libraries(${EXECUTEABLE} boost_thread_win32-mt-s) |
|
||||
target_link_libraries(${EXECUTEABLE} crypt32) |
|
||||
target_link_libraries(${EXECUTEABLE} Qt5PlatformSupport) |
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) |
|
||||
elseif (UNIX) |
|
||||
else () |
else () |
||||
target_link_libraries(${EXECUTEABLE} boost_system) |
set(EXECUTABLE alethzero) |
||||
target_link_libraries(${EXECUTEABLE} boost_filesystem) |
|
||||
find_package(Threads REQUIRED) |
|
||||
target_link_libraries(${EXECUTEABLE} ${CMAKE_THREAD_LIBS_INIT}) |
|
||||
install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin ) |
|
||||
endif () |
endif () |
||||
|
|
||||
|
# eth_add_executable is defined in cmake/EthExecutableHelper.cmake |
||||
|
eth_add_executable(${EXECUTABLE} |
||||
|
ICON alethzero |
||||
|
UI_RESOURCES alethzero.icns Main.ui |
||||
|
WIN_RESOURCES alethzero.rc |
||||
|
) |
||||
|
|
||||
|
add_dependencies(${EXECUTABLE} BuildInfo.h) |
||||
|
|
||||
|
target_link_libraries(${EXECUTABLE} Qt5::Core) |
||||
|
target_link_libraries(${EXECUTABLE} webthree) |
||||
|
target_link_libraries(${EXECUTABLE} qethereum) |
||||
|
target_link_libraries(${EXECUTABLE} ethereum) |
||||
|
target_link_libraries(${EXECUTABLE} evm) |
||||
|
target_link_libraries(${EXECUTABLE} ethcore) |
||||
|
target_link_libraries(${EXECUTABLE} devcrypto) |
||||
|
target_link_libraries(${EXECUTABLE} secp256k1) |
||||
|
target_link_libraries(${EXECUTABLE} serpent) |
||||
|
target_link_libraries(${EXECUTABLE} lll) |
||||
|
target_link_libraries(${EXECUTABLE} solidity) |
||||
|
target_link_libraries(${EXECUTABLE} evmcore) |
||||
|
target_link_libraries(${EXECUTABLE} devcore) |
||||
|
target_link_libraries(${EXECUTABLE} web3jsonrpc) |
||||
|
target_link_libraries(${EXECUTABLE} jsqrc) |
||||
|
|
||||
|
# eth_install_executable is defined in cmake/EthExecutableHelper.cmake |
||||
|
eth_install_executable(${EXECUTABLE}) |
||||
|
|
||||
|
After Width: | Height: | Size: 361 KiB |
@ -0,0 +1 @@ |
|||||
|
APP_ICON ICON DISCARDABLE "alethzero.ico" |
@ -1,50 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process.hpp |
|
||||
* |
|
||||
* Convenience header that includes all other Boost.Process public header |
|
||||
* files. It is important to note that those headers that are specific to |
|
||||
* a given platform are only included if the library is being used in that |
|
||||
* same platform. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_HPP |
|
||||
#define BOOST_PROCESS_HPP |
|
||||
|
|
||||
#include <boost/process/config.hpp> |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
# include <boost/process/posix_child.hpp> |
|
||||
# include <boost/process/posix_context.hpp> |
|
||||
# include <boost/process/posix_operations.hpp> |
|
||||
# include <boost/process/posix_status.hpp> |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
# include <boost/process/win32_child.hpp> |
|
||||
# include <boost/process/win32_context.hpp> |
|
||||
# include <boost/process/win32_operations.hpp> |
|
||||
#else |
|
||||
# error "Unsupported platform." |
|
||||
#endif |
|
||||
|
|
||||
#include <boost/process/child.hpp> |
|
||||
#include <boost/process/context.hpp> |
|
||||
#include <boost/process/environment.hpp> |
|
||||
#include <boost/process/operations.hpp> |
|
||||
#include <boost/process/pistream.hpp> |
|
||||
#include <boost/process/postream.hpp> |
|
||||
#include <boost/process/process.hpp> |
|
||||
#include <boost/process/self.hpp> |
|
||||
#include <boost/process/status.hpp> |
|
||||
#include <boost/process/stream_behavior.hpp> |
|
||||
|
|
||||
#endif |
|
@ -1,200 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/child.hpp |
|
||||
* |
|
||||
* Includes the declaration of the child class. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_CHILD_HPP |
|
||||
#define BOOST_PROCESS_CHILD_HPP |
|
||||
|
|
||||
#include <boost/process/config.hpp> |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
# include <sys/types.h> |
|
||||
# include <sys/wait.h> |
|
||||
# include <cerrno> |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
# include <windows.h> |
|
||||
#else |
|
||||
# error "Unsupported platform." |
|
||||
#endif |
|
||||
|
|
||||
#include <boost/process/process.hpp> |
|
||||
#include <boost/process/pistream.hpp> |
|
||||
#include <boost/process/postream.hpp> |
|
||||
#include <boost/process/status.hpp> |
|
||||
#include <boost/process/detail/file_handle.hpp> |
|
||||
#include <boost/system/system_error.hpp> |
|
||||
#include <boost/throw_exception.hpp> |
|
||||
#include <boost/shared_ptr.hpp> |
|
||||
#include <boost/assert.hpp> |
|
||||
#include <vector> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
/**
|
|
||||
* Generic implementation of the Child concept. |
|
||||
* |
|
||||
* The child class implements the Child concept in an operating system |
|
||||
* agnostic way. |
|
||||
*/ |
|
||||
class child : public process |
|
||||
{ |
|
||||
public: |
|
||||
/**
|
|
||||
* Gets a reference to the child's standard input stream. |
|
||||
* |
|
||||
* Returns a reference to a postream object that represents the |
|
||||
* standard input communication channel with the child process. |
|
||||
*/ |
|
||||
postream &get_stdin() const |
|
||||
{ |
|
||||
BOOST_ASSERT(stdin_); |
|
||||
|
|
||||
return *stdin_; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Gets a reference to the child's standard output stream. |
|
||||
* |
|
||||
* Returns a reference to a pistream object that represents the |
|
||||
* standard output communication channel with the child process. |
|
||||
*/ |
|
||||
pistream &get_stdout() const |
|
||||
{ |
|
||||
BOOST_ASSERT(stdout_); |
|
||||
|
|
||||
return *stdout_; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Gets a reference to the child's standard error stream. |
|
||||
* |
|
||||
* Returns a reference to a pistream object that represents the |
|
||||
* standard error communication channel with the child process. |
|
||||
*/ |
|
||||
pistream &get_stderr() const |
|
||||
{ |
|
||||
BOOST_ASSERT(stderr_); |
|
||||
|
|
||||
return *stderr_; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Blocks and waits for the child process to terminate. |
|
||||
* |
|
||||
* Returns a status object that represents the child process' |
|
||||
* finalization condition. The child process object ceases to be |
|
||||
* valid after this call. |
|
||||
* |
|
||||
* \remark Blocking remarks: This call blocks if the child |
|
||||
* process has not finalized execution and waits until |
|
||||
* it terminates. |
|
||||
*/ |
|
||||
status wait() |
|
||||
{ |
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
int s; |
|
||||
if (::waitpid(get_id(), &s, 0) == -1) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::child::wait: waitpid(2) failed")); |
|
||||
return status(s); |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
::WaitForSingleObject(process_handle_.get(), INFINITE); |
|
||||
DWORD code; |
|
||||
if (!::GetExitCodeProcess(process_handle_.get(), &code)) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::child::wait: GetExitCodeProcess failed")); |
|
||||
return status(code); |
|
||||
#endif |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Creates a new child object that represents the just spawned child |
|
||||
* process \a id. |
|
||||
* |
|
||||
* The \a fhstdin, \a fhstdout and \a fhstderr file handles represent |
|
||||
* the parent's handles used to communicate with the corresponding |
|
||||
* data streams. They needn't be valid but their availability must |
|
||||
* match the redirections configured by the launcher that spawned this |
|
||||
* process. |
|
||||
* |
|
||||
* The \a fhprocess handle represents a handle to the child process. |
|
||||
* It is only used on Windows as the implementation of wait() needs a |
|
||||
* process handle. |
|
||||
*/ |
|
||||
child(id_type id, detail::file_handle fhstdin, detail::file_handle fhstdout, detail::file_handle fhstderr, detail::file_handle fhprocess = detail::file_handle()) |
|
||||
: process(id) |
|
||||
#if defined(BOOST_WINDOWS_API) |
|
||||
, process_handle_(fhprocess.release(), ::CloseHandle) |
|
||||
#endif |
|
||||
{ |
|
||||
if (fhstdin.valid()) |
|
||||
stdin_.reset(new postream(fhstdin)); |
|
||||
if (fhstdout.valid()) |
|
||||
stdout_.reset(new pistream(fhstdout)); |
|
||||
if (fhstderr.valid()) |
|
||||
stderr_.reset(new pistream(fhstderr)); |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
/**
|
|
||||
* The standard input stream attached to the child process. |
|
||||
* |
|
||||
* This postream object holds the communication channel with the |
|
||||
* child's process standard input. It is stored in a pointer because |
|
||||
* this field is only valid when the user requested to redirect this |
|
||||
* data stream. |
|
||||
*/ |
|
||||
boost::shared_ptr<postream> stdin_; |
|
||||
|
|
||||
/**
|
|
||||
* The standard output stream attached to the child process. |
|
||||
* |
|
||||
* This postream object holds the communication channel with the |
|
||||
* child's process standard output. It is stored in a pointer because |
|
||||
* this field is only valid when the user requested to redirect this |
|
||||
* data stream. |
|
||||
*/ |
|
||||
boost::shared_ptr<pistream> stdout_; |
|
||||
|
|
||||
/**
|
|
||||
* The standard error stream attached to the child process. |
|
||||
* |
|
||||
* This postream object holds the communication channel with the |
|
||||
* child's process standard error. It is stored in a pointer because |
|
||||
* this field is only valid when the user requested to redirect this |
|
||||
* data stream. |
|
||||
*/ |
|
||||
boost::shared_ptr<pistream> stderr_; |
|
||||
|
|
||||
#if defined(BOOST_WINDOWS_API) |
|
||||
/**
|
|
||||
* Process handle owned by RAII object. |
|
||||
*/ |
|
||||
boost::shared_ptr<void> process_handle_; |
|
||||
#endif |
|
||||
}; |
|
||||
|
|
||||
/**
|
|
||||
* Collection of child objects. |
|
||||
* |
|
||||
* This convenience type represents a collection of child objects backed |
|
||||
* by a vector. |
|
||||
*/ |
|
||||
typedef std::vector<child> children; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,41 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/config.hpp |
|
||||
* |
|
||||
* Defines macros that are used by the library's code to determine the |
|
||||
* operating system it is running under and the features it supports. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_CONFIG_HPP |
|
||||
#define BOOST_PROCESS_CONFIG_HPP |
|
||||
|
|
||||
#include <boost/config.hpp> |
|
||||
#include <boost/system/config.hpp> |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) |
|
||||
# if !defined(BOOST_PROCESS_POSIX_PATH_MAX) |
|
||||
/**
|
|
||||
* The macro BOOST_PROCESS_POSIX_PATH_MAX is set to a positive integer |
|
||||
* value which specifies the system's maximal supported path length. |
|
||||
* By default it is set to 259. You should set the macro to PATH_MAX |
|
||||
* which should be defined in limits.h provided by your operating system |
|
||||
* if you experience problems when instantiating a context. The |
|
||||
* constructor of basic_work_directory_context tries to find out |
|
||||
* dynamically the maximal supported path length but uses |
|
||||
* BOOST_PROCESS_POSIX_PATH_MAX if it fails. |
|
||||
*/ |
|
||||
# define BOOST_PROCESS_POSIX_PATH_MAX 259 |
|
||||
# endif |
|
||||
#endif |
|
||||
|
|
||||
#endif |
|
@ -1,209 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/context.hpp |
|
||||
* |
|
||||
* Includes the declaration of the context class and several accessory |
|
||||
* base classes. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_CONTEXT_HPP |
|
||||
#define BOOST_PROCESS_CONTEXT_HPP |
|
||||
|
|
||||
#include <boost/process/config.hpp> |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
# include <boost/scoped_array.hpp> |
|
||||
# include <cerrno> |
|
||||
# include <unistd.h> |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
# include <windows.h> |
|
||||
#else |
|
||||
# error "Unsupported platform." |
|
||||
#endif |
|
||||
|
|
||||
#include <boost/process/environment.hpp> |
|
||||
#include <boost/process/stream_behavior.hpp> |
|
||||
#include <boost/system/system_error.hpp> |
|
||||
#include <boost/throw_exception.hpp> |
|
||||
#include <boost/assert.hpp> |
|
||||
#include <string> |
|
||||
#include <vector> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
/**
|
|
||||
* Base context class that defines the child's work directory. |
|
||||
* |
|
||||
* Base context class that defines the necessary fields to configure a |
|
||||
* child's work directory. This class is useless on its own because no |
|
||||
* function in the library will accept it as a valid Context |
|
||||
* implementation. |
|
||||
*/ |
|
||||
template <class Path> |
|
||||
class basic_work_directory_context |
|
||||
{ |
|
||||
public: |
|
||||
/**
|
|
||||
* Constructs a new work directory context. |
|
||||
* |
|
||||
* Constructs a new work directory context making the work directory |
|
||||
* described by the new object point to the caller's current working |
|
||||
* directory. |
|
||||
*/ |
|
||||
basic_work_directory_context() |
|
||||
{ |
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
errno = 0; |
|
||||
long size = ::pathconf(".", _PC_PATH_MAX); |
|
||||
if (size == -1 && errno) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::basic_work_directory_context::basic_work_directory_context: pathconf(2) failed")); |
|
||||
else if (size == -1) |
|
||||
size = BOOST_PROCESS_POSIX_PATH_MAX; |
|
||||
boost::scoped_array<char> cwd(new char[size]); |
|
||||
if (!::getcwd(cwd.get(), size)) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::basic_work_directory_context::basic_work_directory_context: getcwd(2) failed")); |
|
||||
work_directory = cwd.get(); |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
char cwd[MAX_PATH]; |
|
||||
if (!::GetCurrentDirectoryA(sizeof(cwd), cwd)) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::basic_work_directory_context::basic_work_directory_context: GetCurrentDirectory failed")); |
|
||||
work_directory = cwd; |
|
||||
#endif |
|
||||
BOOST_ASSERT(!work_directory.empty()); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* The process' initial work directory. |
|
||||
* |
|
||||
* The work directory is the directory in which the process starts |
|
||||
* execution. |
|
||||
*/ |
|
||||
Path work_directory; |
|
||||
}; |
|
||||
|
|
||||
/**
|
|
||||
* Base context class that defines the child's environment. |
|
||||
* |
|
||||
* Base context class that defines the necessary fields to configure a |
|
||||
* child's environment variables. This class is useless on its own |
|
||||
* because no function in the library will accept it as a valid Context |
|
||||
* implementation. |
|
||||
*/ |
|
||||
class environment_context |
|
||||
{ |
|
||||
public: |
|
||||
/**
|
|
||||
* The process' environment. |
|
||||
* |
|
||||
* Contains the list of environment variables, alongside with their |
|
||||
* values, that will be passed to the spawned child process. |
|
||||
*/ |
|
||||
boost::process::environment environment; |
|
||||
}; |
|
||||
|
|
||||
/**
|
|
||||
* Process startup execution context. |
|
||||
* |
|
||||
* The context class groups all the parameters needed to configure a |
|
||||
* process' environment during its creation. |
|
||||
*/ |
|
||||
template <class Path> |
|
||||
class basic_context : public basic_work_directory_context<Path>, public environment_context |
|
||||
{ |
|
||||
public: |
|
||||
/**
|
|
||||
* Child's stdin behavior. |
|
||||
*/ |
|
||||
stream_behavior stdin_behavior; |
|
||||
|
|
||||
/**
|
|
||||
* Child's stdout behavior. |
|
||||
*/ |
|
||||
stream_behavior stdout_behavior; |
|
||||
|
|
||||
/**
|
|
||||
* Child's stderr behavior. |
|
||||
*/ |
|
||||
stream_behavior stderr_behavior; |
|
||||
}; |
|
||||
|
|
||||
typedef basic_context<std::string> context; |
|
||||
|
|
||||
/**
|
|
||||
* Represents a child process in a pipeline. |
|
||||
* |
|
||||
* This convenience class is a triplet that holds all the data required |
|
||||
* to spawn a new child process in a pipeline. |
|
||||
*/ |
|
||||
template <class Executable, class Arguments, class Context> |
|
||||
class basic_pipeline_entry |
|
||||
{ |
|
||||
public: |
|
||||
/**
|
|
||||
* The executable to launch. |
|
||||
*/ |
|
||||
Executable executable; |
|
||||
|
|
||||
/**
|
|
||||
* The set of arguments to pass to the executable. |
|
||||
*/ |
|
||||
Arguments arguments; |
|
||||
|
|
||||
/**
|
|
||||
* The child's execution context. |
|
||||
*/ |
|
||||
Context context; |
|
||||
|
|
||||
/**
|
|
||||
* The type of the Executable concept used in this template |
|
||||
* instantiation. |
|
||||
*/ |
|
||||
typedef Executable executable_type; |
|
||||
|
|
||||
/**
|
|
||||
* The type of the Arguments concept used in this template |
|
||||
* instantiation. |
|
||||
*/ |
|
||||
typedef Arguments arguments_type; |
|
||||
|
|
||||
/**
|
|
||||
* The type of the Context concept used in this template |
|
||||
* instantiation. |
|
||||
*/ |
|
||||
typedef Context context_type; |
|
||||
|
|
||||
/**
|
|
||||
* Constructs a new pipeline_entry object. |
|
||||
* |
|
||||
* Given the executable, set of arguments and execution triplet, |
|
||||
* constructs a new pipeline_entry object that holds the three |
|
||||
* values. |
|
||||
*/ |
|
||||
basic_pipeline_entry(const Executable &exe, const Arguments &args, const Context &ctx) |
|
||||
: executable(exe), |
|
||||
arguments(args), |
|
||||
context(ctx) |
|
||||
{ |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
/**
|
|
||||
* Default instantiation of basic_pipeline_entry. |
|
||||
*/ |
|
||||
typedef basic_pipeline_entry<std::string, std::vector<std::string>, context> pipeline_entry; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,406 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/detail/file_handle.hpp |
|
||||
* |
|
||||
* Includes the declaration of the file_handle class. This file is for |
|
||||
* internal usage only and must not be included by the library user. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_DETAIL_FILE_HANDLE_HPP |
|
||||
#define BOOST_PROCESS_DETAIL_FILE_HANDLE_HPP |
|
||||
|
|
||||
#include <boost/process/config.hpp> |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
# include <cerrno> |
|
||||
# include <unistd.h> |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
# include <windows.h> |
|
||||
#else |
|
||||
# error "Unsupported platform." |
|
||||
#endif |
|
||||
|
|
||||
#include <boost/assert.hpp> |
|
||||
#include <boost/system/system_error.hpp> |
|
||||
#include <boost/throw_exception.hpp> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
namespace detail { |
|
||||
|
|
||||
/**
|
|
||||
* Simple RAII model for system file handles. |
|
||||
* |
|
||||
* The \a file_handle class is a simple RAII model for native system file |
|
||||
* handles. This class wraps one of such handles grabbing its ownership, |
|
||||
* and automaticaly closes it upon destruction. It is basically used |
|
||||
* inside the library to avoid leaking open file handles, shall an |
|
||||
* unexpected execution trace occur. |
|
||||
* |
|
||||
* A \a file_handle object can be copied but doing so invalidates the |
|
||||
* source object. There can only be a single valid \a file_handle object |
|
||||
* for a given system file handle. This is similar to std::auto_ptr's |
|
||||
* semantics. |
|
||||
* |
|
||||
* This class also provides some convenience methods to issue special file |
|
||||
* operations under their respective platforms. |
|
||||
*/ |
|
||||
class file_handle |
|
||||
{ |
|
||||
public: |
|
||||
#if defined(BOOST_PROCESS_DOXYGEN) |
|
||||
/**
|
|
||||
* Opaque name for the native handle type. |
|
||||
* |
|
||||
* Each operating system identifies file handles using a specific type. |
|
||||
* The \a handle_type type is used to transparently refer to file |
|
||||
* handles regarless of the operating system in which this class is |
|
||||
* used. |
|
||||
* |
|
||||
* If this class is used on a POSIX system, \a NativeSystemHandle is |
|
||||
* an integer type while it is a \a HANDLE on a Windows system. |
|
||||
*/ |
|
||||
typedef NativeSystemHandle handle_type; |
|
||||
#elif defined(BOOST_POSIX_API) |
|
||||
typedef int handle_type; |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
typedef HANDLE handle_type; |
|
||||
#endif |
|
||||
|
|
||||
/**
|
|
||||
* Constructs an invalid file handle. |
|
||||
* |
|
||||
* This constructor creates a new \a file_handle object that represents |
|
||||
* an invalid file handle. An invalid file handle can be copied but |
|
||||
* cannot be manipulated in any way (except checking for its validity). |
|
||||
* |
|
||||
* \see valid() |
|
||||
*/ |
|
||||
file_handle() |
|
||||
: handle_(invalid_value()) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Constructs a new file handle from a native file handle. |
|
||||
* |
|
||||
* This constructor creates a new \a file_handle object that takes |
|
||||
* ownership of the given \a h native file handle. The user must not |
|
||||
* close \a h on his own during the lifetime of the new object. |
|
||||
* Ownership can be reclaimed using release(). |
|
||||
* |
|
||||
* \pre The native file handle must be valid; a close operation must |
|
||||
* succeed on it. |
|
||||
* \see release() |
|
||||
*/ |
|
||||
file_handle(handle_type h) |
|
||||
: handle_(h) |
|
||||
{ |
|
||||
BOOST_ASSERT(handle_ != invalid_value()); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Copy constructor; invalidates the source handle. |
|
||||
* |
|
||||
* This copy constructor creates a new file handle from a given one. |
|
||||
* Ownership of the native file handle is transferred to the new |
|
||||
* object, effectively invalidating the source file handle. This |
|
||||
* avoids having two live \a file_handle objects referring to the |
|
||||
* same native file handle. The source file handle needs not be |
|
||||
* valid in the name of simplicity. |
|
||||
* |
|
||||
* \post The source file handle is invalid. |
|
||||
* \post The new file handle owns the source's native file handle. |
|
||||
*/ |
|
||||
file_handle(const file_handle &fh) |
|
||||
: handle_(fh.handle_) |
|
||||
{ |
|
||||
fh.handle_ = invalid_value(); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Releases resources if the handle is valid. |
|
||||
* |
|
||||
* If the file handle is valid, the destructor closes it. |
|
||||
* |
|
||||
* \see valid() |
|
||||
*/ |
|
||||
~file_handle() |
|
||||
{ |
|
||||
if (valid()) |
|
||||
close(); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Assignment operator; invalidates the source handle. |
|
||||
* |
|
||||
* This assignment operator transfers ownership of the RHS file |
|
||||
* handle to the LHS one, effectively invalidating the source file |
|
||||
* handle. This avoids having two live \a file_handle objects |
|
||||
* referring to the same native file handle. The source file |
|
||||
* handle needs not be valid in the name of simplicity. |
|
||||
* |
|
||||
* \post The RHS file handle is invalid. |
|
||||
* \post The LHS file handle owns RHS' native file handle. |
|
||||
* \return A reference to the LHS file handle. |
|
||||
*/ |
|
||||
file_handle &operator=(const file_handle &fh) |
|
||||
{ |
|
||||
handle_ = fh.handle_; |
|
||||
fh.handle_ = invalid_value(); |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Checks whether the file handle is valid or not. |
|
||||
* |
|
||||
* Returns a boolean indicating whether the file handle is valid or |
|
||||
* not. If the file handle is invalid, no other methods can be |
|
||||
* executed other than the destructor. |
|
||||
* |
|
||||
* \return true if the file handle is valid; false otherwise. |
|
||||
*/ |
|
||||
bool valid() const |
|
||||
{ |
|
||||
return handle_ != invalid_value(); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Closes the file handle. |
|
||||
* |
|
||||
* Explicitly closes the file handle, which must be valid. Upon |
|
||||
* exit, the handle is not valid any more. |
|
||||
* |
|
||||
* \pre The file handle is valid. |
|
||||
* \post The file handle is invalid. |
|
||||
* \post The native file handle is closed. |
|
||||
*/ |
|
||||
void close() |
|
||||
{ |
|
||||
BOOST_ASSERT(valid()); |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
::close(handle_); |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
::CloseHandle(handle_); |
|
||||
#endif |
|
||||
|
|
||||
handle_ = invalid_value(); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Reclaims ownership of the native file handle. |
|
||||
* |
|
||||
* Explicitly reclaims ownership of the native file handle contained |
|
||||
* in the \a file_handle object, returning the native file handle. |
|
||||
* The caller is responsible of closing it later on. |
|
||||
* |
|
||||
* \pre The file handle is valid. |
|
||||
* \post The file handle is invalid. |
|
||||
* \return The native file handle. |
|
||||
*/ |
|
||||
handle_type release() |
|
||||
{ |
|
||||
BOOST_ASSERT(valid()); |
|
||||
|
|
||||
handle_type h = handle_; |
|
||||
handle_ = invalid_value(); |
|
||||
return h; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Gets the native file handle. |
|
||||
* |
|
||||
* Returns the native file handle for the \a file_handle object. |
|
||||
* The caller can issue any operation on it except closing it. |
|
||||
* If closing is required, release() shall be used. |
|
||||
* |
|
||||
* \pre The file handle is valid. |
|
||||
* \post The file handle is valid. |
|
||||
* \return The native file handle. |
|
||||
*/ |
|
||||
handle_type get() const |
|
||||
{ |
|
||||
BOOST_ASSERT(valid()); |
|
||||
|
|
||||
return handle_; |
|
||||
} |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) |
|
||||
/**
|
|
||||
* Changes the native file handle to the given one. |
|
||||
* |
|
||||
* Given a new native file handle \a h, this operation assigns this |
|
||||
* handle to the current object, closing its old native file handle. |
|
||||
* In other words, it first calls dup2() to remap the old handle to |
|
||||
* the new one and then closes the old handle. |
|
||||
* |
|
||||
* If \a h is open, it is automatically closed by dup2(). |
|
||||
* |
|
||||
* This operation is only available in POSIX systems. |
|
||||
* |
|
||||
* \pre The file handle is valid. |
|
||||
* \pre The native file handle \a h is valid; i.e., it must be |
|
||||
* closeable. |
|
||||
* \post The file handle's native file handle is \a h. |
|
||||
* \throw boost::system::system_error If the internal remapping |
|
||||
* operation fails. |
|
||||
*/ |
|
||||
void posix_remap(handle_type h) |
|
||||
{ |
|
||||
BOOST_ASSERT(valid()); |
|
||||
|
|
||||
if (::dup2(handle_, h) == -1) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::file_handle::posix_remap: dup2(2) failed")); |
|
||||
|
|
||||
if (::close(handle_) == -1) |
|
||||
{ |
|
||||
::close(h); |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::file_handle::posix_remap: close(2) failed")); |
|
||||
} |
|
||||
|
|
||||
handle_ = h; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Duplicates an open native file handle. |
|
||||
* |
|
||||
* Given a native file handle \a h1, this routine duplicates it so |
|
||||
* that it ends up being identified by the native file handle \a h2 |
|
||||
* and returns a new \a file_handle owning \a h2. |
|
||||
* |
|
||||
* This operation is only available in POSIX systems. |
|
||||
* |
|
||||
* \pre The native file handle \a h1 is open. |
|
||||
* \pre The native file handle \a h2 is valid (non-negative). |
|
||||
* \post The native file handle \a h1 is closed. |
|
||||
* \post The native file handle \a h2 is the same as the old \a h1 |
|
||||
* from the operating system's point of view. |
|
||||
* \return A new \a file_handle object that owns \a h2. |
|
||||
* \throw boost::system::system_error If dup2() fails. |
|
||||
*/ |
|
||||
static file_handle posix_dup(int h1, int h2) |
|
||||
{ |
|
||||
if (::dup2(h1, h2) == -1) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::file_handle::posix_dup: dup2(2) failed")); |
|
||||
|
|
||||
return file_handle(h2); |
|
||||
} |
|
||||
#endif |
|
||||
|
|
||||
#if defined(BOOST_WINDOWS_API) || defined(BOOST_PROCESS_DOXYGEN) |
|
||||
/**
|
|
||||
* Duplicates the \a h native file handle. |
|
||||
* |
|
||||
* Given a native file handle \a h, this routine constructs a new |
|
||||
* \a file_handle object that owns a new duplicate of \a h. The |
|
||||
* duplicate's inheritable flag is set to the value of \a inheritable. |
|
||||
* |
|
||||
* This operation is only available in Windows systems. |
|
||||
* |
|
||||
* \pre The native file handle \a h is valid. |
|
||||
* \return A file handle owning a duplicate of \a h. |
|
||||
* \throw boost::system::system_error If DuplicateHandle() fails. |
|
||||
*/ |
|
||||
static file_handle win32_dup(HANDLE h, bool inheritable) |
|
||||
{ |
|
||||
HANDLE h2; |
|
||||
if (!::DuplicateHandle(::GetCurrentProcess(), h, ::GetCurrentProcess(), &h2, 0, inheritable ? TRUE : FALSE, DUPLICATE_SAME_ACCESS)) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::file_handle::win32_dup: DuplicateHandle failed")); |
|
||||
|
|
||||
return file_handle(h2); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Creates a new duplicate of a standard file handle. |
|
||||
* |
|
||||
* Constructs a new \a file_handle object that owns a duplicate of a |
|
||||
* standard file handle. The \a d parameter specifies which standard |
|
||||
* file handle to duplicate and can be one of \a STD_INPUT_HANDLE, |
|
||||
* \a STD_OUTPUT_HANDLE or \a STD_ERROR_HANDLE. The duplicate's |
|
||||
* inheritable flag is set to the value of \a inheritable. |
|
||||
* |
|
||||
* This operation is only available in Windows systems. |
|
||||
* |
|
||||
* \pre \a d refers to one of the standard handles as described above. |
|
||||
* \return A file handle owning a duplicate of the standard handle |
|
||||
* referred to by \a d. |
|
||||
* \throw boost::system::system_error If GetStdHandle() or |
|
||||
* DuplicateHandle() fails. |
|
||||
*/ |
|
||||
static file_handle win32_std(DWORD d, bool inheritable) |
|
||||
{ |
|
||||
BOOST_ASSERT(d == STD_INPUT_HANDLE || d == STD_OUTPUT_HANDLE || d == STD_ERROR_HANDLE); |
|
||||
|
|
||||
HANDLE h = ::GetStdHandle(d); |
|
||||
if (h == INVALID_HANDLE_VALUE) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::file_handle::win32_std: GetStdHandle failed")); |
|
||||
|
|
||||
return win32_dup(h, inheritable); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Changes the file handle's inheritable flag. |
|
||||
* |
|
||||
* Changes the file handle's inheritable flag to \a i. It is not |
|
||||
* necessary for the file handle's flag to be different than \a i. |
|
||||
* |
|
||||
* This operation is only available in Windows systems. |
|
||||
* |
|
||||
* \pre The file handle is valid. |
|
||||
* \post The native file handle's inheritable flag is set to \a i. |
|
||||
* \throw boost::system::system_error If the property change fails. |
|
||||
*/ |
|
||||
void win32_set_inheritable(bool i) |
|
||||
{ |
|
||||
BOOST_ASSERT(valid()); |
|
||||
|
|
||||
if (!::SetHandleInformation(handle_, HANDLE_FLAG_INHERIT, i ? HANDLE_FLAG_INHERIT : 0)) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::file_handle::win32_set_inheritable: SetHandleInformation failed")); |
|
||||
} |
|
||||
#endif |
|
||||
|
|
||||
private: |
|
||||
/**
|
|
||||
* Internal handle value. |
|
||||
* |
|
||||
* This variable holds the native handle value for the file handle |
|
||||
* hold by this object. It is interesting to note that this needs |
|
||||
* to be mutable because the copy constructor and the assignment |
|
||||
* operator invalidate the source object. |
|
||||
*/ |
|
||||
mutable handle_type handle_; |
|
||||
|
|
||||
/**
|
|
||||
* Constant function representing an invalid handle value. |
|
||||
* |
|
||||
* Returns the platform-specific handle value that represents an |
|
||||
* invalid handle. This is a constant function rather than a regular |
|
||||
* constant because, in the latter case, we cannot define it under |
|
||||
* Windows due to the value being of a complex type. |
|
||||
*/ |
|
||||
static handle_type invalid_value() |
|
||||
{ |
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
return -1; |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
return INVALID_HANDLE_VALUE; |
|
||||
#endif |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,187 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/detail/pipe.hpp |
|
||||
* |
|
||||
* Includes the declaration of the pipe class. This file is for |
|
||||
* internal usage only and must not be included by the library user. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_DETAIL_PIPE_HPP |
|
||||
#define BOOST_PROCESS_DETAIL_PIPE_HPP |
|
||||
|
|
||||
#include <boost/process/config.hpp> |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
# include <unistd.h> |
|
||||
# include <cerrno> |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
# if defined(BOOST_PROCESS_WINDOWS_USE_NAMED_PIPE) |
|
||||
# include <boost/lexical_cast.hpp> |
|
||||
# include <string> |
|
||||
# endif |
|
||||
# include <windows.h> |
|
||||
#else |
|
||||
# error "Unsupported platform." |
|
||||
#endif |
|
||||
|
|
||||
#include <boost/process/detail/file_handle.hpp> |
|
||||
#include <boost/system/system_error.hpp> |
|
||||
#include <boost/throw_exception.hpp> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
namespace detail { |
|
||||
|
|
||||
/**
|
|
||||
* Simple RAII model for anonymous pipes. |
|
||||
* |
|
||||
* The pipe class is a simple RAII model for anonymous pipes. It |
|
||||
* provides a portable constructor that allocates a new %pipe and creates |
|
||||
* a pipe object that owns the two file handles associated to it: the |
|
||||
* read end and the write end. |
|
||||
* |
|
||||
* These handles can be retrieved for modification according to |
|
||||
* file_handle semantics. Optionally, their ownership can be transferred |
|
||||
* to external \a file_handle objects which comes handy when the two |
|
||||
* ends need to be used in different places (i.e. after a POSIX fork() |
|
||||
* system call). |
|
||||
* |
|
||||
* Pipes can be copied following the same semantics as file handles. |
|
||||
* In other words, copying a %pipe object invalidates the source one. |
|
||||
* |
|
||||
* \see file_handle |
|
||||
*/ |
|
||||
class pipe |
|
||||
{ |
|
||||
public: |
|
||||
/**
|
|
||||
* Creates a new %pipe. |
|
||||
* |
|
||||
* The default pipe constructor allocates a new anonymous %pipe |
|
||||
* and assigns its ownership to the created pipe object. On Windows |
|
||||
* when the macro BOOST_PROCESS_WINDOWS_USE_NAMED_PIPE is defined |
|
||||
* a named pipe is created. This is required if asynchronous I/O |
|
||||
* should be used as asynchronous I/O is only supported by named |
|
||||
* pipes on Windows. |
|
||||
* |
|
||||
* \throw boost::system::system_error If the anonymous %pipe |
|
||||
* creation fails. |
|
||||
*/ |
|
||||
pipe() |
|
||||
{ |
|
||||
file_handle::handle_type hs[2]; |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
if (::pipe(hs) == -1) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::pipe::pipe: pipe(2) failed")); |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
SECURITY_ATTRIBUTES sa; |
|
||||
ZeroMemory(&sa, sizeof(sa)); |
|
||||
sa.nLength = sizeof(sa); |
|
||||
sa.lpSecurityDescriptor = NULL; |
|
||||
sa.bInheritHandle = FALSE; |
|
||||
|
|
||||
# if defined(BOOST_PROCESS_WINDOWS_USE_NAMED_PIPE) |
|
||||
static unsigned int nextid = 0; |
|
||||
std::string pipe = "\\\\.\\pipe\\boost_process_" + boost::lexical_cast<std::string>(::GetCurrentProcessId()) + "_" + boost::lexical_cast<std::string>(nextid++); |
|
||||
hs[0] = ::CreateNamedPipeA(pipe.c_str(), PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, 0, 1, 8192, 8192, 0, &sa); |
|
||||
if (hs[0] == INVALID_HANDLE_VALUE) |
|
||||
boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category(), "boost::process::detail::pipe::pipe: CreateNamedPipe failed")); |
|
||||
hs[1] = ::CreateFileA(pipe.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); |
|
||||
if (hs[1] == INVALID_HANDLE_VALUE) |
|
||||
boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category(), "boost::process::detail::pipe::pipe: CreateFile failed")); |
|
||||
|
|
||||
OVERLAPPED overlapped; |
|
||||
ZeroMemory(&overlapped, sizeof(overlapped)); |
|
||||
overlapped.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); |
|
||||
if (!overlapped.hEvent) |
|
||||
boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category(), "boost::process::detail::pipe::pipe: CreateEvent failed")); |
|
||||
BOOL b = ::ConnectNamedPipe(hs[0], &overlapped); |
|
||||
if (!b) |
|
||||
{ |
|
||||
if (::GetLastError() == ERROR_IO_PENDING) |
|
||||
{ |
|
||||
if (::WaitForSingleObject(overlapped.hEvent, INFINITE) == WAIT_FAILED) |
|
||||
{ |
|
||||
::CloseHandle(overlapped.hEvent); |
|
||||
boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category(), "boost::process::detail::pipe::pipe: WaitForSingleObject failed")); |
|
||||
} |
|
||||
} |
|
||||
else if (::GetLastError() != ERROR_PIPE_CONNECTED) |
|
||||
{ |
|
||||
::CloseHandle(overlapped.hEvent); |
|
||||
boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category(), "boost::process::detail::pipe::pipe: ConnectNamedPipe failed")); |
|
||||
} |
|
||||
} |
|
||||
::CloseHandle(overlapped.hEvent); |
|
||||
# else |
|
||||
if (!::CreatePipe(&hs[0], &hs[1], &sa, 0)) |
|
||||
boost::throw_exception(boost::system::system_error(::GetLastError(), boost::system::system_category(), "boost::process::detail::pipe::pipe: CreatePipe failed")); |
|
||||
# endif |
|
||||
#endif |
|
||||
|
|
||||
read_end_ = file_handle(hs[0]); |
|
||||
write_end_ = file_handle(hs[1]); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Returns the %pipe's read end file handle. |
|
||||
* |
|
||||
* Obtains a reference to the %pipe's read end file handle. Care |
|
||||
* should be taken to not duplicate the returned object if ownership |
|
||||
* shall remain to the %pipe. |
|
||||
* |
|
||||
* Duplicating the returned object invalidates its corresponding file |
|
||||
* handle in the %pipe. |
|
||||
* |
|
||||
* \return A reference to the %pipe's read end file handle. |
|
||||
*/ |
|
||||
file_handle &rend() |
|
||||
{ |
|
||||
return read_end_; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Returns the %pipe's write end file handle. |
|
||||
* |
|
||||
* Obtains a reference to the %pipe's write end file handle. Care |
|
||||
* should be taken to not duplicate the returned object if ownership |
|
||||
* shall remain to the %pipe. |
|
||||
* |
|
||||
* Duplicating the returned object invalidates its corresponding file |
|
||||
* handle in the %pipe. |
|
||||
* |
|
||||
* \return A reference to the %pipe's write end file handle. |
|
||||
*/ |
|
||||
file_handle &wend() |
|
||||
{ |
|
||||
return write_end_; |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
/**
|
|
||||
* The %pipe's read end file handle. |
|
||||
*/ |
|
||||
file_handle read_end_; |
|
||||
|
|
||||
/**
|
|
||||
* The %pipe's write end file handle. |
|
||||
*/ |
|
||||
file_handle write_end_; |
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,495 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/detail/posix_ops.hpp |
|
||||
* |
|
||||
* Provides some convenience functions to start processes under POSIX |
|
||||
* operating systems. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_DETAIL_POSIX_OPS_HPP |
|
||||
#define BOOST_PROCESS_DETAIL_POSIX_OPS_HPP |
|
||||
|
|
||||
#include <boost/process/environment.hpp> |
|
||||
#include <boost/process/detail/file_handle.hpp> |
|
||||
#include <boost/process/detail/pipe.hpp> |
|
||||
#include <boost/process/detail/stream_info.hpp> |
|
||||
#include <boost/scoped_array.hpp> |
|
||||
#include <boost/assert.hpp> |
|
||||
#include <boost/system/system_error.hpp> |
|
||||
#include <boost/throw_exception.hpp> |
|
||||
#include <map> |
|
||||
#include <utility> |
|
||||
#include <string> |
|
||||
#include <cerrno> |
|
||||
#include <cstdlib> |
|
||||
#include <cstring> |
|
||||
#include <fcntl.h> |
|
||||
#include <unistd.h> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
namespace detail { |
|
||||
|
|
||||
/**
|
|
||||
* Converts the command line to an array of C strings. |
|
||||
* |
|
||||
* Converts the command line's list of arguments to the format expected |
|
||||
* by the \a argv parameter in the POSIX execve() system call. |
|
||||
* |
|
||||
* This operation is only available on POSIX systems. |
|
||||
* |
|
||||
* \return The first argument of the pair is an integer that indicates |
|
||||
* how many strings are stored in the second argument. The |
|
||||
* second argument is a NULL-terminated, dynamically allocated |
|
||||
* array of dynamically allocated strings holding the arguments |
|
||||
* to the executable. The caller is responsible of freeing them. |
|
||||
*/ |
|
||||
template <class Arguments> |
|
||||
inline std::pair<std::size_t, char**> collection_to_posix_argv(const Arguments &args) |
|
||||
{ |
|
||||
std::size_t nargs = args.size(); |
|
||||
BOOST_ASSERT(nargs > 0); |
|
||||
|
|
||||
char **argv = new char*[nargs + 1]; |
|
||||
typename Arguments::size_type i = 0; |
|
||||
for (typename Arguments::const_iterator it = args.begin(); it != args.end(); ++it) |
|
||||
{ |
|
||||
argv[i] = new char[it->size() + 1]; |
|
||||
std::strncpy(argv[i], it->c_str(), it->size() + 1); |
|
||||
++i; |
|
||||
} |
|
||||
argv[nargs] = 0; |
|
||||
|
|
||||
return std::pair<std::size_t, char**>(nargs, argv); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Converts an environment to a char** table as used by execve(). |
|
||||
* |
|
||||
* Converts the environment's contents to the format used by the |
|
||||
* execve() system call. The returned char** array is allocated |
|
||||
* in dynamic memory; the caller must free it when not used any |
|
||||
* more. Each entry is also allocated in dynamic memory and is a |
|
||||
* NULL-terminated string of the form var=value; these must also be |
|
||||
* released by the caller. |
|
||||
* |
|
||||
* \return A dynamically allocated char** array that represents |
|
||||
* the environment's content. Each array entry is a |
|
||||
* NULL-terminated string of the form var=value. |
|
||||
*/ |
|
||||
inline char **environment_to_envp(const environment &env) |
|
||||
{ |
|
||||
char **envp = new char*[env.size() + 1]; |
|
||||
|
|
||||
environment::size_type i = 0; |
|
||||
for (environment::const_iterator it = env.begin(); it != env.end(); ++it) |
|
||||
{ |
|
||||
std::string s = it->first + "=" + it->second; |
|
||||
envp[i] = new char[s.size() + 1]; |
|
||||
std::strncpy(envp[i], s.c_str(), s.size() + 1); |
|
||||
++i; |
|
||||
} |
|
||||
envp[i] = 0; |
|
||||
|
|
||||
return envp; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Holds a mapping between native file descriptors and their corresponding |
|
||||
* pipes to set up communication between the parent and the %child process. |
|
||||
*/ |
|
||||
typedef std::map<int, stream_info> info_map; |
|
||||
|
|
||||
/**
|
|
||||
* Helper class to configure a POSIX %child. |
|
||||
* |
|
||||
* This helper class is used to hold all the attributes that configure a |
|
||||
* new POSIX %child process and to centralize all the actions needed to |
|
||||
* make them effective. |
|
||||
* |
|
||||
* All its fields are public for simplicity. It is only intended for |
|
||||
* internal use and it is heavily coupled with the Context |
|
||||
* implementations. |
|
||||
*/ |
|
||||
struct posix_setup |
|
||||
{ |
|
||||
/**
|
|
||||
* The work directory. |
|
||||
* |
|
||||
* This string specifies the directory in which the %child process |
|
||||
* starts execution. It cannot be empty. |
|
||||
*/ |
|
||||
std::string work_directory; |
|
||||
|
|
||||
/**
|
|
||||
* The chroot directory, if any. |
|
||||
* |
|
||||
* Specifies the directory in which the %child process is chrooted |
|
||||
* before execution. Empty if this feature is not desired. |
|
||||
*/ |
|
||||
std::string chroot; |
|
||||
|
|
||||
/**
|
|
||||
* The user credentials. |
|
||||
* |
|
||||
* UID that specifies the user credentials to use to run the %child |
|
||||
* process. Defaults to the current UID. |
|
||||
*/ |
|
||||
uid_t uid; |
|
||||
|
|
||||
/**
|
|
||||
* The effective user credentials. |
|
||||
* |
|
||||
* EUID that specifies the effective user credentials to use to run |
|
||||
* the %child process. Defaults to the current EUID. |
|
||||
*/ |
|
||||
uid_t euid; |
|
||||
|
|
||||
/**
|
|
||||
* The group credentials. |
|
||||
* |
|
||||
* GID that specifies the group credentials to use to run the %child |
|
||||
* process. Defaults to the current GID. |
|
||||
*/ |
|
||||
gid_t gid; |
|
||||
|
|
||||
/**
|
|
||||
* The effective group credentials. |
|
||||
* |
|
||||
* EGID that specifies the effective group credentials to use to run |
|
||||
* the %child process. Defaults to the current EGID. |
|
||||
*/ |
|
||||
gid_t egid; |
|
||||
|
|
||||
/**
|
|
||||
* Creates a new properties set. |
|
||||
* |
|
||||
* Creates a new object that has sensible default values for all the |
|
||||
* properties. |
|
||||
*/ |
|
||||
posix_setup() |
|
||||
: uid(::getuid()), |
|
||||
euid(::geteuid()), |
|
||||
gid(::getgid()), |
|
||||
egid(::getegid()) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Sets up the execution environment. |
|
||||
* |
|
||||
* Modifies the current execution environment (that of the %child) so |
|
||||
* that the properties become effective. |
|
||||
* |
|
||||
* \throw boost::system::system_error If any error ocurred during |
|
||||
* environment configuration. The child process should abort |
|
||||
* execution if this happens because its start conditions |
|
||||
* cannot be met. |
|
||||
*/ |
|
||||
void operator()() const |
|
||||
{ |
|
||||
if (!chroot.empty() && ::chroot(chroot.c_str()) == -1) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: chroot(2) failed")); |
|
||||
|
|
||||
if (gid != ::getgid() && ::setgid(gid) == -1) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: setgid(2) failed")); |
|
||||
|
|
||||
if (egid != ::getegid() && ::setegid(egid) == -1) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: setegid(2) failed")); |
|
||||
|
|
||||
if (uid != ::getuid() && ::setuid(uid) == -1) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: setuid(2) failed")); |
|
||||
|
|
||||
if (euid != ::geteuid() && ::seteuid(euid) == -1) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: seteuid(2) failed")); |
|
||||
|
|
||||
BOOST_ASSERT(!work_directory.empty()); |
|
||||
if (::chdir(work_directory.c_str()) == -1) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_setup: chdir(2) failed")); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
/**
|
|
||||
* Configures child process' input streams. |
|
||||
* |
|
||||
* Sets up the current process' input streams to behave according to the |
|
||||
* information in the \a info map. \a closeflags is modified to reflect |
|
||||
* those descriptors that should not be closed because they where modified |
|
||||
* by the function. |
|
||||
* |
|
||||
* Modifies the current execution environment, so this should only be run |
|
||||
* on the child process after the fork(2) has happened. |
|
||||
* |
|
||||
* \throw boost::system::system_error If any error occurs during the |
|
||||
* configuration. |
|
||||
*/ |
|
||||
inline void setup_input(info_map &info, bool *closeflags, int maxdescs) |
|
||||
{ |
|
||||
for (info_map::iterator it = info.begin(); it != info.end(); ++it) |
|
||||
{ |
|
||||
int d = it->first; |
|
||||
stream_info &si = it->second; |
|
||||
|
|
||||
BOOST_ASSERT(d < maxdescs); |
|
||||
closeflags[d] = false; |
|
||||
|
|
||||
switch (si.type_) |
|
||||
{ |
|
||||
case stream_info::use_file: |
|
||||
{ |
|
||||
int fd = ::open(si.file_.c_str(), O_RDONLY); |
|
||||
if (fd == -1) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::setup_input: open(2) of " + si.file_ + " failed")); |
|
||||
if (fd != d) |
|
||||
{ |
|
||||
file_handle h(fd); |
|
||||
h.posix_remap(d); |
|
||||
h.release(); |
|
||||
} |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::use_handle: |
|
||||
{ |
|
||||
if (si.handle_.get() != d) |
|
||||
si.handle_.posix_remap(d); |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::use_pipe: |
|
||||
{ |
|
||||
si.pipe_->wend().close(); |
|
||||
if (d != si.pipe_->rend().get()) |
|
||||
si.pipe_->rend().posix_remap(d); |
|
||||
break; |
|
||||
} |
|
||||
default: |
|
||||
{ |
|
||||
BOOST_ASSERT(si.type_ == stream_info::inherit); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Configures child process' output streams. |
|
||||
* |
|
||||
* Sets up the current process' output streams to behave according to the |
|
||||
* information in the \a info map. \a closeflags is modified to reflect |
|
||||
* those descriptors that should not be closed because they where |
|
||||
* modified by the function. |
|
||||
* |
|
||||
* Modifies the current execution environment, so this should only be run |
|
||||
* on the child process after the fork(2) has happened. |
|
||||
* |
|
||||
* \throw boost::system::system_error If any error occurs during the |
|
||||
* configuration. |
|
||||
*/ |
|
||||
inline void setup_output(info_map &info, bool *closeflags, int maxdescs) |
|
||||
{ |
|
||||
for (info_map::iterator it = info.begin(); it != info.end(); ++it) |
|
||||
{ |
|
||||
int d = it->first; |
|
||||
stream_info &si = it->second; |
|
||||
|
|
||||
BOOST_ASSERT(d < maxdescs); |
|
||||
closeflags[d] = false; |
|
||||
|
|
||||
switch (si.type_) |
|
||||
{ |
|
||||
case stream_info::redirect: |
|
||||
{ |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::use_file: |
|
||||
{ |
|
||||
int fd = ::open(si.file_.c_str(), O_WRONLY); |
|
||||
if (fd == -1) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::setup_output: open(2) of " + si.file_ + " failed")); |
|
||||
if (fd != d) |
|
||||
{ |
|
||||
file_handle h(fd); |
|
||||
h.posix_remap(d); |
|
||||
h.release(); |
|
||||
} |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::use_handle: |
|
||||
{ |
|
||||
if (si.handle_.get() != d) |
|
||||
si.handle_.posix_remap(d); |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::use_pipe: |
|
||||
{ |
|
||||
si.pipe_->rend().close(); |
|
||||
if (d != si.pipe_->wend().get()) |
|
||||
si.pipe_->wend().posix_remap(d); |
|
||||
break; |
|
||||
} |
|
||||
default: |
|
||||
{ |
|
||||
BOOST_ASSERT(si.type_ == stream_info::inherit); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
for (info_map::const_iterator it = info.begin(); it != info.end(); ++it) |
|
||||
{ |
|
||||
int d = it->first; |
|
||||
const stream_info &si = it->second; |
|
||||
|
|
||||
if (si.type_ == stream_info::redirect) |
|
||||
file_handle::posix_dup(si.desc_to_, d).release(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Starts a new child process in a POSIX operating system. |
|
||||
* |
|
||||
* This helper functions is provided to simplify the Context's task when |
|
||||
* it comes to starting up a new process in a POSIX operating system. |
|
||||
* The function hides all the details of the fork/exec pair of calls as |
|
||||
* well as all the setup of communication pipes and execution environment. |
|
||||
* |
|
||||
* \param exe The executable to spawn the child process. |
|
||||
* \param args The arguments for the executable. |
|
||||
* \param env The environment variables that the new child process |
|
||||
* receives. |
|
||||
* \param infoin A map describing all input file descriptors to be |
|
||||
* redirected. |
|
||||
* \param infoout A map describing all output file descriptors to be |
|
||||
* redirected. |
|
||||
* \param setup A helper object used to configure the child's execution |
|
||||
* environment. |
|
||||
* \return The new process' PID. The caller is responsible of creating |
|
||||
* an appropriate Child representation for it. |
|
||||
*/ |
|
||||
template <class Executable, class Arguments> |
|
||||
inline pid_t posix_start(const Executable &exe, const Arguments &args, const environment &env, info_map &infoin, info_map &infoout, const posix_setup &setup) |
|
||||
{ |
|
||||
pid_t pid = ::fork(); |
|
||||
if (pid == -1) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_start: fork(2) failed")); |
|
||||
else if (pid == 0) |
|
||||
{ |
|
||||
#if defined(F_MAXFD) |
|
||||
int maxdescs = ::fcntl(-1, F_MAXFD, 0); |
|
||||
if (maxdescs == -1) |
|
||||
maxdescs = ::sysconf(_SC_OPEN_MAX); |
|
||||
#else |
|
||||
int maxdescs = ::sysconf(_SC_OPEN_MAX); |
|
||||
#endif |
|
||||
if (maxdescs == -1) |
|
||||
maxdescs = 1024; |
|
||||
try |
|
||||
{ |
|
||||
boost::scoped_array<bool> closeflags(new bool[maxdescs]); |
|
||||
for (int i = 0; i < maxdescs; ++i) |
|
||||
closeflags[i] = true; |
|
||||
|
|
||||
setup_input(infoin, closeflags.get(), maxdescs); |
|
||||
setup_output(infoout, closeflags.get(), maxdescs); |
|
||||
|
|
||||
for (int i = 0; i < maxdescs; ++i) |
|
||||
{ |
|
||||
if (closeflags[i]) |
|
||||
::close(i); |
|
||||
} |
|
||||
|
|
||||
setup(); |
|
||||
} |
|
||||
catch (const boost::system::system_error &e) |
|
||||
{ |
|
||||
::write(STDERR_FILENO, e.what(), std::strlen(e.what())); |
|
||||
::write(STDERR_FILENO, "\n", 1); |
|
||||
std::exit(EXIT_FAILURE); |
|
||||
} |
|
||||
|
|
||||
std::pair<std::size_t, char**> argcv = collection_to_posix_argv(args); |
|
||||
char **envp = environment_to_envp(env); |
|
||||
|
|
||||
::execve(exe.c_str(), argcv.second, envp); |
|
||||
boost::system::system_error e(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::detail::posix_start: execve(2) failed"); |
|
||||
|
|
||||
for (std::size_t i = 0; i < argcv.first; ++i) |
|
||||
delete[] argcv.second[i]; |
|
||||
delete[] argcv.second; |
|
||||
|
|
||||
for (std::size_t i = 0; i < env.size(); ++i) |
|
||||
delete[] envp[i]; |
|
||||
delete[] envp; |
|
||||
|
|
||||
::write(STDERR_FILENO, e.what(), std::strlen(e.what())); |
|
||||
::write(STDERR_FILENO, "\n", 1); |
|
||||
std::exit(EXIT_FAILURE); |
|
||||
} |
|
||||
|
|
||||
BOOST_ASSERT(pid > 0); |
|
||||
|
|
||||
for (info_map::iterator it = infoin.begin(); it != infoin.end(); ++it) |
|
||||
{ |
|
||||
stream_info &si = it->second; |
|
||||
if (si.type_ == stream_info::use_pipe) |
|
||||
si.pipe_->rend().close(); |
|
||||
} |
|
||||
|
|
||||
for (info_map::iterator it = infoout.begin(); it != infoout.end(); ++it) |
|
||||
{ |
|
||||
stream_info &si = it->second; |
|
||||
if (si.type_ == stream_info::use_pipe) |
|
||||
si.pipe_->wend().close(); |
|
||||
} |
|
||||
|
|
||||
return pid; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Locates a communication pipe and returns one of its endpoints. |
|
||||
* |
|
||||
* Given a \a info map, and a file descriptor \a desc, searches for its |
|
||||
* communicataion pipe in the map and returns one of its endpoints as |
|
||||
* indicated by the \a out flag. This is intended to be used by a |
|
||||
* parent process after a fork(2) call. |
|
||||
* |
|
||||
* \pre If the info map contains the given descriptor, it is configured |
|
||||
* to use a pipe. |
|
||||
* \post The info map does not contain the given descriptor. |
|
||||
* \return If the file descriptor is found in the map, returns the pipe's |
|
||||
* read end if out is true; otherwise its write end. If the |
|
||||
* descriptor is not found returns an invalid file handle. |
|
||||
*/ |
|
||||
inline file_handle posix_info_locate_pipe(info_map &info, int desc, bool out) |
|
||||
{ |
|
||||
file_handle fh; |
|
||||
|
|
||||
info_map::iterator it = info.find(desc); |
|
||||
if (it != info.end()) |
|
||||
{ |
|
||||
stream_info &si = it->second; |
|
||||
if (si.type_ == stream_info::use_pipe) |
|
||||
{ |
|
||||
fh = out ? si.pipe_->rend().release() : si.pipe_->wend().release(); |
|
||||
BOOST_ASSERT(fh.valid()); |
|
||||
} |
|
||||
info.erase(it); |
|
||||
} |
|
||||
|
|
||||
return fh; |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,176 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/detail/stream_info.hpp |
|
||||
* |
|
||||
* Provides the definition of the stream_info structure. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_DETAIL_STREAM_INFO_HPP |
|
||||
#define BOOST_PROCESS_DETAIL_STREAM_INFO_HPP |
|
||||
|
|
||||
#include <boost/process/config.hpp> |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
# include <unistd.h> |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
#else |
|
||||
# error "Unsupported platform." |
|
||||
#endif |
|
||||
|
|
||||
#include <boost/process/stream_behavior.hpp> |
|
||||
#include <boost/process/detail/file_handle.hpp> |
|
||||
#include <boost/process/detail/pipe.hpp> |
|
||||
#include <boost/optional.hpp> |
|
||||
#include <boost/assert.hpp> |
|
||||
#include <string> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
namespace detail { |
|
||||
|
|
||||
/**
|
|
||||
* Configuration data for a file descriptor. |
|
||||
* |
|
||||
* This convenience structure provides a compact way to pass information |
|
||||
* around on how to configure a file descriptor. It is a lower-level |
|
||||
* representation of stream_behavior, as it can hold the same information |
|
||||
* but in a way that can be used by the underlying operating system. |
|
||||
*/ |
|
||||
struct stream_info |
|
||||
{ |
|
||||
/**
|
|
||||
* Supported stream types. |
|
||||
*/ |
|
||||
enum type |
|
||||
{ |
|
||||
/**
|
|
||||
* Matches stream_behavior::close. |
|
||||
*/ |
|
||||
close, |
|
||||
|
|
||||
/**
|
|
||||
* Matches stream_behavior::inherit. |
|
||||
*/ |
|
||||
inherit, |
|
||||
|
|
||||
/**
|
|
||||
* Matches stream_behavior::redirect_to_stdout and |
|
||||
* stream_behavior::posix_redirect. |
|
||||
*/ |
|
||||
redirect, |
|
||||
|
|
||||
/**
|
|
||||
* Matches stream_behavior::silence. |
|
||||
*/ |
|
||||
use_file, |
|
||||
|
|
||||
/**
|
|
||||
* TODO: Matches nothing yet ... |
|
||||
*/ |
|
||||
use_handle, |
|
||||
|
|
||||
/**
|
|
||||
* Matches stream_behavior::capture. |
|
||||
*/ |
|
||||
use_pipe |
|
||||
}; |
|
||||
|
|
||||
/**
|
|
||||
* Stream type. |
|
||||
*/ |
|
||||
type type_; |
|
||||
|
|
||||
/**
|
|
||||
* Descriptor to use when stream type is set to \a redirect. |
|
||||
*/ |
|
||||
int desc_to_; |
|
||||
|
|
||||
/**
|
|
||||
* File to use when stream type is set to \a use_file. |
|
||||
*/ |
|
||||
std::string file_; |
|
||||
|
|
||||
/**
|
|
||||
* Handle to use when stream type is set to \a use_handle. |
|
||||
*/ |
|
||||
file_handle handle_; |
|
||||
|
|
||||
/**
|
|
||||
* Pipe to use when stream type is set to \a use_pipe. |
|
||||
*/ |
|
||||
boost::optional<pipe> pipe_; |
|
||||
|
|
||||
/**
|
|
||||
* Constructs a new stream_info object. |
|
||||
*/ |
|
||||
stream_info(const stream_behavior &sb, bool out) |
|
||||
{ |
|
||||
switch (sb.type_) |
|
||||
{ |
|
||||
case stream_behavior::close: |
|
||||
{ |
|
||||
type_ = close; |
|
||||
break; |
|
||||
} |
|
||||
case stream_behavior::inherit: |
|
||||
{ |
|
||||
type_ = inherit; |
|
||||
break; |
|
||||
} |
|
||||
case stream_behavior::redirect_to_stdout: |
|
||||
{ |
|
||||
type_ = redirect; |
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
desc_to_ = STDOUT_FILENO; |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
desc_to_ = 1; |
|
||||
#endif |
|
||||
break; |
|
||||
} |
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
case stream_behavior::posix_redirect: |
|
||||
{ |
|
||||
type_ = redirect; |
|
||||
desc_to_ = sb.desc_to_; |
|
||||
break; |
|
||||
} |
|
||||
#endif |
|
||||
case stream_behavior::silence: |
|
||||
{ |
|
||||
type_ = use_file; |
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
file_ = out ? "/dev/null" : "/dev/zero"; |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
file_ = "NUL"; |
|
||||
#endif |
|
||||
break; |
|
||||
} |
|
||||
case stream_behavior::capture: |
|
||||
{ |
|
||||
type_ = use_pipe; |
|
||||
pipe_ = pipe(); |
|
||||
break; |
|
||||
} |
|
||||
default: |
|
||||
{ |
|
||||
BOOST_ASSERT(false); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,231 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/detail/systembuf.hpp |
|
||||
* |
|
||||
* Includes the declaration of the systembuf class. This file is for |
|
||||
* internal usage only and must not be included by the library user. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_DETAIL_SYSTEMBUF_HPP |
|
||||
#define BOOST_PROCESS_DETAIL_SYSTEMBUF_HPP |
|
||||
|
|
||||
#include <boost/process/config.hpp> |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
# include <sys/types.h> |
|
||||
# include <unistd.h> |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
# include <windows.h> |
|
||||
#else |
|
||||
# error "Unsupported platform." |
|
||||
#endif |
|
||||
|
|
||||
#include <boost/noncopyable.hpp> |
|
||||
#include <boost/scoped_array.hpp> |
|
||||
#include <boost/assert.hpp> |
|
||||
#include <streambuf> |
|
||||
#include <cstddef> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
class postream; |
|
||||
|
|
||||
namespace detail { |
|
||||
|
|
||||
/**
|
|
||||
* std::streambuf implementation for system file handles. |
|
||||
* |
|
||||
* systembuf provides a std::streambuf implementation for system file |
|
||||
* handles. Contrarywise to file_handle, this class does \b not take |
|
||||
* ownership of the native file handle; this should be taken care of |
|
||||
* somewhere else. |
|
||||
* |
|
||||
* This class follows the expected semantics of a std::streambuf object. |
|
||||
* However, it is not copyable to avoid introducing inconsistences with |
|
||||
* the on-disk file and the in-memory buffers. |
|
||||
*/ |
|
||||
class systembuf : public std::streambuf, public boost::noncopyable |
|
||||
{ |
|
||||
friend class ::boost::process::postream; |
|
||||
|
|
||||
public: |
|
||||
#if defined(BOOST_PROCESS_DOXYGEN) |
|
||||
/**
|
|
||||
* Opaque name for the native handle type. |
|
||||
*/ |
|
||||
typedef NativeHandleType handle_type; |
|
||||
#elif defined(BOOST_POSIX_API) |
|
||||
typedef int handle_type; |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
typedef HANDLE handle_type; |
|
||||
#endif |
|
||||
|
|
||||
/**
|
|
||||
* Constructs a new systembuf for the given file handle. |
|
||||
* |
|
||||
* This constructor creates a new systembuf object that reads or |
|
||||
* writes data from/to the \a h native file handle. This handle |
|
||||
* is \b not owned by the created systembuf object; the code |
|
||||
* should take care of it externally. |
|
||||
* |
|
||||
* This class buffers input and output; the buffer size may be |
|
||||
* tuned through the \a bufsize parameter, which defaults to 8192 |
|
||||
* bytes. |
|
||||
* |
|
||||
* \see pistream and postream |
|
||||
*/ |
|
||||
explicit systembuf(handle_type h, std::size_t bufsize = 8192) |
|
||||
: handle_(h), |
|
||||
bufsize_(bufsize), |
|
||||
read_buf_(new char[bufsize]), |
|
||||
write_buf_(new char[bufsize]) |
|
||||
{ |
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
BOOST_ASSERT(handle_ >= 0); |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
BOOST_ASSERT(handle_ != INVALID_HANDLE_VALUE); |
|
||||
#endif |
|
||||
BOOST_ASSERT(bufsize_ > 0); |
|
||||
|
|
||||
setp(write_buf_.get(), write_buf_.get() + bufsize_); |
|
||||
} |
|
||||
|
|
||||
protected: |
|
||||
/**
|
|
||||
* Reads new data from the native file handle. |
|
||||
* |
|
||||
* This operation is called by input methods when there is no more |
|
||||
* data in the input buffer. The function fills the buffer with new |
|
||||
* data, if available. |
|
||||
* |
|
||||
* \pre All input positions are exhausted (gptr() >= egptr()). |
|
||||
* \post The input buffer has new data, if available. |
|
||||
* \returns traits_type::eof() if a read error occurrs or there are |
|
||||
* no more data to be read. Otherwise returns |
|
||||
* traits_type::to_int_type(*gptr()). |
|
||||
*/ |
|
||||
virtual int_type underflow() |
|
||||
{ |
|
||||
BOOST_ASSERT(gptr() >= egptr()); |
|
||||
|
|
||||
bool ok; |
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
ssize_t cnt = ::read(handle_, read_buf_.get(), bufsize_); |
|
||||
ok = (cnt != -1 && cnt != 0); |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
DWORD cnt; |
|
||||
BOOL res = ::ReadFile(handle_, read_buf_.get(), bufsize_, &cnt, NULL); |
|
||||
ok = (res && cnt > 0); |
|
||||
#endif |
|
||||
|
|
||||
if (!ok) |
|
||||
return traits_type::eof(); |
|
||||
else |
|
||||
{ |
|
||||
setg(read_buf_.get(), read_buf_.get(), read_buf_.get() + cnt); |
|
||||
return traits_type::to_int_type(*gptr()); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Makes room in the write buffer for additional data. |
|
||||
* |
|
||||
* This operation is called by output methods when there is no more |
|
||||
* space in the output buffer to hold a new element. The function |
|
||||
* first flushes the buffer's contents to disk and then clears it to |
|
||||
* leave room for more characters. The given \a c character is |
|
||||
* stored at the beginning of the new space. |
|
||||
* |
|
||||
* \pre All output positions are exhausted (pptr() >= epptr()). |
|
||||
* \post The output buffer has more space if no errors occurred |
|
||||
* during the write to disk. |
|
||||
* \post *(pptr() - 1) is \a c. |
|
||||
* \returns traits_type::eof() if a write error occurrs. Otherwise |
|
||||
* returns traits_type::not_eof(c). |
|
||||
*/ |
|
||||
virtual int_type overflow(int c) |
|
||||
{ |
|
||||
BOOST_ASSERT(pptr() >= epptr()); |
|
||||
|
|
||||
if (sync() == -1) |
|
||||
return traits_type::eof(); |
|
||||
|
|
||||
if (!traits_type::eq_int_type(c, traits_type::eof())) |
|
||||
{ |
|
||||
traits_type::assign(*pptr(), c); |
|
||||
pbump(1); |
|
||||
} |
|
||||
|
|
||||
return traits_type::not_eof(c); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Flushes the output buffer to disk. |
|
||||
* |
|
||||
* Synchronizes the systembuf buffers with the contents of the file |
|
||||
* associated to this object through the native file handle. The |
|
||||
* output buffer is flushed to disk and cleared to leave new room |
|
||||
* for more data. |
|
||||
* |
|
||||
* \returns 0 on success, -1 if an error occurred. |
|
||||
*/ |
|
||||
virtual int sync() |
|
||||
{ |
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
ssize_t cnt = pptr() - pbase(); |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
long cnt = pptr() - pbase(); |
|
||||
#endif |
|
||||
|
|
||||
bool ok; |
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
ok = ::write(handle_, pbase(), cnt) == cnt; |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
DWORD rcnt; |
|
||||
BOOL res = ::WriteFile(handle_, pbase(), cnt, &rcnt, NULL); |
|
||||
ok = (res && static_cast<long>(rcnt) == cnt); |
|
||||
#endif |
|
||||
|
|
||||
if (ok) |
|
||||
pbump(-cnt); |
|
||||
return ok ? 0 : -1; |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
/**
|
|
||||
* Native file handle used by the systembuf object. |
|
||||
*/ |
|
||||
handle_type handle_; |
|
||||
|
|
||||
/**
|
|
||||
* Internal buffer size used during read and write operations. |
|
||||
*/ |
|
||||
std::size_t bufsize_; |
|
||||
|
|
||||
/**
|
|
||||
* Internal buffer used during read operations. |
|
||||
*/ |
|
||||
boost::scoped_array<char> read_buf_; |
|
||||
|
|
||||
/**
|
|
||||
* Internal buffer used during write operations. |
|
||||
*/ |
|
||||
boost::scoped_array<char> write_buf_; |
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,355 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/detail/win32_ops.hpp |
|
||||
* |
|
||||
* Provides some convenience functions to start processes under |
|
||||
* Windows-compatible operating systems. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_DETAIL_WIN32_OPS_HPP |
|
||||
#define BOOST_PROCESS_DETAIL_WIN32_OPS_HPP |
|
||||
|
|
||||
#include <boost/process/environment.hpp> |
|
||||
#include <boost/process/detail/file_handle.hpp> |
|
||||
#include <boost/process/detail/pipe.hpp> |
|
||||
#include <boost/process/detail/stream_info.hpp> |
|
||||
#include <boost/scoped_ptr.hpp> |
|
||||
#include <boost/shared_array.hpp> |
|
||||
#include <boost/scoped_array.hpp> |
|
||||
#include <boost/assert.hpp> |
|
||||
#include <boost/system/system_error.hpp> |
|
||||
#include <boost/throw_exception.hpp> |
|
||||
#include <vector> |
|
||||
#include <string> |
|
||||
#include <cstddef> |
|
||||
#include <string.h> |
|
||||
#include <windows.h> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
namespace detail { |
|
||||
|
|
||||
/**
|
|
||||
* Converts the command line to a plain string. Converts the command line's |
|
||||
* list of arguments to the format expected by the \a lpCommandLine parameter |
|
||||
* in the CreateProcess() system call. |
|
||||
* |
|
||||
* This operation is only available on Windows systems. |
|
||||
* |
|
||||
* \return A dynamically allocated string holding the command line |
|
||||
* to be passed to the executable. It is returned in a |
|
||||
* shared_array object to ensure its release at some point. |
|
||||
*/ |
|
||||
template <class Arguments> |
|
||||
inline boost::shared_array<char> collection_to_win32_cmdline(const Arguments &args) |
|
||||
{ |
|
||||
typedef std::vector<std::string> arguments_t; |
|
||||
arguments_t args2; |
|
||||
typename Arguments::size_type i = 0; |
|
||||
std::size_t size = 0; |
|
||||
for (typename Arguments::const_iterator it = args.begin(); it != args.end(); ++it) |
|
||||
{ |
|
||||
std::string arg = *it; |
|
||||
|
|
||||
std::string::size_type pos = 0; |
|
||||
while ( (pos = arg.find('"', pos)) != std::string::npos) |
|
||||
{ |
|
||||
arg.replace(pos, 1, "\\\""); |
|
||||
pos += 2; |
|
||||
} |
|
||||
|
|
||||
if (arg.find(' ') != std::string::npos) |
|
||||
arg = '\"' + arg + '\"'; |
|
||||
|
|
||||
if (i++ != args.size() - 1) |
|
||||
arg += ' '; |
|
||||
|
|
||||
args2.push_back(arg); |
|
||||
size += arg.size() + 1; |
|
||||
} |
|
||||
|
|
||||
boost::shared_array<char> cmdline(new char[size]); |
|
||||
cmdline.get()[0] = '\0'; |
|
||||
for (arguments_t::size_type i = 0; i < args.size(); ++i) |
|
||||
#if defined(__CYGWIN__) |
|
||||
::strncat(cmdline.get(), args2[i].c_str(), args2[i].size()); |
|
||||
#else |
|
||||
::strcat_s(cmdline.get(), size, args2[i].c_str()); |
|
||||
#endif |
|
||||
|
|
||||
return cmdline; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Converts an environment to a string used by CreateProcess(). |
|
||||
* |
|
||||
* Converts the environment's contents to the format used by the |
|
||||
* CreateProcess() system call. The returned char* string is |
|
||||
* allocated in dynamic memory; the caller must free it when not |
|
||||
* used any more. This is enforced by the use of a shared pointer. |
|
||||
* |
|
||||
* \return A dynamically allocated char* string that represents |
|
||||
* the environment's content. This string is of the form |
|
||||
* var1=value1\\0var2=value2\\0\\0. |
|
||||
*/ |
|
||||
inline boost::shared_array<char> environment_to_win32_strings(const environment &env) |
|
||||
{ |
|
||||
boost::shared_array<char> envp; |
|
||||
|
|
||||
if (env.empty()) |
|
||||
{ |
|
||||
envp.reset(new char[2]); |
|
||||
::ZeroMemory(envp.get(), 2); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
std::string s; |
|
||||
for (environment::const_iterator it = env.begin(); it != env.end(); ++it) |
|
||||
{ |
|
||||
s += it->first + "=" + it->second; |
|
||||
s.push_back(0); |
|
||||
} |
|
||||
|
|
||||
envp.reset(new char[s.size() + 1]); |
|
||||
#if defined(__CYGWIN__) |
|
||||
::memcpy(envp.get(), s.c_str(), s.size() + 1); |
|
||||
#else |
|
||||
::memcpy_s(envp.get(), s.size() + 1, s.c_str(), s.size() + 1); |
|
||||
#endif |
|
||||
} |
|
||||
|
|
||||
return envp; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Helper class to configure a Win32 %child. |
|
||||
* |
|
||||
* This helper class is used to hold all the attributes that configure a |
|
||||
* new Win32 %child process. |
|
||||
* |
|
||||
* All its fields are public for simplicity. It is only intended for |
|
||||
* internal use and it is heavily coupled with the Context |
|
||||
* implementations. |
|
||||
*/ |
|
||||
struct win32_setup |
|
||||
{ |
|
||||
/**
|
|
||||
* The work directory. |
|
||||
* |
|
||||
* This string specifies the directory in which the %child process |
|
||||
* starts execution. It cannot be empty. |
|
||||
*/ |
|
||||
std::string work_directory; |
|
||||
|
|
||||
/**
|
|
||||
* The process startup properties. |
|
||||
* |
|
||||
* This Win32-specific object holds a list of properties that describe |
|
||||
* how the new process should be started. The \a STARTF_USESTDHANDLES |
|
||||
* flag should not be set in it because it is automatically configured |
|
||||
* by win32_start(). |
|
||||
*/ |
|
||||
STARTUPINFOA *startupinfo; |
|
||||
}; |
|
||||
|
|
||||
/**
|
|
||||
* Starts a new child process in a Win32 operating system. |
|
||||
* |
|
||||
* This helper functions is provided to simplify the Context's task when |
|
||||
* it comes to starting up a new process in a Win32 operating system. |
|
||||
* |
|
||||
* \param exe The executable to spawn the child process. |
|
||||
* \param args The arguments for the executable. |
|
||||
* \param env The environment variables that the new child process |
|
||||
* receives. |
|
||||
* \param infoin Information that describes stdin's behavior. |
|
||||
* \param infoout Information that describes stdout's behavior. |
|
||||
* \param infoerr Information that describes stderr's behavior. |
|
||||
* \param setup A helper object holding extra child information. |
|
||||
* \return The new process' information as returned by the CreateProcess() |
|
||||
* system call. The caller is responsible of creating an |
|
||||
* appropriate Child representation for it. |
|
||||
* \pre \a setup.startupinfo_ cannot have the \a STARTF_USESTDHANDLES set |
|
||||
* in the \a dwFlags field. |
|
||||
*/ |
|
||||
template <class Executable, class Arguments> |
|
||||
inline PROCESS_INFORMATION win32_start(const Executable &exe, const Arguments &args, const environment &env, stream_info &infoin, stream_info &infoout, stream_info &infoerr, const win32_setup &setup) |
|
||||
{ |
|
||||
file_handle chin, chout, cherr; |
|
||||
|
|
||||
BOOST_ASSERT(setup.startupinfo->cb >= sizeof(STARTUPINFOA)); |
|
||||
BOOST_ASSERT(!(setup.startupinfo->dwFlags & STARTF_USESTDHANDLES)); |
|
||||
|
|
||||
boost::scoped_ptr<STARTUPINFOA> si(new STARTUPINFOA); |
|
||||
::CopyMemory(si.get(), setup.startupinfo, sizeof(*setup.startupinfo)); |
|
||||
si->dwFlags |= STARTF_USESTDHANDLES; |
|
||||
|
|
||||
switch (infoin.type_) |
|
||||
{ |
|
||||
case stream_info::close: |
|
||||
{ |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::inherit: |
|
||||
{ |
|
||||
chin = file_handle::win32_std(STD_INPUT_HANDLE, true); |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::use_file: |
|
||||
{ |
|
||||
HANDLE h = ::CreateFileA(infoin.file_.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); |
|
||||
if (h == INVALID_HANDLE_VALUE) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateFile failed")); |
|
||||
chin = file_handle(h); |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::use_handle: |
|
||||
{ |
|
||||
chin = infoin.handle_; |
|
||||
chin.win32_set_inheritable(true); |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::use_pipe: |
|
||||
{ |
|
||||
infoin.pipe_->rend().win32_set_inheritable(true); |
|
||||
chin = infoin.pipe_->rend(); |
|
||||
break; |
|
||||
} |
|
||||
default: |
|
||||
{ |
|
||||
BOOST_ASSERT(false); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
si->hStdInput = chin.valid() ? chin.get() : INVALID_HANDLE_VALUE; |
|
||||
|
|
||||
switch (infoout.type_) |
|
||||
{ |
|
||||
case stream_info::close: |
|
||||
{ |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::inherit: |
|
||||
{ |
|
||||
chout = file_handle::win32_std(STD_OUTPUT_HANDLE, true); |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::use_file: |
|
||||
{ |
|
||||
HANDLE h = ::CreateFileA(infoout.file_.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
|
||||
if (h == INVALID_HANDLE_VALUE) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateFile failed")); |
|
||||
chout = file_handle(h); |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::use_handle: |
|
||||
{ |
|
||||
chout = infoout.handle_; |
|
||||
chout.win32_set_inheritable(true); |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::use_pipe: |
|
||||
{ |
|
||||
infoout.pipe_->wend().win32_set_inheritable(true); |
|
||||
chout = infoout.pipe_->wend(); |
|
||||
break; |
|
||||
} |
|
||||
default: |
|
||||
{ |
|
||||
BOOST_ASSERT(false); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
si->hStdOutput = chout.valid() ? chout.get() : INVALID_HANDLE_VALUE; |
|
||||
|
|
||||
switch (infoerr.type_) |
|
||||
{ |
|
||||
case stream_info::close: |
|
||||
{ |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::inherit: |
|
||||
{ |
|
||||
cherr = file_handle::win32_std(STD_ERROR_HANDLE, true); |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::redirect: |
|
||||
{ |
|
||||
BOOST_ASSERT(infoerr.desc_to_ == 1); |
|
||||
BOOST_ASSERT(chout.valid()); |
|
||||
cherr = file_handle::win32_dup(chout.get(), true); |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::use_file: |
|
||||
{ |
|
||||
HANDLE h = ::CreateFileA(infoerr.file_.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
|
||||
if (h == INVALID_HANDLE_VALUE) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateFile failed")); |
|
||||
cherr = file_handle(h); |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::use_handle: |
|
||||
{ |
|
||||
cherr = infoerr.handle_; |
|
||||
cherr.win32_set_inheritable(true); |
|
||||
break; |
|
||||
} |
|
||||
case stream_info::use_pipe: |
|
||||
{ |
|
||||
infoerr.pipe_->wend().win32_set_inheritable(true); |
|
||||
cherr = infoerr.pipe_->wend(); |
|
||||
break; |
|
||||
} |
|
||||
default: |
|
||||
{ |
|
||||
BOOST_ASSERT(false); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
si->hStdError = cherr.valid() ? cherr.get() : INVALID_HANDLE_VALUE; |
|
||||
|
|
||||
PROCESS_INFORMATION pi; |
|
||||
::ZeroMemory(&pi, sizeof(pi)); |
|
||||
|
|
||||
boost::shared_array<char> cmdline = collection_to_win32_cmdline(args); |
|
||||
|
|
||||
boost::scoped_array<char> executable(new char[exe.size() + 1]); |
|
||||
#if defined(__CYGWIN__) |
|
||||
::strcpy(executable.get(), exe.c_str()); |
|
||||
#else |
|
||||
::strcpy_s(executable.get(), exe.size() + 1, exe.c_str()); |
|
||||
#endif |
|
||||
|
|
||||
boost::scoped_array<char> workdir(new char[setup.work_directory.size() + 1]); |
|
||||
#if defined(__CYGWIN__) |
|
||||
::strcpy(workdir.get(), setup.work_directory.c_str()); |
|
||||
#else |
|
||||
::strcpy_s(workdir.get(), setup.work_directory.size() + 1, setup.work_directory.c_str()); |
|
||||
#endif |
|
||||
|
|
||||
boost::shared_array<char> envstrs = environment_to_win32_strings(env); |
|
||||
|
|
||||
if (!::CreateProcessA(executable.get()[0] ? executable.get() : NULL, cmdline.get(), NULL, NULL, TRUE, CREATE_NO_WINDOW, envstrs.get(), workdir.get(), si.get(), &pi)) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::detail::win32_start: CreateProcess failed")); |
|
||||
|
|
||||
return pi; |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,50 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/environment.hpp |
|
||||
* |
|
||||
* Includes the declaration of the environment class. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_ENVIRONMENT_HPP |
|
||||
#define BOOST_PROCESS_ENVIRONMENT_HPP |
|
||||
|
|
||||
#include <string> |
|
||||
#include <map> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
/**
|
|
||||
* Representation of a process' environment variables. |
|
||||
* |
|
||||
* The environment is a map that stablishes an unidirectional |
|
||||
* association between variable names and their values and is |
|
||||
* represented by a string to string map. |
|
||||
* |
|
||||
* Variables may be defined to the empty string. Be aware that doing so |
|
||||
* is not portable: POSIX systems will treat such variables as being |
|
||||
* defined to the empty value, but Windows systems are not able to |
|
||||
* distinguish them from undefined variables. |
|
||||
* |
|
||||
* Neither POSIX nor Windows systems support a variable with no name. |
|
||||
* |
|
||||
* It is worthy to note that the environment is sorted alphabetically. |
|
||||
* This is provided for-free by the map container used to implement this |
|
||||
* type, and this behavior is required by Windows systems. |
|
||||
*/ |
|
||||
typedef std::map<std::string, std::string> environment; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,583 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/operations.hpp |
|
||||
* |
|
||||
* Provides miscellaneous free functions. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_OPERATIONS_HPP |
|
||||
#define BOOST_PROCESS_OPERATIONS_HPP |
|
||||
|
|
||||
#include <boost/process/config.hpp> |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
# include <boost/process/detail/posix_ops.hpp> |
|
||||
# include <stdlib.h> |
|
||||
# include <unistd.h> |
|
||||
# if defined(__CYGWIN__) |
|
||||
# include <boost/scoped_array.hpp> |
|
||||
# include <sys/cygwin.h> |
|
||||
# endif |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
# include <boost/process/detail/win32_ops.hpp> |
|
||||
# include <boost/algorithm/string/predicate.hpp> |
|
||||
# include <windows.h> |
|
||||
#else |
|
||||
# error "Unsupported platform." |
|
||||
#endif |
|
||||
|
|
||||
#include <boost/process/child.hpp> |
|
||||
#include <boost/process/stream_behavior.hpp> |
|
||||
#include <boost/process/status.hpp> |
|
||||
#include <boost/process/detail/file_handle.hpp> |
|
||||
#include <boost/process/detail/pipe.hpp> |
|
||||
#include <boost/process/detail/stream_info.hpp> |
|
||||
#include <boost/filesystem/path.hpp> |
|
||||
#include <boost/algorithm/string/predicate.hpp> |
|
||||
#include <boost/system/system_error.hpp> |
|
||||
#include <boost/throw_exception.hpp> |
|
||||
#include <boost/scoped_array.hpp> |
|
||||
#include <boost/assert.hpp> |
|
||||
#include <string> |
|
||||
#include <vector> |
|
||||
#include <stdexcept> |
|
||||
#include <cstddef> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
/**
|
|
||||
* Locates the executable program \a file in all the directory components |
|
||||
* specified in \a path. If \a path is empty, the value of the PATH |
|
||||
* environment variable is used. |
|
||||
* |
|
||||
* The path variable is interpreted following the same conventions used |
|
||||
* to parse the PATH environment variable in the underlying platform. |
|
||||
* |
|
||||
* \throw boost::filesystem::filesystem_error If the file cannot be found |
|
||||
* in the path. |
|
||||
*/ |
|
||||
inline std::string find_executable_in_path(const std::string &file, std::string path = "") |
|
||||
{ |
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
BOOST_ASSERT(file.find('/') == std::string::npos); |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
BOOST_ASSERT(file.find_first_of("\\/") == std::string::npos); |
|
||||
#endif |
|
||||
|
|
||||
std::string result; |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
if (path.empty()) |
|
||||
{ |
|
||||
const char *envpath = ::getenv("PATH"); |
|
||||
// if (!envpath)
|
|
||||
// boost::throw_exception(boost::filesystem::filesystem_error("boost::process::find_executable_in_path: retrieving PATH failed", file, boost::system::errc::make_error_code(boost::system::errc::no_such_file_or_directory)));
|
|
||||
|
|
||||
path = envpath; |
|
||||
} |
|
||||
BOOST_ASSERT(!path.empty()); |
|
||||
|
|
||||
#if defined(__CYGWIN__) |
|
||||
if (!::cygwin_posix_path_list_p(path.c_str())) |
|
||||
{ |
|
||||
int size = ::cygwin_win32_to_posix_path_list_buf_size(path.c_str()); |
|
||||
boost::scoped_array<char> cygpath(new char[size]); |
|
||||
::cygwin_win32_to_posix_path_list(path.c_str(), cygpath.get()); |
|
||||
path = cygpath.get(); |
|
||||
} |
|
||||
#endif |
|
||||
|
|
||||
std::string::size_type pos1 = 0, pos2; |
|
||||
do |
|
||||
{ |
|
||||
pos2 = path.find(':', pos1); |
|
||||
std::string dir = (pos2 != std::string::npos) ? path.substr(pos1, pos2 - pos1) : path.substr(pos1); |
|
||||
std::string f = dir + (boost::algorithm::ends_with(dir, "/") ? "" : "/") + file; |
|
||||
if (!::access(f.c_str(), X_OK)) |
|
||||
result = f; |
|
||||
pos1 = pos2 + 1; |
|
||||
} while (pos2 != std::string::npos && result.empty()); |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
const char *exts[] = { "", ".exe", ".com", ".bat", NULL }; |
|
||||
const char **ext = exts; |
|
||||
while (*ext) |
|
||||
{ |
|
||||
char buf[MAX_PATH]; |
|
||||
char *dummy; |
|
||||
DWORD size = ::SearchPathA(path.empty() ? NULL : path.c_str(), file.c_str(), *ext, MAX_PATH, buf, &dummy); |
|
||||
BOOST_ASSERT(size < MAX_PATH); |
|
||||
if (size > 0) |
|
||||
{ |
|
||||
result = buf; |
|
||||
break; |
|
||||
} |
|
||||
++ext; |
|
||||
} |
|
||||
#endif |
|
||||
|
|
||||
// if (result.empty())
|
|
||||
// boost::throw_exception(boost::filesystem::filesystem_error("boost::process::find_executable_in_path: file not found", file, boost::system::errc::make_error_code(boost::system::errc::no_such_file_or_directory)));
|
|
||||
|
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Extracts the program name from a given executable. |
|
||||
* |
|
||||
* \return The program name. On Windows the program name |
|
||||
* is returned without a file extension. |
|
||||
*/ |
|
||||
inline std::string executable_to_progname(const std::string &exe) |
|
||||
{ |
|
||||
std::string::size_type begin = 0; |
|
||||
std::string::size_type end = std::string::npos; |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
std::string::size_type slash = exe.rfind('/'); |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
std::string::size_type slash = exe.find_last_of("/\\"); |
|
||||
#endif |
|
||||
if (slash != std::string::npos) |
|
||||
begin = slash + 1; |
|
||||
|
|
||||
#if defined(BOOST_WINDOWS_API) |
|
||||
if (exe.size() > 4 && |
|
||||
(boost::algorithm::iends_with(exe, ".exe") || boost::algorithm::iends_with(exe, ".com") || boost::algorithm::iends_with(exe, ".bat"))) |
|
||||
end = exe.size() - 4; |
|
||||
#endif |
|
||||
|
|
||||
return exe.substr(begin, end - begin); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Starts a new child process. |
|
||||
* |
|
||||
* Launches a new process based on the binary image specified by the |
|
||||
* executable, the set of arguments to be passed to it and several |
|
||||
* parameters that describe the execution context. |
|
||||
* |
|
||||
* \remark Blocking remarks: This function may block if the device |
|
||||
* holding the executable blocks when loading the image. This might |
|
||||
* happen if, e.g., the binary is being loaded from a network share. |
|
||||
* |
|
||||
* \return A handle to the new child process. |
|
||||
*/ |
|
||||
template <class Executable, class Arguments, class Context> |
|
||||
inline child launch(const Executable &exe, const Arguments &args, const Context &ctx) |
|
||||
{ |
|
||||
detail::file_handle fhstdin, fhstdout, fhstderr; |
|
||||
|
|
||||
BOOST_ASSERT(!args.empty()); |
|
||||
BOOST_ASSERT(!ctx.work_directory.empty()); |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
detail::info_map infoin, infoout; |
|
||||
|
|
||||
if (ctx.stdin_behavior.get_type() != stream_behavior::close) |
|
||||
{ |
|
||||
detail::stream_info si = detail::stream_info(ctx.stdin_behavior, false); |
|
||||
infoin.insert(detail::info_map::value_type(STDIN_FILENO, si)); |
|
||||
} |
|
||||
|
|
||||
if (ctx.stdout_behavior.get_type() != stream_behavior::close) |
|
||||
{ |
|
||||
detail::stream_info si = detail::stream_info(ctx.stdout_behavior, true); |
|
||||
infoout.insert(detail::info_map::value_type(STDOUT_FILENO, si)); |
|
||||
} |
|
||||
|
|
||||
if (ctx.stderr_behavior.get_type() != stream_behavior::close) |
|
||||
{ |
|
||||
detail::stream_info si = detail::stream_info(ctx.stderr_behavior, true); |
|
||||
infoout.insert(detail::info_map::value_type(STDERR_FILENO, si)); |
|
||||
} |
|
||||
|
|
||||
detail::posix_setup s; |
|
||||
s.work_directory = ctx.work_directory; |
|
||||
|
|
||||
child::id_type pid = detail::posix_start(exe, args, ctx.environment, infoin, infoout, s); |
|
||||
|
|
||||
if (ctx.stdin_behavior.get_type() == stream_behavior::capture) |
|
||||
{ |
|
||||
fhstdin = detail::posix_info_locate_pipe(infoin, STDIN_FILENO, false); |
|
||||
BOOST_ASSERT(fhstdin.valid()); |
|
||||
} |
|
||||
|
|
||||
if (ctx.stdout_behavior.get_type() == stream_behavior::capture) |
|
||||
{ |
|
||||
fhstdout = detail::posix_info_locate_pipe(infoout, STDOUT_FILENO, true); |
|
||||
BOOST_ASSERT(fhstdout.valid()); |
|
||||
} |
|
||||
|
|
||||
if (ctx.stderr_behavior.get_type() == stream_behavior::capture) |
|
||||
{ |
|
||||
fhstderr = detail::posix_info_locate_pipe(infoout, STDERR_FILENO, true); |
|
||||
BOOST_ASSERT(fhstderr.valid()); |
|
||||
} |
|
||||
|
|
||||
return child(pid, fhstdin, fhstdout, fhstderr); |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
detail::stream_info behin = detail::stream_info(ctx.stdin_behavior, false); |
|
||||
if (behin.type_ == detail::stream_info::use_pipe) |
|
||||
fhstdin = behin.pipe_->wend(); |
|
||||
detail::stream_info behout = detail::stream_info(ctx.stdout_behavior, true); |
|
||||
if (behout.type_ == detail::stream_info::use_pipe) |
|
||||
fhstdout = behout.pipe_->rend(); |
|
||||
detail::stream_info beherr = detail::stream_info(ctx.stderr_behavior, true); |
|
||||
if (beherr.type_ == detail::stream_info::use_pipe) |
|
||||
fhstderr = beherr.pipe_->rend(); |
|
||||
|
|
||||
STARTUPINFOA si; |
|
||||
::ZeroMemory(&si, sizeof(si)); |
|
||||
si.cb = sizeof(si); |
|
||||
|
|
||||
detail::win32_setup s; |
|
||||
s.work_directory = ctx.work_directory; |
|
||||
s.startupinfo = &si; |
|
||||
|
|
||||
PROCESS_INFORMATION pi = detail::win32_start(exe, args, ctx.environment, behin, behout, beherr, s); |
|
||||
|
|
||||
if (!::CloseHandle(pi.hThread)) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch: CloseHandle failed")); |
|
||||
|
|
||||
return child(pi.dwProcessId, fhstdin, fhstdout, fhstderr, detail::file_handle(pi.hProcess)); |
|
||||
#endif |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Launches a shell-based command. |
|
||||
* |
|
||||
* Executes the given command through the default system shell. The |
|
||||
* command is subject to pattern expansion, redirection and pipelining. |
|
||||
* The shell is launched as described by the parameters in the execution |
|
||||
* context. |
|
||||
* |
|
||||
* This function behaves similarly to the system(3) system call. In a |
|
||||
* POSIX system, the command is fed to /bin/sh whereas under a Windows |
|
||||
* system, it is fed to cmd.exe. It is difficult to write portable |
|
||||
* commands as the first parameter, but this function comes in handy in |
|
||||
* multiple situations. |
|
||||
*/ |
|
||||
template <class Context> |
|
||||
inline child launch_shell(const std::string &command, const Context &ctx) |
|
||||
{ |
|
||||
std::string exe; |
|
||||
std::vector<std::string> args; |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
exe = "/bin/sh"; |
|
||||
args.push_back("sh"); |
|
||||
args.push_back("-c"); |
|
||||
args.push_back(command); |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
char sysdir[MAX_PATH]; |
|
||||
UINT size = ::GetSystemDirectoryA(sysdir, sizeof(sysdir)); |
|
||||
if (!size) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_shell: GetWindowsDirectory failed")); |
|
||||
BOOST_ASSERT(size < MAX_PATH); |
|
||||
|
|
||||
exe = std::string(sysdir) + (sysdir[size - 1] != '\\' ? "\\cmd.exe" : "cmd.exe"); |
|
||||
args.push_back("cmd"); |
|
||||
args.push_back("/c"); |
|
||||
args.push_back(command); |
|
||||
#endif |
|
||||
|
|
||||
return launch(exe, args, ctx); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Launches a pipelined set of child processes. |
|
||||
* |
|
||||
* Given a collection of pipeline_entry objects describing how to launch |
|
||||
* a set of child processes, spawns them all and connects their inputs and |
|
||||
* outputs in a way that permits pipelined communication. |
|
||||
* |
|
||||
* \pre Let 1..N be the processes in the collection: the input behavior of |
|
||||
* the 2..N processes must be set to close_stream(). |
|
||||
* \pre Let 1..N be the processes in the collection: the output behavior of |
|
||||
* the 1..N-1 processes must be set to close_stream(). |
|
||||
* \remark Blocking remarks: This function may block if the device holding |
|
||||
* the executable of one of the entries blocks when loading the |
|
||||
* image. This might happen if, e.g., the binary is being loaded |
|
||||
* from a network share. |
|
||||
* \return A set of Child objects that represent all the processes spawned |
|
||||
* by this call. You should use wait_children() to wait for their |
|
||||
* termination. |
|
||||
*/ |
|
||||
template <class Entries> |
|
||||
inline children launch_pipeline(const Entries &entries) |
|
||||
{ |
|
||||
BOOST_ASSERT(entries.size() >= 2); |
|
||||
|
|
||||
children cs; |
|
||||
detail::file_handle fhinvalid; |
|
||||
|
|
||||
boost::scoped_array<detail::pipe> pipes(new detail::pipe[entries.size() - 1]); |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
{ |
|
||||
typename Entries::size_type i = 0; |
|
||||
const typename Entries::value_type::context_type &ctx = entries[i].context; |
|
||||
|
|
||||
detail::info_map infoin, infoout; |
|
||||
|
|
||||
if (ctx.stdin_behavior.get_type() != stream_behavior::close) |
|
||||
{ |
|
||||
detail::stream_info si = detail::stream_info(ctx.stdin_behavior, false); |
|
||||
infoin.insert(detail::info_map::value_type(STDIN_FILENO, si)); |
|
||||
} |
|
||||
|
|
||||
BOOST_ASSERT(ctx.stdout_behavior.get_type() == stream_behavior::close); |
|
||||
detail::stream_info si2(close_stream(), true); |
|
||||
si2.type_ = detail::stream_info::use_handle; |
|
||||
si2.handle_ = pipes[i].wend().release(); |
|
||||
infoout.insert(detail::info_map::value_type(STDOUT_FILENO, si2)); |
|
||||
|
|
||||
if (ctx.stderr_behavior.get_type() != stream_behavior::close) |
|
||||
{ |
|
||||
detail::stream_info si = detail::stream_info(ctx.stderr_behavior, true); |
|
||||
infoout.insert(detail::info_map::value_type(STDERR_FILENO, si)); |
|
||||
} |
|
||||
|
|
||||
detail::posix_setup s; |
|
||||
s.work_directory = ctx.work_directory; |
|
||||
|
|
||||
pid_t pid = detail::posix_start(entries[i].executable, entries[i].arguments, ctx.environment, infoin, infoout, s); |
|
||||
|
|
||||
detail::file_handle fhstdin; |
|
||||
|
|
||||
if (ctx.stdin_behavior.get_type() == stream_behavior::capture) |
|
||||
{ |
|
||||
fhstdin = detail::posix_info_locate_pipe(infoin, STDIN_FILENO, false); |
|
||||
BOOST_ASSERT(fhstdin.valid()); |
|
||||
} |
|
||||
|
|
||||
cs.push_back(child(pid, fhstdin, fhinvalid, fhinvalid)); |
|
||||
} |
|
||||
|
|
||||
for (typename Entries::size_type i = 1; i < entries.size() - 1; ++i) |
|
||||
{ |
|
||||
const typename Entries::value_type::context_type &ctx = entries[i].context; |
|
||||
detail::info_map infoin, infoout; |
|
||||
|
|
||||
BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close); |
|
||||
detail::stream_info si1(close_stream(), false); |
|
||||
si1.type_ = detail::stream_info::use_handle; |
|
||||
si1.handle_ = pipes[i - 1].rend().release(); |
|
||||
infoin.insert(detail::info_map::value_type(STDIN_FILENO, si1)); |
|
||||
|
|
||||
BOOST_ASSERT(ctx.stdout_behavior.get_type() == stream_behavior::close); |
|
||||
detail::stream_info si2(close_stream(), true); |
|
||||
si2.type_ = detail::stream_info::use_handle; |
|
||||
si2.handle_ = pipes[i].wend().release(); |
|
||||
infoout.insert(detail::info_map::value_type(STDOUT_FILENO, si2)); |
|
||||
|
|
||||
if (ctx.stderr_behavior.get_type() != stream_behavior::close) |
|
||||
{ |
|
||||
detail::stream_info si = detail::stream_info(ctx.stderr_behavior, true); |
|
||||
infoout.insert(detail::info_map::value_type(STDERR_FILENO, si)); |
|
||||
} |
|
||||
|
|
||||
detail::posix_setup s; |
|
||||
s.work_directory = ctx.work_directory; |
|
||||
|
|
||||
pid_t pid = detail::posix_start(entries[i].executable, entries[i].arguments, ctx.environment, infoin, infoout, s); |
|
||||
|
|
||||
cs.push_back(child(pid, fhinvalid, fhinvalid, fhinvalid)); |
|
||||
} |
|
||||
|
|
||||
{ |
|
||||
typename Entries::size_type i = entries.size() - 1; |
|
||||
const typename Entries::value_type::context_type &ctx = entries[i].context; |
|
||||
|
|
||||
detail::info_map infoin, infoout; |
|
||||
|
|
||||
BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close); |
|
||||
detail::stream_info si1(close_stream(), false); |
|
||||
si1.type_ = detail::stream_info::use_handle; |
|
||||
si1.handle_ = pipes[i - 1].rend().release(); |
|
||||
infoin.insert(detail::info_map::value_type(STDIN_FILENO, si1)); |
|
||||
|
|
||||
if (ctx.stdout_behavior.get_type() != stream_behavior::close) |
|
||||
{ |
|
||||
detail::stream_info si = detail::stream_info(ctx.stdout_behavior, true); |
|
||||
infoout.insert(detail::info_map::value_type(STDOUT_FILENO, si)); |
|
||||
} |
|
||||
|
|
||||
if (ctx.stderr_behavior.get_type() != stream_behavior::close) |
|
||||
{ |
|
||||
detail::stream_info si = detail::stream_info(ctx.stderr_behavior, true); |
|
||||
infoout.insert(detail::info_map::value_type(STDERR_FILENO, si)); |
|
||||
} |
|
||||
|
|
||||
detail::posix_setup s; |
|
||||
s.work_directory = ctx.work_directory; |
|
||||
|
|
||||
pid_t pid = detail::posix_start(entries[i].executable, entries[i].arguments, ctx.environment, infoin, infoout, s); |
|
||||
|
|
||||
detail::file_handle fhstdout, fhstderr; |
|
||||
|
|
||||
if (ctx.stdout_behavior.get_type() == stream_behavior::capture) |
|
||||
{ |
|
||||
fhstdout = detail::posix_info_locate_pipe(infoout, STDOUT_FILENO, true); |
|
||||
BOOST_ASSERT(fhstdout.valid()); |
|
||||
} |
|
||||
|
|
||||
if (ctx.stderr_behavior.get_type() == stream_behavior::capture) |
|
||||
{ |
|
||||
fhstderr = detail::posix_info_locate_pipe(infoout, STDERR_FILENO, true); |
|
||||
BOOST_ASSERT(fhstderr.valid()); |
|
||||
} |
|
||||
|
|
||||
cs.push_back(child(pid, fhinvalid, fhstdout, fhstderr)); |
|
||||
} |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
STARTUPINFOA si; |
|
||||
detail::win32_setup s; |
|
||||
s.startupinfo = &si; |
|
||||
|
|
||||
{ |
|
||||
typename Entries::size_type i = 0; |
|
||||
const typename Entries::value_type::context_type &ctx = entries[i].context; |
|
||||
|
|
||||
detail::stream_info sii = detail::stream_info(ctx.stdin_behavior, false); |
|
||||
detail::file_handle fhstdin; |
|
||||
if (sii.type_ == detail::stream_info::use_pipe) |
|
||||
fhstdin = sii.pipe_->wend(); |
|
||||
|
|
||||
BOOST_ASSERT(ctx.stdout_behavior.get_type() == stream_behavior::close); |
|
||||
detail::stream_info sio(close_stream(), true); |
|
||||
sio.type_ = detail::stream_info::use_handle; |
|
||||
sio.handle_ = pipes[i].wend().release(); |
|
||||
|
|
||||
detail::stream_info sie(ctx.stderr_behavior, true); |
|
||||
|
|
||||
s.work_directory = ctx.work_directory; |
|
||||
|
|
||||
::ZeroMemory(&si, sizeof(si)); |
|
||||
si.cb = sizeof(si); |
|
||||
PROCESS_INFORMATION pi = detail::win32_start(entries[i].executable, entries[i].arguments, ctx.environment, sii, sio, sie, s); |
|
||||
|
|
||||
if (!::CloseHandle(pi.hThread)) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_pipeline: CloseHandle failed")); |
|
||||
|
|
||||
cs.push_back(child(pi.dwProcessId, fhstdin, fhinvalid, fhinvalid, detail::file_handle(pi.hProcess))); |
|
||||
} |
|
||||
|
|
||||
for (typename Entries::size_type i = 1; i < entries.size() - 1; ++i) |
|
||||
{ |
|
||||
const typename Entries::value_type::context_type &ctx = entries[i].context; |
|
||||
|
|
||||
BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close); |
|
||||
detail::stream_info sii(close_stream(), false); |
|
||||
sii.type_ = detail::stream_info::use_handle; |
|
||||
sii.handle_ = pipes[i - 1].rend().release(); |
|
||||
|
|
||||
detail::stream_info sio(close_stream(), true); |
|
||||
sio.type_ = detail::stream_info::use_handle; |
|
||||
sio.handle_ = pipes[i].wend().release(); |
|
||||
|
|
||||
detail::stream_info sie(ctx.stderr_behavior, true); |
|
||||
|
|
||||
s.work_directory = ctx.work_directory; |
|
||||
|
|
||||
::ZeroMemory(&si, sizeof(si)); |
|
||||
si.cb = sizeof(si); |
|
||||
PROCESS_INFORMATION pi = detail::win32_start(entries[i].executable, entries[i].arguments, ctx.environment, sii, sio, sie, s); |
|
||||
|
|
||||
if (!::CloseHandle(pi.hThread)) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_pipeline: CloseHandle failed")); |
|
||||
|
|
||||
cs.push_back(child(pi.dwProcessId, fhinvalid, fhinvalid, fhinvalid, detail::file_handle(pi.hProcess))); |
|
||||
} |
|
||||
|
|
||||
{ |
|
||||
typename Entries::size_type i = entries.size() - 1; |
|
||||
const typename Entries::value_type::context_type &ctx = entries[i].context; |
|
||||
|
|
||||
BOOST_ASSERT(ctx.stdin_behavior.get_type() == stream_behavior::close); |
|
||||
detail::stream_info sii(close_stream(), false); |
|
||||
sii.type_ = detail::stream_info::use_handle; |
|
||||
sii.handle_ = pipes[i - 1].rend().release(); |
|
||||
|
|
||||
detail::file_handle fhstdout, fhstderr; |
|
||||
|
|
||||
detail::stream_info sio(ctx.stdout_behavior, true); |
|
||||
if (sio.type_ == detail::stream_info::use_pipe) |
|
||||
fhstdout = sio.pipe_->rend(); |
|
||||
detail::stream_info sie(ctx.stderr_behavior, true); |
|
||||
if (sie.type_ == detail::stream_info::use_pipe) |
|
||||
fhstderr = sie.pipe_->rend(); |
|
||||
|
|
||||
s.work_directory = ctx.work_directory; |
|
||||
|
|
||||
::ZeroMemory(&si, sizeof(si)); |
|
||||
si.cb = sizeof(si); |
|
||||
PROCESS_INFORMATION pi = detail::win32_start(entries[i].executable, entries[i].arguments, ctx.environment, sii, sio, sie, s); |
|
||||
|
|
||||
if (!::CloseHandle(pi.hThread)) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::launch_pipeline: CloseHandle failed")); |
|
||||
|
|
||||
cs.push_back(child(pi.dwProcessId, fhinvalid, fhstdout, fhstderr, detail::file_handle(pi.hProcess))); |
|
||||
} |
|
||||
#endif |
|
||||
|
|
||||
return cs; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Waits for a collection of children to terminate. |
|
||||
* |
|
||||
* Given a collection of Child objects (such as std::vector<child> or |
|
||||
* the convenience children type), waits for the termination of all of |
|
||||
* them. |
|
||||
* |
|
||||
* \remark Blocking remarks: This call blocks if any of the children |
|
||||
* processes in the collection has not finalized execution and |
|
||||
* waits until it terminates. |
|
||||
* |
|
||||
* \return The exit status of the first process that returns an error |
|
||||
* code or, if all of them executed correctly, the exit status |
|
||||
* of the last process in the collection. |
|
||||
*/ |
|
||||
template <class Children> |
|
||||
inline status wait_children(Children &cs) |
|
||||
{ |
|
||||
BOOST_ASSERT(cs.size() >= 2); |
|
||||
|
|
||||
typename Children::iterator it = cs.begin(); |
|
||||
while (it != cs.end()) |
|
||||
{ |
|
||||
const status s = it->wait(); |
|
||||
++it; |
|
||||
if (it == cs.end()) |
|
||||
return s; |
|
||||
else if (!s.exited() || s.exit_status() != EXIT_SUCCESS) |
|
||||
{ |
|
||||
while (it != cs.end()) |
|
||||
{ |
|
||||
it->wait(); |
|
||||
++it; |
|
||||
} |
|
||||
return s; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
BOOST_ASSERT(false); |
|
||||
return cs.begin()->wait(); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,116 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/pistream.hpp |
|
||||
* |
|
||||
* Includes the declaration of the pistream class. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_PISTREAM_HPP |
|
||||
#define BOOST_PROCESS_PISTREAM_HPP |
|
||||
|
|
||||
#include <boost/process/detail/file_handle.hpp> |
|
||||
#include <boost/process/detail/systembuf.hpp> |
|
||||
#include <boost/noncopyable.hpp> |
|
||||
#include <istream> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
/**
|
|
||||
* Child process' output stream. |
|
||||
* |
|
||||
* The pistream class represents an output communication channel with the |
|
||||
* child process. The child process writes data to this stream and the |
|
||||
* parent process can read it through the pistream object. In other |
|
||||
* words, from the child's point of view, the communication channel is an |
|
||||
* output one, but from the parent's point of view it is an input one; |
|
||||
* hence the confusing pistream name. |
|
||||
* |
|
||||
* pistream objects cannot be copied because they own the file handle |
|
||||
* they use to communicate with the child and because they buffer data |
|
||||
* that flows through the communication channel. |
|
||||
* |
|
||||
* A pistream object behaves as a std::istream stream in all senses. |
|
||||
* The class is only provided because it must provide a method to let |
|
||||
* the caller explicitly close the communication channel. |
|
||||
* |
|
||||
* \remark Blocking remarks: Functions that read data from this |
|
||||
* stream can block if the associated file handle blocks during |
|
||||
* the read. As this class is used to communicate with child |
|
||||
* processes through anonymous pipes, the most typical blocking |
|
||||
* condition happens when the child has no more data to send to |
|
||||
* the pipe's system buffer. When this happens, the buffer |
|
||||
* eventually empties and the system blocks until the writer |
|
||||
* generates some data. |
|
||||
*/ |
|
||||
class pistream : public std::istream, public boost::noncopyable |
|
||||
{ |
|
||||
public: |
|
||||
/**
|
|
||||
* Creates a new process' output stream. |
|
||||
* |
|
||||
* Given a file handle, this constructor creates a new pistream |
|
||||
* object that owns the given file handle \a fh. Ownership of |
|
||||
* \a fh is transferred to the created pistream object. |
|
||||
* |
|
||||
* \pre \a fh is valid. |
|
||||
* \post \a fh is invalid. |
|
||||
* \post The new pistream object owns \a fh. |
|
||||
*/ |
|
||||
explicit pistream(detail::file_handle &fh) |
|
||||
: std::istream(0), |
|
||||
handle_(fh), |
|
||||
systembuf_(handle_.get()) |
|
||||
{ |
|
||||
rdbuf(&systembuf_); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Returns the file handle managed by this stream. |
|
||||
* |
|
||||
* The file handle must not be copied. Copying invalidates |
|
||||
* the source file handle making the pistream unusable. |
|
||||
*/ |
|
||||
detail::file_handle &handle() |
|
||||
{ |
|
||||
return handle_; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Closes the file handle managed by this stream. |
|
||||
* |
|
||||
* Explicitly closes the file handle managed by this stream. This |
|
||||
* function can be used by the user to tell the child process it's |
|
||||
* not willing to receive more data. |
|
||||
*/ |
|
||||
void close() |
|
||||
{ |
|
||||
handle_.close(); |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
/**
|
|
||||
* The file handle managed by this stream. |
|
||||
*/ |
|
||||
detail::file_handle handle_; |
|
||||
|
|
||||
/**
|
|
||||
* The systembuf object used to manage this stream's data. |
|
||||
*/ |
|
||||
detail::systembuf systembuf_; |
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,178 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/posix_child.hpp |
|
||||
* |
|
||||
* Includes the declaration of the posix_child class. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_POSIX_CHILD_HPP |
|
||||
#define BOOST_PROCESS_POSIX_CHILD_HPP |
|
||||
|
|
||||
#include <boost/process/child.hpp> |
|
||||
#include <boost/process/pistream.hpp> |
|
||||
#include <boost/process/postream.hpp> |
|
||||
#include <boost/process/detail/pipe.hpp> |
|
||||
#include <boost/process/detail/posix_ops.hpp> |
|
||||
#include <boost/process/detail/stream_info.hpp> |
|
||||
#include <boost/shared_ptr.hpp> |
|
||||
#include <boost/assert.hpp> |
|
||||
#include <map> |
|
||||
#include <unistd.h> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
/**
|
|
||||
* POSIX implementation of the Child concept. |
|
||||
* |
|
||||
* The posix_child class implements the Child concept in a POSIX |
|
||||
* operating system. |
|
||||
* |
|
||||
* A POSIX child differs from a regular child (represented by a |
|
||||
* child object) in that it supports more than three communication |
|
||||
* channels with its parent. These channels are identified by regular |
|
||||
* file descriptors (integers). |
|
||||
* |
|
||||
* This class is built on top of the generic child so as to allow its |
|
||||
* trivial adoption. When a program is changed to use the POSIX-specific |
|
||||
* context (posix_context), it will most certainly need to migrate its |
|
||||
* use of the child class to posix_child. Doing so is only a matter of |
|
||||
* redefining the appropriate object and later using the required extra |
|
||||
* features: there should be no need to modify the existing code (e.g. |
|
||||
* method calls) in any other way. |
|
||||
*/ |
|
||||
class posix_child : public child |
|
||||
{ |
|
||||
public: |
|
||||
/**
|
|
||||
* Gets a reference to the child's input stream \a desc. |
|
||||
* |
|
||||
* Returns a reference to a postream object that represents one of |
|
||||
* the multiple input communication channels with the child process. |
|
||||
* The channel is identified by \a desc as seen from the child's |
|
||||
* point of view. The parent can use the returned stream to send |
|
||||
* data to the child. |
|
||||
* |
|
||||
* Giving this function the STDIN_FILENO constant (defined in |
|
||||
* unistd.h) is a synonym for the get_stdin() call inherited from |
|
||||
* child. |
|
||||
*/ |
|
||||
postream &get_input(int desc) const |
|
||||
{ |
|
||||
if (desc == STDIN_FILENO) |
|
||||
return posix_child::get_stdin(); |
|
||||
else |
|
||||
{ |
|
||||
input_map_t::const_iterator it = input_map_.find(desc); |
|
||||
BOOST_ASSERT(it != input_map_.end()); |
|
||||
return *it->second; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Gets a reference to the child's output stream \a desc. |
|
||||
* |
|
||||
* Returns a reference to a pistream object that represents one of |
|
||||
* the multiple output communication channels with the child process. |
|
||||
* The channel is identified by \a desc as seen from the child's |
|
||||
* point of view. The parent can use the returned stream to retrieve |
|
||||
* data from the child. |
|
||||
* |
|
||||
* Giving this function the STDOUT_FILENO or STDERR_FILENO constants |
|
||||
* (both defined in unistd.h) are synonyms for the get_stdout() and |
|
||||
* get_stderr() calls inherited from child, respectively. |
|
||||
*/ |
|
||||
pistream &get_output(int desc) const |
|
||||
{ |
|
||||
if (desc == STDOUT_FILENO) |
|
||||
return posix_child::get_stdout(); |
|
||||
else if (desc == STDERR_FILENO) |
|
||||
return posix_child::get_stderr(); |
|
||||
else |
|
||||
{ |
|
||||
output_map_t::const_iterator it = output_map_.find(desc); |
|
||||
BOOST_ASSERT(it != output_map_.end()); |
|
||||
return *it->second; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Constructs a new POSIX child object representing a just |
|
||||
* spawned child process. |
|
||||
* |
|
||||
* Creates a new child object that represents the just spawned process |
|
||||
* \a id. |
|
||||
* |
|
||||
* The \a infoin and \a infoout maps contain the pipes used to handle |
|
||||
* the redirections of the child process; at the moment, no other |
|
||||
* stream_info types are supported. If the launcher was asked to |
|
||||
* redirect any of the three standard flows, their pipes must be |
|
||||
* present in these maps. |
|
||||
*/ |
|
||||
posix_child(id_type id, detail::info_map &infoin, detail::info_map &infoout) |
|
||||
: child(id, |
|
||||
detail::posix_info_locate_pipe(infoin, STDIN_FILENO, false), |
|
||||
detail::posix_info_locate_pipe(infoout, STDOUT_FILENO, true), |
|
||||
detail::posix_info_locate_pipe(infoout, STDERR_FILENO, true)) |
|
||||
{ |
|
||||
for (detail::info_map::iterator it = infoin.begin(); it != infoin.end(); ++it) |
|
||||
{ |
|
||||
detail::stream_info &si = it->second; |
|
||||
if (si.type_ == detail::stream_info::use_pipe) |
|
||||
{ |
|
||||
BOOST_ASSERT(si.pipe_->wend().valid()); |
|
||||
boost::shared_ptr<postream> st(new postream(si.pipe_->wend())); |
|
||||
input_map_.insert(input_map_t::value_type(it->first, st)); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
for (detail::info_map::iterator it = infoout.begin(); it != infoout.end(); ++it) |
|
||||
{ |
|
||||
detail::stream_info &si = it->second; |
|
||||
if (si.type_ == detail::stream_info::use_pipe) |
|
||||
{ |
|
||||
BOOST_ASSERT(si.pipe_->rend().valid()); |
|
||||
boost::shared_ptr<pistream> st(new pistream(si.pipe_->rend())); |
|
||||
output_map_.insert(output_map_t::value_type(it->first, st)); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
/**
|
|
||||
* Maps child's file descriptors to postream objects. |
|
||||
*/ |
|
||||
typedef std::map<int, boost::shared_ptr<postream> > input_map_t; |
|
||||
|
|
||||
/**
|
|
||||
* Contains all relationships between child's input file |
|
||||
* descriptors and their corresponding postream objects. |
|
||||
*/ |
|
||||
input_map_t input_map_; |
|
||||
|
|
||||
/**
|
|
||||
* Maps child's file descriptors to pistream objects. |
|
||||
*/ |
|
||||
typedef std::map<int, boost::shared_ptr<pistream> > output_map_t; |
|
||||
|
|
||||
/**
|
|
||||
* Contains all relationships between child's output file |
|
||||
* descriptors and their corresponding pistream objects. |
|
||||
*/ |
|
||||
output_map_t output_map_; |
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,118 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/posix_context.hpp |
|
||||
* |
|
||||
* Includes the declaration of the posix_context class. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_POSIX_CONTEXT_HPP |
|
||||
#define BOOST_PROCESS_POSIX_CONTEXT_HPP |
|
||||
|
|
||||
#include <boost/process/context.hpp> |
|
||||
#include <boost/process/stream_behavior.hpp> |
|
||||
#include <map> |
|
||||
#include <string> |
|
||||
#include <unistd.h> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
/**
|
|
||||
* Holds a mapping between native file descriptors and their corresponding |
|
||||
* pipes to set up communication between the parent and the %child process. |
|
||||
*/ |
|
||||
typedef std::map<int, stream_behavior> behavior_map; |
|
||||
|
|
||||
template <class Path> |
|
||||
class posix_basic_context : public basic_work_directory_context<Path>, public environment_context |
|
||||
{ |
|
||||
public: |
|
||||
/**
|
|
||||
* Constructs a new POSIX-specific context. |
|
||||
* |
|
||||
* Constructs a new context. It is configured as follows: |
|
||||
* * All communcation channels with the child process are closed. |
|
||||
* * There are no channel mergings. |
|
||||
* * The initial work directory of the child processes is set to the |
|
||||
* current working directory. |
|
||||
* * The environment variables table is empty. |
|
||||
* * The credentials are the same as those of the current process. |
|
||||
*/ |
|
||||
posix_basic_context() |
|
||||
: uid(::getuid()), |
|
||||
euid(::geteuid()), |
|
||||
gid(::getgid()), |
|
||||
egid(::getegid()) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* List of input streams that will be redirected. |
|
||||
*/ |
|
||||
behavior_map input_behavior; |
|
||||
|
|
||||
/**
|
|
||||
* List of output streams that will be redirected. |
|
||||
*/ |
|
||||
behavior_map output_behavior; |
|
||||
|
|
||||
/**
|
|
||||
* The user credentials. |
|
||||
* |
|
||||
* UID that specifies the user credentials to use to run the %child |
|
||||
* process. Defaults to the current UID. |
|
||||
*/ |
|
||||
uid_t uid; |
|
||||
|
|
||||
/**
|
|
||||
* The effective user credentials. |
|
||||
* |
|
||||
* EUID that specifies the effective user credentials to use to run |
|
||||
* the %child process. Defaults to the current EUID. |
|
||||
*/ |
|
||||
uid_t euid; |
|
||||
|
|
||||
/**
|
|
||||
* The group credentials. |
|
||||
* |
|
||||
* GID that specifies the group credentials to use to run the %child |
|
||||
* process. Defaults to the current GID. |
|
||||
*/ |
|
||||
gid_t gid; |
|
||||
|
|
||||
/**
|
|
||||
* The effective group credentials. |
|
||||
* |
|
||||
* EGID that specifies the effective group credentials to use to run |
|
||||
* the %child process. Defaults to the current EGID. |
|
||||
*/ |
|
||||
gid_t egid; |
|
||||
|
|
||||
/**
|
|
||||
* The chroot directory, if any. |
|
||||
* |
|
||||
* Specifies the directory in which the %child process is chrooted |
|
||||
* before execution. Empty if this feature is not desired. |
|
||||
*/ |
|
||||
Path chroot; |
|
||||
}; |
|
||||
|
|
||||
/**
|
|
||||
* Default instantiation of posix_basic_context. |
|
||||
*/ |
|
||||
typedef posix_basic_context<std::string> posix_context; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,81 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/posix_operations.hpp |
|
||||
* |
|
||||
* Provides miscellaneous free functions specific to POSIX operating |
|
||||
* systems. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_POSIX_OPERATIONS_HPP |
|
||||
#define BOOST_PROCESS_POSIX_OPERATIONS_HPP |
|
||||
|
|
||||
#include <boost/process/posix_child.hpp> |
|
||||
#include <boost/process/posix_context.hpp> |
|
||||
#include <boost/process/stream_behavior.hpp> |
|
||||
#include <boost/process/detail/stream_info.hpp> |
|
||||
#include <boost/process/detail/posix_ops.hpp> |
|
||||
#include <sys/types.h> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
/**
|
|
||||
* Starts a new child process. |
|
||||
* |
|
||||
* Given an executable and the set of arguments passed to it, starts |
|
||||
* a new process with all the parameters configured in the context. |
|
||||
* The context can be reused afterwards to launch other different |
|
||||
* processes. |
|
||||
* |
|
||||
* \return A handle to the new child process. |
|
||||
*/ |
|
||||
template <class Executable, class Arguments, class Posix_Context> |
|
||||
inline posix_child posix_launch(const Executable &exe, const Arguments &args, const Posix_Context &ctx) |
|
||||
{ |
|
||||
detail::info_map input_info; |
|
||||
for (behavior_map::const_iterator it = ctx.input_behavior.begin(); it != ctx.input_behavior.end(); ++it) |
|
||||
{ |
|
||||
if (it->second.get_type() != stream_behavior::close) |
|
||||
{ |
|
||||
detail::stream_info si = detail::stream_info(it->second, false); |
|
||||
input_info.insert(detail::info_map::value_type(it->first, si)); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
detail::info_map output_info; |
|
||||
for (behavior_map::const_iterator it = ctx.output_behavior.begin(); it != ctx.output_behavior.end(); ++it) |
|
||||
{ |
|
||||
if (it->second.get_type() != stream_behavior::close) |
|
||||
{ |
|
||||
detail::stream_info si = detail::stream_info(it->second, true); |
|
||||
output_info.insert(detail::info_map::value_type(it->first, si)); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
detail::posix_setup s; |
|
||||
s.work_directory = ctx.work_directory; |
|
||||
s.uid = ctx.uid; |
|
||||
s.euid = ctx.euid; |
|
||||
s.gid = ctx.gid; |
|
||||
s.egid = ctx.egid; |
|
||||
s.chroot = ctx.chroot; |
|
||||
|
|
||||
pid_t pid = detail::posix_start(exe, args, ctx.environment, input_info, output_info, s); |
|
||||
|
|
||||
return posix_child(pid, input_info, output_info); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,128 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/posix_status.hpp |
|
||||
* |
|
||||
* Includes the declaration of the posix_status class. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_POSIX_STATUS_HPP |
|
||||
#define BOOST_PROCESS_POSIX_STATUS_HPP |
|
||||
|
|
||||
#include <boost/process/config.hpp> |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
# include <sys/wait.h> |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
#else |
|
||||
# error "Unsupported platform." |
|
||||
#endif |
|
||||
|
|
||||
#include <boost/process/status.hpp> |
|
||||
#include <boost/assert.hpp> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
/**
|
|
||||
* Status returned by a finalized %child process on a POSIX system. |
|
||||
* |
|
||||
* This class represents the %status returned by a child process after it |
|
||||
* has terminated. It contains some methods not available in the status |
|
||||
* class that provide information only available in POSIX systems. |
|
||||
*/ |
|
||||
class posix_status : public status |
|
||||
{ |
|
||||
public: |
|
||||
/**
|
|
||||
* Creates a posix_status object from an existing status object. |
|
||||
* |
|
||||
* Creates a new status object representing the exit status of a |
|
||||
* child process. The construction is done based on an existing |
|
||||
* status object which already contains all the available |
|
||||
* information: this class only provides controlled access to it. |
|
||||
*/ |
|
||||
posix_status(const status &s) |
|
||||
: status(s) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Returns whether the process exited due to an external |
|
||||
* signal. |
|
||||
*/ |
|
||||
bool signaled() const |
|
||||
{ |
|
||||
return WIFSIGNALED(flags_); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* If signaled, returns the terminating signal code. |
|
||||
* |
|
||||
* If the process was signaled, returns the terminating signal code. |
|
||||
* |
|
||||
* \pre signaled() is true. |
|
||||
*/ |
|
||||
int term_signal() const |
|
||||
{ |
|
||||
BOOST_ASSERT(signaled()); |
|
||||
|
|
||||
return WTERMSIG(flags_); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* If signaled, returns whether the process dumped core. |
|
||||
* |
|
||||
* If the process was signaled, returns whether the process |
|
||||
* produced a core dump. |
|
||||
* |
|
||||
* \pre signaled() is true. |
|
||||
*/ |
|
||||
bool dumped_core() const |
|
||||
{ |
|
||||
BOOST_ASSERT(signaled()); |
|
||||
|
|
||||
#ifdef WCOREDUMP |
|
||||
return WCOREDUMP(flags_); |
|
||||
#else |
|
||||
return false; |
|
||||
#endif |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Returns whether the process was stopped by an external |
|
||||
* signal. |
|
||||
*/ |
|
||||
bool stopped() const |
|
||||
{ |
|
||||
return WIFSTOPPED(flags_); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* If stopped, returns the stop signal code. |
|
||||
* |
|
||||
* If the process was stopped, returns the stop signal code. |
|
||||
* |
|
||||
* \pre stopped() is true. |
|
||||
*/ |
|
||||
int stop_signal() const |
|
||||
{ |
|
||||
BOOST_ASSERT(stopped()); |
|
||||
|
|
||||
return WSTOPSIG(flags_); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,117 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/postream.hpp |
|
||||
* |
|
||||
* Includes the declaration of the postream class. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_POSTREAM_HPP |
|
||||
#define BOOST_PROCESS_POSTREAM_HPP |
|
||||
|
|
||||
#include <boost/process/detail/file_handle.hpp> |
|
||||
#include <boost/process/detail/systembuf.hpp> |
|
||||
#include <boost/noncopyable.hpp> |
|
||||
#include <ostream> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
/**
|
|
||||
* Child process' input stream. |
|
||||
* |
|
||||
* The postream class represents an input communication channel with the |
|
||||
* child process. The child process reads data from this stream and the |
|
||||
* parent process can write to it through the postream object. In other |
|
||||
* words, from the child's point of view, the communication channel is an |
|
||||
* input one, but from the parent's point of view it is an output one; |
|
||||
* hence the confusing postream name. |
|
||||
* |
|
||||
* postream objects cannot be copied because they own the file handle |
|
||||
* they use to communicate with the child and because they buffer data |
|
||||
* that flows through the communication channel. |
|
||||
* |
|
||||
* A postream object behaves as a std::ostream stream in all senses. |
|
||||
* The class is only provided because it must provide a method to let |
|
||||
* the caller explicitly close the communication channel. |
|
||||
* |
|
||||
* \remark Blocking remarks: Functions that write data to this |
|
||||
* stream can block if the associated file handle blocks during |
|
||||
* the write. As this class is used to communicate with child |
|
||||
* processes through anonymous pipes, the most typical blocking |
|
||||
* condition happens when the child is not processing the data |
|
||||
* in the pipe's system buffer. When this happens, the buffer |
|
||||
* eventually fills up and the system blocks until the reader |
|
||||
* consumes some data, leaving some new room. |
|
||||
*/ |
|
||||
class postream : public std::ostream, public boost::noncopyable |
|
||||
{ |
|
||||
public: |
|
||||
/**
|
|
||||
* Creates a new process' input stream. |
|
||||
* |
|
||||
* Given a file handle, this constructor creates a new postream |
|
||||
* object that owns the given file handle \a fh. Ownership of |
|
||||
* \a fh is transferred to the created postream object. |
|
||||
* |
|
||||
* \pre \a fh is valid. |
|
||||
* \post \a fh is invalid. |
|
||||
* \post The new postream object owns \a fh. |
|
||||
*/ |
|
||||
explicit postream(detail::file_handle &fh) |
|
||||
: std::ostream(0), |
|
||||
handle_(fh), |
|
||||
systembuf_(handle_.get()) |
|
||||
{ |
|
||||
rdbuf(&systembuf_); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Returns the file handle managed by this stream. |
|
||||
* |
|
||||
* The file handle must not be copied. Copying invalidates |
|
||||
* the source file handle making the postream unusable. |
|
||||
*/ |
|
||||
detail::file_handle &handle() |
|
||||
{ |
|
||||
return handle_; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Closes the file handle managed by this stream. |
|
||||
* |
|
||||
* Explicitly closes the file handle managed by this stream. This |
|
||||
* function can be used by the user to tell the child process there |
|
||||
* is no more data to send. |
|
||||
*/ |
|
||||
void close() |
|
||||
{ |
|
||||
systembuf_.sync(); |
|
||||
handle_.close(); |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
/**
|
|
||||
* The file handle managed by this stream. |
|
||||
*/ |
|
||||
detail::file_handle handle_; |
|
||||
|
|
||||
/**
|
|
||||
* The systembuf object used to manage this stream's data. |
|
||||
*/ |
|
||||
detail::systembuf systembuf_; |
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,130 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/process.hpp |
|
||||
* |
|
||||
* Includes the declaration of the process class. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_PROCESS_HPP |
|
||||
#define BOOST_PROCESS_PROCESS_HPP |
|
||||
|
|
||||
#include <boost/process/config.hpp> |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
# include <cerrno> |
|
||||
# include <signal.h> |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
# include <cstdlib> |
|
||||
# include <windows.h> |
|
||||
#else |
|
||||
# error "Unsupported platform." |
|
||||
#endif |
|
||||
|
|
||||
#include <boost/system/system_error.hpp> |
|
||||
#include <boost/throw_exception.hpp> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
/**
|
|
||||
* Generic implementation of the Process concept. |
|
||||
* |
|
||||
* The process class implements the Process concept in an operating system |
|
||||
* agnostic way. |
|
||||
*/ |
|
||||
class process |
|
||||
{ |
|
||||
public: |
|
||||
#if defined(BOOST_PROCESS_DOXYGEN) |
|
||||
/**
|
|
||||
* Opaque name for the native process' identifier type. |
|
||||
* |
|
||||
* Each operating system identifies processes using a specific type. |
|
||||
* The \a id_type type is used to transparently refer to a process |
|
||||
* regardless of the operating system in which this class is used. |
|
||||
* |
|
||||
* This type is guaranteed to be an integral type on all supported |
|
||||
* platforms. |
|
||||
*/ |
|
||||
typedef NativeProcessId id_type; |
|
||||
#elif defined(BOOST_POSIX_API) |
|
||||
typedef pid_t id_type; |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
typedef DWORD id_type; |
|
||||
#endif |
|
||||
|
|
||||
/**
|
|
||||
* Constructs a new process object. |
|
||||
* |
|
||||
* Creates a new process object that represents a running process |
|
||||
* within the system. |
|
||||
*/ |
|
||||
process(id_type id) |
|
||||
: id_(id) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Returns the process' identifier. |
|
||||
*/ |
|
||||
id_type get_id() const |
|
||||
{ |
|
||||
return id_; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Terminates the process execution. |
|
||||
* |
|
||||
* Forces the termination of the process execution. Some platforms |
|
||||
* allow processes to ignore some external termination notifications |
|
||||
* or to capture them for a proper exit cleanup. You can set the |
|
||||
* \a force flag to true in them to force their termination regardless |
|
||||
* of any exit handler. |
|
||||
* |
|
||||
* After this call, accessing this object can be dangerous because the |
|
||||
* process identifier may have been reused by a different process. It |
|
||||
* might still be valid, though, if the process has refused to die. |
|
||||
* |
|
||||
* \throw boost::system::system_error If the system call used to |
|
||||
* terminate the process fails. |
|
||||
*/ |
|
||||
void terminate(bool force = false) const |
|
||||
{ |
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
if (::kill(id_, force ? SIGKILL : SIGTERM) == -1) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(errno, boost::system::get_system_category()), "boost::process::process::terminate: kill(2) failed")); |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
HANDLE h = ::OpenProcess(PROCESS_TERMINATE, FALSE, id_); |
|
||||
if (h == NULL) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::process::terminate: OpenProcess failed")); |
|
||||
if (!::TerminateProcess(h, EXIT_FAILURE)) |
|
||||
{ |
|
||||
::CloseHandle(h); |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::process::terminate: TerminateProcess failed")); |
|
||||
} |
|
||||
if (!::CloseHandle(h)) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::process::terminate: CloseHandle failed")); |
|
||||
#endif |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
/**
|
|
||||
* The process' identifier. |
|
||||
*/ |
|
||||
id_type id_; |
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,134 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/self.hpp |
|
||||
* |
|
||||
* Includes the declaration of the self class. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_SELF_HPP |
|
||||
#define BOOST_PROCESS_SELF_HPP |
|
||||
|
|
||||
#include <boost/process/config.hpp> |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
# include <unistd.h> |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
# include <windows.h> |
|
||||
#else |
|
||||
# error "Unsupported platform." |
|
||||
#endif |
|
||||
|
|
||||
#include <boost/process/process.hpp> |
|
||||
#include <boost/process/environment.hpp> |
|
||||
#include <boost/system/system_error.hpp> |
|
||||
#include <boost/throw_exception.hpp> |
|
||||
#include <boost/noncopyable.hpp> |
|
||||
#include <string> |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
extern "C" |
|
||||
{ |
|
||||
extern char **environ; |
|
||||
} |
|
||||
#endif |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
/**
|
|
||||
* Generic implementation of the Process concept. |
|
||||
* |
|
||||
* The self singleton provides access to the current process. |
|
||||
*/ |
|
||||
class self : public process, boost::noncopyable |
|
||||
{ |
|
||||
public: |
|
||||
/**
|
|
||||
* Returns the self instance representing the caller's process. |
|
||||
*/ |
|
||||
static self &get_instance() |
|
||||
{ |
|
||||
static self *instance = 0; |
|
||||
if (!instance) |
|
||||
instance = new self; |
|
||||
return *instance; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Returns the current environment. |
|
||||
* |
|
||||
* Returns the current process' environment variables. Modifying the |
|
||||
* returned object has no effect on the current environment. |
|
||||
*/ |
|
||||
static environment get_environment() |
|
||||
{ |
|
||||
environment e; |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
char **env = ::environ; |
|
||||
while (*env) |
|
||||
{ |
|
||||
std::string s = *env; |
|
||||
std::string::size_type pos = s.find('='); |
|
||||
e.insert(boost::process::environment::value_type(s.substr(0, pos), s.substr(pos + 1))); |
|
||||
++env; |
|
||||
} |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
#ifdef GetEnvironmentStrings |
|
||||
#undef GetEnvironmentStrings |
|
||||
#endif |
|
||||
char *environ = ::GetEnvironmentStrings(); |
|
||||
if (!environ) |
|
||||
boost::throw_exception(boost::system::system_error(boost::system::error_code(::GetLastError(), boost::system::get_system_category()), "boost::process::self::get_environment: GetEnvironmentStrings failed")); |
|
||||
try |
|
||||
{ |
|
||||
char *env = environ; |
|
||||
while (*env) |
|
||||
{ |
|
||||
std::string s = env; |
|
||||
std::string::size_type pos = s.find('='); |
|
||||
e.insert(boost::process::environment::value_type(s.substr(0, pos), s.substr(pos + 1))); |
|
||||
env += s.size() + 1; |
|
||||
} |
|
||||
} |
|
||||
catch (...) |
|
||||
{ |
|
||||
::FreeEnvironmentStringsA(environ); |
|
||||
throw; |
|
||||
} |
|
||||
::FreeEnvironmentStringsA(environ); |
|
||||
#endif |
|
||||
|
|
||||
return e; |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
/**
|
|
||||
* Constructs a new self object. |
|
||||
* |
|
||||
* Creates a new self object that represents the current process. |
|
||||
*/ |
|
||||
self() : |
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
process(::getpid()) |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
process(::GetCurrentProcessId()) |
|
||||
#endif |
|
||||
{ |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,105 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/status.hpp |
|
||||
* |
|
||||
* Includes the declaration of the status class. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_STATUS_HPP |
|
||||
#define BOOST_PROCESS_STATUS_HPP |
|
||||
|
|
||||
#include <boost/process/config.hpp> |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
# include <sys/wait.h> |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
#else |
|
||||
# error "Unsupported platform." |
|
||||
#endif |
|
||||
|
|
||||
#include <boost/assert.hpp> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
class child; |
|
||||
|
|
||||
/**
|
|
||||
* Status returned by a finalized %child process. |
|
||||
* |
|
||||
* This class represents the %status returned by a child process after it |
|
||||
* has terminated. It only provides that information available under all |
|
||||
* supported platforms. |
|
||||
* |
|
||||
* \see posix_status |
|
||||
*/ |
|
||||
class status |
|
||||
{ |
|
||||
friend class child; |
|
||||
|
|
||||
public: |
|
||||
/**
|
|
||||
* Returns whether the process exited gracefully or not. |
|
||||
*/ |
|
||||
bool exited() const |
|
||||
{ |
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
return WIFEXITED(flags_); |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
return true; |
|
||||
#endif |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* If exited, returns the exit code. |
|
||||
* |
|
||||
* If the process exited, returns the exit code it returned. |
|
||||
* |
|
||||
* \pre exited() is true. |
|
||||
*/ |
|
||||
int exit_status() const |
|
||||
{ |
|
||||
BOOST_ASSERT(exited()); |
|
||||
#if defined(BOOST_POSIX_API) |
|
||||
return WEXITSTATUS(flags_); |
|
||||
#elif defined(BOOST_WINDOWS_API) |
|
||||
return flags_; |
|
||||
#endif |
|
||||
} |
|
||||
|
|
||||
protected: |
|
||||
/**
|
|
||||
* Creates a status object based on exit information. |
|
||||
* |
|
||||
* Creates a new status object representing the exit status of a |
|
||||
* child process. |
|
||||
* |
|
||||
* \param flags In a POSIX system this parameter contains the |
|
||||
* flags returned by the ::waitpid() call. In a |
|
||||
* Windows system it contains the exit code only. |
|
||||
*/ |
|
||||
status(int flags) |
|
||||
: flags_(flags) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* OS-specific codification of exit status. |
|
||||
*/ |
|
||||
int flags_; |
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,234 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/stream_behavior.hpp |
|
||||
* |
|
||||
* Includes the declaration of the stream_behavior class and associated |
|
||||
* free functions. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_STREAM_BEHAVIOR_HPP |
|
||||
#define BOOST_PROCESS_STREAM_BEHAVIOR_HPP |
|
||||
|
|
||||
#include <boost/process/config.hpp> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
namespace detail { |
|
||||
struct stream_info; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Describes the possible states for a communication stream. |
|
||||
*/ |
|
||||
class stream_behavior |
|
||||
{ |
|
||||
public: |
|
||||
friend struct detail::stream_info; |
|
||||
friend stream_behavior capture_stream(); |
|
||||
friend stream_behavior close_stream(); |
|
||||
friend stream_behavior inherit_stream(); |
|
||||
friend stream_behavior redirect_stream_to_stdout(); |
|
||||
friend stream_behavior silence_stream(); |
|
||||
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) |
|
||||
friend stream_behavior posix_redirect_stream(int to); |
|
||||
#endif |
|
||||
|
|
||||
/**
|
|
||||
* Describes the possible states for a communication stream. |
|
||||
*/ |
|
||||
enum type |
|
||||
{ |
|
||||
/**
|
|
||||
* The child's stream is connected to the parent by using an |
|
||||
* anonymous pipe so that they can send and receive data to/from |
|
||||
* each other. |
|
||||
*/ |
|
||||
capture, |
|
||||
|
|
||||
/**
|
|
||||
* The child's stream is closed upon startup so that it will not |
|
||||
* have any access to it. |
|
||||
*/ |
|
||||
close, |
|
||||
|
|
||||
/**
|
|
||||
* The child's stream is connected to the same stream used by the |
|
||||
* parent. In other words, the corresponding parent's stream is |
|
||||
* inherited. |
|
||||
*/ |
|
||||
inherit, |
|
||||
|
|
||||
/**
|
|
||||
* The child's stream is connected to child's standard output. |
|
||||
* This is typically used when configuring the standard error |
|
||||
* stream. |
|
||||
*/ |
|
||||
redirect_to_stdout, |
|
||||
|
|
||||
/**
|
|
||||
* The child's stream is redirected to a null device so that its |
|
||||
* input is always zero or its output is lost, depending on |
|
||||
* whether the stream is an input or an output one. It is |
|
||||
* important to notice that this is different from close because |
|
||||
* the child is still able to write data. If we closed, e.g. |
|
||||
* stdout, the child might not work at all! |
|
||||
*/ |
|
||||
silence, |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) |
|
||||
/**
|
|
||||
* The child redirects the stream's output to the provided file |
|
||||
* descriptor. This is a generalization of the portable |
|
||||
* redirect_to_stdout behavior. |
|
||||
*/ |
|
||||
posix_redirect |
|
||||
#endif |
|
||||
}; |
|
||||
|
|
||||
/**
|
|
||||
* Constructs a new stream behavior of type close. |
|
||||
* |
|
||||
* The public constructor creates a new stream behavior that defaults |
|
||||
* to the close behavior. In general, you will want to use the |
|
||||
* available free functions to construct a stream behavior (including |
|
||||
* the close one). |
|
||||
*/ |
|
||||
stream_behavior() |
|
||||
: type_(stream_behavior::close) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Returns this stream's behavior type. |
|
||||
*/ |
|
||||
type get_type() const |
|
||||
{ |
|
||||
return type_; |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
/**
|
|
||||
* Constructs a new stream behavior of type \a t. |
|
||||
* |
|
||||
* Constructs a new stream behavior of type \a t. It is the |
|
||||
* responsibility of the caller to fill in any other attributes |
|
||||
* required by the specified type, if any. |
|
||||
*/ |
|
||||
stream_behavior(type t) |
|
||||
: type_(t) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* This stream's behavior type. |
|
||||
*/ |
|
||||
type type_; |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) |
|
||||
/**
|
|
||||
* File descriptor the stream is redirected to. |
|
||||
*/ |
|
||||
int desc_to_; |
|
||||
#endif |
|
||||
}; |
|
||||
|
|
||||
/**
|
|
||||
* Creates a new stream_behavior of type stream_behavior::capture. |
|
||||
* |
|
||||
* Creates a new stream_behavior of type stream_behavior::capture, |
|
||||
* meaning that the child's stream is connected to the parent by using an |
|
||||
* anonymous pipe so that they can send and receive data to/from each |
|
||||
* other. |
|
||||
*/ |
|
||||
inline stream_behavior capture_stream() |
|
||||
{ |
|
||||
return stream_behavior(stream_behavior::capture); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Creates a new stream_behavior of type stream_behavior::close. |
|
||||
* |
|
||||
* Creates a new stream_behavior of type stream_behavior::close, |
|
||||
* meaning that the child's stream is closed upon startup so that it |
|
||||
* will not have any access to it. |
|
||||
*/ |
|
||||
inline stream_behavior close_stream() |
|
||||
{ |
|
||||
return stream_behavior(stream_behavior::close); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Creates a new stream_behavior of type stream_behavior::inherit. |
|
||||
* |
|
||||
* Creates a new stream_behavior of type stream_behavior::inherit, |
|
||||
* meaning that the child's stream is connected to the same stream used |
|
||||
* by the parent. In other words, the corresponding parent's stream is |
|
||||
* inherited. |
|
||||
*/ |
|
||||
inline stream_behavior inherit_stream() |
|
||||
{ |
|
||||
return stream_behavior(stream_behavior::inherit); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Creates a new stream_behavior of type |
|
||||
* stream_behavior::redirect_to_stdout. |
|
||||
* |
|
||||
* Creates a new stream_behavior of type |
|
||||
* stream_behavior::redirect_to_stdout, meaning that the child's stream is |
|
||||
* connected to child's standard output. This is typically used when |
|
||||
* configuring the standard error stream. |
|
||||
*/ |
|
||||
inline stream_behavior redirect_stream_to_stdout() |
|
||||
{ |
|
||||
return stream_behavior(stream_behavior::redirect_to_stdout); |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Creates a new stream_behavior of type stream_behavior::silence. |
|
||||
* |
|
||||
* Creates a new stream_behavior of type stream_behavior::silence, |
|
||||
* meaning that the child's stream is redirected to a null device so that |
|
||||
* its input is always zero or its output is lost, depending on whether |
|
||||
* the stream is an input or an output one. It is important to notice |
|
||||
* that this is different from close because the child is still able to |
|
||||
* write data. If we closed, e.g. stdout, the child might not work at |
|
||||
* all! |
|
||||
*/ |
|
||||
inline stream_behavior silence_stream() |
|
||||
{ |
|
||||
return stream_behavior(stream_behavior::silence); |
|
||||
} |
|
||||
|
|
||||
#if defined(BOOST_POSIX_API) || defined(BOOST_PROCESS_DOXYGEN) |
|
||||
/**
|
|
||||
* Creates a new stream_behavior of type stream_behavior::posix_redirect. |
|
||||
* |
|
||||
* Creates a new stream_behavior of type stream_behavior::posix_redirect, |
|
||||
* meaning that the child's stream is redirected to the \a to child's |
|
||||
* file descriptor. This is a generalization of the portable |
|
||||
* redirect_stream_to_stdout() behavior. |
|
||||
*/ |
|
||||
inline stream_behavior posix_redirect_stream(int to) |
|
||||
{ |
|
||||
stream_behavior sb(stream_behavior::posix_redirect); |
|
||||
sb.desc_to_ = to; |
|
||||
return sb; |
|
||||
} |
|
||||
#endif |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,128 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/win32_child.hpp |
|
||||
* |
|
||||
* Includes the declaration of the win32_child class. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_WIN32_CHILD_HPP |
|
||||
#define BOOST_PROCESS_WIN32_CHILD_HPP |
|
||||
|
|
||||
#include <boost/process/child.hpp> |
|
||||
#include <boost/process/detail/file_handle.hpp> |
|
||||
#include <windows.h> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
/**
|
|
||||
* Windows implementation of the Child concept. |
|
||||
* |
|
||||
* The win32_child class implements the Child concept in a Windows |
|
||||
* operating system. |
|
||||
* |
|
||||
* A Windows child differs from a regular %child (represented by a |
|
||||
* child object) in that it holds additional information about a process. |
|
||||
* Aside from the standard handle, it also includes a handle to the |
|
||||
* process' main thread, together with identifiers to both entities. |
|
||||
* |
|
||||
* This class is built on top of the generic child so as to allow its |
|
||||
* trivial adoption. When a program is changed to use the |
|
||||
* Windows-specific context (win32_context), it will most certainly need |
|
||||
* to migrate its use of the child class to win32_child. Doing so is only |
|
||||
* a matter of redefining the appropriate object and later using the |
|
||||
* required extra features: there should be no need to modify the existing |
|
||||
* code (e.g. method calls) in any other way. |
|
||||
*/ |
|
||||
class win32_child : public child |
|
||||
{ |
|
||||
public: |
|
||||
/**
|
|
||||
* Constructs a new Windows child object representing a just |
|
||||
* spawned %child process. |
|
||||
* |
|
||||
* Creates a new %child object that represents the process described by |
|
||||
* the \a pi structure. |
|
||||
* |
|
||||
* The \a fhstdin, \a fhstdout and \a fhstderr parameters hold the |
|
||||
* communication streams used to interact with the %child process if |
|
||||
* the launcher configured redirections. See the parent class' |
|
||||
* constructor for more details on these. |
|
||||
* |
|
||||
* \see child |
|
||||
*/ |
|
||||
win32_child(const PROCESS_INFORMATION &pi, detail::file_handle fhstdin, detail::file_handle fhstdout, detail::file_handle fhstderr) |
|
||||
: child(pi.dwProcessId, fhstdin, fhstdout, fhstderr, pi.hProcess), |
|
||||
process_information_(pi), |
|
||||
thread_handle_(process_information_.hThread) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Returns the process handle. |
|
||||
* |
|
||||
* Returns a process-specific handle that can be used to access the |
|
||||
* process. This is the value of the \a hProcess field in the |
|
||||
* PROCESS_INFORMATION structure returned by CreateProcess(). |
|
||||
* |
|
||||
* \see get_id() |
|
||||
*/ |
|
||||
HANDLE get_handle() const |
|
||||
{ |
|
||||
return process_information_.hProcess; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Returns the primary thread's handle. |
|
||||
* |
|
||||
* Returns a handle to the primary thread of the new process. This is |
|
||||
* the value of the \a hThread field in the PROCESS_INFORMATION |
|
||||
* structure returned by CreateProcess(). |
|
||||
* |
|
||||
* \see get_primary_thread_id() |
|
||||
*/ |
|
||||
HANDLE get_primary_thread_handle() const |
|
||||
{ |
|
||||
return process_information_.hThread; |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Returns the primary thread's identifier. |
|
||||
* |
|
||||
* Returns a system-wide value that identifies the process's primary |
|
||||
* thread. This is the value of the \a dwThreadId field in the |
|
||||
* PROCESS_INFORMATION structure returned by CreateProcess(). |
|
||||
* |
|
||||
* \see get_primary_thread_handle() |
|
||||
*/ |
|
||||
DWORD get_primary_thread_id() const |
|
||||
{ |
|
||||
return process_information_.dwThreadId; |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
/**
|
|
||||
* Windows-specific process information. |
|
||||
*/ |
|
||||
PROCESS_INFORMATION process_information_; |
|
||||
|
|
||||
/**
|
|
||||
* Thread handle owned by RAII object. |
|
||||
*/ |
|
||||
detail::file_handle thread_handle_; |
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,61 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/win_32context.hpp |
|
||||
* |
|
||||
* Includes the declaration of the win32_context class. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_WIN32_CONTEXT_HPP |
|
||||
#define BOOST_PROCESS_WIN32_CONTEXT_HPP |
|
||||
|
|
||||
#include <boost/process/context.hpp> |
|
||||
#include <string> |
|
||||
#include <windows.h> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
/**
|
|
||||
* Generic implementation of the Context concept. |
|
||||
* |
|
||||
* The context class implements the Context concept in an operating |
|
||||
* system agnostic way; it allows spawning new child processes using |
|
||||
* a single and common interface across different systems. |
|
||||
*/ |
|
||||
template <class String> |
|
||||
class win32_basic_context : public basic_context<String> |
|
||||
{ |
|
||||
public: |
|
||||
/**
|
|
||||
* Initializes the Win32-specific process startup information with NULL. |
|
||||
*/ |
|
||||
win32_basic_context() |
|
||||
: startupinfo(NULL) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/**
|
|
||||
* Win32-specific process startup information. |
|
||||
*/ |
|
||||
STARTUPINFOA *startupinfo; |
|
||||
}; |
|
||||
|
|
||||
/**
|
|
||||
* Default instantiation of win32_basic_context. |
|
||||
*/ |
|
||||
typedef win32_basic_context<std::string> win32_context; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -1,77 +0,0 @@ |
|||||
//
|
|
||||
// Boost.Process
|
|
||||
// ~~~~~~~~~~~~~
|
|
||||
//
|
|
||||
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
|
|
||||
// Copyright (c) 2008, 2009 Boris Schaeling
|
|
||||
//
|
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||
//
|
|
||||
|
|
||||
/**
|
|
||||
* \file boost/process/win32_operations.hpp |
|
||||
* |
|
||||
* Provides miscellaneous free functions specific to Windows operating |
|
||||
* systems. |
|
||||
*/ |
|
||||
|
|
||||
#ifndef BOOST_PROCESS_WIN32_OPERATIONS_HPP |
|
||||
#define BOOST_PROCESS_WIN32_OPERATIONS_HPP |
|
||||
|
|
||||
#include <boost/process/win32_child.hpp> |
|
||||
#include <boost/process/detail/file_handle.hpp> |
|
||||
#include <boost/process/detail/stream_info.hpp> |
|
||||
#include <boost/process/detail/win32_ops.hpp> |
|
||||
#include <windows.h> |
|
||||
|
|
||||
namespace boost { |
|
||||
namespace process { |
|
||||
|
|
||||
/**
|
|
||||
* Starts a new child process. |
|
||||
* |
|
||||
* Given an executable and the set of arguments passed to it, starts |
|
||||
* a new process with all the parameters configured in the context. |
|
||||
* The context can be reused afterwards to launch other different |
|
||||
* processes. |
|
||||
* |
|
||||
* \return A handle to the new child process. |
|
||||
*/ |
|
||||
template <class Executable, class Arguments, class Win32_Context> |
|
||||
inline win32_child win32_launch(const Executable &exe, const Arguments &args, const Win32_Context &ctx) |
|
||||
{ |
|
||||
detail::file_handle fhstdin, fhstdout, fhstderr; |
|
||||
|
|
||||
detail::stream_info behin = detail::stream_info(ctx.stdin_behavior, false); |
|
||||
if (behin.type_ == detail::stream_info::use_pipe) |
|
||||
fhstdin = behin.pipe_->wend(); |
|
||||
detail::stream_info behout = detail::stream_info(ctx.stdout_behavior, true); |
|
||||
if (behout.type_ == detail::stream_info::use_pipe) |
|
||||
fhstdout = behout.pipe_->rend(); |
|
||||
detail::stream_info beherr = detail::stream_info(ctx.stderr_behavior, true); |
|
||||
if (beherr.type_ == detail::stream_info::use_pipe) |
|
||||
fhstderr = beherr.pipe_->rend(); |
|
||||
|
|
||||
detail::win32_setup s; |
|
||||
s.work_directory = ctx.work_directory; |
|
||||
|
|
||||
STARTUPINFOA si; |
|
||||
if (!ctx.startupinfo) |
|
||||
{ |
|
||||
::ZeroMemory(&si, sizeof(si)); |
|
||||
si.cb = sizeof(si); |
|
||||
s.startupinfo = &si; |
|
||||
} |
|
||||
else |
|
||||
s.startupinfo = ctx.startupinfo; |
|
||||
|
|
||||
PROCESS_INFORMATION pi = detail::win32_start(exe, args, ctx.environment, behin, behout, beherr, s); |
|
||||
|
|
||||
return win32_child(pi, fhstdin, fhstdout, fhstderr); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
#endif |
|
@ -0,0 +1,27 @@ |
|||||
|
#!/usr/bin/python |
||||
|
# cpp-ethereum build script |
||||
|
# to be used from CI server, or to build locally |
||||
|
# uses python instead of bash script for better cross-platform support |
||||
|
|
||||
|
# TODO Initial version. Needs much more improvements |
||||
|
|
||||
|
import argparse |
||||
|
import os |
||||
|
import subprocess |
||||
|
|
||||
|
def build_dependencies(): |
||||
|
if os.path.exists("extdep"): |
||||
|
os.chdir("extdep") |
||||
|
if not os.path.exists("build"): |
||||
|
os.makedirs("build") |
||||
|
os.chdir("build") |
||||
|
subprocess.check_call(["cmake", ".."]) |
||||
|
subprocess.check_call("make") |
||||
|
|
||||
|
parser = argparse.ArgumentParser() |
||||
|
parser.add_argument("cmd", help="what to build") |
||||
|
|
||||
|
args = parser.parse_args() |
||||
|
if args.cmd == "dep": |
||||
|
build_dependencies() |
||||
|
|
@ -1,59 +1,39 @@ |
|||||
# Set necessary compile and link flags |
# Set necessary compile and link flags |
||||
|
|
||||
|
|
||||
# C++11 check and activation |
# C++11 check and activation |
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") |
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") |
||||
|
|
||||
|
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB -fPIC") |
||||
|
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") |
||||
|
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") |
||||
|
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE") |
||||
|
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG") |
||||
|
set(ETH_SHARED 1) |
||||
|
|
||||
execute_process( |
execute_process( |
||||
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) |
COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) |
||||
if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)) |
if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)) |
||||
message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.7 or greater.") |
message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.7 or greater.") |
||||
endif () |
endif () |
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") |
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") |
|
||||
else () |
|
||||
message(FATAL_ERROR "Your C++ compiler does not support C++11.") |
|
||||
endif () |
|
||||
|
|
||||
|
|
||||
|
|
||||
# Initialize CXXFLAGS |
|
||||
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB") |
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") |
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") |
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG -DETH_RELEASE") |
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG") |
|
||||
|
|
||||
# Windows |
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") |
||||
if ("${TARGET_PLATFORM}" STREQUAL "w64") |
|
||||
set(CMAKE_SYSTEM_NAME Windows) |
|
||||
|
|
||||
set(CMAKE_CXX_LIBRARY_ARCHITECTURE x86_64-w64-mingw32) |
|
||||
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) |
|
||||
set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) |
|
||||
set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) |
|
||||
set(CMAKE_AR x86_64-w64-mingw32-ar) |
|
||||
set(CMAKE_RANLIB x86_64-w64-mingw32-ranlib) |
|
||||
|
|
||||
set(CMAKE_EXECUTABLE_SUFFIX .exe) |
|
||||
|
|
||||
set(CMAKE_FIND_ROOT_PATH |
|
||||
/usr/x86_64-w64-mingw32 |
|
||||
) |
|
||||
|
|
||||
include_directories(/usr/x86_64-w64-mingw32/include/cryptopp) |
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB -fPIC") |
||||
|
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") |
||||
|
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") |
||||
|
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE") |
||||
|
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG") |
||||
|
set(ETH_SHARED 1) |
||||
|
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) |
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") |
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) |
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) |
|
||||
|
|
||||
set(CMAKE_INSTALL_PREFIX /usr/x86_64-w64-mingw32) |
# specify Exception Handling Model in msvc |
||||
set(ETH_BUILD_PLATFORM "windows") |
set(CMAKE_C_FLAGS "/EHsc") |
||||
|
set(CMAKE_CXX_FLAGS "/EHsc") |
||||
|
# windows likes static |
||||
set(ETH_STATIC 1) |
set(ETH_STATIC 1) |
||||
else () |
|
||||
set(ETH_BUILD_PLATFORM ${CMAKE_SYSTEM_NAME}) |
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") |
|
||||
set(ETH_SHARED 1) |
|
||||
endif() |
|
||||
|
|
||||
|
|
||||
|
else () |
||||
|
message(WARNING "Your compiler is not tested, if you run into any issues, we'd welcome any patches.") |
||||
|
endif () |
||||
|
|
||||
|
@ -0,0 +1,148 @@ |
|||||
|
# all dependencies that are not directly included in the cpp-ethereum distribution are defined here |
||||
|
# for this to work, download the dependency via the cmake script in extdep or install them manually! |
||||
|
|
||||
|
# by defining this variable, cmake will look for dependencies first in our own repository before looking in system paths like /usr/local/ ... |
||||
|
# this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory |
||||
|
string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) |
||||
|
set (ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") |
||||
|
set (CMAKE_PREFIX_PATH ${ETH_DEPENDENCY_INSTALL_DIR}) |
||||
|
|
||||
|
# Qt5 requires opengl |
||||
|
# TODO use proper version of windows SDK (32 vs 64) |
||||
|
# TODO make it possible to use older versions of windows SDK (7.0+ should also work) |
||||
|
# TODO it windows SDK is NOT FOUND, throw ERROR |
||||
|
if (WIN32) |
||||
|
set (CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:/Program Files/Windows Kits/8.1/Lib/winv6.3/um/x86") |
||||
|
message(" - Found windows 8.1 SDK") |
||||
|
#set (CMAKE_PREFIX_PATH "C:/Program Files/Windows Kits/8.1/Lib/winv6.3/um/x64") |
||||
|
endif() |
||||
|
|
||||
|
# homebrew installs qts in opt |
||||
|
if (APPLE) |
||||
|
set (CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/usr/local/opt/qt5") |
||||
|
endif() |
||||
|
|
||||
|
# Dependencies must have a version number, to ensure reproducible build. The version provided here is the one that is in the extdep repository. If you use system libraries, version numbers may be different. |
||||
|
|
||||
|
find_package (CryptoPP 5.6.2 EXACT REQUIRED) |
||||
|
message(" - CryptoPP header: ${CRYPTOPP_INCLUDE_DIRS}") |
||||
|
message(" - CryptoPP lib : ${CRYPTOPP_LIBRARIES}") |
||||
|
|
||||
|
find_package (LevelDB REQUIRED) |
||||
|
message(" - LevelDB header: ${LEVELDB_INCLUDE_DIRS}") |
||||
|
message(" - LevelDB lib: ${LEVELDB_LIBRARIES}") |
||||
|
|
||||
|
# TODO the Jsoncpp package does not yet check for correct version number |
||||
|
find_package (Jsoncpp 0.60 REQUIRED) |
||||
|
message(" - Jsoncpp header: ${JSONCPP_INCLUDE_DIRS}") |
||||
|
message(" - Jsoncpp lib : ${JSONCPP_LIBRARIES}") |
||||
|
|
||||
|
# TODO the JsonRpcCpp package does not yet check for correct version number |
||||
|
# json-rpc-cpp support is currently not mandatory |
||||
|
# TODO make headless client optional |
||||
|
# TODO get rid of -DETH_JSONRPC |
||||
|
if (JSONRPC) |
||||
|
|
||||
|
find_package (JsonRpcCpp 0.3.2) |
||||
|
if (NOT JSON_RPC_CPP_FOUND) |
||||
|
message (FATAL_ERROR "JSONRPC 0.3.2. not found") |
||||
|
endif() |
||||
|
message (" - json-rpc-cpp header: ${JSON_RPC_CPP_INCLUDE_DIRS}") |
||||
|
message (" - json-rpc-cpp lib : ${JSON_RPC_CPP_LIBRARIES}") |
||||
|
add_definitions(-DETH_JSONRPC) |
||||
|
|
||||
|
endif() #JSONRPC |
||||
|
|
||||
|
# TODO readline package does not yet check for correct version number |
||||
|
# TODO make readline package dependent on cmake options |
||||
|
# TODO get rid of -DETH_READLINE |
||||
|
find_package (Readline 6.3.8) |
||||
|
if (READLINE_FOUND) |
||||
|
message (" - readline header: ${READLINE_INCLUDE_DIRS}") |
||||
|
message (" - readline lib : ${READLINE_LIBRARIES}") |
||||
|
add_definitions(-DETH_READLINE) |
||||
|
endif () |
||||
|
|
||||
|
# TODO miniupnpc package does not yet check for correct version number |
||||
|
# TODO make miniupnpc package dependent on cmake options |
||||
|
# TODO get rid of -DMINIUPNPC |
||||
|
find_package (Miniupnpc 1.8.2013) |
||||
|
if (MINIUPNPC_FOUND) |
||||
|
message (" - miniupnpc header: ${MINIUPNPC_INCLUDE_DIRS}") |
||||
|
message (" - miniupnpc lib : ${MINIUPNPC_LIBRARIES}") |
||||
|
add_definitions(-DETH_MINIUPNPC) |
||||
|
endif() |
||||
|
|
||||
|
# TODO gmp package does not yet check for correct version number |
||||
|
# TODO it is also not required in msvc build |
||||
|
find_package (Gmp 6.0.0) |
||||
|
if (GMP_FOUND) |
||||
|
message(" - gmp Header: ${GMP_INCLUDE_DIRS}") |
||||
|
message(" - gmp lib : ${GMP_LIBRARIES}") |
||||
|
endif() |
||||
|
|
||||
|
# curl is only requried for tests |
||||
|
# TODO specify min curl version, on windows we are currently using 7.29 |
||||
|
find_package (CURL) |
||||
|
message(" - curl header: ${CURL_INCLUDE_DIRS}") |
||||
|
message(" - curl lib : ${CURL_LIBRARIES}") |
||||
|
|
||||
|
# do not compile GUI |
||||
|
if (NOT HEADLESS) |
||||
|
|
||||
|
# we need json rpc to build alethzero |
||||
|
if (NOT JSON_RPC_CPP_FOUND) |
||||
|
message (FATAL_ERROR "JSONRPC is required for GUI client") |
||||
|
endif() |
||||
|
|
||||
|
# find all of the Qt packages |
||||
|
# remember to use 'Qt' instead of 'QT', cause unix is case sensitive |
||||
|
# TODO make headless client optional |
||||
|
find_package (Qt5Core REQUIRED) |
||||
|
find_package (Qt5Gui REQUIRED) |
||||
|
find_package (Qt5Quick REQUIRED) |
||||
|
find_package (Qt5Qml REQUIRED) |
||||
|
find_package (Qt5Network REQUIRED) |
||||
|
find_package (Qt5Widgets REQUIRED) |
||||
|
find_package (Qt5WebKit REQUIRED) |
||||
|
find_package (Qt5WebKitWidgets REQUIRED) |
||||
|
|
||||
|
# we need to find path to macdeployqt on mac |
||||
|
if (APPLE) |
||||
|
set (MACDEPLOYQT_APP ${Qt5Core_DIR}/../../../bin/macdeployqt) |
||||
|
message(" - macdeployqt path: ${MACDEPLOYQT_APP}") |
||||
|
endif() |
||||
|
|
||||
|
endif() #HEADLESS |
||||
|
|
||||
|
# use multithreaded boost libraries, with -mt suffix |
||||
|
set(Boost_USE_MULTITHREADED ON) |
||||
|
|
||||
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") |
||||
|
|
||||
|
# TODO hanlde other msvc versions or it will fail find them |
||||
|
set(Boost_COMPILER -vc120) |
||||
|
# use static boost libraries *.lib |
||||
|
set(Boost_USE_STATIC_LIBS ON) |
||||
|
|
||||
|
elseif (APPLE) |
||||
|
|
||||
|
# use static boost libraries *.a |
||||
|
set(Boost_USE_STATIC_LIBS ON) |
||||
|
|
||||
|
elseif (UNIX) |
||||
|
# use dynamic boost libraries .dll |
||||
|
set(Boost_USE_STATIC_LIBS OFF) |
||||
|
|
||||
|
endif() |
||||
|
|
||||
|
find_package(Boost 1.54.0 REQUIRED COMPONENTS thread date_time system regex chrono filesystem unit_test_framework program_options) |
||||
|
|
||||
|
message(" - boost header: ${Boost_INCLUDE_DIRS}") |
||||
|
message(" - boost lib : ${Boost_LIBRARIES}") |
||||
|
|
||||
|
if (APPLE) |
||||
|
link_directories(/usr/local/lib) |
||||
|
include_directories(/usr/local/include) |
||||
|
endif() |
||||
|
|
@ -1,210 +0,0 @@ |
|||||
# search for and configure dependencies |
|
||||
|
|
||||
# deprecated. TODO will rewrite to proper CMake packages |
|
||||
|
|
||||
|
|
||||
|
|
||||
if("${TARGET_PLATFORM}" STREQUAL "w64") |
|
||||
# set(MINIUPNPC_LS /usr/x86_64-w64-mingw32/lib/libminiupnpc.a) |
|
||||
set(LEVELDB_LS leveldb) |
|
||||
set(CRYPTOPP_LS cryptopp) |
|
||||
set(CRYPTOPP_ID /usr/x86_64-w64-mingw32/include/cryptopp) |
|
||||
else() |
|
||||
# Look for available Crypto++ version and if it is >= 5.6.2 |
|
||||
find_path(ID cryptlib.h |
|
||||
../cryptopp/src |
|
||||
../../cryptopp/src |
|
||||
/usr/include/cryptopp |
|
||||
/usr/include/crypto++ |
|
||||
/usr/local/include/cryptopp |
|
||||
/usr/local/include/crypto++ |
|
||||
/opt/local/include/cryptopp |
|
||||
/opt/local/include/crypto++ |
|
||||
) |
|
||||
find_library(LS NAMES cryptoppeth cryptopp |
|
||||
../cryptopp/src/../target/build/release |
|
||||
../../cryptopp/src/../target/build/release |
|
||||
PATHS |
|
||||
/usr/lib |
|
||||
/usr/local/lib |
|
||||
/opt/local/lib |
|
||||
) |
|
||||
|
|
||||
if (ID AND LS) |
|
||||
message(STATUS "Found Crypto++: ${ID}, ${LS}") |
|
||||
set(_CRYPTOPP_VERSION_HEADER ${ID}/config.h) |
|
||||
if(EXISTS ${_CRYPTOPP_VERSION_HEADER}) |
|
||||
file(STRINGS ${_CRYPTOPP_VERSION_HEADER} _CRYPTOPP_VERSION REGEX "^#define CRYPTOPP_VERSION[ \t]+[0-9]+$") |
|
||||
string(REGEX REPLACE "^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION ${_CRYPTOPP_VERSION}) |
|
||||
if(${_CRYPTOPP_VERSION} LESS 562) |
|
||||
message(FATAL_ERROR "Crypto++ version found is smaller than 5.6.2.") |
|
||||
else() |
|
||||
set(CRYPTOPP_ID ${ID} CACHE FILEPATH "") |
|
||||
set(CRYPTOPP_LS ${LS} CACHE FILEPATH "") |
|
||||
message(STATUS "Crypto++ found and version greater or equal to 5.6.2") |
|
||||
endif() |
|
||||
endif() |
|
||||
else() |
|
||||
message(STATUS "Crypto++ Not Found: ${CRYPTOPP_ID}, ${CRYPTOPP_LS}") |
|
||||
endif() |
|
||||
|
|
||||
find_path( LEVELDB_ID leveldb/db.h |
|
||||
/usr/include |
|
||||
/usr/local/include |
|
||||
) |
|
||||
if ( LEVELDB_ID STREQUAL "LEVELDB_ID-NOTFOUND" ) |
|
||||
message(FATAL_ERROR "Failed to find the LevelDB headers") |
|
||||
else () |
|
||||
message(STATUS "Found LevelDB Headers") |
|
||||
|
|
||||
# Check for accessory dev libraries leveldb and miniupnpc |
|
||||
find_library( LEVELDB_LS NAMES leveldb |
|
||||
PATHS |
|
||||
/usr/lib |
|
||||
/usr/local/lib |
|
||||
/opt/local/lib |
|
||||
/usr/lib/*/ |
|
||||
) |
|
||||
if ( LEVELDB_LS STREQUAL "LEVELDB_LS-NOTFOUND" ) |
|
||||
message(FATAL_ERROR "Failed to find the LevelDB Library!") |
|
||||
else () |
|
||||
message(STATUS "Found LevelDB Library: ${LEVELDB_LS}") |
|
||||
add_definitions(-DETH_LEVELDB) |
|
||||
endif () |
|
||||
endif () |
|
||||
|
|
||||
find_path( PYTHON_ID pyconfig.h |
|
||||
${PYTHON_INCLUDE_DIR} |
|
||||
/usr/include/python2.7 |
|
||||
/usr/local/include/python2.7 |
|
||||
) |
|
||||
if ( PYTHON_ID STREQUAL "PYTHON_ID-NOTFOUND" ) |
|
||||
message(STATUS "Failed to find the Python-2.7 headers") |
|
||||
else () |
|
||||
message(STATUS "Found Python-2.7 Headers: ${PYTHON_ID}") |
|
||||
|
|
||||
# Check for accessory dev libraries leveldb and miniupnpc |
|
||||
find_library( PYTHON_LS NAMES python2.7 |
|
||||
PATHS |
|
||||
/usr/lib |
|
||||
/usr/local/lib |
|
||||
/opt/local/lib |
|
||||
/usr/lib/*/ |
|
||||
) |
|
||||
if ( PYTHON_LS STREQUAL "PYTHON_LS-NOTFOUND" ) |
|
||||
message(STATUS "Failed to find the Python-2.7 Library!") |
|
||||
set(PYTHON_ID) |
|
||||
set(PYTHON_LS) |
|
||||
else () |
|
||||
message(STATUS "Found Python-2.7 Library: ${PYTHON_LS}") |
|
||||
add_definitions(-DETH_PYTHON) |
|
||||
endif () |
|
||||
endif () |
|
||||
|
|
||||
find_path( MINIUPNPC_ID miniupnpc/miniwget.h |
|
||||
/usr/include |
|
||||
/usr/local/include |
|
||||
) |
|
||||
if ( MINIUPNPC_ID ) |
|
||||
message(STATUS "Found miniupnpc headers") |
|
||||
|
|
||||
find_library( MINIUPNPC_LS NAMES miniupnpc |
|
||||
PATHS |
|
||||
/usr/lib |
|
||||
/usr/local/lib |
|
||||
/opt/local/lib |
|
||||
/usr/lib/*/ |
|
||||
) |
|
||||
if ( MINIUPNPC_LS ) |
|
||||
message(STATUS "Found miniupnpc library: ${MINIUPNPC_LS}") |
|
||||
add_definitions(-DETH_MINIUPNPC) |
|
||||
else () |
|
||||
message(STATUS "Failed to find the miniupnpc library!") |
|
||||
endif () |
|
||||
else () |
|
||||
message(STATUS "Failed to find the miniupnpc headers!") |
|
||||
endif () |
|
||||
|
|
||||
find_path( JSONRPC_ID jsonrpc/rpc.h |
|
||||
/usr/include |
|
||||
/usr/local/include |
|
||||
../libjson-rpc-cpp/src |
|
||||
) |
|
||||
if ( JSONRPC_ID ) |
|
||||
message(STATUS "Found jsonrpc headers") |
|
||||
find_library( JSONRPC_LS NAMES jsonrpc |
|
||||
PATHS |
|
||||
/usr/lib |
|
||||
/usr/local/lib |
|
||||
/opt/local/lib |
|
||||
/usr/lib/*/ |
|
||||
../libjson-rpc-cpp/build/out |
|
||||
) |
|
||||
if ( JSONRPC_LS ) |
|
||||
message(STATUS "Found jsonrpc library: ${JSONRPC_LS}") |
|
||||
add_definitions(-DETH_JSONRPC) |
|
||||
else () |
|
||||
message(STATUS "Failed to find the jsonrpc library!") |
|
||||
endif () |
|
||||
else () |
|
||||
message(STATUS "Failed to find the jsonrpc headers!") |
|
||||
endif () |
|
||||
|
|
||||
find_path( READLINE_ID readline/readline.h |
|
||||
/usr/include |
|
||||
/usr/local/include |
|
||||
) |
|
||||
if ( READLINE_ID ) |
|
||||
message(STATUS "Found readline headers") |
|
||||
find_library( READLINE_LS NAMES readline |
|
||||
PATHS |
|
||||
/usr/lib |
|
||||
/usr/local/lib |
|
||||
/opt/local/lib |
|
||||
/usr/lib/*/ |
|
||||
) |
|
||||
if ( READLINE_LS ) |
|
||||
message(STATUS "Found readline library: ${READLINE_LS}") |
|
||||
add_definitions(-DETH_READLINE) |
|
||||
else () |
|
||||
message(STATUS "Failed to find the readline library!") |
|
||||
endif () |
|
||||
else () |
|
||||
message(STATUS "Failed to find the readline headers!") |
|
||||
endif () |
|
||||
|
|
||||
if (LANGUAGES) |
|
||||
find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time) |
|
||||
else() |
|
||||
find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time system regex) |
|
||||
endif() |
|
||||
|
|
||||
set(QTQML 1) |
|
||||
endif() |
|
||||
|
|
||||
if(CRYPTOPP_ID) |
|
||||
include_directories(${CRYPTOPP_ID}) |
|
||||
endif() |
|
||||
if(PYTHON_ID) |
|
||||
include_directories(${PYTHON_ID}) |
|
||||
endif() |
|
||||
if(MINIUPNPC_ID) |
|
||||
include_directories(${MINIUPNPC_ID}) |
|
||||
endif() |
|
||||
if(LEVELDB_ID) |
|
||||
include_directories(${LEVELDB_ID}) |
|
||||
endif() |
|
||||
if(READLINE_ID) |
|
||||
include_directories(${READLINE_ID}) |
|
||||
endif() |
|
||||
if(JSONRPC_ID) |
|
||||
include_directories(${JSONRPC_ID}) |
|
||||
endif() |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") |
|
||||
link_directories(/usr/local/lib) |
|
||||
include_directories(/usr/local/include) |
|
||||
endif() |
|
@ -0,0 +1,152 @@ |
|||||
|
# |
||||
|
# this function requires the following variables to be specified: |
||||
|
# ETH_VERSION |
||||
|
# PROJECT_NAME |
||||
|
# PROJECT_VERSION |
||||
|
# PROJECT_COPYRIGHT_YEAR |
||||
|
# PROJECT_VENDOR |
||||
|
# PROJECT_DOMAIN_SECOND |
||||
|
# PROJECT_DOMAIN_FIRST |
||||
|
# SRC_LIST |
||||
|
# HEADERS |
||||
|
# |
||||
|
# params: |
||||
|
# ICON |
||||
|
# |
||||
|
|
||||
|
macro(eth_add_executable EXECUTABLE) |
||||
|
set (extra_macro_args ${ARGN}) |
||||
|
set (options) |
||||
|
set (one_value_args ICON) |
||||
|
set (multi_value_args UI_RESOURCES WIN_RESOURCES) |
||||
|
cmake_parse_arguments (ETH_ADD_EXECUTABLE "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}") |
||||
|
|
||||
|
if (APPLE) |
||||
|
|
||||
|
add_executable(${EXECUTABLE} MACOSX_BUNDLE ${SRC_LIST} ${HEADERS} ${ETH_ADD_EXECUTABLE_UI_RESOURCES}) |
||||
|
set(PROJECT_VERSION "${ETH_VERSION}") |
||||
|
set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") |
||||
|
set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}") |
||||
|
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") |
||||
|
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") |
||||
|
set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") |
||||
|
set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") |
||||
|
set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE}) |
||||
|
set(MACOSX_BUNDLE_ICON_FILE ${ETH_ADD_EXECUTABLE_ICON}) |
||||
|
set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") |
||||
|
set_source_files_properties(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) |
||||
|
set_source_files_properties(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) |
||||
|
|
||||
|
else () |
||||
|
add_executable(${EXECUTABLE} ${ETH_ADD_EXECUTABLE_UI_RESOURCES} ${ETH_ADD_EXECUTABLE_WIN_RESOURCES} ${SRC_LIST} ${HEADERS}) |
||||
|
endif() |
||||
|
|
||||
|
endmacro() |
||||
|
|
||||
|
# |
||||
|
# this function requires the following variables to be specified: |
||||
|
# ETH_DEPENDENCY_INSTALL_DIR |
||||
|
# |
||||
|
# params: |
||||
|
# QMLDIR |
||||
|
# |
||||
|
|
||||
|
macro(eth_install_executable EXECUTABLE) |
||||
|
|
||||
|
set (extra_macro_args ${ARGN}) |
||||
|
set (options) |
||||
|
set (one_value_args QMLDIR) |
||||
|
set (multi_value_args) |
||||
|
cmake_parse_arguments (ETH_INSTALL_EXECUTABLE "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}") |
||||
|
|
||||
|
if (ETH_INSTALL_EXECUTABLE_QMLDIR) |
||||
|
if (APPLE) |
||||
|
set(eth_qml_dir "-qmldir=${ETH_INSTALL_EXECUTABLE_QMLDIR}") |
||||
|
elseif (WIN32) |
||||
|
set(eth_qml_dir --qmldir ${ETH_INSTALL_EXECUTABLE_QMLDIR}) |
||||
|
endif() |
||||
|
message(STATUS "${EXECUTABLE} qmldir: ${eth_qml_dir}") |
||||
|
endif() |
||||
|
|
||||
|
if (APPLE) |
||||
|
# First have qt5 install plugins and frameworks |
||||
|
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD |
||||
|
COMMAND ${MACDEPLOYQT_APP} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app ${eth_qml_dir} |
||||
|
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} |
||||
|
) |
||||
|
|
||||
|
# This tool and next will inspect linked libraries in order to determine which dependencies are required |
||||
|
if (${CMAKE_CFG_INTDIR} STREQUAL ".") |
||||
|
set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.app") |
||||
|
else () |
||||
|
set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTABLE}.app") |
||||
|
endif () |
||||
|
|
||||
|
# TODO check, how fixup_bundle works and if it is required |
||||
|
install(CODE " |
||||
|
include(BundleUtilities) |
||||
|
set(BU_CHMOD_BUNDLE_ITEMS 1) |
||||
|
fixup_bundle(\"${APP_BUNDLE_PATH}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\") |
||||
|
" COMPONENT RUNTIME ) |
||||
|
# Cleanup duplicate libs from macdeployqt |
||||
|
install(CODE " |
||||
|
file(GLOB LINGER_RM \"${APP_BUNDLE_PATH}/Contents/Frameworks/*.dylib\") |
||||
|
if (LINGER_RM) |
||||
|
file(REMOVE \${LINGER_RM}) |
||||
|
endif () |
||||
|
") |
||||
|
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") |
||||
|
|
||||
|
# copy all dlls to executable directory |
||||
|
# TODO improve that by copying only required dlls |
||||
|
file (GLOB DLLS ${ETH_DEPENDENCY_INSTALL_DIR}/bin/*.dll) |
||||
|
|
||||
|
foreach(DLL ${DLLS}) |
||||
|
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD |
||||
|
COMMAND cmake -E copy "${DLL}" "$<TARGET_FILE_DIR:${EXECUTABLE}>" |
||||
|
) |
||||
|
endforeach() |
||||
|
|
||||
|
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD |
||||
|
COMMAND cmake -E copy_directory |
||||
|
"${ETH_DEPENDENCY_INSTALL_DIR}/plugins/platforms" |
||||
|
$<TARGET_FILE_DIR:${EXECUTABLE}>/platforms |
||||
|
) |
||||
|
|
||||
|
# ugly way, improve that |
||||
|
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD |
||||
|
COMMAND cmake -E copy_directory |
||||
|
"${ETH_DEPENDENCY_INSTALL_DIR}/qml" |
||||
|
$<TARGET_FILE_DIR:${EXECUTABLE}> |
||||
|
) |
||||
|
|
||||
|
install( FILES ${DLLS} |
||||
|
DESTINATION bin |
||||
|
COMPONENT ${EXECUTABLE} |
||||
|
) |
||||
|
|
||||
|
install( DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/plugins/platforms |
||||
|
DESTINATION bin |
||||
|
COMPONENT ${EXECUTABLE} |
||||
|
) |
||||
|
|
||||
|
file (GLOB QMLS ${ETH_DEPENDENCY_INSTALL_DIR}/qml/*) |
||||
|
foreach(QML ${QMLS}) |
||||
|
install( DIRECTORY ${QML} |
||||
|
DESTINATION bin |
||||
|
COMPONENT ${EXECUTABLE} |
||||
|
) |
||||
|
endforeach() |
||||
|
|
||||
|
install( TARGETS ${EXECUTABLE} RUNTIME |
||||
|
DESTINATION bin |
||||
|
COMPONENT ${EXECUTABLE} |
||||
|
) |
||||
|
|
||||
|
else() |
||||
|
install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) |
||||
|
endif () |
||||
|
|
||||
|
endmacro() |
||||
|
|
||||
|
|
@ -0,0 +1,49 @@ |
|||||
|
# Find CURL |
||||
|
# |
||||
|
# Find the curl includes and library |
||||
|
# |
||||
|
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH |
||||
|
# |
||||
|
# This module defines |
||||
|
# CURL_INCLUDE_DIRS, where to find header, etc. |
||||
|
# CURL_LIBRARIES, the libraries needed to use curl. |
||||
|
# CURL_FOUND, If false, do not try to use curl. |
||||
|
|
||||
|
# only look in default directories |
||||
|
find_path( |
||||
|
CURL_INCLUDE_DIR |
||||
|
NAMES curl/curl.h |
||||
|
DOC "curl include dir" |
||||
|
) |
||||
|
|
||||
|
find_library( |
||||
|
CURL_LIBRARY |
||||
|
# names from cmake's FindCURL |
||||
|
NAMES curl curllib libcurl_imp curllib_static libcurl |
||||
|
DOC "curl library" |
||||
|
) |
||||
|
|
||||
|
set(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR}) |
||||
|
set(CURL_LIBRARIES ${CURL_LIBRARY}) |
||||
|
|
||||
|
# debug library on windows |
||||
|
# same naming convention as in qt (appending debug library with d) |
||||
|
# boost is using the same "hack" as us with "optimized" and "debug" |
||||
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") |
||||
|
find_library( |
||||
|
CURL_LIBRARY_DEBUG |
||||
|
NAMES curld libcurld |
||||
|
DOC "curl debug library" |
||||
|
) |
||||
|
|
||||
|
set(CURL_LIBRARIES optimized ${CURL_LIBRARIES} debug ${CURL_LIBRARY_DEBUG}) |
||||
|
|
||||
|
endif() |
||||
|
|
||||
|
# handle the QUIETLY and REQUIRED arguments and set CURL_FOUND to TRUE |
||||
|
# if all listed variables are TRUE, hide their existence from configuration view |
||||
|
include(FindPackageHandleStandardArgs) |
||||
|
find_package_handle_standard_args(CURL DEFAULT_MSG |
||||
|
CURL_INCLUDE_DIR CURL_LIBRARY) |
||||
|
mark_as_advanced (CURL_INCLUDE_DIR CURL_LIBRARY) |
||||
|
|
@ -0,0 +1,108 @@ |
|||||
|
# Module for locating the Crypto++ encryption library. |
||||
|
# |
||||
|
# Customizable variables: |
||||
|
# CRYPTOPP_ROOT_DIR |
||||
|
# This variable points to the CryptoPP root directory. On Windows the |
||||
|
# library location typically will have to be provided explicitly using the |
||||
|
# -D command-line option. The directory should include the include/cryptopp, |
||||
|
# lib and/or bin sub-directories. |
||||
|
# |
||||
|
# Read-only variables: |
||||
|
# CRYPTOPP_FOUND |
||||
|
# Indicates whether the library has been found. |
||||
|
# |
||||
|
# CRYPTOPP_INCLUDE_DIRS |
||||
|
# Points to the CryptoPP include directory. |
||||
|
# |
||||
|
# CRYPTOPP_LIBRARIES |
||||
|
# Points to the CryptoPP libraries that should be passed to |
||||
|
# target_link_libararies. |
||||
|
# |
||||
|
# |
||||
|
# Copyright (c) 2012 Sergiu Dotenco |
||||
|
# |
||||
|
# 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. |
||||
|
|
||||
|
INCLUDE (FindPackageHandleStandardArgs) |
||||
|
|
||||
|
FIND_PATH (CRYPTOPP_ROOT_DIR |
||||
|
NAMES cryptopp/cryptlib.h include/cryptopp/cryptlib.h |
||||
|
PATHS ENV CRYPTOPPROOT |
||||
|
DOC "CryptoPP root directory") |
||||
|
|
||||
|
# Re-use the previous path: |
||||
|
FIND_PATH (CRYPTOPP_INCLUDE_DIR |
||||
|
NAMES cryptopp/cryptlib.h |
||||
|
HINTS ${CRYPTOPP_ROOT_DIR} |
||||
|
PATH_SUFFIXES include |
||||
|
DOC "CryptoPP include directory") |
||||
|
|
||||
|
FIND_LIBRARY (CRYPTOPP_LIBRARY_DEBUG |
||||
|
NAMES cryptlibd cryptoppd |
||||
|
HINTS ${CRYPTOPP_ROOT_DIR} |
||||
|
PATH_SUFFIXES lib |
||||
|
DOC "CryptoPP debug library") |
||||
|
|
||||
|
FIND_LIBRARY (CRYPTOPP_LIBRARY_RELEASE |
||||
|
NAMES cryptlib cryptopp |
||||
|
HINTS ${CRYPTOPP_ROOT_DIR} |
||||
|
PATH_SUFFIXES lib |
||||
|
DOC "CryptoPP release library") |
||||
|
|
||||
|
IF (CRYPTOPP_LIBRARY_DEBUG AND CRYPTOPP_LIBRARY_RELEASE) |
||||
|
SET (CRYPTOPP_LIBRARY |
||||
|
optimized ${CRYPTOPP_LIBRARY_RELEASE} |
||||
|
debug ${CRYPTOPP_LIBRARY_DEBUG} CACHE DOC "CryptoPP library") |
||||
|
ELSEIF (CRYPTOPP_LIBRARY_RELEASE) |
||||
|
SET (CRYPTOPP_LIBRARY ${CRYPTOPP_LIBRARY_RELEASE} CACHE DOC |
||||
|
"CryptoPP library") |
||||
|
ENDIF (CRYPTOPP_LIBRARY_DEBUG AND CRYPTOPP_LIBRARY_RELEASE) |
||||
|
|
||||
|
IF (CRYPTOPP_INCLUDE_DIR) |
||||
|
SET (_CRYPTOPP_VERSION_HEADER ${CRYPTOPP_INCLUDE_DIR}/cryptopp/config.h) |
||||
|
|
||||
|
IF (EXISTS ${_CRYPTOPP_VERSION_HEADER}) |
||||
|
FILE (STRINGS ${_CRYPTOPP_VERSION_HEADER} _CRYPTOPP_VERSION_TMP REGEX |
||||
|
"^#define CRYPTOPP_VERSION[ \t]+[0-9]+$") |
||||
|
|
||||
|
STRING (REGEX REPLACE |
||||
|
"^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION_TMP |
||||
|
${_CRYPTOPP_VERSION_TMP}) |
||||
|
|
||||
|
STRING (REGEX REPLACE "([0-9]+)[0-9][0-9]" "\\1" CRYPTOPP_VERSION_MAJOR |
||||
|
${_CRYPTOPP_VERSION_TMP}) |
||||
|
STRING (REGEX REPLACE "[0-9]([0-9])[0-9]" "\\1" CRYPTOPP_VERSION_MINOR |
||||
|
${_CRYPTOPP_VERSION_TMP}) |
||||
|
STRING (REGEX REPLACE "[0-9][0-9]([0-9])" "\\1" CRYPTOPP_VERSION_PATCH |
||||
|
${_CRYPTOPP_VERSION_TMP}) |
||||
|
|
||||
|
SET (CRYPTOPP_VERSION_COUNT 3) |
||||
|
SET (CRYPTOPP_VERSION |
||||
|
${CRYPTOPP_VERSION_MAJOR}.${CRYPTOPP_VERSION_MINOR}.${CRYPTOPP_VERSION_PATCH}) |
||||
|
ENDIF (EXISTS ${_CRYPTOPP_VERSION_HEADER}) |
||||
|
ENDIF (CRYPTOPP_INCLUDE_DIR) |
||||
|
|
||||
|
SET (CRYPTOPP_INCLUDE_DIRS ${CRYPTOPP_INCLUDE_DIR}) |
||||
|
SET (CRYPTOPP_LIBRARIES ${CRYPTOPP_LIBRARY}) |
||||
|
|
||||
|
MARK_AS_ADVANCED (CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARY CRYPTOPP_LIBRARY_DEBUG |
||||
|
CRYPTOPP_LIBRARY_RELEASE) |
||||
|
|
||||
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS (CryptoPP REQUIRED_VARS |
||||
|
CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARY VERSION_VAR CRYPTOPP_VERSION) |
@ -0,0 +1,34 @@ |
|||||
|
# Find gmp |
||||
|
# |
||||
|
# Find the gmp includes and library |
||||
|
# |
||||
|
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH |
||||
|
# |
||||
|
# This module defines |
||||
|
# GMP_INCLUDE_DIRS, where to find header, etc. |
||||
|
# GMP_LIBRARIES, the libraries needed to use gmp. |
||||
|
# GMP_FOUND, If false, do not try to use gmp. |
||||
|
|
||||
|
# only look in default directories |
||||
|
find_path( |
||||
|
GMP_INCLUDE_DIR |
||||
|
NAMES gmp.h |
||||
|
DOC "gmp include dir" |
||||
|
) |
||||
|
|
||||
|
find_library( |
||||
|
GMP_LIBRARY |
||||
|
NAMES gmp |
||||
|
DOC "gmp library" |
||||
|
) |
||||
|
|
||||
|
set(GMP_INCLUDE_DIRS ${GMP_INCLUDE_DIR}) |
||||
|
set(GMP_LIBRARIES ${GMP_LIBRARY}) |
||||
|
|
||||
|
# handle the QUIETLY and REQUIRED arguments and set GMP_FOUND to TRUE |
||||
|
# if all listed variables are TRUE, hide their existence from configuration view |
||||
|
include(FindPackageHandleStandardArgs) |
||||
|
find_package_handle_standard_args(gmp DEFAULT_MSG |
||||
|
GMP_INCLUDE_DIR GMP_LIBRARY) |
||||
|
mark_as_advanced (GMP_INCLUDE_DIR GMP_LIBRARY) |
||||
|
|
@ -0,0 +1,99 @@ |
|||||
|
# Find json-rcp-cpp |
||||
|
# |
||||
|
# Find the json-rpc-cpp includes and library |
||||
|
# |
||||
|
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH |
||||
|
# |
||||
|
# This module defines |
||||
|
# JSON_RCP_CPP_INCLUDE_DIRS, where to find header, etc. |
||||
|
# JSON_RCP_CPP_LIBRARIES, the libraries needed to use json-rpc-cpp. |
||||
|
# JSON_RPC_CPP_SERVER_LIBRARIES, the libraries needed to use json-rpc-cpp-server |
||||
|
# JSON_RPC_CPP_CLIENT_LIBRARIES, the libraries needed to use json-rpc-cpp-client |
||||
|
# JSON_RCP_CPP_FOUND, If false, do not try to use json-rpc-cpp. |
||||
|
|
||||
|
# only look in default directories |
||||
|
find_path( |
||||
|
JSON_RPC_CPP_INCLUDE_DIR |
||||
|
NAMES jsonrpccpp/server.h |
||||
|
PATH_SUFFIXES jsonrpc |
||||
|
DOC "json-rpc-cpp include dir" |
||||
|
) |
||||
|
|
||||
|
find_library( |
||||
|
JSON_RPC_CPP_COMMON_LIBRARY |
||||
|
NAMES jsonrpccpp-common |
||||
|
DOC "json-rpc-cpp common library" |
||||
|
) |
||||
|
|
||||
|
find_library( |
||||
|
JSON_RPC_CPP_SERVER_LIBRARY |
||||
|
NAMES jsonrpccpp-server |
||||
|
DOC "json-rpc-cpp server library" |
||||
|
) |
||||
|
|
||||
|
find_library( |
||||
|
JSON_RPC_CPP_CLIENT_LIBRARY |
||||
|
NAMES jsonrpccpp-client |
||||
|
DOC "json-rpc-cpp client library" |
||||
|
) |
||||
|
|
||||
|
# these are the variables to be uses by the calling script |
||||
|
set (JSON_RPC_CPP_INCLUDE_DIRS ${JSON_RPC_CPP_INCLUDE_DIR}) |
||||
|
set (JSON_RPC_CPP_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_SERVER_LIBRARY} ${JSON_RPC_CPP_CLIENT_LIBRARY}) |
||||
|
set (JSON_RPC_CPP_SERVER_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_SERVER_LIBRARY}) |
||||
|
set (JSON_RPC_CPP_CLIENT_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_CLIENT_LIBRARY}) |
||||
|
|
||||
|
# debug library on windows |
||||
|
# same naming convention as in qt (appending debug library with d) |
||||
|
# boost is using the same "hack" as us with "optimized" and "debug" |
||||
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") |
||||
|
find_library( |
||||
|
JSON_RPC_CPP_COMMON_LIBRARY_DEBUG |
||||
|
NAMES jsonrpccpp-commond |
||||
|
DOC "json-rpc-cpp common debug library" |
||||
|
) |
||||
|
|
||||
|
find_library( |
||||
|
JSON_RPC_CPP_SERVER_LIBRARY_DEBUG |
||||
|
NAMES jsonrpccpp-serverd |
||||
|
DOC "json-rpc-cpp server debug library" |
||||
|
) |
||||
|
|
||||
|
find_library( |
||||
|
JSON_RPC_CPP_CLIENT_LIBRARY_DEBUG |
||||
|
NAMES jsonrpccpp-clientd |
||||
|
DOC "json-rpc-cpp client debug library" |
||||
|
) |
||||
|
|
||||
|
set (JSON_RPC_CPP_LIBRARIES |
||||
|
optimized ${JSON_RPC_CPP_COMMON_LIBRARY} |
||||
|
optimized ${JSON_RPC_CPP_SERVER_LIBRARY} |
||||
|
optimized ${JSON_RPC_CPP_CLIENT_LIBRARY} |
||||
|
debug ${JSON_RPC_CPP_COMMON_LIBRARY_DEBUG} |
||||
|
debug ${JSON_RPC_CPP_SERVER_LIBRARY_DEBUG} |
||||
|
debug ${JSON_RPC_CPP_CLIENT_LIBRARY_DEBUG} |
||||
|
) |
||||
|
|
||||
|
set (JSON_RPC_CPP_SERVER_LIBRARIES |
||||
|
optimized ${JSON_RPC_CPP_COMMON_LIBRARY} |
||||
|
optimized ${JSON_RPC_CPP_SERVER_LIBRARY} |
||||
|
debug ${JSON_RPC_CPP_COMMON_LIBRARY_DEBUG} |
||||
|
debug ${JSON_RPC_CPP_SERVER_LIBRARY_DEBUG} |
||||
|
) |
||||
|
|
||||
|
set (JSON_RPC_CPP_CLIENT_LIBRARIES |
||||
|
optimized ${JSON_RPC_CPP_COMMON_LIBRARY} |
||||
|
optimized ${JSON_RPC_CPP_CLIENT_LIBRARY} |
||||
|
debug ${JSON_RPC_CPP_COMMON_LIBRARY_DEBUG} |
||||
|
debug ${JSON_RPC_CPP_CLIENT_LIBRARY_DEBUG} |
||||
|
) |
||||
|
|
||||
|
endif() |
||||
|
|
||||
|
# handle the QUIETLY and REQUIRED arguments and set JSON_RPC_CPP_FOUND to TRUE |
||||
|
# if all listed variables are TRUE, hide their existence from configuration view |
||||
|
include(FindPackageHandleStandardArgs) |
||||
|
find_package_handle_standard_args(json_rpc_cpp DEFAULT_MSG |
||||
|
JSON_RPC_CPP_COMMON_LIBRARY JSON_RPC_CPP_SERVER_LIBRARY JSON_RPC_CPP_CLIENT_LIBRARY JSON_RPC_CPP_INCLUDE_DIR) |
||||
|
mark_as_advanced (JSON_RPC_CPP_COMMON_LIBRARY JSON_RPC_CPP_SERVER_LIBRARY JSON_RPC_CPP_CLIENT_LIBRARY JSON_RPC_CPP_INCLUDE_DIR) |
||||
|
|
@ -0,0 +1,48 @@ |
|||||
|
# Find jsoncpp |
||||
|
# |
||||
|
# Find the jsoncpp includes and library |
||||
|
# |
||||
|
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH |
||||
|
# |
||||
|
# This module defines |
||||
|
# JSONCPP_INCLUDE_DIRS, where to find header, etc. |
||||
|
# JSONCPP_LIBRARIES, the libraries needed to use jsoncpp. |
||||
|
# JSONCPP_FOUND, If false, do not try to use jsoncpp. |
||||
|
|
||||
|
# only look in default directories |
||||
|
find_path( |
||||
|
JSONCPP_INCLUDE_DIR |
||||
|
NAMES jsoncpp/json/json.h |
||||
|
DOC "jsoncpp include dir" |
||||
|
) |
||||
|
|
||||
|
find_library( |
||||
|
JSONCPP_LIBRARY |
||||
|
NAMES jsoncpp |
||||
|
DOC "jsoncpp library" |
||||
|
) |
||||
|
|
||||
|
set(JSONCPP_INCLUDE_DIRS ${JSONCPP_INCLUDE_DIR}) |
||||
|
set(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY}) |
||||
|
|
||||
|
# debug library on windows |
||||
|
# same naming convention as in qt (appending debug library with d) |
||||
|
# boost is using the same "hack" as us with "optimized" and "debug" |
||||
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") |
||||
|
find_library( |
||||
|
JSONCPP_LIBRARY_DEBUG |
||||
|
NAMES jsoncppd |
||||
|
DOC "jsoncpp debug library" |
||||
|
) |
||||
|
|
||||
|
set(JSONCPP_LIBRARIES optimized ${JSONCPP_LIBRARIES} debug ${JSONCPP_LIBRARY_DEBUG}) |
||||
|
|
||||
|
endif() |
||||
|
|
||||
|
# handle the QUIETLY and REQUIRED arguments and set JSONCPP_FOUND to TRUE |
||||
|
# if all listed variables are TRUE, hide their existence from configuration view |
||||
|
include(FindPackageHandleStandardArgs) |
||||
|
find_package_handle_standard_args(jsoncpp DEFAULT_MSG |
||||
|
JSONCPP_INCLUDE_DIR JSONCPP_LIBRARY) |
||||
|
mark_as_advanced (JSONCPP_INCLUDE_DIR JSONCPP_LIBRARY) |
||||
|
|
@ -0,0 +1,48 @@ |
|||||
|
# Find leveldb |
||||
|
# |
||||
|
# Find the leveldb includes and library |
||||
|
# |
||||
|
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH |
||||
|
# |
||||
|
# This module defines |
||||
|
# LEVELDB_INCLUDE_DIRS, where to find header, etc. |
||||
|
# LEVELDB_LIBRARIES, the libraries needed to use leveldb. |
||||
|
# LEVELDB_FOUND, If false, do not try to use leveldb. |
||||
|
|
||||
|
# only look in default directories |
||||
|
find_path( |
||||
|
LEVELDB_INCLUDE_DIR |
||||
|
NAMES leveldb/db.h |
||||
|
DOC "leveldb include dir" |
||||
|
) |
||||
|
|
||||
|
find_library( |
||||
|
LEVELDB_LIBRARY |
||||
|
NAMES leveldb |
||||
|
DOC "leveldb library" |
||||
|
) |
||||
|
|
||||
|
set(LEVELDB_INCLUDE_DIRS ${LEVELDB_INCLUDE_DIR}) |
||||
|
set(LEVELDB_LIBRARIES ${LEVELDB_LIBRARY}) |
||||
|
|
||||
|
# debug library on windows |
||||
|
# same naming convention as in qt (appending debug library with d) |
||||
|
# boost is using the same "hack" as us with "optimized" and "debug" |
||||
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") |
||||
|
find_library( |
||||
|
LEVELDB_LIBRARY_DEBUG |
||||
|
NAMES leveldbd |
||||
|
DOC "leveldb debug library" |
||||
|
) |
||||
|
|
||||
|
set(LEVELDB_LIBRARIES optimized ${LEVELDB_LIBRARIES} debug ${LEVELDB_LIBRARY_DEBUG}) |
||||
|
|
||||
|
endif() |
||||
|
|
||||
|
# handle the QUIETLY and REQUIRED arguments and set LEVELDB_FOUND to TRUE |
||||
|
# if all listed variables are TRUE, hide their existence from configuration view |
||||
|
include(FindPackageHandleStandardArgs) |
||||
|
find_package_handle_standard_args(leveldb DEFAULT_MSG |
||||
|
LEVELDB_INCLUDE_DIR LEVELDB_LIBRARY) |
||||
|
mark_as_advanced (LEVELDB_INCLUDE_DIR LEVELDB_LIBRARY) |
||||
|
|
@ -0,0 +1,34 @@ |
|||||
|
# Find miniupnpc |
||||
|
# |
||||
|
# Find the miniupnpc includes and library |
||||
|
# |
||||
|
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH |
||||
|
# |
||||
|
# This module defines |
||||
|
# MINIUPNPC_INCLUDE_DIRS, where to find header, etc. |
||||
|
# MINIUPNPC_LIBRARIES, the libraries needed to use gmp. |
||||
|
# MINIUPNPC_FOUND, If false, do not try to use gmp. |
||||
|
|
||||
|
# only look in default directories |
||||
|
find_path( |
||||
|
MINIUPNPC_INCLUDE_DIR |
||||
|
NAMES miniupnpc/miniupnpc.h |
||||
|
DOC "miniupnpc include dir" |
||||
|
) |
||||
|
|
||||
|
find_library( |
||||
|
MINIUPNPC_LIBRARY |
||||
|
NAMES miniupnpc |
||||
|
DOC "miniupnpc library" |
||||
|
) |
||||
|
|
||||
|
set(MINIUPNPC_INCLUDE_DIRS ${MINIUPNPC_INCLUDE_DIR}) |
||||
|
set(MINIUPNPC_LIBRARIES ${MINIUPNPC_LIBRARY}) |
||||
|
|
||||
|
# handle the QUIETLY and REQUIRED arguments and set MINIUPNPC_FOUND to TRUE |
||||
|
# if all listed variables are TRUE, hide their existence from configuration view |
||||
|
include(FindPackageHandleStandardArgs) |
||||
|
find_package_handle_standard_args(miniupnpc DEFAULT_MSG |
||||
|
MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY) |
||||
|
mark_as_advanced (MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY) |
||||
|
|
@ -0,0 +1,34 @@ |
|||||
|
# Find readline |
||||
|
# |
||||
|
# Find the readline includes and library |
||||
|
# |
||||
|
# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH |
||||
|
# |
||||
|
# This module defines |
||||
|
# READLINE_INCLUDE_DIRS, where to find header, etc. |
||||
|
# READLINE_LIBRARIES, the libraries needed to use readline. |
||||
|
# READLINE_FOUND, If false, do not try to use readline. |
||||
|
|
||||
|
# only look in default directories |
||||
|
find_path( |
||||
|
READLINE_INCLUDE_DIR |
||||
|
NAMES readline/readline.h |
||||
|
DOC "readling include dir" |
||||
|
) |
||||
|
|
||||
|
find_library( |
||||
|
READLINE_LIBRARY |
||||
|
NAMES readline |
||||
|
DOC "readline library" |
||||
|
) |
||||
|
|
||||
|
set(READLINE_INCLUDE_DIRS ${READLINE_INCLUDE_DIR}) |
||||
|
set(READLINE_LIBRARIES ${READLINE_LIBRARY}) |
||||
|
|
||||
|
# handle the QUIETLY and REQUIRED arguments and set READLINE_FOUND to TRUE |
||||
|
# if all listed variables are TRUE, hide their existence from configuration view |
||||
|
include(FindPackageHandleStandardArgs) |
||||
|
find_package_handle_standard_args(readline DEFAULT_MSG |
||||
|
READLINE_INCLUDE_DIR READLINE_LIBRARY) |
||||
|
mark_as_advanced (READLINE_INCLUDE_DIR READLINE_LIBRARY) |
||||
|
|
File diff suppressed because it is too large
@ -1,48 +1,33 @@ |
|||||
cmake_policy(SET CMP0015 NEW) |
cmake_policy(SET CMP0015 NEW) |
||||
|
set(CMAKE_AUTOMOC OFF) |
||||
|
|
||||
aux_source_directory(. SRC_LIST) |
aux_source_directory(. SRC_LIST) |
||||
|
|
||||
|
include_directories(${Boost_INCLUDE_DIRS}) |
||||
|
include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) |
||||
include_directories(..) |
include_directories(..) |
||||
|
|
||||
set(EXECUTABLE eth) |
set(EXECUTABLE eth) |
||||
|
|
||||
file(GLOB HEADERS "*.h") |
file(GLOB HEADERS "*.h") |
||||
|
|
||||
add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) |
add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) |
||||
|
|
||||
target_link_libraries(${EXECUTABLE} webthree) |
add_dependencies(${EXECUTABLE} BuildInfo.h) |
||||
target_link_libraries(${EXECUTABLE} secp256k1) |
|
||||
target_link_libraries(${EXECUTABLE} gmp) |
target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES}) |
||||
if(MINIUPNPC_LS) |
target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) |
||||
target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) |
|
||||
endif() |
if (READLINE_FOUND) |
||||
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) |
target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES}) |
||||
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) |
|
||||
if(JSONRPC_LS) |
|
||||
target_link_libraries(${EXECUTABLE} web3jsonrpc) |
|
||||
endif() |
endif() |
||||
if(READLINE_LS) |
|
||||
target_link_libraries(${EXECUTABLE} ${READLINE_LS}) |
if (JSONRPC) |
||||
|
target_link_libraries(${EXECUTABLE} web3jsonrpc) |
||||
endif() |
endif() |
||||
|
|
||||
if ("${TARGET_PLATFORM}" STREQUAL "w64") |
target_link_libraries(${EXECUTABLE} webthree) |
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") |
target_link_libraries(${EXECUTABLE} secp256k1) |
||||
target_link_libraries(${EXECUTABLE} boost_system-mt-s) |
|
||||
target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) |
|
||||
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) |
|
||||
target_link_libraries(${EXECUTABLE} gcc) |
|
||||
target_link_libraries(${EXECUTABLE} gdi32) |
|
||||
target_link_libraries(${EXECUTABLE} ws2_32) |
|
||||
target_link_libraries(${EXECUTABLE} mswsock) |
|
||||
target_link_libraries(${EXECUTABLE} shlwapi) |
|
||||
target_link_libraries(${EXECUTABLE} iphlpapi) |
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) |
|
||||
elseif (UNIX) |
|
||||
else () |
|
||||
target_link_libraries(${EXECUTABLE} boost_system) |
|
||||
target_link_libraries(${EXECUTABLE} boost_filesystem) |
|
||||
find_package(Threads REQUIRED) |
|
||||
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) |
|
||||
endif () |
|
||||
|
|
||||
install( TARGETS ${EXECUTABLE} DESTINATION bin ) |
install( TARGETS ${EXECUTABLE} DESTINATION bin ) |
||||
|
|
||||
|
@ -0,0 +1,55 @@ |
|||||
|
cmake_minimum_required(VERSION 2.8.12) |
||||
|
|
||||
|
include(ExternalProject) |
||||
|
include(CMakeParseArguments) |
||||
|
include(eth_download.cmake) |
||||
|
|
||||
|
# all dependencies will be installed into this directory, separated by platform |
||||
|
string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) |
||||
|
set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${_system_name}") |
||||
|
set(ETH_DEPENDENCY_SERVER "http://poc-7.ethdev.com/precompiled/${_system_name}") |
||||
|
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/lib) |
||||
|
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include) |
||||
|
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/bin) |
||||
|
|
||||
|
if (ETH_COMPILE) |
||||
|
# json-rpc-cpp and its dependencies |
||||
|
include(compile/jsoncpp.cmake) |
||||
|
include(compile/argtable2.cmake) |
||||
|
include(compile/curl.cmake) |
||||
|
include(compile/json-rpc-cpp.cmake) |
||||
|
|
||||
|
# qt and its dependencies |
||||
|
include(compile/icu.cmake) |
||||
|
include(compile/jom.cmake) |
||||
|
include(compile/qt.cmake) |
||||
|
|
||||
|
# leveldb and its dependencies |
||||
|
include(compile/snappy.cmake) |
||||
|
include(compile/leveldb.cmake) |
||||
|
|
||||
|
# cryptopp |
||||
|
include(compile/cryptopp.cmake) |
||||
|
|
||||
|
# boost |
||||
|
include(compile/boost.cmake) |
||||
|
else() |
||||
|
eth_download(jsoncpp) |
||||
|
eth_download(json-rpc-cpp OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh) |
||||
|
|
||||
|
if (APPLE) |
||||
|
eth_download(snappy OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snappy_osx.sh) |
||||
|
endif() |
||||
|
|
||||
|
eth_download(leveldb OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/leveldb_osx.sh) |
||||
|
eth_download(qt) |
||||
|
eth_download(cryptopp) |
||||
|
eth_download(boost) |
||||
|
eth_download(curl) |
||||
|
|
||||
|
endif() |
||||
|
|
||||
|
# will be re-eanbled later |
||||
|
# include(miniupnpc.cmake) |
||||
|
# if install phase of extep fails, even if libs are already created, the ethereum install will fail |
||||
|
|
@ -0,0 +1,16 @@ |
|||||
|
# cpp-ethereum external dependencies |
||||
|
|
||||
|
**This is Work-in-Progress!** |
||||
|
|
||||
|
This directory hosts the external libraries that are needed to build cpp-ethereum. |
||||
|
|
||||
|
To automatically download, build, and link libraries, do |
||||
|
``` |
||||
|
cd extdep; mkdir build; cd build; cmake ..; make |
||||
|
``` |
||||
|
this will take some time. |
||||
|
|
||||
|
|
||||
|
To check which libraries are already included, check `CMakeLists.txt`. Other libraries still need to be fetched via the system's package manager. |
||||
|
|
||||
|
Libraries will be installed in `cpp-ethereum/extdep/install/<platform-name>` |
@ -0,0 +1,9 @@ |
|||||
|
# hacky way to resolve nested dependencies - needed for json-rpc-cpp |
||||
|
find_library(CURL_LIBRARY NAMES curl |
||||
|
PATHS |
||||
|
${ETH_DEPENDENCY_INSTALL_DIR}/lib |
||||
|
) |
||||
|
|
||||
|
set(CURL_LIBRARIES ${CURL_LIBRARY}) |
||||
|
set(CURL_INCLUDE_DIRS ${ETH_DEPENDENCY_INSTALL_DIR}/include) |
||||
|
|
@ -0,0 +1,13 @@ |
|||||
|
if (APPLE) |
||||
|
|
||||
|
elseif (WIN32) |
||||
|
ExternalProject_Add(argtable2 |
||||
|
GIT_REPOSITORY https://github.com/debris/argtable.git |
||||
|
GIT_TAG master |
||||
|
BINARY_DIR argtable2-prefix/src/argtable2 |
||||
|
CONFIGURE_COMMAND cmake . |
||||
|
BUILD_COMMAND devenv argtable2.sln /build release |
||||
|
INSTALL_COMMAND cmd /c cp src/Release/argtable2.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp src/argtable2.h ${ETH_DEPENDENCY_INSTALL_DIR}/include |
||||
|
) |
||||
|
else() |
||||
|
endif() |
@ -0,0 +1,19 @@ |
|||||
|
if (APPLE) |
||||
|
|
||||
|
elseif (WIN32) |
||||
|
set(boost_address_model) |
||||
|
# on windows 64: |
||||
|
# set(boost_address_model address-model=64) |
||||
|
|
||||
|
set(boost_targets --with-filesystem --with-system --with-thread --with-date_time --with-regex --with-test --with-chrono --with-program_options) |
||||
|
ExternalProject_Add(boost |
||||
|
URL http://downloads.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.tar.gz |
||||
|
BINARY_DIR boost-prefix/src/boost |
||||
|
CONFIGURE_COMMAND ./bootstrap.bat |
||||
|
BUILD_COMMAND ./b2.exe -j4 --build-type=complete link=static runtime-link=shared variant=debug,release threading=multi ${boost_addressModel} ${boost_targets} install --prefix=${ETH_DEPENDENCY_INSTALL_DIR} |
||||
|
INSTALL_COMMAND cmake -E rename ${ETH_DEPENDENCY_INSTALL_DIR}/include/boost-1_55/boost ${ETH_DEPENDENCY_INSTALL_DIR}/include/boost |
||||
|
) |
||||
|
else() |
||||
|
|
||||
|
endif() |
||||
|
|
@ -0,0 +1,33 @@ |
|||||
|
# CryptoPP does not have good cross-platform support, there exist several different other projects to make it work ... |
||||
|
|
||||
|
# TODO the OS X build throws a lot of warnings, but compiles fine |
||||
|
if (APPLE) |
||||
|
ExternalProject_Add(cryptopp |
||||
|
URL https://downloads.sourceforge.net/project/cryptopp/cryptopp/5.6.2/cryptopp562.zip |
||||
|
BINARY_DIR cryptopp-prefix/src/cryptopp |
||||
|
CONFIGURE_COMMAND "" |
||||
|
BUILD_COMMAND make CXX=clang++ CXXFLAGS=-DCRYPTOPP_DISABLE_ASM |
||||
|
INSTALL_COMMAND make install PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} |
||||
|
) |
||||
|
elseif (WIN32) |
||||
|
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include/cryptopp) |
||||
|
|
||||
|
ExternalProject_Add(cryptopp |
||||
|
SVN_REPOSITORY http://svn.code.sf.net/p/cryptopp/code/trunk/c5 |
||||
|
SVN_REVISION -r "541" |
||||
|
BINARY_DIR cryptopp-prefix/src/cryptopp |
||||
|
CONFIGURE_COMMAND devenv cryptest.sln /upgrade |
||||
|
BUILD_COMMAND devenv cryptest.sln /build release |
||||
|
INSTALL_COMMAND cmd /c cp Win32/DLL_Output/Release/cryptopp.dll ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp Win32/DLL_Output/Release/cryptopp.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp *.h ${ETH_DEPENDENCY_INSTALL_DIR}/include/cryptopp |
||||
|
) |
||||
|
# on Linux, the default Makefile does not work. |
||||
|
else() |
||||
|
ExternalProject_Add(cryptopp |
||||
|
URL https://github.com/mmoss/cryptopp/archive/v5.6.2.zip |
||||
|
BINARY_DIR cryptopp-prefix/src/cryptopp |
||||
|
CONFIGURE_COMMAND "" |
||||
|
BUILD_COMMAND scons --shared --prefix=${ETH_DEPENDENCY_INSTALL_DIR} |
||||
|
INSTALL_COMMAND "" |
||||
|
) |
||||
|
endif() |
||||
|
|
@ -0,0 +1,29 @@ |
|||||
|
if (APPLE) |
||||
|
ExternalProject_Add(curl |
||||
|
URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2 |
||||
|
BINARY_DIR curl-prefix/src/curl |
||||
|
CONFIGURE_COMMAND ./configure --with-darwinssl --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR} |
||||
|
BUILD_COMMAND make -j 3 |
||||
|
INSTALL_COMMAND make install |
||||
|
) |
||||
|
elseif (WIN32) |
||||
|
ExternalProject_Add(curl |
||||
|
GIT_REPOSITORY https://github.com/debris/libcurl-7.29 |
||||
|
GIT_TAG master |
||||
|
BINARY_DIR curl-prefix/src/curl |
||||
|
CONFIGURE_COMMAND "" |
||||
|
BUILD_COMMAND "" |
||||
|
INSTALL_COMMAND cmd /c cp lib/release/libcurl.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/curl ${ETH_DEPENDENCY_INSTALL_DIR}/include |
||||
|
) |
||||
|
|
||||
|
else() |
||||
|
ExternalProject_Add(curl |
||||
|
URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2 |
||||
|
BINARY_DIR curl-prefix/src/curl |
||||
|
CONFIGURE_COMMAND CONFIG_CMD ./configure --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR} |
||||
|
BUILD_COMMAND make -j 3 |
||||
|
INSTALL_COMMAND make install |
||||
|
) |
||||
|
|
||||
|
endif() |
||||
|
|
@ -0,0 +1,17 @@ |
|||||
|
if (APPLE) |
||||
|
|
||||
|
elseif (WIN32) |
||||
|
ExternalProject_Add(icu |
||||
|
GIT_REPOSITORY https://github.com/debris/icu-win32.git |
||||
|
GIT_TAG master |
||||
|
BINARY_DIR icu-prefix/src/icu |
||||
|
CONFIGURE_COMMAND "" |
||||
|
BUILD_COMMAND "" |
||||
|
INSTALL_COMMAND cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR} |
||||
|
) |
||||
|
|
||||
|
else() |
||||
|
|
||||
|
endif() |
||||
|
|
||||
|
|
@ -0,0 +1,16 @@ |
|||||
|
if (APPLE) |
||||
|
|
||||
|
|
||||
|
elseif (WIN32) |
||||
|
ExternalProject_Add(jom |
||||
|
URL http://download.qt-project.org/official_releases/jom/jom.zip |
||||
|
BINARY_DIR jom-prefix/src/jom |
||||
|
CONFIGURE_COMMAND "" |
||||
|
BUILD_COMMAND "" |
||||
|
INSTALL_COMMAND cmake -E copy jom.exe ${ETH_DEPENDENCY_INSTALL_DIR}/bin |
||||
|
) |
||||
|
|
||||
|
else() |
||||
|
|
||||
|
endif() |
||||
|
|
@ -0,0 +1,40 @@ |
|||||
|
# json-rpc-cpp is under heavy development, not yet stable, and multiplatform builds are not yet available. |
||||
|
# DO NOT MESS WITH THESE SETTINGS! IF YOU HAVE TO MAKE CHANGES HERE, CONSULT sven@ethdev.com BEFOREHAND!! |
||||
|
|
||||
|
# DO NOT CHANGE ANYTHING HERE! |
||||
|
if(APPLE) |
||||
|
ExternalProject_Add(json-rpc-cpp |
||||
|
# DEPENDS argtable2 jsoncpp |
||||
|
# DEPENDS curl # re-enable later, when we build curl again |
||||
|
GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git |
||||
|
GIT_TAG v0.3.2 |
||||
|
BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp |
||||
|
CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR}/cmake -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev . |
||||
|
BUILD_COMMAND make -j 3 |
||||
|
INSTALL_COMMAND make install && ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh . ${ETH_DEPENDENCY_INSTALL_DIR} |
||||
|
) |
||||
|
|
||||
|
elseif (WIN32) |
||||
|
ExternalProject_Add(json-rpc-cpp |
||||
|
DEPENDS argtable2 jsoncpp curl |
||||
|
GIT_REPOSITORY https://github.com/debris/libjson-rpc-cpp.git |
||||
|
GIT_TAG windows |
||||
|
BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp |
||||
|
CONFIGURE_COMMAND cmake -DCMAKE_PREFIX_PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCURL_LIBRARIES=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libcurl.lib . |
||||
|
BUILD_COMMAND devenv libjson-rpc-cpp.sln /build release |
||||
|
INSTALL_COMMAND cmd /c cp lib/Release/* ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R src/jsonrpccpp ${ETH_DEPENDENCY_INSTALL_DIR}/include |
||||
|
) |
||||
|
else() |
||||
|
ExternalProject_Add(json-rpc-cpp |
||||
|
# DEPENDS argtable2 jsoncpp |
||||
|
# DEPENDS curl # re-enable later, when we build curl again |
||||
|
GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git |
||||
|
GIT_TAG v0.3.2 |
||||
|
BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp |
||||
|
CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR}/cmake -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST . |
||||
|
BUILD_COMMAND make -j 3 |
||||
|
INSTALL_COMMAND make install |
||||
|
) |
||||
|
|
||||
|
endif() |
||||
|
|
@ -0,0 +1,16 @@ |
|||||
|
if (APPLE) |
||||
|
|
||||
|
elseif (WIN32) |
||||
|
|
||||
|
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include/jsoncpp) |
||||
|
ExternalProject_Add(jsoncpp |
||||
|
GIT_REPOSITORY https://github.com/open-source-parsers/jsoncpp |
||||
|
GIT_TAG svn-import |
||||
|
BINARY_DIR jsoncpp-prefix/src/jsoncpp |
||||
|
CONFIGURE_COMMAND cmake . |
||||
|
BUILD_COMMAND devenv jsoncpp.sln /build release |
||||
|
INSTALL_COMMAND cmd /c cp lib/Release/jsoncpp.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/json ${ETH_DEPENDENCY_INSTALL_DIR}/include/jsoncpp |
||||
|
) |
||||
|
|
||||
|
else() |
||||
|
endif() |
@ -0,0 +1,23 @@ |
|||||
|
if (APPLE) |
||||
|
ExternalProject_Add(leveldb |
||||
|
#DEPENDS snappy |
||||
|
URL https://leveldb.googlecode.com/files/leveldb-1.15.0.tar.gz |
||||
|
BINARY_DIR leveldb-prefix/src/leveldb |
||||
|
#CONFIGURE_COMMAND patch < ${CMAKE_CURRENT_SOURCE_DIR}/compile/leveldb_osx.patch |
||||
|
CONFIGURE_COMMAND "" |
||||
|
BUILD_COMMAND export ETH_DEPENDENCY_INSTALL_DIR=${ETH_DEPENDENCY_INSTALL_DIR} && make -j 3 |
||||
|
INSTALL_COMMAND cp -rf include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include/ && cp libleveldb.a ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp libleveldb.dylib.1.15 ${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib |
||||
|
) |
||||
|
elseif (WIN32) |
||||
|
ExternalProject_Add(leveldb |
||||
|
GIT_REPOSITORY https://github.com/debris/leveldb-win32.git |
||||
|
GIT_TAG master |
||||
|
BINARY_DIR leveldb-prefix/src/leveldb |
||||
|
CONFIGURE_COMMAND "" |
||||
|
BUILD_COMMAND "" |
||||
|
INSTALL_COMMAND cmd /c cp lib/LibLevelDB.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib/leveldb.lib && cp -R include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include |
||||
|
) |
||||
|
else() |
||||
|
|
||||
|
endif() |
||||
|
|
@ -0,0 +1,18 @@ |
|||||
|
--- Makefile 2014-11-07 00:54:05.000000000 +0100
|
||||
|
+++ MakefilePatch 2014-11-07 00:56:59.000000000 +0100
|
||||
|
@@ -17,11 +17,11 @@
|
||||
|
# this file is generated by the previous line to set build flags and sources |
||||
|
include build_config.mk |
||||
|
|
||||
|
-CFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)
|
||||
|
-CXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT)
|
||||
|
+CFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)
|
||||
|
+CXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT) -DSNAPPY -I$(ETH_DEPENDENCY_INSTALL_DIR)/include
|
||||
|
|
||||
|
-LDFLAGS += $(PLATFORM_LDFLAGS)
|
||||
|
-LIBS += $(PLATFORM_LIBS)
|
||||
|
+LDFLAGS += $(PLATFORM_LDFLAGS) -L$(ETH_DEPENDENCY_INSTALL_DIR)/lib
|
||||
|
+LIBS += $(PLATFORM_LIBS) -lsnappy
|
||||
|
|
||||
|
LIBOBJECTS = $(SOURCES:.cc=.o) |
||||
|
MEMENVOBJECTS = $(MEMENV_SOURCES:.cc=.o) |
@ -0,0 +1,32 @@ |
|||||
|
if (APPLE) |
||||
|
ExternalProject_add(qt |
||||
|
URL http://qtmirror.ics.com/pub/qtproject/official_releases/qt/5.3/5.3.2/single/qt-everywhere-opensource-src-5.3.2.tar.gz |
||||
|
BINARY_DIR qt-prefix/src/qt |
||||
|
PATCH_COMMAND patch -d qtmultimedia/src/plugins/avfoundation/mediaplayer < ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_osx.patch |
||||
|
CONFIGURE_COMMAND ./configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -system-zlib -qt-libpng -qt-libjpeg -confirm-license -opensource -nomake tests -release -nomake examples -no-xcb -arch x86_64 |
||||
|
BUILD_COMMAND make |
||||
|
INSTALL_COMMAND make install |
||||
|
) |
||||
|
elseif(WIN32) |
||||
|
ExternalProject_Add(qt |
||||
|
DEPENDS icu jom |
||||
|
URL http://qtmirror.ics.com/pub/qtproject/official_releases/qt/5.3/5.3.2/single/qt-everywhere-opensource-src-5.3.2.tar.gz |
||||
|
BINARY_DIR qt-prefix/src/qt |
||||
|
UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_tools.bat |
||||
|
#PATCH_COMMAND cmake -E copy ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_configure.bat qtbase/configure.bat |
||||
|
CONFIGURE_COMMAND configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -opensource -confirm-license -release -opengl desktop -platform win32-msvc2013 -icu -I ${ETH_DEPENDENCY_INSTALL_DIR}/include -L ${ETH_DEPENDENCY_INSTALL_DIR}/lib -nomake tests -nomake examples |
||||
|
BUILD_COMMAND nmake |
||||
|
INSTALL_COMMAND nmake install |
||||
|
) |
||||
|
|
||||
|
ExternalProject_Add_Step(qt configure_paths |
||||
|
COMMAND set PATH=${ETH_DEPENDENCY_INSTALL_DIR}/bin;%cd%/gnuwin32/bin;%cd%/qtbase/bin;%PATH% |
||||
|
DEPENDEES patch |
||||
|
DEPENDERS configure |
||||
|
) |
||||
|
|
||||
|
else() |
||||
|
|
||||
|
endif() |
||||
|
|
||||
|
|
@ -0,0 +1,111 @@ |
|||||
|
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |
||||
|
:: |
||||
|
:: Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). |
||||
|
:: Contact: http://www.qt-project.org/legal |
||||
|
:: |
||||
|
:: This file is part of the tools applications of the Qt Toolkit. |
||||
|
:: |
||||
|
:: $QT_BEGIN_LICENSE:LGPL$ |
||||
|
:: Commercial License Usage |
||||
|
:: Licensees holding valid commercial Qt licenses may use this file in |
||||
|
:: accordance with the commercial license agreement provided with the |
||||
|
:: Software or, alternatively, in accordance with the terms contained in |
||||
|
:: a written agreement between you and Digia. For licensing terms and |
||||
|
:: conditions see http://qt.digia.com/licensing. For further information |
||||
|
:: use the contact form at http://qt.digia.com/contact-us. |
||||
|
:: |
||||
|
:: GNU Lesser General Public License Usage |
||||
|
:: Alternatively, this file may be used under the terms of the GNU Lesser |
||||
|
:: General Public License version 2.1 as published by the Free Software |
||||
|
:: Foundation and appearing in the file LICENSE.LGPL included in the |
||||
|
:: packaging of this file. Please review the following information to |
||||
|
:: ensure the GNU Lesser General Public License version 2.1 requirements |
||||
|
:: will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
||||
|
:: |
||||
|
:: In addition, as a special exception, Digia gives you certain additional |
||||
|
:: rights. These rights are described in the Digia Qt LGPL Exception |
||||
|
:: version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
||||
|
:: |
||||
|
:: GNU General Public License Usage |
||||
|
:: Alternatively, this file may be used under the terms of the GNU |
||||
|
:: General Public License version 3.0 as published by the Free Software |
||||
|
:: Foundation and appearing in the file LICENSE.GPL included in the |
||||
|
:: packaging of this file. Please review the following information to |
||||
|
:: ensure the GNU General Public License version 3.0 requirements will be |
||||
|
:: met: http://www.gnu.org/copyleft/gpl.html. |
||||
|
:: |
||||
|
:: |
||||
|
:: $QT_END_LICENSE$ |
||||
|
:: |
||||
|
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: |
||||
|
|
||||
|
@echo off |
||||
|
set QTSRC=%~dp0 |
||||
|
set QTDIR=%CD% |
||||
|
::if not exist %QTSRC%\.gitignore goto sconf |
||||
|
echo Please wait while bootstrapping configure ... |
||||
|
|
||||
|
for %%C in (cl.exe icl.exe g++.exe perl.exe) do set %%C=%%~$PATH:C |
||||
|
|
||||
|
if "%perl.exe%" == "" ( |
||||
|
echo Perl not found in PATH. Aborting. >&2 |
||||
|
exit /b 1 |
||||
|
) |
||||
|
if not exist mkspecs ( |
||||
|
md mkspecs |
||||
|
if errorlevel 1 goto exit |
||||
|
) |
||||
|
perl %QTSRC%bin\syncqt.pl -minimal -module QtCore -outdir %QTDIR% %QTSRC% |
||||
|
if errorlevel 1 goto exit |
||||
|
|
||||
|
if not exist tools\configure ( |
||||
|
md tools\configure |
||||
|
if errorlevel 1 goto exit |
||||
|
) |
||||
|
cd tools\configure |
||||
|
if errorlevel 1 goto exit |
||||
|
|
||||
|
echo #### Generated by configure.bat - DO NOT EDIT! ####> Makefile |
||||
|
echo/>> Makefile |
||||
|
for /f "tokens=3 usebackq" %%V in (`findstr QT_VERSION_STR %QTSRC%\src\corelib\global\qglobal.h`) do @echo QTVERSION = %%~V>> Makefile |
||||
|
if not "%cl.exe%" == "" ( |
||||
|
echo CXX = cl>>Makefile |
||||
|
echo EXTRA_CXXFLAGS =>>Makefile |
||||
|
rem This must have a trailing space. |
||||
|
echo QTSRC = %QTSRC% >> Makefile |
||||
|
set tmpl=win32 |
||||
|
set make=nmake |
||||
|
) else if not "%icl.exe%" == "" ( |
||||
|
echo CXX = icl>>Makefile |
||||
|
echo EXTRA_CXXFLAGS = /Zc:forScope>>Makefile |
||||
|
rem This must have a trailing space. |
||||
|
echo QTSRC = %QTSRC% >> Makefile |
||||
|
set tmpl=win32 |
||||
|
set make=nmake |
||||
|
) else if not "%g++.exe%" == "" ( |
||||
|
echo CXX = g++>>Makefile |
||||
|
echo EXTRA_CXXFLAGS =>>Makefile |
||||
|
rem This must NOT have a trailing space. |
||||
|
echo QTSRC = %QTSRC:\=/%>> Makefile |
||||
|
set tmpl=mingw |
||||
|
set make=mingw32-make |
||||
|
) else ( |
||||
|
echo No suitable compiler found in PATH. Aborting. >&2 |
||||
|
cd ..\.. |
||||
|
exit /b 1 |
||||
|
) |
||||
|
echo/>> Makefile |
||||
|
type %QTSRC%tools\configure\Makefile.%tmpl% >> Makefile |
||||
|
|
||||
|
%make% |
||||
|
if errorlevel 1 (cd ..\.. & exit /b 1) |
||||
|
|
||||
|
cd ..\.. |
||||
|
|
||||
|
:conf |
||||
|
configure.exe -srcdir %QTSRC% %* |
||||
|
goto exit |
||||
|
|
||||
|
:sconf |
||||
|
%QTSRC%\configure.exe %* |
||||
|
:exit |
@ -0,0 +1,11 @@ |
|||||
|
--- avfmediaplayersession.mm 2014-09-11 12:48:26.000000000 +0200
|
||||
|
+++ avfmediaplayersessionPatch.mm 2014-12-01 12:53:14.000000000 +0100
|
||||
|
@@ -295,7 +295,7 @@
|
||||
|
//AVPlayerItem "status" property value observer. |
||||
|
if (context == AVFMediaPlayerSessionObserverStatusObservationContext) |
||||
|
{ |
||||
|
- AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
|
||||
|
+ AVPlayerStatus status = (AVPlayerStatus)[[change objectForKey:NSKeyValueChangeNewKey] integerValue];
|
||||
|
switch (status) |
||||
|
{ |
||||
|
//Indicates that the status of the player is not yet known because |
@ -0,0 +1,2 @@ |
|||||
|
rem : import VC environment vars |
||||
|
call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86 |
@ -0,0 +1,14 @@ |
|||||
|
if (APPLE) |
||||
|
ExternalProject_Add(snappy |
||||
|
URL https://snappy.googlecode.com/files/snappy-1.1.1.tar.gz |
||||
|
BINARY_DIR snappy-prefix/src/snappy |
||||
|
CONFIGURE_COMMAND ./configure --disable-dependency-tracking --prefix=${ETH_DEPENDENCY_INSTALL_DIR} |
||||
|
BUILD_COMMAND "" |
||||
|
INSTALL_COMMAND make install |
||||
|
) |
||||
|
elseif(WIN32) |
||||
|
|
||||
|
else() |
||||
|
|
||||
|
endif() |
||||
|
|
@ -0,0 +1,74 @@ |
|||||
|
# this macro requires the following variables to be specified: |
||||
|
# |
||||
|
# ETH_DEPENDENCY_SERVER - server from which dependencies should be downloaded |
||||
|
# ETH_DEPENDENCY_INSTALL_DIR - install location for all dependencies |
||||
|
# |
||||
|
# usage: |
||||
|
# |
||||
|
# eth_download("json-rpc-cpp") |
||||
|
# eth_download("json-rpc-cpp" VERSION "0.3.2") |
||||
|
# |
||||
|
# params: |
||||
|
# VERSION - exact version we want to use |
||||
|
# OSX_SCRIPT - script which will be executed on apple in install phase |
||||
|
# UNIX_SCRIPT - script which will be executed on unix in install phase |
||||
|
# WIN_SCRIPT - script which will be executed on win in install phase |
||||
|
|
||||
|
# OSX_SCRIPT, WIN_SCRIPT, UNIX_SCRIPT are taking 2 params: |
||||
|
# $1 is package_source, |
||||
|
# $2 is ETH_DEPENDENCY_INSTALL_DIR |
||||
|
# |
||||
|
# parsing arguments |
||||
|
# http://www.cmake.org/cmake/help/v3.0/module/CMakeParseArguments.html |
||||
|
# |
||||
|
# for macos you may need to specify OSX_SCRIPT with install_name_tool to fix dylib |
||||
|
# http://stackoverflow.com/questions/2985315/using-install-name-tool-whats-going-wrong |
||||
|
# |
||||
|
# TODO: |
||||
|
# check if install_command is handling symlinks correctly on linux and windows |
||||
|
|
||||
|
macro(eth_download eth_package_name) |
||||
|
|
||||
|
set (extra_macro_args ${ARGN}) |
||||
|
set (options) |
||||
|
set (one_value_args VERSION OSX_SCRIPT UNIX_SCRIPT WIN_SCRIPT) |
||||
|
set (multi_value_args) |
||||
|
cmake_parse_arguments (ETH_DOWNLOAD "${options}" "${one_value_args}" "${multi_value_args}" ${extra_macro_args}) |
||||
|
|
||||
|
if (ETH_DOWNLOAD_VERSION) |
||||
|
set(eth_tar_name "${eth_package_name}-${ETH_DOWNLOAD_VERSION}.tar.gz") |
||||
|
else() |
||||
|
set(eth_tar_name "${eth_package_name}.tar.gz") |
||||
|
endif() |
||||
|
|
||||
|
message(STATUS "download path for ${eth_package_name} is : ${ETH_DEPENDENCY_SERVER}/${eth_tar_name}") |
||||
|
|
||||
|
# we need that to copy symlinks |
||||
|
# see http://superuser.com/questions/138587/how-to-copy-symbolic-links |
||||
|
if (APPLE) |
||||
|
set (eth_package_copy cp -a . ${ETH_DEPENDENCY_INSTALL_DIR}) |
||||
|
set (eth_package_install ${ETH_DOWNLOAD_OSX_SCRIPT}) |
||||
|
elseif (UNIX) |
||||
|
set (eth_package_copy cp -a . ${ETH_DEPENDENCY_INSTALL_DIR}) |
||||
|
set (eth_package_install ${ETH_DOWNLOAD_UNIX_SCRIPT}) |
||||
|
else () |
||||
|
set (eth_package_copy cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR}) |
||||
|
set (eth_package_install ${ETH_DOWNLOAD_WIN_SCRIPT}) |
||||
|
endif() |
||||
|
|
||||
|
if (eth_package_install) |
||||
|
message(STATUS "install script: ${eth_package_install}") |
||||
|
set (eth_package_install ${eth_package_install} . ${ETH_DEPENDENCY_INSTALL_DIR}) |
||||
|
else () |
||||
|
set (eth_package_install echo 0) # cause empty string is not handled properly |
||||
|
endif() |
||||
|
|
||||
|
ExternalProject_Add(${eth_package_name} |
||||
|
URL ${ETH_DEPENDENCY_SERVER}/${eth_tar_name} |
||||
|
BINARY_DIR ${eth_package_name}-prefix/src/${eth_package_name} |
||||
|
CONFIGURE_COMMAND "" |
||||
|
BUILD_COMMAND ${eth_package_copy} |
||||
|
INSTALL_COMMAND ${eth_package_install} |
||||
|
) |
||||
|
endmacro() |
||||
|
|
@ -0,0 +1,11 @@ |
|||||
|
# TODO this file is not used yet, but will be in future |
||||
|
include(ExternalProject) |
||||
|
|
||||
|
ExternalProject_Add(miniupnpc |
||||
|
URL http://miniupnp.tuxfamily.org/files/download.php?file=miniupnpc-1.9.20141027.tar.gz |
||||
|
BINARY_DIR miniupnpc-prefix/src/miniupnpc |
||||
|
CONFIGURE_COMMAND "" |
||||
|
BUILD_COMMAND make -j 3 |
||||
|
INSTALL_COMMAND make install INSTALLPREFIX=${ETH_DEPENDENCY_INSTALL_DIR} |
||||
|
) |
||||
|
|
@ -0,0 +1,29 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
ETH_DEPENDENCY_SOURCE_DIR=$1 |
||||
|
ETH_DEPENDENCY_INSTALL_DIR=$2 |
||||
|
|
||||
|
OLD_COMMON_DYLIB="libjsonrpccpp-common.0.dylib" |
||||
|
|
||||
|
COMMON_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libjsonrpccpp-common.0.dylib |
||||
|
SERVER_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libjsonrpccpp-server.0.dylib |
||||
|
CLIENT_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libjsonrpccpp-client.0.dylib |
||||
|
|
||||
|
# fix bin |
||||
|
STAB_EXEC=${ETH_DEPENDENCY_INSTALL_DIR}/bin/jsonrpcstub |
||||
|
install_name_tool -change ${OLD_COMMON_DYLIB} ${COMMON_DYLIB} ${STAB_EXEC} |
||||
|
|
||||
|
# fix common |
||||
|
install_name_tool -id ${COMMON_DYLIB} ${COMMON_DYLIB} |
||||
|
|
||||
|
# fix server |
||||
|
install_name_tool -id ${SERVER_DYLIB} ${SERVER_DYLIB} |
||||
|
install_name_tool -change ${OLD_COMMON_DYLIB} ${COMMON_DYLIB} ${SERVER_DYLIB} |
||||
|
|
||||
|
# fix client |
||||
|
install_name_tool -id ${CLIENT_DYLIB} ${CLIENT_DYLIB} |
||||
|
install_name_tool -change ${OLD_COMMON_DYLIB} ${COMMON_DYLIB} ${CLIENT_DYLIB} |
||||
|
|
||||
|
# TODO fix argtable and jsoncpp once they are downloaded as dependencies |
||||
|
|
||||
|
|
@ -0,0 +1,12 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
ETH_DEPENDENCY_SOURCE_DIR=$1 |
||||
|
ETH_DEPENDENCY_INSTALL_DIR=$2 |
||||
|
|
||||
|
OLD_SNAPPY_DYLIB="/Users/marekkotewicz/ethereum/cpp-ethereum/extdep/install/darwin/lib/libsnappy.1.dylib" |
||||
|
SNAPPY_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libsnappy.dylib |
||||
|
LEVELDB_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib |
||||
|
|
||||
|
install_name_tool -id ${LEVELDB_DYLIB} ${LEVELDB_DYLIB} |
||||
|
install_name_tool -change ${OLD_SNAPPY_DYLIB} ${SNAPPY_DYLIB} ${LEVELDB_DYLIB} |
||||
|
|
@ -0,0 +1,8 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
ETH_DEPENDENCY_SOURCE_DIR=$1 |
||||
|
ETH_DEPENDENCY_INSTALL_DIR=$2 |
||||
|
|
||||
|
SNAPPY_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libsnappy.dylib |
||||
|
install_name_tool -id ${SNAPPY_DYLIB} ${SNAPPY_DYLIB} |
||||
|
|
@ -1,117 +0,0 @@ |
|||||
cmake_policy(SET CMP0015 NEW) |
|
||||
|
|
||||
if ("${TARGET_PLATFORM}" STREQUAL "w64") |
|
||||
cmake_policy(SET CMP0020 NEW) |
|
||||
endif () |
|
||||
|
|
||||
|
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON) |
|
||||
aux_source_directory(. SRC_LIST) |
|
||||
|
|
||||
include_directories(..) |
|
||||
link_directories(../libethcore) |
|
||||
link_directories(../libethereum) |
|
||||
link_directories(../libqethereum) |
|
||||
|
|
||||
# Find Qt5 for Apple and update src_list for windows |
|
||||
if (APPLE) |
|
||||
# homebrew defaults to qt4 and installs qt5 as 'keg-only' |
|
||||
# which places it into /usr/local/opt insteadof /usr/local. |
|
||||
|
|
||||
set(CMAKE_PREFIX_PATH /usr/local/opt/qt5) |
|
||||
include_directories(/usr/local/opt/qt5/include /usr/local/include) |
|
||||
elseif ("${TARGET_PLATFORM}" STREQUAL "w64") |
|
||||
set(SRC_LIST ${SRC_LIST} ../windows/qt_plugin_import.cpp) |
|
||||
elseif (UNIX) |
|
||||
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake") |
|
||||
endif () |
|
||||
|
|
||||
|
|
||||
find_package(Qt5Widgets REQUIRED) |
|
||||
find_package(Qt5Gui REQUIRED) |
|
||||
find_package(Qt5Quick REQUIRED) |
|
||||
find_package(Qt5Qml REQUIRED) |
|
||||
find_package(Qt5Network REQUIRED) |
|
||||
qt5_wrap_ui(ui_Main.h Main.ui) |
|
||||
qt5_add_resources(RESOURCE_ADDED Resources.qrc) |
|
||||
|
|
||||
# Set name of binary and add_executable() |
|
||||
if (APPLE) |
|
||||
set(EXECUTEABLE IEthXi) |
|
||||
set(CMAKE_INSTALL_PREFIX ./) |
|
||||
set(BIN_INSTALL_DIR ".") |
|
||||
set(DOC_INSTALL_DIR ".") |
|
||||
|
|
||||
set(PROJECT_VERSION "${ETH_VERSION}") |
|
||||
set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") |
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}") |
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") |
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") |
|
||||
set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") |
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") |
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTEABLE}) |
|
||||
include(BundleUtilities) |
|
||||
|
|
||||
add_executable(${EXECUTEABLE} MACOSX_BUNDLE Main.ui ${RESOURCE_ADDED} ${SRC_LIST}) |
|
||||
else () |
|
||||
set(EXECUTEABLE iethxi) |
|
||||
add_executable(${EXECUTEABLE} Main.ui ${RESOURCE_ADDED} ${SRC_LIST}) |
|
||||
endif () |
|
||||
|
|
||||
qt5_use_modules(${EXECUTEABLE} Core Gui Widgets Network Quick Qml) |
|
||||
target_link_libraries(${EXECUTEABLE} qethereum ethereum secp256k1 ${CRYPTOPP_LS}) |
|
||||
|
|
||||
if (APPLE) |
|
||||
if (${ADDFRAMEWORKS}) |
|
||||
set_target_properties(${EXECUTEABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") |
|
||||
endif () |
|
||||
|
|
||||
SET_SOURCE_FILES_PROPERTIES(${EXECUTEABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) |
|
||||
|
|
||||
# This is a workaround for when the build-type defaults to Debug, and when a multi-config generator like xcode is used, where the type |
|
||||
# will not be set but defaults to release. |
|
||||
set(generator_lowercase "${CMAKE_GENERATOR}") |
|
||||
string(TOLOWER "${CMAKE_GENERATOR}" generator_lowercase) |
|
||||
if ("${generator_lowercase}" STREQUAL "xcode") |
|
||||
# TODO: Not sure how to resolve this. Possibly \${TARGET_BUILD_DIR} |
|
||||
set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}/Debug") |
|
||||
else () |
|
||||
set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}") |
|
||||
endif () |
|
||||
|
|
||||
set(APPS ${binary_build_dir}/${EXECUTEABLE}.app) |
|
||||
|
|
||||
# This tool and the next will automatically looked at the linked libraries in order to determine what dependencies are required. Thus, target_link_libaries only needs to add ethereum and secp256k1 (above) |
|
||||
install(CODE " |
|
||||
include(BundleUtilities) |
|
||||
set(BU_CHMOD_BUNDLE_ITEMS 1) |
|
||||
fixup_bundle(\"${APPS}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\") |
|
||||
" COMPONENT RUNTIME ) |
|
||||
|
|
||||
if (${ADDFRAMEWORKS}) |
|
||||
add_custom_target(addframeworks ALL |
|
||||
COMMAND /usr/local/opt/qt5/bin/macdeployqt ${binary_build_dir}/${EXECUTEABLE}.app |
|
||||
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} |
|
||||
DEPENDS ${PROJECT_NAME} |
|
||||
) |
|
||||
endif () |
|
||||
|
|
||||
elseif ("${TARGET_PLATFORM}" STREQUAL "w64") |
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -static-libgcc -static-libstdc++ -static") |
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s -Wl,-subsystem,windows -mthreads -L/usr/x86_64-w64-mingw32/plugins/platforms") |
|
||||
target_link_libraries(${EXECUTEABLE} gcc) |
|
||||
target_link_libraries(${EXECUTEABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32) |
|
||||
target_link_libraries(${EXECUTEABLE} boost_system-mt-s) |
|
||||
target_link_libraries(${EXECUTEABLE} boost_filesystem-mt-s) |
|
||||
target_link_libraries(${EXECUTEABLE} boost_thread_win32-mt-s) |
|
||||
target_link_libraries(${EXECUTEABLE} Qt5PlatformSupport) |
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) |
|
||||
elseif (UNIX) |
|
||||
else () |
|
||||
target_link_libraries(${EXECUTEABLE} boost_system) |
|
||||
target_link_libraries(${EXECUTEABLE} boost_filesystem) |
|
||||
find_package(Threads REQUIRED) |
|
||||
target_link_libraries(${EXECUTEABLE} ${CMAKE_THREAD_LIBS_INIT}) |
|
||||
install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin ) |
|
||||
endif () |
|
||||
|
|
@ -1,38 +0,0 @@ |
|||||
<?xml version="1.0" encoding="UTF-8"?> |
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
|
||||
<plist version="1.0"> |
|
||||
<dict> |
|
||||
<key>CFBundleDevelopmentRegion</key> |
|
||||
<string>English</string> |
|
||||
<key>CFBundleExecutable</key> |
|
||||
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string> |
|
||||
<key>CFBundleGetInfoString</key> |
|
||||
<string>${MACOSX_BUNDLE_INFO_STRING}</string> |
|
||||
<key>CFBundleIconFile</key> |
|
||||
<string>${MACOSX_BUNDLE_ICON_FILE}</string> |
|
||||
<key>CFBundleIdentifier</key> |
|
||||
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string> |
|
||||
<key>CFBundleInfoDictionaryVersion</key> |
|
||||
<string>6.0</string> |
|
||||
<key>CFBundleLongVersionString</key> |
|
||||
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string> |
|
||||
<key>CFBundleName</key> |
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string> |
|
||||
<key>CFBundlePackageType</key> |
|
||||
<string>APPL</string> |
|
||||
<key>CFBundleShortVersionString</key> |
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string> |
|
||||
<key>CFBundleSignature</key> |
|
||||
<string>????</string> |
|
||||
<key>CFBundleVersion</key> |
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string> |
|
||||
<key>CSResourcesFileMapped</key> |
|
||||
<true/> |
|
||||
<key>LSRequiresCarbon</key> |
|
||||
<true/> |
|
||||
<key>NSHumanReadableCopyright</key> |
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string> |
|
||||
<key>NSHighResolutionCapable</key> |
|
||||
<true/> |
|
||||
</dict> |
|
||||
</plist> |
|
@ -1,168 +0,0 @@ |
|||||
<?xml version="1.0" encoding="UTF-8"?> |
|
||||
<ui version="4.0"> |
|
||||
<class>Main</class> |
|
||||
<widget class="QMainWindow" name="Main"> |
|
||||
<property name="geometry"> |
|
||||
<rect> |
|
||||
<x>0</x> |
|
||||
<y>0</y> |
|
||||
<width>562</width> |
|
||||
<height>488</height> |
|
||||
</rect> |
|
||||
</property> |
|
||||
<property name="windowTitle"> |
|
||||
<string>Walleth</string> |
|
||||
</property> |
|
||||
<property name="dockNestingEnabled"> |
|
||||
<bool>true</bool> |
|
||||
</property> |
|
||||
<property name="dockOptions"> |
|
||||
<set>QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::VerticalTabs</set> |
|
||||
</property> |
|
||||
<property name="sizeGripEnabled" stdset="0"> |
|
||||
<bool>true</bool> |
|
||||
</property> |
|
||||
<widget class="QWidget" name="centralwidget"> |
|
||||
<layout class="QVBoxLayout" name="verticalLayout"> |
|
||||
<property name="leftMargin"> |
|
||||
<number>0</number> |
|
||||
</property> |
|
||||
<property name="topMargin"> |
|
||||
<number>0</number> |
|
||||
</property> |
|
||||
<property name="rightMargin"> |
|
||||
<number>0</number> |
|
||||
</property> |
|
||||
<property name="bottomMargin"> |
|
||||
<number>0</number> |
|
||||
</property> |
|
||||
<item> |
|
||||
<layout class="QHBoxLayout" name="fullDisplay"> |
|
||||
<item> |
|
||||
<widget class="QLabel" name="balance"> |
|
||||
<property name="text"> |
|
||||
<string>0 wei</string> |
|
||||
</property> |
|
||||
</widget> |
|
||||
</item> |
|
||||
<item> |
|
||||
<widget class="QLabel" name="peerCount"> |
|
||||
<property name="text"> |
|
||||
<string>0 peers</string> |
|
||||
</property> |
|
||||
</widget> |
|
||||
</item> |
|
||||
<item> |
|
||||
<widget class="QLabel" name="blockCount"> |
|
||||
<property name="text"> |
|
||||
<string>1 block</string> |
|
||||
</property> |
|
||||
</widget> |
|
||||
</item> |
|
||||
</layout> |
|
||||
</item> |
|
||||
</layout> |
|
||||
</widget> |
|
||||
<widget class="QMenuBar" name="menubar"> |
|
||||
<property name="geometry"> |
|
||||
<rect> |
|
||||
<x>0</x> |
|
||||
<y>0</y> |
|
||||
<width>562</width> |
|
||||
<height>25</height> |
|
||||
</rect> |
|
||||
</property> |
|
||||
<widget class="QMenu" name="menu_File"> |
|
||||
<property name="title"> |
|
||||
<string>&File</string> |
|
||||
</property> |
|
||||
<addaction name="quit"/> |
|
||||
</widget> |
|
||||
<widget class="QMenu" name="menu_Network"> |
|
||||
<property name="title"> |
|
||||
<string>&Network</string> |
|
||||
</property> |
|
||||
<addaction name="upnp"/> |
|
||||
<addaction name="net"/> |
|
||||
<addaction name="connect"/> |
|
||||
</widget> |
|
||||
<widget class="QMenu" name="menu_Tools"> |
|
||||
<property name="title"> |
|
||||
<string>T&ools</string> |
|
||||
</property> |
|
||||
<addaction name="mine"/> |
|
||||
<addaction name="create"/> |
|
||||
<addaction name="preview"/> |
|
||||
</widget> |
|
||||
<widget class="QMenu" name="menu_Help"> |
|
||||
<property name="title"> |
|
||||
<string>&Help</string> |
|
||||
</property> |
|
||||
<addaction name="about"/> |
|
||||
</widget> |
|
||||
<addaction name="menu_File"/> |
|
||||
<addaction name="menu_Network"/> |
|
||||
<addaction name="menu_Tools"/> |
|
||||
<addaction name="menu_Help"/> |
|
||||
</widget> |
|
||||
<widget class="QStatusBar" name="statusbar"/> |
|
||||
<action name="quit"> |
|
||||
<property name="text"> |
|
||||
<string>&Quit</string> |
|
||||
</property> |
|
||||
</action> |
|
||||
<action name="upnp"> |
|
||||
<property name="checkable"> |
|
||||
<bool>true</bool> |
|
||||
</property> |
|
||||
<property name="checked"> |
|
||||
<bool>true</bool> |
|
||||
</property> |
|
||||
<property name="text"> |
|
||||
<string>Use &UPnP</string> |
|
||||
</property> |
|
||||
</action> |
|
||||
<action name="connect"> |
|
||||
<property name="text"> |
|
||||
<string>&Connect to Peer...</string> |
|
||||
</property> |
|
||||
</action> |
|
||||
<action name="net"> |
|
||||
<property name="checkable"> |
|
||||
<bool>true</bool> |
|
||||
</property> |
|
||||
<property name="text"> |
|
||||
<string>Enable &Network</string> |
|
||||
</property> |
|
||||
</action> |
|
||||
<action name="mine"> |
|
||||
<property name="checkable"> |
|
||||
<bool>true</bool> |
|
||||
</property> |
|
||||
<property name="text"> |
|
||||
<string>&Mine</string> |
|
||||
</property> |
|
||||
</action> |
|
||||
<action name="create"> |
|
||||
<property name="text"> |
|
||||
<string>&New Address</string> |
|
||||
</property> |
|
||||
</action> |
|
||||
<action name="about"> |
|
||||
<property name="text"> |
|
||||
<string>&About...</string> |
|
||||
</property> |
|
||||
</action> |
|
||||
<action name="preview"> |
|
||||
<property name="checkable"> |
|
||||
<bool>true</bool> |
|
||||
</property> |
|
||||
<property name="text"> |
|
||||
<string>&Preview</string> |
|
||||
</property> |
|
||||
</action> |
|
||||
</widget> |
|
||||
<layoutdefault spacing="6" margin="11"/> |
|
||||
<resources/> |
|
||||
<connections/> |
|
||||
</ui> |
|
@ -1,59 +0,0 @@ |
|||||
#include <QtNetwork/QNetworkReply> |
|
||||
#include <QtQuick/QQuickView> |
|
||||
#include <QtQml/QQmlContext> |
|
||||
#include <QtQml/QQmlEngine> |
|
||||
#include <QtQml/QtQml> |
|
||||
#include <QtWidgets/QMessageBox> |
|
||||
#include <QtWidgets/QInputDialog> |
|
||||
#include <QtGui/QClipboard> |
|
||||
#include <QtCore/QtCore> |
|
||||
#include <libethcore/FileSystem.h> |
|
||||
#include <libethcore/Dagger.h> |
|
||||
#include <libevmcore/Instruction.h> |
|
||||
#include <libethereum/Client.h> |
|
||||
#include <libethereum/EthereumHost.h> |
|
||||
#include "BuildInfo.h" |
|
||||
#include "MainWin.h" |
|
||||
#include "ui_Main.h" |
|
||||
using namespace std; |
|
||||
using namespace eth; |
|
||||
|
|
||||
Main::Main(QWidget *parent) : |
|
||||
QObject(parent) |
|
||||
{ |
|
||||
/* qRegisterMetaType<eth::u256>("eth::u256");
|
|
||||
qRegisterMetaType<eth::KeyPair>("eth::KeyPair"); |
|
||||
qRegisterMetaType<eth::Secret>("eth::Secret"); |
|
||||
qRegisterMetaType<eth::Address>("eth::Address"); |
|
||||
qRegisterMetaType<QmlAccount*>("QmlAccount*"); |
|
||||
qRegisterMetaType<QmlEthereum*>("QmlEthereum*"); |
|
||||
|
|
||||
qmlRegisterType<QmlEthereum>("org.ethereum", 1, 0, "Ethereum"); |
|
||||
qmlRegisterType<QmlAccount>("org.ethereum", 1, 0, "Account"); |
|
||||
qmlRegisterSingletonType<QmlU256Helper>("org.ethereum", 1, 0, "Balance", QmlEthereum::constructU256Helper); |
|
||||
qmlRegisterSingletonType<QmlKeyHelper>("org.ethereum", 1, 0, "Key", QmlEthereum::constructKeyHelper); |
|
||||
*/ |
|
||||
/*
|
|
||||
ui->librariesView->setModel(m_libraryMan); |
|
||||
ui->graphsView->setModel(m_graphMan); |
|
||||
*/ |
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
// QQmlContext* context = m_view->rootContext();
|
|
||||
// context->setContextProperty("u256", new U256Helper(this));
|
|
||||
} |
|
||||
|
|
||||
Main::~Main() |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
// extra bits needed to link on VS
|
|
||||
#ifdef _MSC_VER |
|
||||
|
|
||||
// include moc file, ofuscated to hide from automoc
|
|
||||
#include\ |
|
||||
"moc_MainWin.cpp" |
|
||||
|
|
||||
#endif |
|
@ -1,18 +0,0 @@ |
|||||
#ifndef MAIN_H |
|
||||
#define MAIN_H |
|
||||
|
|
||||
#include <QtQml/QQmlApplicationEngine> |
|
||||
|
|
||||
class Main: public QObject |
|
||||
{ |
|
||||
Q_OBJECT |
|
||||
|
|
||||
public: |
|
||||
explicit Main(QWidget *parent = 0); |
|
||||
~Main(); |
|
||||
|
|
||||
private: |
|
||||
QQmlApplicationEngine* m_view; |
|
||||
}; |
|
||||
|
|
||||
#endif // MAIN_H
|
|
@ -1,5 +0,0 @@ |
|||||
<RCC> |
|
||||
<qresource prefix="/"> |
|
||||
<file>Simple.qml</file> |
|
||||
</qresource> |
|
||||
</RCC> |
|
@ -1,9 +0,0 @@ |
|||||
import QtQuick.Controls 1.1 |
|
||||
|
|
||||
ApplicationWindow { |
|
||||
title: "My App" |
|
||||
Button { |
|
||||
text: "Push Me" |
|
||||
anchors.centerIn: parent |
|
||||
} |
|
||||
} |
|
@ -1,9 +0,0 @@ |
|||||
#include <QtQml/QQmlApplicationEngine> |
|
||||
#include <QtWidgets/QApplication> |
|
||||
|
|
||||
int main(int argc, char *argv[]) |
|
||||
{ |
|
||||
QApplication a(argc, argv); |
|
||||
QQmlApplicationEngine app(QUrl("qrc:/Simple.qml")); |
|
||||
return a.exec(); |
|
||||
} |
|
@ -1,8 +0,0 @@ |
|||||
#pragma once |
|
||||
|
|
||||
#include "Common.h" |
|
||||
#include "CommonData.h" |
|
||||
#include "CommonIO.h" |
|
||||
#include "FixedHash.h" |
|
||||
#include "Log.h" |
|
||||
#include "RLP.h" |
|
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue