mirror of
https://github.com/facebook/proxygen.git
synced 2025-08-08 18:02:05 +03:00
Forced watchman daemon to always operate in non elevated mode on Windows (#878)
Summary: Recently I found that its impossible to access elevated Watchman daemon from non-elevated process on Windows. ``` events.js:174 throw er; // Unhandled 'error' event ^ Error: connect EPERM \\.\pipe\watchman at PipeConnectWrap.afterConnect [as oncomplete] (net.js:1106:14) Emitted 'error' event at: at Socket.<anonymous> (C:\open\ovrsource\unity\socialvr\_js\node_modules\fb-watchman\index.js:118:12) at Socket.emit (events.js:198:13) at emitErrorNT (internal/streams/destroy.js:91:8) at emitErrorAndCloseNT (internal/streams/destroy.js:59:3) at process._tickCallback (internal/process/next_tick.js:63:19) ``` To fix this, it was suggested by wez to use [his library](https://github.com/wez/EleDo) to force Watchman daemon always start in normal mode on Windows. In this stack of commits I did integrated his library into project and used it to force daemon restart in normal mode when spawned from elevated terminal. To make it happen, I checked-in library sources and created proxy project which depends on the initial library and contains header bindings and cmake configuration. I did copy pasted Rust cmake macroses from another facebook project - eden, and also created analogue of autogen.sh but for Windows - autogen.cmd. Pull Request resolved: https://github.com/facebook/watchman/pull/878 Test Plan: Launch elevated terminal Start watchman.exe produced from sources Observe daemon starting and answering In process monitor, observe watchman.exe process running under user group Reviewed By: fanzeyi Differential Revision: D25595879 Pulled By: arhelmus fbshipit-source-id: 15eb29adcf5bd4a5708b6533a1b2bacbf13f431c
This commit is contained in:
committed by
Facebook GitHub Bot
parent
89a9ef90ce
commit
046a69f909
289
build/fbcode_builder/CMake/RustStaticLibrary.cmake
Normal file
289
build/fbcode_builder/CMake/RustStaticLibrary.cmake
Normal file
@@ -0,0 +1,289 @@
|
||||
include(FBCMakeParseArgs)
|
||||
|
||||
set(
|
||||
USE_CARGO_VENDOR AUTO CACHE STRING
|
||||
"Download Rust Crates from an internally vendored location"
|
||||
)
|
||||
set_property(CACHE USE_CARGO_VENDOR PROPERTY STRINGS AUTO ON OFF)
|
||||
|
||||
set(RUST_VENDORED_CRATES_DIR "$ENV{RUST_VENDORED_CRATES_DIR}")
|
||||
if("${USE_CARGO_VENDOR}" STREQUAL "AUTO")
|
||||
if(EXISTS "${RUST_VENDORED_CRATES_DIR}")
|
||||
set(USE_CARGO_VENDOR ON)
|
||||
else()
|
||||
set(USE_CARGO_VENDOR OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(USE_CARGO_VENDOR)
|
||||
if(NOT EXISTS "${RUST_VENDORED_CRATES_DIR}")
|
||||
message(
|
||||
FATAL "vendored rust crates not present: "
|
||||
"${RUST_VENDORED_CRATES_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(RUST_CARGO_HOME "${CMAKE_BINARY_DIR}/_cargo_home")
|
||||
file(MAKE_DIRECTORY "${RUST_CARGO_HOME}")
|
||||
|
||||
file(
|
||||
TO_NATIVE_PATH "${RUST_VENDORED_CRATES_DIR}"
|
||||
ESCAPED_RUST_VENDORED_CRATES_DIR
|
||||
)
|
||||
string(
|
||||
REPLACE "\\" "\\\\"
|
||||
ESCAPED_RUST_VENDORED_CRATES_DIR
|
||||
"${ESCAPED_RUST_VENDORED_CRATES_DIR}"
|
||||
)
|
||||
file(
|
||||
WRITE "${RUST_CARGO_HOME}/config"
|
||||
"[source.crates-io]\n"
|
||||
"replace-with = \"vendored-sources\"\n"
|
||||
"\n"
|
||||
"[source.vendored-sources]\n"
|
||||
"directory = \"${ESCAPED_RUST_VENDORED_CRATES_DIR}\"\n"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Cargo is a build system in itself, and thus will try to take advantage of all
|
||||
# the cores on the system. Unfortunately, this conflicts with Ninja, since it
|
||||
# also tries to utilize all the cores. This can lead to a system that is
|
||||
# completely overloaded with compile jobs to the point where nothing else can
|
||||
# be achieved on the system.
|
||||
#
|
||||
# Let's inform Ninja of this fact so it won't try to spawn other jobs while
|
||||
# Rust being compiled.
|
||||
set_property(GLOBAL APPEND PROPERTY JOB_POOLS rust_job_pool=1)
|
||||
|
||||
# This function creates an interface library target based on the static library
|
||||
# built by Cargo. It will call Cargo to build a staticlib and generate a CMake
|
||||
# interface library with it.
|
||||
#
|
||||
# This function requires `find_package(Python COMPONENTS Interpreter)`.
|
||||
#
|
||||
# You need to set `lib:crate-type = ["staticlib"]` in your Cargo.toml to make
|
||||
# Cargo build static library.
|
||||
#
|
||||
# ```cmake
|
||||
# rust_static_library(<TARGET> [CRATE <CRATE_NAME>])
|
||||
# ```
|
||||
#
|
||||
# Parameters:
|
||||
# - TARGET:
|
||||
# Name of the target name. This function will create an interface library
|
||||
# target with this name.
|
||||
# - CRATE_NAME:
|
||||
# Name of the crate. This parameter is optional. If unspecified, it will
|
||||
# fallback to `${TARGET}`.
|
||||
#
|
||||
# This function creates two targets:
|
||||
# - "${TARGET}": an interface library target contains the static library built
|
||||
# from Cargo.
|
||||
# - "${TARGET}.cargo": an internal custom target that invokes Cargo.
|
||||
#
|
||||
# If you are going to use this static library from C/C++, you will need to
|
||||
# write header files for the library (or generate with cbindgen) and bind these
|
||||
# headers with the interface library.
|
||||
#
|
||||
function(rust_static_library TARGET)
|
||||
fb_cmake_parse_args(ARG "" "CRATE" "" "${ARGN}")
|
||||
|
||||
if(DEFINED ARG_CRATE)
|
||||
set(crate_name "${ARG_CRATE}")
|
||||
else()
|
||||
set(crate_name "${TARGET}")
|
||||
endif()
|
||||
|
||||
set(cargo_target "${TARGET}.cargo")
|
||||
set(target_dir $<IF:$<CONFIG:Debug>,debug,release>)
|
||||
set(staticlib_name "${CMAKE_STATIC_LIBRARY_PREFIX}${crate_name}${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
set(rust_staticlib "${CMAKE_CURRENT_BINARY_DIR}/${target_dir}/${staticlib_name}")
|
||||
|
||||
set(cargo_cmd cargo)
|
||||
if(WIN32)
|
||||
set(cargo_cmd cargo.exe)
|
||||
endif()
|
||||
|
||||
set(cargo_flags build $<IF:$<CONFIG:Debug>,,--release> -p ${crate_name})
|
||||
if(USE_CARGO_VENDOR)
|
||||
set(extra_cargo_env "CARGO_HOME=${RUST_CARGO_HOME}")
|
||||
set(cargo_flags ${cargo_flags})
|
||||
endif()
|
||||
|
||||
add_custom_target(
|
||||
${cargo_target}
|
||||
COMMAND
|
||||
"${CMAKE_COMMAND}" -E remove -f "${CMAKE_CURRENT_SOURCE_DIR}/Cargo.lock"
|
||||
COMMAND
|
||||
"${CMAKE_COMMAND}" -E env
|
||||
"CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}"
|
||||
${extra_cargo_env}
|
||||
${cargo_cmd}
|
||||
${cargo_flags}
|
||||
COMMENT "Building Rust crate '${crate_name}'..."
|
||||
JOB_POOL rust_job_pool
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
BYPRODUCTS
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/debug/${staticlib_name}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/release/${staticlib_name}"
|
||||
)
|
||||
|
||||
add_library(${TARGET} INTERFACE)
|
||||
add_dependencies(${TARGET} ${cargo_target})
|
||||
set_target_properties(
|
||||
${TARGET}
|
||||
PROPERTIES
|
||||
INTERFACE_STATICLIB_OUTPUT_PATH "${rust_staticlib}"
|
||||
INTERFACE_INSTALL_LIBNAME
|
||||
"${CMAKE_STATIC_LIBRARY_PREFIX}${crate_name}_rs${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
)
|
||||
target_link_libraries(
|
||||
${TARGET}
|
||||
INTERFACE "$<BUILD_INTERFACE:${rust_staticlib}>"
|
||||
)
|
||||
endfunction()
|
||||
|
||||
# This function instructs cmake to define a target that will use `cargo build`
|
||||
# to build a bin crate referenced by the Cargo.toml file in the current source
|
||||
# directory.
|
||||
# It accepts a single `TARGET` parameter which will be passed as the package
|
||||
# name to `cargo build -p TARGET`. If binary has different name as package,
|
||||
# use optional flag BINARY_NAME to override it.
|
||||
# The cmake target will be registered to build by default as part of the
|
||||
# ALL target.
|
||||
function(rust_executable TARGET)
|
||||
fb_cmake_parse_args(ARG "" "BINARY_NAME" "" "${ARGN}")
|
||||
|
||||
set(crate_name "${TARGET}")
|
||||
set(cargo_target "${TARGET}.cargo")
|
||||
set(target_dir $<IF:$<CONFIG:Debug>,debug,release>)
|
||||
|
||||
if(DEFINED ARG_BINARY_NAME)
|
||||
set(executable_name "${ARG_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
|
||||
else()
|
||||
set(executable_name "${crate_name}${CMAKE_EXECUTABLE_SUFFIX}")
|
||||
endif()
|
||||
|
||||
set(cargo_cmd cargo)
|
||||
if(WIN32)
|
||||
set(cargo_cmd cargo.exe)
|
||||
endif()
|
||||
|
||||
set(cargo_flags build $<IF:$<CONFIG:Debug>,,--release> -p ${crate_name})
|
||||
if(USE_CARGO_VENDOR)
|
||||
set(extra_cargo_env "CARGO_HOME=${RUST_CARGO_HOME}")
|
||||
set(cargo_flags ${cargo_flags})
|
||||
endif()
|
||||
|
||||
add_custom_target(
|
||||
${cargo_target}
|
||||
ALL
|
||||
COMMAND
|
||||
"${CMAKE_COMMAND}" -E remove -f "${CMAKE_CURRENT_SOURCE_DIR}/Cargo.lock"
|
||||
COMMAND
|
||||
"${CMAKE_COMMAND}" -E env
|
||||
"CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR}"
|
||||
${extra_cargo_env}
|
||||
${cargo_cmd}
|
||||
${cargo_flags}
|
||||
COMMENT "Building Rust executable '${crate_name}'..."
|
||||
JOB_POOL rust_job_pool
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
BYPRODUCTS
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/debug/${executable_name}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/release/${executable_name}"
|
||||
)
|
||||
|
||||
set_property(TARGET "${cargo_target}"
|
||||
PROPERTY EXECUTABLE "${CMAKE_CURRENT_BINARY_DIR}/${target_dir}/${executable_name}")
|
||||
endfunction()
|
||||
|
||||
# This function can be used to install the executable generated by a prior
|
||||
# call to the `rust_executable` function.
|
||||
# It requires a `TARGET` parameter to identify the target to be installed,
|
||||
# and an optional `DESTINATION` parameter to specify the installation
|
||||
# directory. If DESTINATION is not specified then the `bin` directory
|
||||
# will be assumed.
|
||||
function(install_rust_executable TARGET)
|
||||
# Parse the arguments
|
||||
set(one_value_args DESTINATION)
|
||||
set(multi_value_args)
|
||||
fb_cmake_parse_args(
|
||||
ARG "" "${one_value_args}" "${multi_value_args}" "${ARGN}"
|
||||
)
|
||||
|
||||
if(NOT DEFINED ARG_DESTINATION)
|
||||
set(ARG_DESTINATION bin)
|
||||
endif()
|
||||
|
||||
get_target_property(foo "${TARGET}.cargo" EXECUTABLE)
|
||||
|
||||
install(
|
||||
PROGRAMS "${foo}"
|
||||
DESTINATION "${ARG_DESTINATION}"
|
||||
)
|
||||
endfunction()
|
||||
|
||||
# This function installs the interface target generated from the function
|
||||
# `rust_static_library`. Use this function if you want to export your Rust
|
||||
# target to external CMake targets.
|
||||
#
|
||||
# ```cmake
|
||||
# install_rust_static_library(
|
||||
# <TARGET>
|
||||
# INSTALL_DIR <INSTALL_DIR>
|
||||
# [EXPORT <EXPORT_NAME>]
|
||||
# )
|
||||
# ```
|
||||
#
|
||||
# Parameters:
|
||||
# - TARGET: Name of the Rust static library target.
|
||||
# - EXPORT_NAME: Name of the exported target.
|
||||
# - INSTALL_DIR: Path to the directory where this library will be installed.
|
||||
#
|
||||
function(install_rust_static_library TARGET)
|
||||
fb_cmake_parse_args(ARG "" "EXPORT;INSTALL_DIR" "" "${ARGN}")
|
||||
|
||||
get_property(
|
||||
staticlib_output_path
|
||||
TARGET "${TARGET}"
|
||||
PROPERTY INTERFACE_STATICLIB_OUTPUT_PATH
|
||||
)
|
||||
get_property(
|
||||
staticlib_output_name
|
||||
TARGET "${TARGET}"
|
||||
PROPERTY INTERFACE_INSTALL_LIBNAME
|
||||
)
|
||||
|
||||
if(NOT DEFINED staticlib_output_path)
|
||||
message(FATAL_ERROR "Not a rust_static_library target.")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED ARG_INSTALL_DIR)
|
||||
message(FATAL_ERROR "Missing required argument.")
|
||||
endif()
|
||||
|
||||
if(DEFINED ARG_EXPORT)
|
||||
set(install_export_args EXPORT "${ARG_EXPORT}")
|
||||
endif()
|
||||
|
||||
set(install_interface_dir "${ARG_INSTALL_DIR}")
|
||||
if(NOT IS_ABSOLUTE "${install_interface_dir}")
|
||||
set(install_interface_dir "\${_IMPORT_PREFIX}/${install_interface_dir}")
|
||||
endif()
|
||||
|
||||
target_link_libraries(
|
||||
${TARGET} INTERFACE
|
||||
"$<INSTALL_INTERFACE:${install_interface_dir}/${staticlib_output_name}>"
|
||||
)
|
||||
install(
|
||||
TARGETS ${TARGET}
|
||||
${install_export_args}
|
||||
LIBRARY DESTINATION ${ARG_INSTALL_DIR}
|
||||
)
|
||||
install(
|
||||
FILES ${staticlib_output_path}
|
||||
RENAME ${staticlib_output_name}
|
||||
DESTINATION ${ARG_INSTALL_DIR}
|
||||
)
|
||||
endfunction()
|
@@ -114,6 +114,10 @@ class ProjectCmdBase(SubCmd):
|
||||
elif len(parts) == 1:
|
||||
project = args.project
|
||||
path = parts[0]
|
||||
# On Windows path contains colon, e.g. C:\open
|
||||
elif os.name == "nt" and len(parts) == 3:
|
||||
project = parts[0]
|
||||
path = parts[1] + ":" + parts[2]
|
||||
else:
|
||||
raise UsageError(
|
||||
"invalid %s argument; too many ':' characters: %s" % (arg_type, arg)
|
||||
|
@@ -19,6 +19,9 @@ folly
|
||||
pcre
|
||||
googletest
|
||||
|
||||
[dependencies.fb=on]
|
||||
rust
|
||||
|
||||
[shipit.pathmap]
|
||||
fbcode/watchman = .
|
||||
fbcode/eden/fs = eden/fs
|
||||
|
Reference in New Issue
Block a user