From d7a313c5c356e1641f18cd14ad0ac0c3901bc0bf Mon Sep 17 00:00:00 2001 From: Albert Ziegenhagel Date: Mon, 28 Aug 2017 10:48:30 +0200 Subject: [vtk] improve portfile: - Use system libharu - Simplyfy enabling/disabling optional modules of VTK - Add options to build VTK python modules or all VTK modules --- ports/vtk/CONTROL | 4 +- ports/vtk/FindGDAL.cmake | 127 ++++++++++++++++++++++++++++++ ports/vtk/fix-find-libharu.patch | 18 +++++ ports/vtk/fix-find-mysql.patch | 10 +++ ports/vtk/fix-find-odbc.patch | 11 +++ ports/vtk/portfile.cmake | 162 ++++++++++++++++++++++++++++++++++----- 6 files changed, 310 insertions(+), 22 deletions(-) create mode 100644 ports/vtk/FindGDAL.cmake create mode 100644 ports/vtk/fix-find-libharu.patch create mode 100644 ports/vtk/fix-find-mysql.patch create mode 100644 ports/vtk/fix-find-odbc.patch diff --git a/ports/vtk/CONTROL b/ports/vtk/CONTROL index 652c27700..13fb6fd7d 100644 --- a/ports/vtk/CONTROL +++ b/ports/vtk/CONTROL @@ -1,4 +1,4 @@ Source: vtk -Version: 8.0.0-1 +Version: 8.0.0-2 Description: Software system for 3D computer graphics, image processing, and visualization -Build-Depends: zlib, libpng, tiff, libxml2, jsoncpp, glew, freetype, expat, hdf5, qt5, msmpi, libjpeg-turbo, proj, lz4, libtheora +Build-Depends: zlib, libpng, tiff, libxml2, jsoncpp, glew, freetype, expat, hdf5, qt5, msmpi, libjpeg-turbo, proj, lz4, libtheora, libharu diff --git a/ports/vtk/FindGDAL.cmake b/ports/vtk/FindGDAL.cmake new file mode 100644 index 000000000..e4f2f303b --- /dev/null +++ b/ports/vtk/FindGDAL.cmake @@ -0,0 +1,127 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#.rst: +# FindGDAL +# -------- +# +# +# +# Locate gdal +# +# This module accepts the following environment variables: +# +# :: +# +# GDAL_DIR or GDAL_ROOT - Specify the location of GDAL +# +# +# +# This module defines the following CMake variables: +# +# :: +# +# GDAL_FOUND - True if libgdal is found +# GDAL_LIBRARY - A variable pointing to the GDAL library +# GDAL_INCLUDE_DIR - Where to find the headers + +# +# $GDALDIR is an environment variable that would +# correspond to the ./configure --prefix=$GDAL_DIR +# used in building gdal. +# +# Created by Eric Wing. I'm not a gdal user, but OpenSceneGraph uses it +# for osgTerrain so I whipped this module together for completeness. +# I actually don't know the conventions or where files are typically +# placed in distros. +# Any real gdal users are encouraged to correct this (but please don't +# break the OS X framework stuff when doing so which is what usually seems +# to happen). + +# This makes the presumption that you are include gdal.h like +# +#include "gdal.h" + +find_path(GDAL_INCLUDE_DIR gdal.h + HINTS + ENV GDAL_DIR + ENV GDAL_ROOT + PATH_SUFFIXES + include/gdal + include/GDAL + include + PATHS + ~/Library/Frameworks/gdal.framework/Headers + /Library/Frameworks/gdal.framework/Headers + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) + +if(UNIX) + # Use gdal-config to obtain the library version (this should hopefully + # allow us to -lgdal1.x.y where x.y are correct version) + # For some reason, libgdal development packages do not contain + # libgdal.so... + find_program(GDAL_CONFIG gdal-config + HINTS + ENV GDAL_DIR + ENV GDAL_ROOT + PATH_SUFFIXES bin + PATHS + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt + ) + + if(GDAL_CONFIG) + exec_program(${GDAL_CONFIG} ARGS --libs OUTPUT_VARIABLE GDAL_CONFIG_LIBS) + if(GDAL_CONFIG_LIBS) + string(REGEX MATCHALL "-l[^ ]+" _gdal_dashl ${GDAL_CONFIG_LIBS}) + string(REPLACE "-l" "" _gdal_lib "${_gdal_dashl}") + string(REGEX MATCHALL "-L[^ ]+" _gdal_dashL ${GDAL_CONFIG_LIBS}) + string(REPLACE "-L" "" _gdal_libpath "${_gdal_dashL}") + endif() + endif() +endif() + +find_library(GDAL_LIBRARY_RELEASE + NAMES ${_gdal_lib} gdal gdal_i gdal1.5.0 gdal1.4.0 gdal1.3.2 GDAL + HINTS + ENV GDAL_DIR + ENV GDAL_ROOT + ${_gdal_libpath} + PATH_SUFFIXES lib + PATHS + /sw + /opt/local + /opt/csw + /opt + /usr/freeware +) + +find_library(GDAL_LIBRARY_DEBUG + NAMES ${_gdal_lib} gdald gdald_i gdald1.5.0 gdald1.4.0 gdald1.3.2 GDALD + HINTS + ENV GDAL_DIR + ENV GDAL_ROOT + ${_gdal_libpath} + PATH_SUFFIXES lib + PATHS + /sw + /opt/local + /opt/csw + /opt + /usr/freeware +) + +include(SelectLibraryConfigurations) +select_library_configurations(GDAL) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(GDAL DEFAULT_MSG GDAL_LIBRARY GDAL_INCLUDE_DIR) + +set(GDAL_LIBRARIES ${GDAL_LIBRARY}) +set(GDAL_INCLUDE_DIRS ${GDAL_INCLUDE_DIR}) diff --git a/ports/vtk/fix-find-libharu.patch b/ports/vtk/fix-find-libharu.patch new file mode 100644 index 000000000..683f7bae6 --- /dev/null +++ b/ports/vtk/fix-find-libharu.patch @@ -0,0 +1,18 @@ +--- a/CMake/FindLibHaru.cmake Mon Jun 26 15:29:04 2017 ++++ b/CMake/FindLibHaru.cmake Wed Aug 16 09:30:12 2017 +@@ -19,9 +19,13 @@ + + find_path(LIBHARU_INCLUDE_DIR hpdf.h) + +-find_library(LIBHARU_LIBRARY NAMES hpdf) ++find_library(LIBHARU_LIBRARY_RELEASE NAMES hpdf libhpdf) ++find_library(LIBHARU_LIBRARY_DEBUG NAMES hpdfd libhpdfd) + +-# handle the QUIETLY and REQUIRED arguments and set FONTCONFIG_FOUND to TRUE if ++include(SelectLibraryConfigurations) ++select_library_configurations(LIBHARU) ++ ++# handle the QUIETLY and REQUIRED arguments and set LIBHARU_FOUND to TRUE if + # all listed variables are TRUE + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(LibHaru DEFAULT_MSG diff --git a/ports/vtk/fix-find-mysql.patch b/ports/vtk/fix-find-mysql.patch new file mode 100644 index 000000000..d2f984cd5 --- /dev/null +++ b/ports/vtk/fix-find-mysql.patch @@ -0,0 +1,10 @@ +--- a/CMake/FindMySQL.cmake Mon Jun 26 15:29:04 2017 ++++ b/CMake/FindMySQL.cmake Wed Aug 16 11:21:58 2017 +@@ -28,6 +28,7 @@ + "C:/MySQL/include" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MySQL AB\\MySQL Server 5.0;Location]/include" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\MySQL AB\\MySQL Server 5.0;Location]/include" ++ PATH_SUFFIXES mysql + DOC "Specify the directory containing mysql.h." + ) + diff --git a/ports/vtk/fix-find-odbc.patch b/ports/vtk/fix-find-odbc.patch new file mode 100644 index 000000000..0690ed0a9 --- /dev/null +++ b/ports/vtk/fix-find-odbc.patch @@ -0,0 +1,11 @@ +--- a/CMake/FindODBC.cmake Mon Jun 26 15:29:04 2017 ++++ b/CMake/FindODBC.cmake Wed Aug 16 12:58:11 2017 +@@ -30,7 +30,7 @@ + ) + + FIND_LIBRARY( ODBC_LIBRARY +- NAMES odbc iodbc unixodbc ++ NAMES odbc iodbc unixodbc odbc32 + PATHS + /usr/lib + /usr/lib/odbc diff --git a/ports/vtk/portfile.cmake b/ports/vtk/portfile.cmake index ff9d457f1..c5ea4c387 100644 --- a/ports/vtk/portfile.cmake +++ b/ports/vtk/portfile.cmake @@ -1,13 +1,26 @@ include(vcpkg_common_functions) +set(VTK_SHORT_VERSION "8.0") +set(VTK_LONG_VERSION "${VTK_SHORT_VERSION}.0") + vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH REPO "Kitware/VTK" - REF "v8.0.0" + REF "v${VTK_LONG_VERSION}" SHA512 1a328f24df0b1c40c623ae80c9d49f8b27570144b10af02aeed41b90b50b8d4e0dd83d1341961f6818cde36e2cd793c578ebc95a46950cebfc518f486f249791 HEAD_REF "master" ) +# ============================================================================= +# Options: These should be set by feature-packages when they become available +set(VTK_WITH_QT ON ) # IMPORTANT: if ON make sure `qt5` is listed as dependency in the CONTROL file +set(VTK_WITH_MPI ON ) # IMPORTANT: if ON make sure `mpi` is listed as dependency in the CONTROL file +set(VTK_WITH_PYTHON OFF) # IMPORTANT: if ON make sure `python3` is listed as dependency in the CONTROL file +set(VTK_WITH_ALL_MODULES OFF) # IMPORTANT: if ON make sure `qt5`, `mpi`, `python3`, `ffmpeg`, `gdal`, `fontconfig`, + # `libmysql` and `atlmfc` are listed as dependency in the CONTROL file + +# ============================================================================= +# Apply patches to the source code vcpkg_apply_patches( SOURCE_PATH ${SOURCE_PATH} PATCHES @@ -28,33 +41,78 @@ vcpkg_apply_patches( ${CMAKE_CURRENT_LIST_DIR}/disable-workaround-findhdf5.patch ${CMAKE_CURRENT_LIST_DIR}/fix-find-libproj4.patch + ${CMAKE_CURRENT_LIST_DIR}/fix-find-libharu.patch + ${CMAKE_CURRENT_LIST_DIR}/fix-find-mysql.patch + ${CMAKE_CURRENT_LIST_DIR}/fix-find-odbc.patch ) -# Remove the FindGLEW.cmake that is distributed with VTK, since it does not -# detect the debug libraries correctly. -# The default file distributed with CMake should be superior by all means. +# Remove the FindGLEW.cmake and FindPythonLibs.cmake that are distributed with VTK, +# since they do not detect the debug libraries correctly. +# The default files distributed with CMake (>= 3.9) should be superior by all means. +# For GDAL, the one distributed with CMake does not detect the debug libraries correctly, +# so we provide an own one. file(REMOVE ${SOURCE_PATH}/CMake/FindGLEW.cmake) +file(REMOVE ${SOURCE_PATH}/CMake/FindPythonLibs.cmake) +file(COPY ${CMAKE_CURRENT_LIST_DIR}/FindGDAL.cmake DESTINATION ${SOURCE_PATH}/CMake) + +# ============================================================================= +# Collect CMake options for optional components +if(VTK_WITH_QT) + list(APPEND ADDITIONAL_OPTIONS + -DVTK_Group_Qt=ON + -DVTK_QT_VERSION=5 + -DVTK_BUILD_QT_DESIGNER_PLUGIN=OFF + ) +endif() + +if(VTK_WITH_MPI) + list(APPEND ADDITIONAL_OPTIONS + -DVTK_Group_MPI=ON + ) +endif() + +if(VTK_WITH_PYTHON) + list(APPEND ADDITIONAL_OPTIONS + -DVTK_WRAP_PYTHON=ON + -DVTK_PYTHON_VERSION=3 + ) +endif() + +if(VTK_WITH_ALL_MODULES) + list(APPEND ADDITIONAL_OPTIONS + -DVTK_BUILD_ALL_MODULES=ON + -DVTK_USE_TK=OFF # TCL/TK currently not included in vcpkg + # -DVTK_USE_SYSTEM_AUTOBAHN=ON + # -DVTK_USE_SYSTEM_SIX=ON + # -DVTK_USE_SYSTEM_MPI4PY=ON + # -DVTK_USE_SYSTEM_CONSTANTLY=ON + # -DVTK_USE_SYSTEM_INCREMENTAL=ON + # -DVTK_USE_SYSTEM_TWISTED=ON + # -DVTK_USE_SYSTEM_XDMF2=ON + # -DVTK_USE_SYSTEM_XDMF3=ON + # -DVTK_USE_SYSTEM_ZFP=ON + # -DVTK_USE_SYSTEM_ZOPE=ON + ) +endif() if(VCPKG_LIBRARY_LINKAGE STREQUAL dynamic) list(APPEND ADDITIONAL_OPTIONS "-DVTK_EXTERNAL_HDF5_IS_SHARED=ON") endif() +# ============================================================================= +# Configure & Install vcpkg_configure_cmake( SOURCE_PATH ${SOURCE_PATH} PREFER_NINJA OPTIONS + -DVTK_Group_Imaging=ON + -DVTK_Group_Views=ON -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF - -DVTK_Group_MPI=ON - -DVTK_Group_Qt=ON - -DVTK_QT_VERSION=5 - -DVTK_BUILD_QT_DESIGNER_PLUGIN=OFF - # -DVTK_WRAP_PYTHON=ON - # -DVTK_PYTHON_VERSION=3 -DVTK_USE_SYSTEM_EXPAT=ON -DVTK_USE_SYSTEM_FREETYPE=ON # -DVTK_USE_SYSTEM_GL2PS=ON - # -DVTK_USE_SYSTEM_LIBHARU=ON + -DVTK_USE_SYSTEM_LIBHARU=ON -DVTK_USE_SYSTEM_JPEG=ON -DVTK_USE_SYSTEM_GLEW=ON -DVTK_USE_SYSTEM_HDF5=ON @@ -85,9 +143,29 @@ vcpkg_configure_cmake( vcpkg_install_cmake() vcpkg_copy_pdbs() +# ============================================================================= +# Fixup target files vcpkg_fixup_cmake_targets() -# For VTK vcpkg_fixup_cmake_targets is not enough: +# For some reason the references to the XDMF libraries in the target files do not end up +# correctly, so we fix them here. +if(VTK_WITH_ALL_MODULES) + file(READ ${CURRENT_PACKAGES_DIR}/share/vtk/VTKTargets-release.cmake VTK_TARGETS_RELEASE_CONTENT) + string(REPLACE "lib/../XdmfCore.lib" "lib/XdmfCore.lib" VTK_TARGETS_RELEASE_CONTENT "${VTK_TARGETS_RELEASE_CONTENT}") + string(REPLACE "bin/../XdmfCore.dll" "bin/XdmfCore.dll" VTK_TARGETS_RELEASE_CONTENT "${VTK_TARGETS_RELEASE_CONTENT}") + string(REPLACE "lib/../vtkxdmf3.lib" "lib/vtkxdmf3.lib" VTK_TARGETS_RELEASE_CONTENT "${VTK_TARGETS_RELEASE_CONTENT}") + string(REPLACE "bin/../vtkxdmf3.dll" "bin/vtkxdmf3.dll" VTK_TARGETS_RELEASE_CONTENT "${VTK_TARGETS_RELEASE_CONTENT}") + file(WRITE ${CURRENT_PACKAGES_DIR}/share/vtk/VTKTargets-release.cmake "${VTK_TARGETS_RELEASE_CONTENT}") + + file(READ ${CURRENT_PACKAGES_DIR}/share/vtk/VTKTargets-debug.cmake VTK_TARGETS_DEBUG_CONTENT) + string(REPLACE "lib/../XdmfCore.lib" "lib/XdmfCore.lib" VTK_TARGETS_DEBUG_CONTENT "${VTK_TARGETS_DEBUG_CONTENT}") + string(REPLACE "bin/../XdmfCore.dll" "bin/XdmfCore.dll" VTK_TARGETS_DEBUG_CONTENT "${VTK_TARGETS_DEBUG_CONTENT}") + string(REPLACE "lib/../vtkxdmf3.lib" "lib/vtkxdmf3.lib" VTK_TARGETS_DEBUG_CONTENT "${VTK_TARGETS_DEBUG_CONTENT}") + string(REPLACE "bin/../vtkxdmf3.dll" "bin/vtkxdmf3.dll" VTK_TARGETS_DEBUG_CONTENT "${VTK_TARGETS_DEBUG_CONTENT}") + file(WRITE ${CURRENT_PACKAGES_DIR}/share/vtk/VTKTargets-debug.cmake "${VTK_TARGETS_DEBUG_CONTENT}") +endif() + +# For VTK `vcpkg_fixup_cmake_targets` is not enough: # Files for system third party dependencies are written to modules that # are located in the paths `share/vtk/Modules` and `debug/share/vtk/Modules`. # In the release folder, only the release libraries are referenced (e.g. "C:/vcpkg/installed/x64-windows/lib/zlib.lib"). @@ -158,8 +236,22 @@ set(SYSTEM_THIRD_PARTY_MODULES vtkpng vtktiff vtkzlib + # vtkgl2ps + vtklibharu ) +if(VTK_WITH_PYTHON OR VTK_WITH_ALL_MODULES) + list(APPEND SYSTEM_THIRD_PARTY_MODULES + vtkPython + ) +endif() + +if(VTK_WITH_ALL_MODULES) + list(APPEND SYSTEM_THIRD_PARTY_MODULES + AutobahnPython + ) +endif() + foreach(MODULE IN LISTS SYSTEM_THIRD_PARTY_MODULES) _vtk_combine_third_party_libraries("${MODULE}") endforeach() @@ -172,16 +264,45 @@ file(READ "${CURRENT_PACKAGES_DIR}/share/vtk/VTKTargets.cmake" VTK_TARGETS_CONTE string(REGEX REPLACE "${CURRENT_INSTALLED_DIR}/lib/[^\\.]*\\.lib" "" VTK_TARGETS_CONTENT "${VTK_TARGETS_CONTENT}") file(WRITE "${CURRENT_PACKAGES_DIR}/share/vtk/VTKTargets.cmake" "${VTK_TARGETS_CONTENT}") -# Move executable to tools directory +# ============================================================================= +# Move executable to tools directory and clean-up other directories file(MAKE_DIRECTORY ${CURRENT_PACKAGES_DIR}/tools/vtk) -file(RENAME ${CURRENT_PACKAGES_DIR}/bin/vtkEncodeString-8.0.exe ${CURRENT_PACKAGES_DIR}/tools/vtk/vtkEncodeString-8.0.exe) -file(RENAME ${CURRENT_PACKAGES_DIR}/bin/vtkHashSource-8.0.exe ${CURRENT_PACKAGES_DIR}/tools/vtk/vtkHashSource-8.0.exe) -if(VCPKG_LIBRARY_LINKAGE STREQUAL dynamic) - file(REMOVE ${CURRENT_PACKAGES_DIR}/debug/bin/vtkEncodeString-8.0.exe) - file(REMOVE ${CURRENT_PACKAGES_DIR}/debug/bin/vtkHashSource-8.0.exe) -else() - # On static builds there should be no bin directory at all +function(_vtk_move_tool TOOL_NAME) + if(EXISTS ${CURRENT_PACKAGES_DIR}/bin/${TOOL_NAME}.exe) + file(RENAME ${CURRENT_PACKAGES_DIR}/bin/${TOOL_NAME}.exe ${CURRENT_PACKAGES_DIR}/tools/vtk/${TOOL_NAME}.exe) + endif() + + file(REMOVE ${CURRENT_PACKAGES_DIR}/debug/bin/${TOOL_NAME}.exe) +endfunction() + +set(VTK_TOOLS + vtkEncodeString-${VTK_SHORT_VERSION} + vtkHashSource-${VTK_SHORT_VERSION} + vtkWrapTclInit-${VTK_SHORT_VERSION} + vtkWrapTcl-${VTK_SHORT_VERSION} + vtkWrapPythonInit-${VTK_SHORT_VERSION} + vtkWrapPython-${VTK_SHORT_VERSION} + vtkWrapJava-${VTK_SHORT_VERSION} + vtkWrapHierarchy-${VTK_SHORT_VERSION} + vtkParseJava-${VTK_SHORT_VERSION} + vtkParseOGLExt-${VTK_SHORT_VERSION} + vtkpython + pvtkpython +) + +foreach(TOOL_NAME IN LISTS VTK_TOOLS) + _vtk_move_tool("${TOOL_NAME}") +endforeach() + +# ============================================================================= +# Remove other files and directories that are not valid for vcpkg +if(VTK_WITH_ALL_MODULES) + file(REMOVE ${CURRENT_PACKAGES_DIR}/XdmfConfig.cmake) + file(REMOVE ${CURRENT_PACKAGES_DIR}/debug/XdmfConfig.cmake) +endif() + +if(VCPKG_LIBRARY_LINKAGE STREQUAL static) file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/bin) file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/bin) endif() @@ -189,6 +310,7 @@ endif() file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include) file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/share) +# ============================================================================= # Handle copyright file(COPY ${SOURCE_PATH}/Copyright.txt DESTINATION ${CURRENT_PACKAGES_DIR}/share/vtk) file(RENAME ${CURRENT_PACKAGES_DIR}/share/vtk/Copyright.txt ${CURRENT_PACKAGES_DIR}/share/vtk/copyright) -- cgit v1.2.3 From 437eb29cda5aaca31c03adb10a51314a35b94105 Mon Sep 17 00:00:00 2001 From: Tsukasa Sugiura Date: Sun, 9 Jul 2017 00:22:48 +0900 Subject: Add Kinect SDK v2.x port Add Kinect for Windows SDK v2.x port. --- ports/kinectsdk2/CONTROL | 3 +++ ports/kinectsdk2/portfile.cmake | 47 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 ports/kinectsdk2/CONTROL create mode 100644 ports/kinectsdk2/portfile.cmake diff --git a/ports/kinectsdk2/CONTROL b/ports/kinectsdk2/CONTROL new file mode 100644 index 000000000..85ccd7f0b --- /dev/null +++ b/ports/kinectsdk2/CONTROL @@ -0,0 +1,3 @@ +Source: kinectsdk2 +Version: 2.0 +Description: Kinect for Windows SDK for Kinect v2 sensor. diff --git a/ports/kinectsdk2/portfile.cmake b/ports/kinectsdk2/portfile.cmake new file mode 100644 index 000000000..5795825dd --- /dev/null +++ b/ports/kinectsdk2/portfile.cmake @@ -0,0 +1,47 @@ +# Common Ambient Variables: +# CURRENT_BUILDTREES_DIR = ${VCPKG_ROOT_DIR}\buildtrees\${PORT} +# CURRENT_PACKAGES_DIR = ${VCPKG_ROOT_DIR}\packages\${PORT}_${TARGET_TRIPLET} +# CURRENT_PORT_DIR = ${VCPKG_ROOT_DIR}\ports\${PORT} +# PORT = current port name (zlib, etc) +# TARGET_TRIPLET = current triplet (x86-windows, x64-windows-static, etc) +# VCPKG_CRT_LINKAGE = C runtime linkage type (static, dynamic) +# VCPKG_LIBRARY_LINKAGE = target library linkage type (static, dynamic) +# VCPKG_ROOT_DIR = +# VCPKG_TARGET_ARCHITECTURE = target architecture (x64, x86, arm) +# + +include(vcpkg_common_functions) + +if(VCPKG_TARGET_ARCHITECTURE STREQUAL "arm") + message(FATAL_ERROR "This port does not currently support architecture: ${VCPKG_TARGET_ARCHITECTURE}") +endif() + +get_filename_component(KINECTSDK20_DIR "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Kinect\\v2.0;SDKInstallPath]" ABSOLUTE CACHE) +if(NOT EXISTS "${KINECTSDK20_DIR}") + message(FATAL_ERROR "Error: Could not find Kinect for Windows SDK v2.x. It can be downloaded from https://www.microsoft.com/en-us/download/details.aspx?id=44561.") +endif() + +file( + INSTALL + "${KINECTSDK20_DIR}/inc/Kinect.h" + DESTINATION + ${CURRENT_PACKAGES_DIR}/include +) + +file( + INSTALL + "${KINECTSDK20_DIR}/Lib/${VCPKG_TARGET_ARCHITECTURE}/Kinect20.lib" + DESTINATION + ${CURRENT_PACKAGES_DIR}/lib +) + +file( + INSTALL + "${KINECTSDK20_DIR}/Lib/${VCPKG_TARGET_ARCHITECTURE}/Kinect20.lib" + DESTINATION + ${CURRENT_PACKAGES_DIR}/debug/lib +) + +# Handle copyright +file(COPY "${KINECTSDK20_DIR}/SDKEula.rtf" DESTINATION ${CURRENT_PACKAGES_DIR}/share/kinectsdk2) +file(RENAME ${CURRENT_PACKAGES_DIR}/share/kinectsdk2/SDKEula.rtf ${CURRENT_PACKAGES_DIR}/share/kinectsdk2/copyright) -- cgit v1.2.3 From 3d90214259726d068af52df5dc8327d7d2140a53 Mon Sep 17 00:00:00 2001 From: Tsukasa Sugiura Date: Sat, 23 Sep 2017 04:41:44 +0900 Subject: Enable pcap option Enable pcap option. You can retrieve data from PCAP file using pcl::HDLGrabber/pcl::VLPGrabber. --- ports/pcl/CONTROL | 4 ++-- ports/pcl/portfile.cmake | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ports/pcl/CONTROL b/ports/pcl/CONTROL index e9547c8cb..d8c38a363 100644 --- a/ports/pcl/CONTROL +++ b/ports/pcl/CONTROL @@ -1,4 +1,4 @@ Source: pcl -Version: 1.8.1-1 -Build-Depends: boost, eigen3, flann, qhull, vtk, openni2, qt5 +Version: 1.8.1-2 +Build-Depends: boost, eigen3, flann, qhull, vtk, openni2, qt5, winpcap Description: Point Cloud Library (PCL) is open source library for 2D/3D image and point cloud processing. diff --git a/ports/pcl/portfile.cmake b/ports/pcl/portfile.cmake index 8010d9c70..cd5c5bedc 100644 --- a/ports/pcl/portfile.cmake +++ b/ports/pcl/portfile.cmake @@ -50,7 +50,7 @@ vcpkg_configure_cmake( -DWITH_CUDA=OFF -DWITH_LIBUSB=OFF -DWITH_OPENNI2=ON - -DWITH_PCAP=OFF + -DWITH_PCAP=ON -DWITH_PNG=OFF -DWITH_QHULL=ON -DWITH_QT=ON -- cgit v1.2.3 From 06798b6528b777ba2e2a9af59774309db5cf5e52 Mon Sep 17 00:00:00 2001 From: glachancecmaisonneuve Date: Mon, 25 Sep 2017 13:05:32 -0400 Subject: Fix for BUILD_ARGS being always added in non ninja build --- scripts/cmake/vcpkg_build_cmake.cmake | 30 +++++++++++++++++++++++++++++- scripts/cmake/vcpkg_install_cmake.cmake | 6 ++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/scripts/cmake/vcpkg_build_cmake.cmake b/scripts/cmake/vcpkg_build_cmake.cmake index 18e2a8b00..546071a36 100644 --- a/scripts/cmake/vcpkg_build_cmake.cmake +++ b/scripts/cmake/vcpkg_build_cmake.cmake @@ -1,3 +1,29 @@ +## # vcpkg_build_cmake +## +## Build a cmake project. +## +## ## Usage: +## ```cmake +## vcpkg_build_cmake([MSVC_64_TOOLSET] [DISABLE_PARALLEL]) +## ``` +## +## ## Parameters: +## ### MSVC_64_TOOLSET +## This adds the `/p:PreferredToolArchitecture=x64` switch to the underlying buildsystem parameters. Some large projects can run out of memory when linking if they use the 32-bit hosted tools. +## +## ### DISABLE_PARALLEL +## The /m parameter will not be added to the underlying buildsystem parameters +## +## ## Notes: +## This command should be preceeded by a call to [`vcpkg_configure_cmake()`](vcpkg_configure_cmake.md). +## Use [`vcpkg_install_cmake()`](vcpkg_configure_cmake.md) function if your CMake script supports the "install" target +## +## ## Examples: +## +## * [zlib](https://github.com/Microsoft/vcpkg/blob/master/ports/zlib/portfile.cmake) +## * [cpprestsdk](https://github.com/Microsoft/vcpkg/blob/master/ports/cpprestsdk/portfile.cmake) +## * [poco](https://github.com/Microsoft/vcpkg/blob/master/ports/poco/portfile.cmake) +## * [opencv](https://github.com/Microsoft/vcpkg/blob/master/ports/opencv/portfile.cmake) function(vcpkg_build_cmake) cmake_parse_arguments(_bc "MSVC_64_TOOLSET;DISABLE_PARALLEL" "" "" ${ARGN}) @@ -19,7 +45,9 @@ function(vcpkg_build_cmake) if(EXISTS ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel/build.ninja) set(BUILD_ARGS -v) # verbose output - else() + endif() + + if(_bc_MSVC_64_TOOLSET) set(BUILD_ARGS ${MSVC_EXTRA_ARGS}) endif() diff --git a/scripts/cmake/vcpkg_install_cmake.cmake b/scripts/cmake/vcpkg_install_cmake.cmake index f778007ef..34ac15fe6 100644 --- a/scripts/cmake/vcpkg_install_cmake.cmake +++ b/scripts/cmake/vcpkg_install_cmake.cmake @@ -9,7 +9,7 @@ ## ## ## Parameters: ## ### MSVC_64_TOOLSET -## This adds the `/p:PreferredToolArchitecture=x64` switch if the underlying buildsystem is MSBuild. Some large projects can run out of memory when linking if they use the 32-bit hosted tools. +## This adds the `/p:PreferredToolArchitecture=x64` switch to the underlying buildsystem parameters. Some large projects can run out of memory when linking if they use the 32-bit hosted tools. ## ## ## Notes: ## This command should be preceeded by a call to [`vcpkg_configure_cmake()`](vcpkg_configure_cmake.md). @@ -41,7 +41,9 @@ function(vcpkg_install_cmake) if(EXISTS ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel/build.ninja) set(BUILD_ARGS -v) # verbose output - else() + endif() + + if(_bc_MSVC_64_TOOLSET) set(BUILD_ARGS ${MSVC_EXTRA_ARGS}) endif() -- cgit v1.2.3 From 6df1629d4dccb5a580e7d3de407cc9d932bfd5e7 Mon Sep 17 00:00:00 2001 From: Mateusz Loskot Date: Tue, 26 Sep 2017 19:13:28 +0200 Subject: [gdal] Update port to latest GDAL 2.2.2 * Bump GDAL version wherever necessary * Update download package and checksum. * Remove 0001-Add-support-for-MSVC1900-backported-from-GDAL2.patch no longer necessary. * Recalculate 000N prefix in patche filenames after the removal. * Update 0002-Ensures-inclusion-of-PDB-in-release-dll-if-so-reques.patch * Patch pushed upstream https://trac.osgeo.org/gdal/ticket/7055 and should no longer be necessary in GDAL 2.2.3 or later * Update 0003-Fix-openjpeg-include.patch --- ...upport-for-MSVC1900-backported-from-GDAL2.patch | 70 ---------------------- ...e-CXX_CRT_FLAGS-to-allow-for-selection-of.patch | 37 ++++++++++++ ...e-CXX_CRT_FLAGS-to-allow-for-selection-of.patch | 50 ---------------- ...lusion-of-PDB-in-release-dll-if-so-reques.patch | 14 +++++ ...lusion-of-PDB-in-release-dll-if-so-reques.patch | 26 -------- ports/gdal/0003-Fix-openjpeg-include.patch | 20 +++++++ ports/gdal/0004-Fix-openjpeg-include.patch | 19 ------ ports/gdal/CONTROL | 2 +- ports/gdal/portfile.cmake | 23 ++++--- 9 files changed, 83 insertions(+), 178 deletions(-) delete mode 100644 ports/gdal/0001-Add-support-for-MSVC1900-backported-from-GDAL2.patch create mode 100644 ports/gdal/0001-Add-variable-CXX_CRT_FLAGS-to-allow-for-selection-of.patch delete mode 100644 ports/gdal/0002-Add-variable-CXX_CRT_FLAGS-to-allow-for-selection-of.patch create mode 100644 ports/gdal/0002-Ensures-inclusion-of-PDB-in-release-dll-if-so-reques.patch delete mode 100644 ports/gdal/0003-Ensures-inclusion-of-PDB-in-release-dll-if-so-reques.patch create mode 100644 ports/gdal/0003-Fix-openjpeg-include.patch delete mode 100644 ports/gdal/0004-Fix-openjpeg-include.patch diff --git a/ports/gdal/0001-Add-support-for-MSVC1900-backported-from-GDAL2.patch b/ports/gdal/0001-Add-support-for-MSVC1900-backported-from-GDAL2.patch deleted file mode 100644 index e29cc5b8e..000000000 --- a/ports/gdal/0001-Add-support-for-MSVC1900-backported-from-GDAL2.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 823171a129401d226ac4821fb997ce585045170c Mon Sep 17 00:00:00 2001 -From: Manuel Massing -Date: Wed, 23 Nov 2016 23:50:12 +0100 -Subject: [PATCH] Add support for MSVC1900 (backported from GDAL2) - ---- - nmake.opt | 6 ++++++ - port/cpl_config.h.vc | 8 +++++--- - 2 files changed, 11 insertions(+), 3 deletions(-) - -diff --git a/nmake.opt b/nmake.opt -index 8900135..4d1c4fa 100644 ---- a/nmake.opt -+++ b/nmake.opt -@@ -31,6 +31,7 @@ - # Check version of Visual C++ compiler: - # nmake -f makefile.vc MSVC_VER=xxxx - # where xxxx is one of following: -+# 1900 = 14.0(2015) - # 1800 = 12.0(2013) - # 1700 = 11.0(2012) - # 1600 = 10.0(2010) -@@ -627,8 +628,13 @@ GDALLIB = $(GDAL_ROOT)/gdal.lib - !ENDIF - - !IFDEF ODBC_SUPPORTED -+!IF $(MSVC_VER) >= 1900 -+# legacy_stdio_definitions.lib : https://connect.microsoft.com/VisualStudio/feedback/details/1134693/vs-2015-ctp-5-c-vsnwprintf-s-and-other-functions-are-not-exported-in-appcrt140-dll-breaking-linkage-of-static-libraries -+ODBCLIB = legacy_stdio_definitions.lib odbc32.lib odbccp32.lib user32.lib -+!ELSE - ODBCLIB = odbc32.lib odbccp32.lib user32.lib - !ENDIF -+!ENDIF - - !IF DEFINED(MRSID_DIR) || DEFINED(MRSID_RASTER_DIR) || DEFINED(MRSID_LIDAR_DIR) - !IF "$(MRSID_PLUGIN)" != "YES" -diff --git a/port/cpl_config.h.vc b/port/cpl_config.h.vc -index bfff8f6..fe7b82a 100644 ---- a/port/cpl_config.h.vc -+++ b/port/cpl_config.h.vc -@@ -1,5 +1,5 @@ - --/* We define this here in general so that a VC++ build will publically -+/* We define this here in general so that a VC++ build will publicly - declare STDCALL interfaces even if an application is built against it - using MinGW */ - -@@ -17,7 +17,9 @@ - #if defined(_MSC_VER) && (_MSC_VER < 1500) - # define vsnprintf _vsnprintf - #endif --#define snprintf _snprintf -+#if defined(_MSC_VER) && (_MSC_VER < 1900) -+# define snprintf _snprintf -+#endif - - #define HAVE_GETCWD 1 - /* gmt_notunix.h from GMT project also redefines getcwd. See #3138 */ -@@ -86,7 +88,7 @@ - /* Set the native cpu bit order */ - #define HOST_FILLORDER FILLORDER_LSB2MSB - --/* Define as 0 or 1 according to the floating point format suported by the -+/* Define as 0 or 1 according to the floating point format supported by the - machine */ - #define HAVE_IEEEFP 1 - --- -2.10.1.windows.1 - diff --git a/ports/gdal/0001-Add-variable-CXX_CRT_FLAGS-to-allow-for-selection-of.patch b/ports/gdal/0001-Add-variable-CXX_CRT_FLAGS-to-allow-for-selection-of.patch new file mode 100644 index 000000000..7817c4a38 --- /dev/null +++ b/ports/gdal/0001-Add-variable-CXX_CRT_FLAGS-to-allow-for-selection-of.patch @@ -0,0 +1,37 @@ +diff --git a/nmake.opt b/nmake.opt +index bd5719c2d1..f6101ccd59 100644 +--- a/nmake.opt ++++ b/nmake.opt +@@ -127,18 +127,28 @@ CXX_PDB_FLAGS=/Zi /Fd$(GDAL_ROOT)\gdal$(VERSION).pdb + CXX_PDB_FLAGS= + !ENDIF + ++# Flags to choose CRT variant to link against (e.g. static: /MT, /MTd, dynamic: /MD, /MDd) ++# Ensure MRSID_CONFIG in mrsid/nmake.opt is set appropriately as well ++!IFNDEF CXX_CRT_FLAGS ++!IFNDEF DEBUG ++CXX_CRT_FLAGS=/MD ++!ELSE ++CXX_CRT_FLAGS=/MDd ++!ENDIF ++!ENDIF ++ + !IFNDEF OPTFLAGS + !IF $(MSVC_VER) >= 1400 + !IFNDEF DEBUG +-OPTFLAGS= $(CXX_ANALYZE_FLAGS) $(CXX_PDB_FLAGS) /nologo /MP /MD /EHsc /Ox /FC /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DNDEBUG ++OPTFLAGS= $(CXX_ANALYZE_FLAGS) $(CXX_PDB_FLAGS) /nologo $(CXX_CRT_FLAGS) /EHsc /Ox /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DNDEBUG + !ELSE +-OPTFLAGS= $(CXX_ANALYZE_FLAGS) $(CXX_PDB_FLAGS) /nologo /MP /MD /EHsc /FC /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DDEBUG ++OPTFLAGS= $(CXX_ANALYZE_FLAGS) $(CXX_PDB_FLAGS) /nologo $(CXX_CRT_FLAGS) /EHsc /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DDEBUG + !ENDIF + !ELSE + !IFNDEF DEBUG +-OPTFLAGS= $(CXX_PDB_FLAGS) /nologo /MD /EHsc /GR /Ox /FC /DNDEBUG ++OPTFLAGS= $(CXX_PDB_FLAGS) /nologo $(CXX_CRT_FLAGS) /EHsc /GR /Ox /DNDEBUG + !ELSE +-OPTFLAGS= $(CXX_PDB_FLAGS) /nologo /MD /EHsc /GR /FC /DDEBUG ++OPTFLAGS= $(CXX_PDB_FLAGS) /nologo $(CXX_CRT_FLAGS) /EHsc /GR /DDEBUG + !ENDIF + !ENDIF #MSVC_VER + !ENDIF # OPTFLAGS diff --git a/ports/gdal/0002-Add-variable-CXX_CRT_FLAGS-to-allow-for-selection-of.patch b/ports/gdal/0002-Add-variable-CXX_CRT_FLAGS-to-allow-for-selection-of.patch deleted file mode 100644 index 0ffcac5fb..000000000 --- a/ports/gdal/0002-Add-variable-CXX_CRT_FLAGS-to-allow-for-selection-of.patch +++ /dev/null @@ -1,50 +0,0 @@ -From b25c3dc49ca1bcf9a789cf64c9fa8694e35127f0 Mon Sep 17 00:00:00 2001 -From: Manuel Massing -Date: Sun, 27 Nov 2016 09:57:04 +0100 -Subject: [PATCH 2/2] Add variable CXX_CRT_FLAGS to allow for selection of C - runtime linkage in nmake build. - ---- - nmake.opt | 18 ++++++++++++++---- - 1 file changed, 14 insertions(+), 4 deletions(-) - -diff --git a/nmake.opt b/nmake.opt -index 4d1c4fa..47c2df8 100644 ---- a/nmake.opt -+++ b/nmake.opt -@@ -125,18 +125,28 @@ CXX_PDB_FLAGS=/Zi /Fd$(GDAL_ROOT)\gdal$(VERSION).pdb - CXX_PDB_FLAGS= - !ENDIF - -+# Flags to choose CRT variant to link against (e.g. static: /MT, /MTd, dynamic: /MD, /MDd) -+# Ensure MRSID_CONFIG in mrsid/nmake.opt is set appropriately as well -+!IFNDEF CXX_CRT_FLAGS -+!IFNDEF DEBUG -+CXX_CRT_FLAGS=/MD -+!ELSE -+CXX_CRT_FLAGS=/MDd -+!ENDIF -+!ENDIF -+ - !IFNDEF OPTFLAGS - !IF $(MSVC_VER) >= 1400 - !IFNDEF DEBUG --OPTFLAGS= $(CXX_ANALYZE_FLAGS) $(CXX_PDB_FLAGS) /nologo /MD /EHsc /Ox /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DNDEBUG -+OPTFLAGS= $(CXX_ANALYZE_FLAGS) $(CXX_PDB_FLAGS) /nologo $(CXX_CRT_FLAGS) /EHsc /Ox /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DNDEBUG - !ELSE --OPTFLAGS= $(CXX_ANALYZE_FLAGS) $(CXX_PDB_FLAGS) /nologo /MD /EHsc /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DDEBUG -+OPTFLAGS= $(CXX_ANALYZE_FLAGS) $(CXX_PDB_FLAGS) /nologo $(CXX_CRT_FLAGS) /EHsc /D_CRT_SECURE_NO_DEPRECATE /D_CRT_NONSTDC_NO_DEPRECATE /DDEBUG - !ENDIF - !ELSE - !IFNDEF DEBUG --OPTFLAGS= $(CXX_PDB_FLAGS) /nologo /MD /EHsc /GR /Ox /DNDEBUG -+OPTFLAGS= $(CXX_PDB_FLAGS) /nologo $(CXX_CRT_FLAGS) /EHsc /GR /Ox /DNDEBUG - !ELSE --OPTFLAGS= $(CXX_PDB_FLAGS) /nologo /MD /EHsc /GR /DDEBUG -+OPTFLAGS= $(CXX_PDB_FLAGS) /nologo $(CXX_CRT_FLAGS) /EHsc /GR /DDEBUG - !ENDIF - !ENDIF #MSVC_VER - !ENDIF # OPTFLAGS --- -2.10.1.windows.1 - diff --git a/ports/gdal/0002-Ensures-inclusion-of-PDB-in-release-dll-if-so-reques.patch b/ports/gdal/0002-Ensures-inclusion-of-PDB-in-release-dll-if-so-reques.patch new file mode 100644 index 000000000..57030b99b --- /dev/null +++ b/ports/gdal/0002-Ensures-inclusion-of-PDB-in-release-dll-if-so-reques.patch @@ -0,0 +1,14 @@ +diff --git a/nmake.opt b/nmake.opt +index bd5719c2d1..c0ca442cbe 100644 +--- a/nmake.opt ++++ b/nmake.opt +@@ -195,6 +205,9 @@ SOFTWARNFLAGS= /wd4244 /wd4702 /wd4701 /wd4013 /wd4706 /wd4057 /wd4210 /wd4305 + # Linker debug options + !IFDEF DEBUG + LDEBUG= /debug ++!ELSEIFDEF WITH_PDB ++# Ensures that PDB is included in release DLL if so requested ++LDEBUG= /debug /opt:ref /opt:icf + !ENDIF + + # Uncomment the following if you are building for 64-bit windows diff --git a/ports/gdal/0003-Ensures-inclusion-of-PDB-in-release-dll-if-so-reques.patch b/ports/gdal/0003-Ensures-inclusion-of-PDB-in-release-dll-if-so-reques.patch deleted file mode 100644 index 1065a2982..000000000 --- a/ports/gdal/0003-Ensures-inclusion-of-PDB-in-release-dll-if-so-reques.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 9da0cb6eed442ebf3eea232cd85e26c155c963ef Mon Sep 17 00:00:00 2001 -From: Manuel Massing -Date: Tue, 29 Nov 2016 12:43:58 +0100 -Subject: [PATCH 3/4] - Ensures inclusion of PDB in release dll if so requested - ---- - gdal/nmake.opt | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/nmake.opt b/nmake.opt -index 47c2df8..4844d22 100644 ---- a/nmake.opt -+++ b/nmake.opt -@@ -174,6 +174,9 @@ SOFTWARNFLAGS= /wd4244 /wd4702 /wd4701 /wd4013 /wd4706 /wd4057 /wd4210 /wd4305 - # Linker debug options - !IFDEF DEBUG - LDEBUG= /debug -+!ELSEIFDEF WITH_PDB -+# Ensures that PDB is included in release DLL if so requested -+LDEBUG= /debug /opt:ref /opt:icf - !ENDIF - - # Uncomment the following if you are building for 64-bit windows --- -2.10.1.windows.1 - diff --git a/ports/gdal/0003-Fix-openjpeg-include.patch b/ports/gdal/0003-Fix-openjpeg-include.patch new file mode 100644 index 000000000..4ea72690c --- /dev/null +++ b/ports/gdal/0003-Fix-openjpeg-include.patch @@ -0,0 +1,20 @@ +diff --git a/frmts/openjpeg/openjpegdataset.cpp b/frmts/openjpeg/openjpegdataset.cpp +index 5978882bc9..72cc7b9559 100644 +--- a/frmts/openjpeg/openjpegdataset.cpp ++++ b/frmts/openjpeg/openjpegdataset.cpp +@@ -34,14 +34,8 @@ + #pragma clang diagnostic ignored "-Wdocumentation" + #endif + +-#if defined(OPENJPEG_VERSION) && OPENJPEG_VERSION >= 20200 +-#include +-#elif defined(OPENJPEG_VERSION) && OPENJPEG_VERSION >= 20100 +-#include +-#else + #include /* openjpeg.h needs FILE* */ +-#include +-#endif ++#include + + #ifdef __clang__ + #pragma clang diagnostic pop diff --git a/ports/gdal/0004-Fix-openjpeg-include.patch b/ports/gdal/0004-Fix-openjpeg-include.patch deleted file mode 100644 index 2865455d8..000000000 --- a/ports/gdal/0004-Fix-openjpeg-include.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff --git a/frmts/openjpeg/openjpegdataset.cpp b/frmts/openjpeg/openjpegdataset.cpp -index 1fd4f4f..417f7a8 100644 ---- a/frmts/openjpeg/openjpegdataset.cpp -+++ b/frmts/openjpeg/openjpegdataset.cpp -@@ -29,12 +29,8 @@ - - /* This file is to be used with openjpeg 2.0 */ - --#if defined(OPENJPEG_VERSION) && OPENJPEG_VERSION >= 20100 --#include --#else --#include /* openjpeg.h needs FILE* */ --#include --#endif -+#include -+#include - #include - - #include "gdaljp2abstractdataset.h" diff --git a/ports/gdal/CONTROL b/ports/gdal/CONTROL index 868a5e929..18aa7f631 100644 --- a/ports/gdal/CONTROL +++ b/ports/gdal/CONTROL @@ -1,4 +1,4 @@ Source: gdal -Version: 1.11.3-5 +Version: 2.2.2 Description: The Geographic Data Abstraction Library for reading and writing geospatial raster and vector data. Build-Depends: proj, libpng, geos, sqlite3, curl, expat, libpq, libmysql, openjpeg, libwebp, libxml2, liblzma diff --git a/ports/gdal/portfile.cmake b/ports/gdal/portfile.cmake index 214ec2024..9bfb92362 100644 --- a/ports/gdal/portfile.cmake +++ b/ports/gdal/portfile.cmake @@ -5,25 +5,24 @@ endif() include(vcpkg_common_functions) vcpkg_download_distfile(ARCHIVE - URLS "http://download.osgeo.org/gdal/1.11.3/gdal1113.zip" - FILENAME "gdal1113.zip" - SHA512 42feb98a54019d3b6ac54f598f299a57e117db500c662d39faa9d5f5090f03c1b8d7680242e1abd8035738edc4fc3197ae118a0ce50733691a76a5cf377bcd46 -) + URLS "http://download.osgeo.org/gdal/2.2.2/gdal222.zip" + FILENAME "gdal222.zip" + SHA512 b886238a7915c97f4acec5920dabe959d1ab15a8be0bc31ba0d05ad69d1d7d96f864faf0aa82921fa1a1b40b733744202b86f2f45ff63d6518cd18a53f3544a8 + ) # Extract source into archictecture specific directory, because GDALs' nmake based build currently does not # support out of source builds. -set(SOURCE_PATH_DEBUG ${CURRENT_BUILDTREES_DIR}/src-${TARGET_TRIPLET}-debug/gdal-1.11.3) -set(SOURCE_PATH_RELEASE ${CURRENT_BUILDTREES_DIR}/src-${TARGET_TRIPLET}-release/gdal-1.11.3) +set(SOURCE_PATH_DEBUG ${CURRENT_BUILDTREES_DIR}/src-${TARGET_TRIPLET}-debug/gdal-2.2.2) +set(SOURCE_PATH_RELEASE ${CURRENT_BUILDTREES_DIR}/src-${TARGET_TRIPLET}-release/gdal-2.2.2) foreach(BUILD_TYPE debug release) vcpkg_extract_source_archive(${ARCHIVE} ${CURRENT_BUILDTREES_DIR}/src-${TARGET_TRIPLET}-${BUILD_TYPE}) vcpkg_apply_patches( - SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src-${TARGET_TRIPLET}-${BUILD_TYPE}/gdal-1.11.3 + SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src-${TARGET_TRIPLET}-${BUILD_TYPE}/gdal-2.2.2 PATCHES - ${CMAKE_CURRENT_LIST_DIR}/0001-Add-support-for-MSVC1900-backported-from-GDAL2.patch - ${CMAKE_CURRENT_LIST_DIR}/0002-Add-variable-CXX_CRT_FLAGS-to-allow-for-selection-of.patch - ${CMAKE_CURRENT_LIST_DIR}/0003-Ensures-inclusion-of-PDB-in-release-dll-if-so-reques.patch - ${CMAKE_CURRENT_LIST_DIR}/0004-Fix-openjpeg-include.patch + ${CMAKE_CURRENT_LIST_DIR}/0001-Add-variable-CXX_CRT_FLAGS-to-allow-for-selection-of.patch + ${CMAKE_CURRENT_LIST_DIR}/0002-Ensures-inclusion-of-PDB-in-release-dll-if-so-reques.patch + ${CMAKE_CURRENT_LIST_DIR}/0003-Fix-openjpeg-include.patch ) endforeach() @@ -211,7 +210,7 @@ if (VCPKG_LIBRARY_LINKAGE STREQUAL static) else() file(GLOB EXE_FILES ${CURRENT_PACKAGES_DIR}/bin/*.exe) file(REMOVE ${EXE_FILES} ${CURRENT_PACKAGES_DIR}/lib/gdal.lib) - file(COPY ${SOURCE_PATH_DEBUG}/gdal111.dll DESTINATION ${CURRENT_PACKAGES_DIR}/debug/bin) + file(COPY ${SOURCE_PATH_DEBUG}/gdal202.dll DESTINATION ${CURRENT_PACKAGES_DIR}/debug/bin) file(COPY ${SOURCE_PATH_DEBUG}/gdal_i.lib DESTINATION ${CURRENT_PACKAGES_DIR}/debug/lib) file(RENAME ${CURRENT_PACKAGES_DIR}/lib/gdal_i.lib ${CURRENT_PACKAGES_DIR}/lib/gdal.lib) file(RENAME ${CURRENT_PACKAGES_DIR}/debug/lib/gdal_i.lib ${CURRENT_PACKAGES_DIR}/debug/lib/gdald.lib) -- cgit v1.2.3 From ba0cc3f1d7edb7e2fee271761b2f37d0c740604f Mon Sep 17 00:00:00 2001 From: Konstantin Podsvirov Date: Mon, 28 Aug 2017 13:54:19 +0300 Subject: WIP: Export IFW Add export to binary crossplatform repository/installer with GUI based on QtIFW: http://doc.qt.io/qtinstallerframework/ifw-overview.html For correct operation of these changes, you must use the corrected QtIFW: https://codereview.qt-project.org/#/c/203958 --- toolsrc/include/vcpkg_Commands_Export_IFW.h | 13 ++ toolsrc/src/commands_export.cpp | 57 ++++- toolsrc/src/commands_export_ifw.cpp | 319 ++++++++++++++++++++++++++++ toolsrc/vcpkglib/vcpkglib.vcxproj | 2 + toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 6 + 5 files changed, 390 insertions(+), 7 deletions(-) create mode 100644 toolsrc/include/vcpkg_Commands_Export_IFW.h create mode 100644 toolsrc/src/commands_export_ifw.cpp diff --git a/toolsrc/include/vcpkg_Commands_Export_IFW.h b/toolsrc/include/vcpkg_Commands_Export_IFW.h new file mode 100644 index 000000000..b25e943eb --- /dev/null +++ b/toolsrc/include/vcpkg_Commands_Export_IFW.h @@ -0,0 +1,13 @@ +#pragma once + +#include "vcpkg_Files.h" +#include "vcpkg_Dependencies.h" + +namespace vcpkg::Commands::Export::IFW +{ + fs::path export_real_package(const fs::path &raw_exported_dir_path, const Dependencies::ExportPlanAction& action, Files::Filesystem& fs); + void export_unique_packages(const fs::path &raw_exported_dir_path, std::map unique_packages, Files::Filesystem& fs); + void export_unique_triplets(const fs::path &raw_exported_dir_path, std::set unique_triplets, Files::Filesystem& fs); + void export_integration(const fs::path &raw_exported_dir_path, Files::Filesystem& fs); + void export_config(const fs::path &raw_exported_dir_path, const std::string ifw_repository_url, Files::Filesystem& fs); +} diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index b416a6f3c..139f19026 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -2,6 +2,7 @@ #include "Paragraphs.h" #include "vcpkg_Commands.h" +#include "vcpkg_Commands_Export_IFW.h" #include "vcpkg_Dependencies.h" #include "vcpkg_Input.h" #include "vcpkg_System.h" @@ -215,10 +216,12 @@ namespace vcpkg::Commands::Export static const std::string OPTION_DRY_RUN = "--dry-run"; static const std::string OPTION_RAW = "--raw"; static const std::string OPTION_NUGET = "--nuget"; + static const std::string OPTION_IFW = "--ifw"; static const std::string OPTION_ZIP = "--zip"; static const std::string OPTION_SEVEN_ZIP = "--7zip"; static const std::string OPTION_NUGET_ID = "--nuget-id"; static const std::string OPTION_NUGET_VERSION = "--nuget-version"; + static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url"; // input sanitization static const std::string EXAMPLE = @@ -236,22 +239,25 @@ namespace vcpkg::Commands::Export OPTION_DRY_RUN, OPTION_RAW, OPTION_NUGET, + OPTION_IFW, OPTION_ZIP, OPTION_SEVEN_ZIP, }, { OPTION_NUGET_ID, OPTION_NUGET_VERSION, + OPTION_IFW_REPOSITORY_URL, }); const bool dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); const bool raw = options.switches.find(OPTION_RAW) != options.switches.cend(); const bool nuget = options.switches.find(OPTION_NUGET) != options.switches.cend(); + const bool ifw = options.switches.find(OPTION_IFW) != options.switches.cend(); const bool zip = options.switches.find(OPTION_ZIP) != options.switches.cend(); const bool seven_zip = options.switches.find(OPTION_SEVEN_ZIP) != options.switches.cend(); - if (!raw && !nuget && !zip && !seven_zip && !dry_run) + if (!raw && !nuget && !ifw && !zip && !seven_zip && !dry_run) { - System::println(System::Color::error, "Must provide at least one export type: --raw --nuget --zip --7zip"); + System::println(System::Color::error, "Must provide at least one export type: --raw --nuget --ifw --zip --7zip"); System::print(EXAMPLE); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -263,6 +269,10 @@ namespace vcpkg::Commands::Export Checks::check_exit( VCPKG_LINE_INFO, !maybe_nuget_version || nuget, "--nuget-version is only valid with --nuget"); + auto maybe_ifw_repository_url = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_URL); + + Checks::check_exit(VCPKG_LINE_INFO, !maybe_ifw_repository_url || ifw, "--ifw-repository-url is only valid with --ifw"); + // create the plan const StatusParagraphs status_db = database_load_check(paths); std::vector export_plan = Dependencies::create_export_plan(paths, specs, status_db); @@ -305,7 +315,11 @@ namespace vcpkg::Commands::Export Checks::exit_success(VCPKG_LINE_INFO); } - const std::string export_id = create_export_id(); + std::string export_id = create_export_id(); + if (ifw) + { + export_id = "vcpkg-export"; // TODO: Remove after debugging + } Files::Filesystem& fs = paths.get_filesystem(); const fs::path export_to_path = paths.root; @@ -315,6 +329,8 @@ namespace vcpkg::Commands::Export fs.create_directory(raw_exported_dir_path, ec); // execute the plan + std::map unique_packages; + std::set unique_triplets; for (const ExportPlanAction& action : export_plan) { if (action.plan_type != ExportPlanType::ALREADY_BUILT) @@ -327,10 +343,21 @@ namespace vcpkg::Commands::Export const BinaryParagraph& binary_paragraph = action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + unique_packages[action.spec.name()] = &action; + unique_triplets.insert(action.spec.triplet().canonical_name()); + + fs::path spec_exported_dir_path = raw_exported_dir_path / "installed"; + if (ifw) + { + // Export real package and return data dir for installation + spec_exported_dir_path = IFW::export_real_package(raw_exported_dir_path, action, fs); + } + const InstallDir dirs = InstallDir::from_destination_root( - raw_exported_dir_path / "installed", + spec_exported_dir_path, action.spec.triplet().to_string(), - raw_exported_dir_path / "installed" / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); + spec_exported_dir_path / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); System::println(System::Color::success, "Exporting package %s... done", display_name); @@ -351,13 +378,29 @@ namespace vcpkg::Commands::Export for (const fs::path& file : integration_files_relative_to_root) { const fs::path source = paths.root / file; - const fs::path destination = raw_exported_dir_path / file; + fs::path destination = raw_exported_dir_path / file; + if (ifw) + { + destination = raw_exported_dir_path / "integration" / "data" / file; + } fs.create_directories(destination.parent_path(), ec); Checks::check_exit(VCPKG_LINE_INFO, !ec); fs.copy_file(source, destination, fs::copy_options::overwrite_existing, ec); Checks::check_exit(VCPKG_LINE_INFO, !ec); } + if (ifw) + { + // Unigue packages + IFW::export_unique_packages(raw_exported_dir_path, unique_packages, fs); + // Unigue triplets + IFW::export_unique_triplets(raw_exported_dir_path, unique_triplets, fs); + // Integration + IFW::export_integration(raw_exported_dir_path, fs); + // Configuration + IFW::export_config(raw_exported_dir_path, maybe_ifw_repository_url.value_or(""), fs); + } + const auto print_next_step_info = [](const fs::path& prefix) { const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; const CMakeVariable cmake_variable = @@ -417,7 +460,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console print_next_step_info("[...]"); } - if (!raw) + if (!raw && !ifw) { fs.remove_all(raw_exported_dir_path, ec); } diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp new file mode 100644 index 000000000..ceedac9a3 --- /dev/null +++ b/toolsrc/src/commands_export_ifw.cpp @@ -0,0 +1,319 @@ +#include "pch.h" + +#include "vcpkg_Commands_Export_IFW.h" + +namespace vcpkg::Commands::Export::IFW +{ + using Dependencies::ExportPlanAction; + + fs::path export_real_package(const fs::path &raw_exported_dir_path, const ExportPlanAction& action, Files::Filesystem& fs) + { + std::error_code ec; + + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + // Prepare meta dir + const fs::path package_xml_file_path = raw_exported_dir_path / Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "meta" / "package.xml"; + const fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); + std::vector lines; + std::string line; std::string skip = " "; + line = ""; + lines.push_back(line); line.clear(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += action.spec.to_string(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += binary_paragraph.version; // TODO: Check IFW version format + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "2017-08-31"; // TODO: Get real package release date + line += ""; + //if (!binary_paragraph.depends.empty()) + //{ + // lines.push_back(line); line = skip; + // line += ""; + //// line += Strings::format("triplets.%s:", action.spec.triplet().canonical_name()); + // line += Strings::format("packages.%s.%s:", binary_paragraph.depends[0], action.spec.triplet().canonical_name()); + // for (size_t i = 1; i < binary_paragraph.depends.size(); ++i) + // { + // line += Strings::format(",packages.%s.%s:", binary_paragraph.depends[i], action.spec.triplet().canonical_name()); + // } + // line += ""; + //} + lines.push_back(line); line = skip; + line += ""; + line += Strings::format("packages.%s:,triplets.%s:", action.spec.name(), action.spec.triplet().canonical_name()); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "true"; // NOTE: hide real package + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "true"; + line += ""; + lines.push_back(line); line.clear(); + line = ""; + lines.push_back(line); line.clear(); + fs.write_lines(package_xml_file_path, lines); + + // Return dir path for export package data + return raw_exported_dir_path / Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "data" / "installed"; + } + + void export_unique_packages(const fs::path &raw_exported_dir_path, std::map unique_packages, Files::Filesystem& fs) + { + std::error_code ec; + + // packages + + fs::path package_xml_file_path = raw_exported_dir_path / "packages" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); + std::vector lines; + std::string line; std::string skip = " "; + line = ""; + lines.push_back(line); line.clear(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "Packages"; + line += ""; + lines.push_back(line); line = skip; + line = ""; + line += "1.0.0"; // TODO: Get real packages package version + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "2017-08-31"; // TODO: Get real package release date + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "true"; + line += ""; + lines.push_back(line); line.clear(); + line = ""; + lines.push_back(line); line.clear(); + fs.write_lines(package_xml_file_path, lines); + + for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) + { + const ExportPlanAction& action = *(package->second); + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + package_xml_file_path = raw_exported_dir_path / Strings::format("packages.%s", package->first) / "meta" / "package.xml"; + package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); + lines.clear(); + line.clear(); + skip = " "; + line = ""; + lines.push_back(line); line.clear(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += action.spec.name(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += binary_paragraph.description; + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += binary_paragraph.version; // TODO: Check IFW version format + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "2017-08-31"; // TODO: Get real package release date + line += ""; + if (!binary_paragraph.depends.empty()) + { + lines.push_back(line); line = skip; + line += ""; + line += Strings::format("packages.%s:", binary_paragraph.depends[0]); + for (size_t i = 1; i < binary_paragraph.depends.size(); ++i) + { + line += Strings::format(",packages.%s:", binary_paragraph.depends[i]); + } + line += ""; + } + lines.push_back(line); line = skip; + line += ""; + line += "true"; + line += ""; + lines.push_back(line); line.clear(); + line = ""; + lines.push_back(line); line.clear(); + fs.write_lines(package_xml_file_path, lines); + } + } + + void export_unique_triplets(const fs::path &raw_exported_dir_path, std::set unique_triplets, Files::Filesystem& fs) + { + std::error_code ec; + + // triplets + + fs::path package_xml_file_path = raw_exported_dir_path / "triplets" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); + std::vector lines; + std::string line; std::string skip = " "; + line = ""; + lines.push_back(line); line.clear(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "Triplets"; + line += ""; + lines.push_back(line); line = skip; + line = ""; + line += "1.0.0"; // TODO: Get real triplits package version + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "2017-08-31"; // TODO: Get real package release date + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "true"; + line += ""; + lines.push_back(line); line.clear(); + line = ""; + lines.push_back(line); line.clear(); + fs.write_lines(package_xml_file_path, lines); + + for (const std::string &triplet : unique_triplets) + { + package_xml_file_path = raw_exported_dir_path / Strings::format("triplets.%s", triplet) / "meta" / "package.xml"; + package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); + lines.clear(); + line.clear(); + skip = " "; + line = ""; + lines.push_back(line); line.clear(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += triplet; + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "1.0.0"; // TODO: Get real package version + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "2017-08-31"; // TODO: Get real package release date + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "true"; + line += ""; + lines.push_back(line); line.clear(); + line = ""; + lines.push_back(line); line.clear(); + fs.write_lines(package_xml_file_path, lines); + } + } + + void export_integration(const fs::path &raw_exported_dir_path, Files::Filesystem& fs) + { + std::error_code ec; + + // integration + fs::path package_xml_file_path = raw_exported_dir_path / "integration" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); + std::vector lines; + std::string line; std::string skip = " "; + line = ""; + lines.push_back(line); line.clear(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "Integration"; + line += ""; + lines.push_back(line); line = skip; + line = ""; + line += "1.0.0"; // TODO: Get real integration package version + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "2017-08-31"; // TODO: Get real package release date + line += ""; + lines.push_back(line); line.clear(); + line = ""; + lines.push_back(line); line.clear(); + fs.write_lines(package_xml_file_path, lines); + } + + void export_config(const fs::path &raw_exported_dir_path, const std::string ifw_repository_url, Files::Filesystem& fs) + { + std::error_code ec; + + // config.xml + fs::path config_xml_file_path = raw_exported_dir_path / "config.xml"; + fs::path config_xml_dir_path = config_xml_file_path.parent_path(); + fs.create_directories(config_xml_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create directory for configuration file %s", config_xml_file_path.generic_string()); + std::vector lines; + std::string line; std::string skip = " "; + line = ""; + lines.push_back(line); line.clear(); + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "vcpkg"; + line += ""; + lines.push_back(line); line = skip; + line += ""; + line += "1.0.0"; // TODO: Get real vcpkg installer version + line += ""; + //lines.push_back(line); line = skip; + //line += "true"; + lines.push_back(line); line = skip; + line += ""; + line += "@RootDir@/src/vcpkg"; + line += ""; + if (!ifw_repository_url.empty()) + { + lines.push_back(line); line = skip; + line += ""; + lines.push_back(line); line = skip + skip; + line += ""; + lines.push_back(line); line = skip + skip + skip; + line += ""; + line += ifw_repository_url; + line += ""; + lines.push_back(line); line = skip + skip; + line += ""; + lines.push_back(line); line = skip; + line += ""; + } + lines.push_back(line); line.clear(); + line = ""; + lines.push_back(line); line.clear(); + fs.write_lines(config_xml_file_path, lines); + } +} diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index edecd7720..3f17ecb3c 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -166,6 +166,7 @@ + @@ -185,6 +186,7 @@ + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 2fbf3d929..7eb077019 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -165,6 +165,9 @@ Source Files + + Source Files + Source Files @@ -218,6 +221,9 @@ Header Files + + Header Files + Header Files -- cgit v1.2.3 From 5199507a5892ab997b1beee2f1b7d2a6c7e75115 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 21 Sep 2017 02:27:00 -0700 Subject: [vcpkg-export-ifw] Use template approach for xml instead of line-by-line --- toolsrc/src/commands_export.cpp | 18 +- toolsrc/src/commands_export_ifw.cpp | 397 ++++++++++++++---------------------- 2 files changed, 161 insertions(+), 254 deletions(-) diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index 139f19026..c143fb9c7 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -257,7 +257,8 @@ namespace vcpkg::Commands::Export if (!raw && !nuget && !ifw && !zip && !seven_zip && !dry_run) { - System::println(System::Color::error, "Must provide at least one export type: --raw --nuget --ifw --zip --7zip"); + System::println(System::Color::error, + "Must provide at least one export type: --raw --nuget --ifw --zip --7zip"); System::print(EXAMPLE); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -271,7 +272,8 @@ namespace vcpkg::Commands::Export auto maybe_ifw_repository_url = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_URL); - Checks::check_exit(VCPKG_LINE_INFO, !maybe_ifw_repository_url || ifw, "--ifw-repository-url is only valid with --ifw"); + Checks::check_exit( + VCPKG_LINE_INFO, !maybe_ifw_repository_url || ifw, "--ifw-repository-url is only valid with --ifw"); // create the plan const StatusParagraphs status_db = database_load_check(paths); @@ -354,10 +356,10 @@ namespace vcpkg::Commands::Export spec_exported_dir_path = IFW::export_real_package(raw_exported_dir_path, action, fs); } - const InstallDir dirs = InstallDir::from_destination_root( - spec_exported_dir_path, - action.spec.triplet().to_string(), - spec_exported_dir_path / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); + const InstallDir dirs = InstallDir::from_destination_root(spec_exported_dir_path, + action.spec.triplet().to_string(), + spec_exported_dir_path / "vcpkg" / "info" / + (binary_paragraph.fullstem() + ".list")); Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); System::println(System::Color::success, "Exporting package %s... done", display_name); @@ -391,9 +393,9 @@ namespace vcpkg::Commands::Export if (ifw) { - // Unigue packages + // Unique packages IFW::export_unique_packages(raw_exported_dir_path, unique_packages, fs); - // Unigue triplets + // Unique triplets IFW::export_unique_triplets(raw_exported_dir_path, unique_triplets, fs); // Integration IFW::export_integration(raw_exported_dir_path, fs); diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index ceedac9a3..4b5bdb902 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -6,7 +6,9 @@ namespace vcpkg::Commands::Export::IFW { using Dependencies::ExportPlanAction; - fs::path export_real_package(const fs::path &raw_exported_dir_path, const ExportPlanAction& action, Files::Filesystem& fs) + fs::path export_real_package(const fs::path& raw_exported_dir_path, + const ExportPlanAction& action, + Files::Filesystem& fs) { std::error_code ec; @@ -14,97 +16,64 @@ namespace vcpkg::Commands::Export::IFW action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; // Prepare meta dir - const fs::path package_xml_file_path = raw_exported_dir_path / Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "meta" / "package.xml"; + const fs::path package_xml_file_path = + raw_exported_dir_path / + Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "meta" / + "package.xml"; const fs::path package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - std::vector lines; - std::string line; std::string skip = " "; - line = ""; - lines.push_back(line); line.clear(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += action.spec.to_string(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += binary_paragraph.version; // TODO: Check IFW version format - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "2017-08-31"; // TODO: Get real package release date - line += ""; - //if (!binary_paragraph.depends.empty()) - //{ - // lines.push_back(line); line = skip; - // line += ""; - //// line += Strings::format("triplets.%s:", action.spec.triplet().canonical_name()); - // line += Strings::format("packages.%s.%s:", binary_paragraph.depends[0], action.spec.triplet().canonical_name()); - // for (size_t i = 1; i < binary_paragraph.depends.size(); ++i) - // { - // line += Strings::format(",packages.%s.%s:", binary_paragraph.depends[i], action.spec.triplet().canonical_name()); - // } - // line += ""; - //} - lines.push_back(line); line = skip; - line += ""; - line += Strings::format("packages.%s:,triplets.%s:", action.spec.name(), action.spec.triplet().canonical_name()); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "true"; // NOTE: hide real package - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "true"; - line += ""; - lines.push_back(line); line.clear(); - line = ""; - lines.push_back(line); line.clear(); - fs.write_lines(package_xml_file_path, lines); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + + fs.write_contents(package_xml_file_path, + Strings::format(R"###( + + + %s + %s + 2017-08-31 + packages.%s:,triplets.%s: + true + true + +)###", + action.spec.to_string(), + binary_paragraph.version, + action.spec.name(), + action.spec.triplet().canonical_name())); // Return dir path for export package data - return raw_exported_dir_path / Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "data" / "installed"; + return raw_exported_dir_path / + Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "data" / + "installed"; } - void export_unique_packages(const fs::path &raw_exported_dir_path, std::map unique_packages, Files::Filesystem& fs) - { - std::error_code ec; - + void export_unique_packages(const fs::path& raw_exported_dir_path, + std::map unique_packages, + Files::Filesystem& fs) + { + std::error_code ec; + // packages fs::path package_xml_file_path = raw_exported_dir_path / "packages" / "meta" / "package.xml"; fs::path package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - std::vector lines; - std::string line; std::string skip = " "; - line = ""; - lines.push_back(line); line.clear(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "Packages"; - line += ""; - lines.push_back(line); line = skip; - line = ""; - line += "1.0.0"; // TODO: Get real packages package version - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "2017-08-31"; // TODO: Get real package release date - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "true"; - line += ""; - lines.push_back(line); line.clear(); - line = ""; - lines.push_back(line); line.clear(); - fs.write_lines(package_xml_file_path, lines); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, R"###( + + + Packages + 1.0.0 + 2017-08-31 + true + +)###"); for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) { @@ -112,56 +81,41 @@ namespace vcpkg::Commands::Export::IFW const BinaryParagraph& binary_paragraph = action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; - package_xml_file_path = raw_exported_dir_path / Strings::format("packages.%s", package->first) / "meta" / "package.xml"; + package_xml_file_path = + raw_exported_dir_path / Strings::format("packages.%s", package->first) / "meta" / "package.xml"; package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - lines.clear(); - line.clear(); - skip = " "; - line = ""; - lines.push_back(line); line.clear(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += action.spec.name(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += binary_paragraph.description; - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += binary_paragraph.version; // TODO: Check IFW version format - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "2017-08-31"; // TODO: Get real package release date - line += ""; - if (!binary_paragraph.depends.empty()) - { - lines.push_back(line); line = skip; - line += ""; - line += Strings::format("packages.%s:", binary_paragraph.depends[0]); - for (size_t i = 1; i < binary_paragraph.depends.size(); ++i) - { - line += Strings::format(",packages.%s:", binary_paragraph.depends[i]); - } - line += ""; - } - lines.push_back(line); line = skip; - line += ""; - line += "true"; - line += ""; - lines.push_back(line); line.clear(); - line = ""; - lines.push_back(line); line.clear(); - fs.write_lines(package_xml_file_path, lines); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + + auto deps = Strings::join( + ",", binary_paragraph.depends, [](const std::string& dep) { return "packages." + dep + ":"; }); + + if (!deps.empty()) deps = "\n " + deps; + + fs.write_contents(package_xml_file_path, + Strings::format(R"###( + + + %s + %s + %s + 2017-08-31%s + true + +)###", + action.spec.name(), + binary_paragraph.description, + binary_paragraph.version, + deps)); } } - void export_unique_triplets(const fs::path &raw_exported_dir_path, std::set unique_triplets, Files::Filesystem& fs) + void export_unique_triplets(const fs::path& raw_exported_dir_path, + std::set unique_triplets, + Files::Filesystem& fs) { std::error_code ec; @@ -170,71 +124,43 @@ namespace vcpkg::Commands::Export::IFW fs::path package_xml_file_path = raw_exported_dir_path / "triplets" / "meta" / "package.xml"; fs::path package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - std::vector lines; - std::string line; std::string skip = " "; - line = ""; - lines.push_back(line); line.clear(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "Triplets"; - line += ""; - lines.push_back(line); line = skip; - line = ""; - line += "1.0.0"; // TODO: Get real triplits package version - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "2017-08-31"; // TODO: Get real package release date - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "true"; - line += ""; - lines.push_back(line); line.clear(); - line = ""; - lines.push_back(line); line.clear(); - fs.write_lines(package_xml_file_path, lines); - - for (const std::string &triplet : unique_triplets) + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, R"###( + + + Triplets + 1.0.0 + 2017-08-31 + true + +)###"); + + for (const std::string& triplet : unique_triplets) { - package_xml_file_path = raw_exported_dir_path / Strings::format("triplets.%s", triplet) / "meta" / "package.xml"; + package_xml_file_path = + raw_exported_dir_path / Strings::format("triplets.%s", triplet) / "meta" / "package.xml"; package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - lines.clear(); - line.clear(); - skip = " "; - line = ""; - lines.push_back(line); line.clear(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += triplet; - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "1.0.0"; // TODO: Get real package version - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "2017-08-31"; // TODO: Get real package release date - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "true"; - line += ""; - lines.push_back(line); line.clear(); - line = ""; - lines.push_back(line); line.clear(); - fs.write_lines(package_xml_file_path, lines); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, Strings::format(R"###( + + + %s + 1.0.0 + 2017-08-31 + true + +)###", triplet)); } } - void export_integration(const fs::path &raw_exported_dir_path, Files::Filesystem& fs) + void export_integration(const fs::path& raw_exported_dir_path, Files::Filesystem& fs) { std::error_code ec; @@ -242,32 +168,25 @@ namespace vcpkg::Commands::Export::IFW fs::path package_xml_file_path = raw_exported_dir_path / "integration" / "meta" / "package.xml"; fs::path package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - std::vector lines; - std::string line; std::string skip = " "; - line = ""; - lines.push_back(line); line.clear(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "Integration"; - line += ""; - lines.push_back(line); line = skip; - line = ""; - line += "1.0.0"; // TODO: Get real integration package version - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "2017-08-31"; // TODO: Get real package release date - line += ""; - lines.push_back(line); line.clear(); - line = ""; - lines.push_back(line); line.clear(); - fs.write_lines(package_xml_file_path, lines); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + + fs.write_contents(package_xml_file_path, R"###( + + + Integration + 1.0.0 + 2017-08-31 + true + +)###"); } - void export_config(const fs::path &raw_exported_dir_path, const std::string ifw_repository_url, Files::Filesystem& fs) + void export_config(const fs::path& raw_exported_dir_path, + const std::string ifw_repository_url, + Files::Filesystem& fs) { std::error_code ec; @@ -275,45 +194,31 @@ namespace vcpkg::Commands::Export::IFW fs::path config_xml_file_path = raw_exported_dir_path / "config.xml"; fs::path config_xml_dir_path = config_xml_file_path.parent_path(); fs.create_directories(config_xml_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for configuration file %s", config_xml_file_path.generic_string()); - std::vector lines; - std::string line; std::string skip = " "; - line = ""; - lines.push_back(line); line.clear(); - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "vcpkg"; - line += ""; - lines.push_back(line); line = skip; - line += ""; - line += "1.0.0"; // TODO: Get real vcpkg installer version - line += ""; - //lines.push_back(line); line = skip; - //line += "true"; - lines.push_back(line); line = skip; - line += ""; - line += "@RootDir@/src/vcpkg"; - line += ""; + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for configuration file %s", + config_xml_file_path.generic_string()); + std::string formatted_repo_url; if (!ifw_repository_url.empty()) { - lines.push_back(line); line = skip; - line += ""; - lines.push_back(line); line = skip + skip; - line += ""; - lines.push_back(line); line = skip + skip + skip; - line += ""; - line += ifw_repository_url; - line += ""; - lines.push_back(line); line = skip + skip; - line += ""; - lines.push_back(line); line = skip; - line += ""; + formatted_repo_url = Strings::format(R"###( + + + %s + + +)###", + formatted_repo_url); } - lines.push_back(line); line.clear(); - line = ""; - lines.push_back(line); line.clear(); - fs.write_lines(config_xml_file_path, lines); + + fs.write_contents(config_xml_file_path, Strings::format(R"###( + + + vcpkg + 1.0.0 + 2017-08-31 + @RootDir@/src/vcpkg%s + +)###", formatted_repo_url)); } } -- cgit v1.2.3 From 68b9c2d8b9119acb48643447a7561a5c2b733d25 Mon Sep 17 00:00:00 2001 From: Konstantin Podsvirov Date: Fri, 22 Sep 2017 02:16:14 +0300 Subject: [vcpkg-export-ifw] Separate IFW loop Separate IFW loop compatible with main export loop Fixed mistakes in templates Set current date to ReleaseDate tag --- toolsrc/include/vcpkg_Commands_Export.h | 14 ++ toolsrc/include/vcpkg_Commands_Export_IFW.h | 13 +- toolsrc/src/commands_export.cpp | 253 ++++++++++++++-------------- toolsrc/src/commands_export_ifw.cpp | 183 +++++++++++++++----- toolsrc/vcpkglib/vcpkglib.vcxproj | 1 + toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 3 + 6 files changed, 294 insertions(+), 173 deletions(-) create mode 100644 toolsrc/include/vcpkg_Commands_Export.h diff --git a/toolsrc/include/vcpkg_Commands_Export.h b/toolsrc/include/vcpkg_Commands_Export.h new file mode 100644 index 000000000..31003422d --- /dev/null +++ b/toolsrc/include/vcpkg_Commands_Export.h @@ -0,0 +1,14 @@ +#pragma once + +#include "StatusParagraphs.h" +#include "VcpkgCmdArguments.h" +#include "VcpkgPaths.h" +#include "VersionT.h" +#include "vcpkg_Build.h" +#include "vcpkg_Dependencies.h" +#include + +namespace vcpkg::Commands::Export +{ + void export_integration_files(const fs::path &raw_exported_dir_path, const VcpkgPaths& paths); +} diff --git a/toolsrc/include/vcpkg_Commands_Export_IFW.h b/toolsrc/include/vcpkg_Commands_Export_IFW.h index b25e943eb..881bbaf63 100644 --- a/toolsrc/include/vcpkg_Commands_Export_IFW.h +++ b/toolsrc/include/vcpkg_Commands_Export_IFW.h @@ -5,9 +5,12 @@ namespace vcpkg::Commands::Export::IFW { - fs::path export_real_package(const fs::path &raw_exported_dir_path, const Dependencies::ExportPlanAction& action, Files::Filesystem& fs); - void export_unique_packages(const fs::path &raw_exported_dir_path, std::map unique_packages, Files::Filesystem& fs); - void export_unique_triplets(const fs::path &raw_exported_dir_path, std::set unique_triplets, Files::Filesystem& fs); - void export_integration(const fs::path &raw_exported_dir_path, Files::Filesystem& fs); - void export_config(const fs::path &raw_exported_dir_path, const std::string ifw_repository_url, Files::Filesystem& fs); + struct Options + { + Optional maybe_repository_url; + Optional maybe_packages_dir_path; + Optional maybe_config_file_path; + }; + + void do_export(const std::vector &export_plan, const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths); } diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index c143fb9c7..6632dfe67 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -211,6 +211,32 @@ namespace vcpkg::Commands::Export return nullopt; } + void export_integration_files(const fs::path &raw_exported_dir_path, const VcpkgPaths& paths) + { + const std::vector integration_files_relative_to_root = { + { ".vcpkg-root" }, + { fs::path{ "scripts" } / "buildsystems" / "msbuild" / "applocal.ps1" }, + { fs::path{ "scripts" } / "buildsystems" / "msbuild" / "vcpkg.targets" }, + { fs::path{ "scripts" } / "buildsystems" / "vcpkg.cmake" }, + { fs::path{ "scripts" } / "cmake" / "vcpkg_get_windows_sdk.cmake" }, + { fs::path{ "scripts" } / "getWindowsSDK.ps1" }, + { fs::path{ "scripts" } / "getProgramFilesPlatformBitness.ps1" }, + { fs::path{ "scripts" } / "getProgramFiles32bit.ps1" }, + }; + + for (const fs::path& file : integration_files_relative_to_root) + { + const fs::path source = paths.root / file; + fs::path destination = raw_exported_dir_path / file; + Files::Filesystem& fs = paths.get_filesystem(); + std::error_code ec; + fs.create_directories(destination.parent_path(), ec); + Checks::check_exit(VCPKG_LINE_INFO, !ec); + fs.copy_file(source, destination, fs::copy_options::overwrite_existing, ec); + Checks::check_exit(VCPKG_LINE_INFO, !ec); + } + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { static const std::string OPTION_DRY_RUN = "--dry-run"; @@ -222,6 +248,8 @@ namespace vcpkg::Commands::Export static const std::string OPTION_NUGET_ID = "--nuget-id"; static const std::string OPTION_NUGET_VERSION = "--nuget-version"; static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url"; + static const std::string OPTION_IFW_PACKAGES_DIR_PATH = "--ifw-packages-directory-path"; + static const std::string OPTION_IFW_CONFIG_FILE_PATH = "--ifw-configuration-file-path"; // input sanitization static const std::string EXAMPLE = @@ -247,6 +275,8 @@ namespace vcpkg::Commands::Export OPTION_NUGET_ID, OPTION_NUGET_VERSION, OPTION_IFW_REPOSITORY_URL, + OPTION_IFW_PACKAGES_DIR_PATH, + OPTION_IFW_CONFIG_FILE_PATH }); const bool dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); const bool raw = options.switches.find(OPTION_RAW) != options.switches.cend(); @@ -270,10 +300,19 @@ namespace vcpkg::Commands::Export Checks::check_exit( VCPKG_LINE_INFO, !maybe_nuget_version || nuget, "--nuget-version is only valid with --nuget"); - auto maybe_ifw_repository_url = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_URL); + IFW::Options ifw_options; + + ifw_options.maybe_repository_url = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_URL); + Checks::check_exit( + VCPKG_LINE_INFO, !ifw_options.maybe_repository_url || ifw, "--ifw-repository-url is only valid with --ifw"); + + ifw_options.maybe_packages_dir_path = maybe_lookup(options.settings, OPTION_IFW_PACKAGES_DIR_PATH); + Checks::check_exit( + VCPKG_LINE_INFO, !ifw_options.maybe_packages_dir_path || ifw, "--ifw-packages-directory-path is only valid with --ifw"); + ifw_options.maybe_config_file_path = maybe_lookup(options.settings, OPTION_IFW_CONFIG_FILE_PATH); Checks::check_exit( - VCPKG_LINE_INFO, !maybe_ifw_repository_url || ifw, "--ifw-repository-url is only valid with --ifw"); + VCPKG_LINE_INFO, !ifw_options.maybe_config_file_path || ifw, "--ifw-configuration-file-path is only valid with --ifw"); // create the plan const StatusParagraphs status_db = database_load_check(paths); @@ -318,153 +357,117 @@ namespace vcpkg::Commands::Export } std::string export_id = create_export_id(); - if (ifw) - { - export_id = "vcpkg-export"; // TODO: Remove after debugging - } - Files::Filesystem& fs = paths.get_filesystem(); - const fs::path export_to_path = paths.root; - const fs::path raw_exported_dir_path = export_to_path / export_id; - std::error_code ec; - fs.remove_all(raw_exported_dir_path, ec); - fs.create_directory(raw_exported_dir_path, ec); + const auto print_next_step_info = [](const fs::path& prefix) { + const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; + const CMakeVariable cmake_variable = + CMakeVariable(L"CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); + System::println("\n" + "To use the exported libraries in CMake projects use:" + "\n" + " %s" + "\n", + Strings::to_utf8(cmake_variable.s)); + }; - // execute the plan - std::map unique_packages; - std::set unique_triplets; - for (const ExportPlanAction& action : export_plan) + // Main loop + if (raw || nuget || zip || seven_zip) { - if (action.plan_type != ExportPlanType::ALREADY_BUILT) + Files::Filesystem& fs = paths.get_filesystem(); + const fs::path export_to_path = paths.root; + const fs::path raw_exported_dir_path = export_to_path / export_id; + std::error_code ec; + fs.remove_all(raw_exported_dir_path, ec); + fs.create_directory(raw_exported_dir_path, ec); + + // execute the plan + for (const ExportPlanAction& action : export_plan) { - Checks::unreachable(VCPKG_LINE_INFO); - } + if (action.plan_type != ExportPlanType::ALREADY_BUILT) + { + Checks::unreachable(VCPKG_LINE_INFO); + } - const std::string display_name = action.spec.to_string(); - System::println("Exporting package %s... ", display_name); + const std::string display_name = action.spec.to_string(); + System::println("Exporting package %s... ", display_name); - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; - unique_packages[action.spec.name()] = &action; - unique_triplets.insert(action.spec.triplet().canonical_name()); + const InstallDir dirs = InstallDir::from_destination_root( + raw_exported_dir_path / "installed", + action.spec.triplet().to_string(), + raw_exported_dir_path / "installed" / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); - fs::path spec_exported_dir_path = raw_exported_dir_path / "installed"; - if (ifw) - { - // Export real package and return data dir for installation - spec_exported_dir_path = IFW::export_real_package(raw_exported_dir_path, action, fs); + Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); + System::println(System::Color::success, "Exporting package %s... done", display_name); } - const InstallDir dirs = InstallDir::from_destination_root(spec_exported_dir_path, - action.spec.triplet().to_string(), - spec_exported_dir_path / "vcpkg" / "info" / - (binary_paragraph.fullstem() + ".list")); - - Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); - System::println(System::Color::success, "Exporting package %s... done", display_name); - } - - // Copy files needed for integration - const std::vector integration_files_relative_to_root = { - {".vcpkg-root"}, - {fs::path{"scripts"} / "buildsystems" / "msbuild" / "applocal.ps1"}, - {fs::path{"scripts"} / "buildsystems" / "msbuild" / "vcpkg.targets"}, - {fs::path{"scripts"} / "buildsystems" / "vcpkg.cmake"}, - {fs::path{"scripts"} / "cmake" / "vcpkg_get_windows_sdk.cmake"}, - {fs::path{"scripts"} / "getWindowsSDK.ps1"}, - {fs::path{"scripts"} / "getProgramFilesPlatformBitness.ps1"}, - {fs::path{"scripts"} / "getProgramFiles32bit.ps1"}, - }; + // Copy files needed for integration + export_integration_files(raw_exported_dir_path, paths); - for (const fs::path& file : integration_files_relative_to_root) - { - const fs::path source = paths.root / file; - fs::path destination = raw_exported_dir_path / file; - if (ifw) + if (raw) { - destination = raw_exported_dir_path / "integration" / "data" / file; + System::println( + System::Color::success, R"(Files exported at: "%s")", raw_exported_dir_path.generic_string()); + print_next_step_info(export_to_path); } - fs.create_directories(destination.parent_path(), ec); - Checks::check_exit(VCPKG_LINE_INFO, !ec); - fs.copy_file(source, destination, fs::copy_options::overwrite_existing, ec); - Checks::check_exit(VCPKG_LINE_INFO, !ec); - } - if (ifw) - { - // Unique packages - IFW::export_unique_packages(raw_exported_dir_path, unique_packages, fs); - // Unique triplets - IFW::export_unique_triplets(raw_exported_dir_path, unique_triplets, fs); - // Integration - IFW::export_integration(raw_exported_dir_path, fs); - // Configuration - IFW::export_config(raw_exported_dir_path, maybe_ifw_repository_url.value_or(""), fs); - } - - const auto print_next_step_info = [](const fs::path& prefix) { - const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; - const CMakeVariable cmake_variable = - CMakeVariable(L"CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); - System::println("\n" - "To use the exported libraries in CMake projects use:" - "\n" - " %s" - "\n", - Strings::to_utf8(cmake_variable.s)); - }; - - if (raw) - { - System::println( - System::Color::success, R"(Files exported at: "%s")", raw_exported_dir_path.generic_string()); - print_next_step_info(export_to_path); - } - - if (nuget) - { - System::println("Creating nuget package... "); + if (nuget) + { + System::println("Creating nuget package... "); - const std::string nuget_id = maybe_nuget_id.value_or(raw_exported_dir_path.filename().string()); - const std::string nuget_version = maybe_nuget_version.value_or("1.0.0"); - const fs::path output_path = - do_nuget_export(paths, nuget_id, nuget_version, raw_exported_dir_path, export_to_path); - System::println(System::Color::success, "Creating nuget package... done"); - System::println(System::Color::success, "NuGet package exported at: %s", output_path.generic_string()); + const std::string nuget_id = maybe_nuget_id.value_or(raw_exported_dir_path.filename().string()); + const std::string nuget_version = maybe_nuget_version.value_or("1.0.0"); + const fs::path output_path = + do_nuget_export(paths, nuget_id, nuget_version, raw_exported_dir_path, export_to_path); + System::println(System::Color::success, "Creating nuget package... done"); + System::println(System::Color::success, "NuGet package exported at: %s", output_path.generic_string()); - System::println(R"( + System::println(R"( With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: Install-Package %s -Source "%s" )" - "\n", - nuget_id, - output_path.parent_path().u8string()); - } + "\n", + nuget_id, + output_path.parent_path().u8string()); + } - if (zip) - { - System::println("Creating zip archive... "); - const fs::path output_path = - do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::ZIP); - System::println(System::Color::success, "Creating zip archive... done"); - System::println(System::Color::success, "Zip archive exported at: %s", output_path.generic_string()); - print_next_step_info("[...]"); - } + if (zip) + { + System::println("Creating zip archive... "); + const fs::path output_path = + do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::ZIP); + System::println(System::Color::success, "Creating zip archive... done"); + System::println(System::Color::success, "Zip archive exported at: %s", output_path.generic_string()); + print_next_step_info("[...]"); + } - if (seven_zip) - { - System::println("Creating 7zip archive... "); - const fs::path output_path = - do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::SEVEN_ZIP); - System::println(System::Color::success, "Creating 7zip archive... done"); - System::println(System::Color::success, "7zip archive exported at: %s", output_path.generic_string()); - print_next_step_info("[...]"); + if (seven_zip) + { + System::println("Creating 7zip archive... "); + const fs::path output_path = + do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::SEVEN_ZIP); + System::println(System::Color::success, "Creating 7zip archive... done"); + System::println(System::Color::success, "7zip archive exported at: %s", output_path.generic_string()); + print_next_step_info("[...]"); + } + + if (!raw) + { + fs.remove_all(raw_exported_dir_path, ec); + } } - if (!raw && !ifw) + // IFW loop + if (ifw) { - fs.remove_all(raw_exported_dir_path, ec); + IFW::do_export(export_plan, export_id, ifw_options, paths); + + // TODO: Download corrected QtIFW tools and automate installer creation + System::println("Use corrected QtIFW tools (for more info see: https://codereview.qt-project.org/#/c/203958) to create installer..."); + + print_next_step_info("[...]"); } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index 4b5bdb902..e2499b75d 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -1,10 +1,30 @@ #include "pch.h" +#include "vcpkg_Commands.h" +#include "vcpkg_Commands_Export.h" #include "vcpkg_Commands_Export_IFW.h" namespace vcpkg::Commands::Export::IFW { using Dependencies::ExportPlanAction; + using Dependencies::ExportPlanType; + using Install::InstallDir; + + static std::string create_release_date() + { + const tm date_time = System::get_current_date_time(); + + // Format is: YYYY-mm-dd + // 10 characters + 1 null terminating character will be written for a total of 11 chars + char mbstr[11]; + const size_t bytes_written = std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d", &date_time); + Checks::check_exit(VCPKG_LINE_INFO, + bytes_written == 10, + "Expected 10 bytes to be written, but %u were written", + bytes_written); + const std::string date_time_as_string(mbstr); + return date_time_as_string; + } fs::path export_real_package(const fs::path& raw_exported_dir_path, const ExportPlanAction& action, @@ -28,19 +48,19 @@ namespace vcpkg::Commands::Export::IFW package_xml_file_path.generic_string()); fs.write_contents(package_xml_file_path, - Strings::format(R"###( - + Strings::format( +R"###( %s %s - 2017-08-31 - packages.%s:,triplets.%s: + %s + packages.%s:,triplets.%s: true - true )###", action.spec.to_string(), binary_paragraph.version, + create_release_date(), action.spec.name(), action.spec.triplet().canonical_name())); @@ -65,15 +85,15 @@ namespace vcpkg::Commands::Export::IFW !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, R"###( - + fs.write_contents(package_xml_file_path, Strings::format( +R"###( Packages 1.0.0 - 2017-08-31 - true + %s -)###"); +)###", + create_release_date())); for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) { @@ -93,22 +113,22 @@ namespace vcpkg::Commands::Export::IFW auto deps = Strings::join( ",", binary_paragraph.depends, [](const std::string& dep) { return "packages." + dep + ":"; }); - if (!deps.empty()) deps = "\n " + deps; + if (!deps.empty()) deps = "\n " + deps + ""; fs.write_contents(package_xml_file_path, - Strings::format(R"###( - + Strings::format( +R"###( %s %s %s - 2017-08-31%s - true + %s%s )###", action.spec.name(), binary_paragraph.description, binary_paragraph.version, + create_release_date(), deps)); } } @@ -128,15 +148,15 @@ namespace vcpkg::Commands::Export::IFW !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, R"###( - + fs.write_contents(package_xml_file_path, Strings::format( +R"###( Triplets 1.0.0 - 2017-08-31 - true + %s -)###"); +)###", + create_release_date())); for (const std::string& triplet : unique_triplets) { @@ -148,15 +168,16 @@ namespace vcpkg::Commands::Export::IFW !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, Strings::format(R"###( - + fs.write_contents(package_xml_file_path, Strings::format( +R"###( %s 1.0.0 - 2017-08-31 - true + %s -)###", triplet)); +)###", + triplet, + create_release_date())); } } @@ -173,52 +194,128 @@ namespace vcpkg::Commands::Export::IFW "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, R"###( - + fs.write_contents(package_xml_file_path, Strings::format( +R"###( Integration 1.0.0 - 2017-08-31 - true + %s -)###"); +)###", + create_release_date())); } - void export_config(const fs::path& raw_exported_dir_path, - const std::string ifw_repository_url, - Files::Filesystem& fs) + void export_config(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) { std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + const fs::path config_xml_file_path = ifw_options.maybe_config_file_path.has_value() ? + fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-configuration") / "config.xml"; - // config.xml - fs::path config_xml_file_path = raw_exported_dir_path / "config.xml"; fs::path config_xml_dir_path = config_xml_file_path.parent_path(); fs.create_directories(config_xml_dir_path, ec); Checks::check_exit(VCPKG_LINE_INFO, !ec, "Could not create directory for configuration file %s", config_xml_file_path.generic_string()); + std::string formatted_repo_url; - if (!ifw_repository_url.empty()) + std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); + if (!ifw_repo_url.empty()) { formatted_repo_url = Strings::format(R"###( %s - -)###", - formatted_repo_url); + )###", + ifw_repo_url); } - fs.write_contents(config_xml_file_path, Strings::format(R"###( - + fs.write_contents(config_xml_file_path, Strings::format( +R"###( vcpkg 1.0.0 - 2017-08-31 @RootDir@/src/vcpkg%s -)###", formatted_repo_url)); +)###", + formatted_repo_url)); + + System::println("Created ifw configuration file: %s", config_xml_file_path.generic_string()); + } + + void do_export(const std::vector &export_plan, const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + { + System::println("Creating ifw packages... "); + + std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + const fs::path ifw_packages_dir_path = ifw_options.maybe_packages_dir_path.has_value() ? + fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-packages"); + + fs.remove_all(ifw_packages_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not remove outdated packages directory %s", + ifw_packages_dir_path.generic_string()); + + fs.create_directory(ifw_packages_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create packages directory %s", + ifw_packages_dir_path.generic_string()); + + // execute the plan + std::map unique_packages; + std::set unique_triplets; + for (const ExportPlanAction& action : export_plan) + { + if (action.plan_type != ExportPlanType::ALREADY_BUILT) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + const std::string display_name = action.spec.to_string(); + System::println("Exporting package %s... ", display_name); + + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + unique_packages[action.spec.name()] = &action; + unique_triplets.insert(action.spec.triplet().canonical_name()); + + // Export real package and return data dir for installation + fs::path ifw_package_dir_path = export_real_package(ifw_packages_dir_path, action, fs); + + // Copy package data + const InstallDir dirs = InstallDir::from_destination_root(ifw_package_dir_path, + action.spec.triplet().to_string(), + ifw_package_dir_path / "vcpkg" / "info" / + (binary_paragraph.fullstem() + ".list")); + + Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); + System::println(System::Color::success, "Exporting package %s... done", display_name); + } + + // Unique packages + export_unique_packages(ifw_packages_dir_path, unique_packages, fs); + + // Unique triplets + export_unique_triplets(ifw_packages_dir_path, unique_triplets, fs); + + // Copy files needed for integration + export_integration_files(ifw_packages_dir_path / "integration" / "data", paths); + // Integration + export_integration(ifw_packages_dir_path, fs); + + System::println("Created ifw packages directory: %s", ifw_packages_dir_path.generic_string()); + + // Configuration + export_config(export_id, ifw_options, paths); } } diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 3f17ecb3c..7c5537e15 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -166,6 +166,7 @@ + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 7eb077019..cc82198ee 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -221,6 +221,9 @@ Header Files + + Header Files + Header Files -- cgit v1.2.3 From c6149fae2f9f33d9ed363650aee6aea642574b0a Mon Sep 17 00:00:00 2001 From: Konstantin Podsvirov Date: Wed, 27 Sep 2017 02:57:51 +0300 Subject: [vcpkg-export-ifw] Usage QtIFW tools Download and use tools to make repository and installer --- scripts/fetchDependency.ps1 | 11 +++ toolsrc/include/VcpkgPaths.h | 6 ++ toolsrc/include/vcpkg_Commands_Export_IFW.h | 2 + toolsrc/src/VcpkgPaths.cpp | 40 ++++++++ toolsrc/src/commands_export.cpp | 19 +++- toolsrc/src/commands_export_ifw.cpp | 145 +++++++++++++++++++++++----- 6 files changed, 193 insertions(+), 30 deletions(-) diff --git a/scripts/fetchDependency.ps1 b/scripts/fetchDependency.ps1 index 2a23002a4..25447c19b 100644 --- a/scripts/fetchDependency.ps1 +++ b/scripts/fetchDependency.ps1 @@ -137,6 +137,17 @@ function SelectProgram([Parameter(Mandatory=$true)][string]$Dependency) $extractionType = $ExtractionType_ZIP $extractionFolder = "$downloadsDir\MinGit-2.14.1-32-bit" } + elseif($Dependency -eq "installerbase") + { + $requiredVersion = "3.1.81" + $downloadVersion = "3.1.81" + $url = "https://github.com/podsvirov/installer-framework/releases/download/cr203958-9/QtInstallerFramework-win-x86.zip" + $downloadPath = "$downloadsDir\QtInstallerFramework-win-x86.zip" + $expectedDownloadedFileHash = "f2ce23cf5cf9fc7ce409bdca49328e09a070c0026d3c8a04e4dfde7b05b83fe8" + $executableFromDownload = "$downloadsDir\QtInstallerFramework-win-x86\bin\installerbase.exe" + $extractionType = $ExtractionType_ZIP + $extractionFolder = $downloadsDir + } else { throw "Unknown program requested" diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index d55c95fe1..e7893ba15 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -57,6 +57,9 @@ namespace vcpkg const fs::path& get_cmake_exe() const; const fs::path& get_git_exe() const; const fs::path& get_nuget_exe() const; + const fs::path& get_ifw_installerbase_exe() const; + const fs::path& get_ifw_binarycreator_exe() const; + const fs::path& get_ifw_repogen_exe() const; /// Retrieve a toolset matching a VS version /// @@ -70,6 +73,9 @@ namespace vcpkg Lazy cmake_exe; Lazy git_exe; Lazy nuget_exe; + Lazy ifw_installerbase_exe; + Lazy ifw_binarycreator_exe; + Lazy ifw_repogen_exe; Lazy> toolsets; }; } diff --git a/toolsrc/include/vcpkg_Commands_Export_IFW.h b/toolsrc/include/vcpkg_Commands_Export_IFW.h index 881bbaf63..c066ca021 100644 --- a/toolsrc/include/vcpkg_Commands_Export_IFW.h +++ b/toolsrc/include/vcpkg_Commands_Export_IFW.h @@ -9,7 +9,9 @@ namespace vcpkg::Commands::Export::IFW { Optional maybe_repository_url; Optional maybe_packages_dir_path; + Optional maybe_repository_dir_path; Optional maybe_config_file_path; + Optional maybe_installer_file_path; }; void do_export(const std::vector &export_plan, const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths); diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 02e238b3f..89435cd38 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -164,6 +164,31 @@ namespace vcpkg return fetch_dependency(scripts_folder, L"git", downloaded_copy, EXPECTED_VERSION); } + static fs::path get_ifw_installerbase_path(const fs::path& downloads_folder, const fs::path& scripts_folder) + { + static constexpr std::array EXPECTED_VERSION = { 3, 1, 81 }; + static const std::wstring VERSION_CHECK_ARGUMENTS = L"--framework-version"; + + const fs::path downloaded_copy = downloads_folder / "QtInstallerFramework-win-x86" / "bin" / "installerbase.exe"; + + std::vector candidate_paths; + candidate_paths.push_back(downloaded_copy); + // TODO: Uncomment later + //const std::vector from_path = Files::find_from_PATH(L"installerbase"); + //candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + //candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe"); + //candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / "QtIFW-3.1.0" / "bin" / "installerbase.exe"); + + const Optional path = + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_dependency(scripts_folder, L"installerbase", downloaded_copy, EXPECTED_VERSION); + } + Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir) { std::error_code ec; @@ -247,6 +272,21 @@ namespace vcpkg return this->nuget_exe.get_lazy([this]() { return get_nuget_path(this->downloads, this->scripts); }); } + const fs::path& VcpkgPaths::get_ifw_installerbase_exe() const + { + return this->ifw_installerbase_exe.get_lazy([this]() { return get_ifw_installerbase_path(this->downloads, this->scripts); }); + } + + const fs::path& VcpkgPaths::get_ifw_binarycreator_exe() const + { + return this->ifw_binarycreator_exe.get_lazy([this]() { return get_ifw_installerbase_exe().parent_path() / "binarycreator.exe"; }); + } + + const fs::path& VcpkgPaths::get_ifw_repogen_exe() const + { + return this->ifw_repogen_exe.get_lazy([this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; }); + } + static std::vector get_vs2017_installation_instances(const VcpkgPaths& paths) { const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index 6632dfe67..3662a46d8 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -249,7 +249,9 @@ namespace vcpkg::Commands::Export static const std::string OPTION_NUGET_VERSION = "--nuget-version"; static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url"; static const std::string OPTION_IFW_PACKAGES_DIR_PATH = "--ifw-packages-directory-path"; + static const std::string OPTION_IFW_REPOSITORY_DIR_PATH = "--ifw-repository-directory-path"; static const std::string OPTION_IFW_CONFIG_FILE_PATH = "--ifw-configuration-file-path"; + static const std::string OPTION_IFW_INSTALLER_FILE_PATH = "--ifw-installer-file-path"; // input sanitization static const std::string EXAMPLE = @@ -276,7 +278,9 @@ namespace vcpkg::Commands::Export OPTION_NUGET_VERSION, OPTION_IFW_REPOSITORY_URL, OPTION_IFW_PACKAGES_DIR_PATH, - OPTION_IFW_CONFIG_FILE_PATH + OPTION_IFW_REPOSITORY_DIR_PATH, + OPTION_IFW_CONFIG_FILE_PATH, + OPTION_IFW_INSTALLER_FILE_PATH }); const bool dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); const bool raw = options.switches.find(OPTION_RAW) != options.switches.cend(); @@ -310,10 +314,18 @@ namespace vcpkg::Commands::Export Checks::check_exit( VCPKG_LINE_INFO, !ifw_options.maybe_packages_dir_path || ifw, "--ifw-packages-directory-path is only valid with --ifw"); + ifw_options.maybe_repository_dir_path = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_DIR_PATH); + Checks::check_exit( + VCPKG_LINE_INFO, !ifw_options.maybe_repository_dir_path || ifw, "--ifw-repository-directory-path is only valid with --ifw"); + ifw_options.maybe_config_file_path = maybe_lookup(options.settings, OPTION_IFW_CONFIG_FILE_PATH); Checks::check_exit( VCPKG_LINE_INFO, !ifw_options.maybe_config_file_path || ifw, "--ifw-configuration-file-path is only valid with --ifw"); + ifw_options.maybe_installer_file_path = maybe_lookup(options.settings, OPTION_IFW_INSTALLER_FILE_PATH); + Checks::check_exit( + VCPKG_LINE_INFO, !ifw_options.maybe_installer_file_path || ifw, "--ifw-installer-file-path is only valid with --ifw"); + // create the plan const StatusParagraphs status_db = database_load_check(paths); std::vector export_plan = Dependencies::create_export_plan(paths, specs, status_db); @@ -464,10 +476,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console { IFW::do_export(export_plan, export_id, ifw_options, paths); - // TODO: Download corrected QtIFW tools and automate installer creation - System::println("Use corrected QtIFW tools (for more info see: https://codereview.qt-project.org/#/c/203958) to create installer..."); - - print_next_step_info("[...]"); + print_next_step_info("@RootDir@/src/vcpkg"); } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index e2499b75d..d1428f5d1 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -26,7 +26,35 @@ namespace vcpkg::Commands::Export::IFW return date_time_as_string; } - fs::path export_real_package(const fs::path& raw_exported_dir_path, + fs::path get_packages_dir_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_packages_dir_path.has_value() ? + fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-packages"); + } + + fs::path get_repository_dir_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_packages_dir_path.has_value() ? + fs::path(ifw_options.maybe_repository_dir_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-repository"); + } + + fs::path get_config_file_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_config_file_path.has_value() ? + fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-configuration.xml"); + } + + fs::path get_installer_file_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_config_file_path.has_value() ? + fs::path(ifw_options.maybe_installer_file_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-installer.exe"); + } + + fs::path export_real_package(const fs::path& ifw_packages_dir_path, const ExportPlanAction& action, Files::Filesystem& fs) { @@ -37,7 +65,7 @@ namespace vcpkg::Commands::Export::IFW // Prepare meta dir const fs::path package_xml_file_path = - raw_exported_dir_path / + ifw_packages_dir_path / Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "meta" / "package.xml"; const fs::path package_xml_dir_path = package_xml_file_path.parent_path(); @@ -47,6 +75,11 @@ namespace vcpkg::Commands::Export::IFW "Could not create directory for package file %s", package_xml_file_path.generic_string()); + auto deps = Strings::join( + ",", binary_paragraph.depends, [](const std::string& dep) { return "packages." + dep + ":"; }); + + if (!deps.empty()) deps = "\n " + deps + ""; + fs.write_contents(package_xml_file_path, Strings::format( R"###( @@ -54,7 +87,7 @@ R"###( %s %s %s - packages.%s:,triplets.%s: + packages.%s:,triplets.%s:%s true )###", @@ -62,10 +95,11 @@ R"###( binary_paragraph.version, create_release_date(), action.spec.name(), - action.spec.triplet().canonical_name())); + action.spec.triplet().canonical_name(), + deps)); // Return dir path for export package data - return raw_exported_dir_path / + return ifw_packages_dir_path / Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "data" / "installed"; } @@ -110,11 +144,6 @@ R"###( "Could not create directory for package file %s", package_xml_file_path.generic_string()); - auto deps = Strings::join( - ",", binary_paragraph.depends, [](const std::string& dep) { return "packages." + dep + ":"; }); - - if (!deps.empty()) deps = "\n " + deps + ""; - fs.write_contents(package_xml_file_path, Strings::format( R"###( @@ -122,14 +151,13 @@ R"###( %s %s %s - %s%s + %s )###", action.spec.name(), binary_paragraph.description, binary_paragraph.version, - create_release_date(), - deps)); + create_release_date())); } } @@ -210,9 +238,7 @@ R"###( std::error_code ec; Files::Filesystem& fs = paths.get_filesystem(); - const fs::path config_xml_file_path = ifw_options.maybe_config_file_path.has_value() ? - fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-configuration") / "config.xml"; + const fs::path config_xml_file_path = get_config_file_path(export_id, ifw_options, paths); fs::path config_xml_dir_path = config_xml_file_path.parent_path(); fs.create_directories(config_xml_dir_path, ec); @@ -243,21 +269,76 @@ R"###( )###", formatted_repo_url)); + } + + void do_repository(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + { + const fs::path& repogen_exe = paths.get_ifw_repogen_exe(); + const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); + const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); + + System::println("Generating repository %s...", repository_dir.generic_string()); - System::println("Created ifw configuration file: %s", config_xml_file_path.generic_string()); + const std::wstring cmd_line = + Strings::wformat(LR"("%s" --packages "%s" "%s" > nul)", + repogen_exe.native(), + packages_dir.native(), + repository_dir.native()); + + const int exit_code = System::cmd_execute_clean(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW repository generating failed"); + + System::println(System::Color::success, "Generating repository %s... done.", repository_dir.generic_string()); + } + + void do_installer(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + { + const fs::path& binarycreator_exe = paths.get_ifw_binarycreator_exe(); + const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); + const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); + const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); + const fs::path installer_file = get_installer_file_path(export_id, ifw_options, paths); + + System::println("Generating installer %s...", installer_file.generic_string()); + + std::wstring cmd_line; + + std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); + if (!ifw_repo_url.empty()) + { + cmd_line = + Strings::wformat(LR"("%s" --online-only --config "%s" --repository "%s" "%s" > nul)", + binarycreator_exe.native(), + config_file.native(), + repository_dir.native(), + installer_file.native()); + } + else + { + cmd_line = + Strings::wformat(LR"("%s" --config "%s" --packages "%s" "%s" > nul)", + binarycreator_exe.native(), + config_file.native(), + packages_dir.native(), + installer_file.native()); + } + + const int exit_code = System::cmd_execute_clean(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW installer generating failed"); + + System::println(System::Color::success, "Generating installer %s... done.", installer_file.generic_string()); } void do_export(const std::vector &export_plan, const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) { - System::println("Creating ifw packages... "); + const fs::path ifw_packages_dir_path = get_packages_dir_path(export_id, ifw_options, paths); + const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); + + System::println("Exporting packages %s... ", ifw_packages_dir_path.generic_string()); std::error_code ec; Files::Filesystem& fs = paths.get_filesystem(); - const fs::path ifw_packages_dir_path = ifw_options.maybe_packages_dir_path.has_value() ? - fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-packages"); - fs.remove_all(ifw_packages_dir_path, ec); Checks::check_exit(VCPKG_LINE_INFO, !ec, @@ -299,9 +380,13 @@ R"###( (binary_paragraph.fullstem() + ".list")); Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); - System::println(System::Color::success, "Exporting package %s... done", display_name); + System::println("Exporting package %s... done", display_name); } + System::println("Exporting packages %s... done", ifw_packages_dir_path.generic_string()); + + System::println("Generating configuration %s...", config_file.generic_string()); + // Unique packages export_unique_packages(ifw_packages_dir_path, unique_packages, fs); @@ -313,9 +398,19 @@ R"###( // Integration export_integration(ifw_packages_dir_path, fs); - System::println("Created ifw packages directory: %s", ifw_packages_dir_path.generic_string()); - // Configuration export_config(export_id, ifw_options, paths); + + System::println("Generating configuration %s... done.", config_file.generic_string()); + + // Do repository (optional) + std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); + if (!ifw_repo_url.empty()) + { + do_repository(export_id, ifw_options, paths); + } + + // Do installer + do_installer(export_id, ifw_options, paths); } } -- cgit v1.2.3 From d25fd5c7b3b0f21581dd9c44a915c9156683877a Mon Sep 17 00:00:00 2001 From: Konstantin Podsvirov Date: Thu, 28 Sep 2017 01:00:40 +0300 Subject: [vcpkg-export-ifw] Some improvements Improvements: - fix typos; - remove outdated repository directory. --- toolsrc/src/commands_export_ifw.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index d1428f5d1..a0692c11e 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -35,7 +35,7 @@ namespace vcpkg::Commands::Export::IFW fs::path get_repository_dir_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) { - return ifw_options.maybe_packages_dir_path.has_value() ? + return ifw_options.maybe_repository_dir_path.has_value() ? fs::path(ifw_options.maybe_repository_dir_path.value_or_exit(VCPKG_LINE_INFO)) : paths.root / (export_id + "-ifw-repository"); } @@ -49,7 +49,7 @@ namespace vcpkg::Commands::Export::IFW fs::path get_installer_file_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) { - return ifw_options.maybe_config_file_path.has_value() ? + return ifw_options.maybe_installer_file_path.has_value() ? fs::path(ifw_options.maybe_installer_file_path.value_or_exit(VCPKG_LINE_INFO)) : paths.root / (export_id + "-ifw-installer.exe"); } @@ -279,6 +279,15 @@ R"###( System::println("Generating repository %s...", repository_dir.generic_string()); + std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + fs.remove_all(repository_dir, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not remove outdated repository directory %s", + repository_dir.generic_string()); + const std::wstring cmd_line = Strings::wformat(LR"("%s" --packages "%s" "%s" > nul)", repogen_exe.native(), -- cgit v1.2.3 From 3035c780b29f88ef177413924921f5adff688fde Mon Sep 17 00:00:00 2001 From: jasjuang Date: Thu, 28 Sep 2017 21:34:08 -0700 Subject: update to 1.2.4 and fix cmake exports --- ports/aws-sdk-cpp/CONTROL | 2 +- ports/aws-sdk-cpp/portfile.cmake | 41 ++++++++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/ports/aws-sdk-cpp/CONTROL b/ports/aws-sdk-cpp/CONTROL index 251e7bdf9..a36263e7a 100644 --- a/ports/aws-sdk-cpp/CONTROL +++ b/ports/aws-sdk-cpp/CONTROL @@ -1,3 +1,3 @@ Source: aws-sdk-cpp -Version: 1.0.61-1 +Version: 1.2.4 Description: AWS SDK for C++ diff --git a/ports/aws-sdk-cpp/portfile.cmake b/ports/aws-sdk-cpp/portfile.cmake index 3a8f9b464..4e0e8bdfe 100644 --- a/ports/aws-sdk-cpp/portfile.cmake +++ b/ports/aws-sdk-cpp/portfile.cmake @@ -1,11 +1,12 @@ include(vcpkg_common_functions) -set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/aws-sdk-cpp-1.0.61) -vcpkg_download_distfile(ARCHIVE - URLS "https://github.com/aws/aws-sdk-cpp/archive/1.0.61.tar.gz" - FILENAME "aws-sdk-cpp-1.0.61.tar.gz" - SHA512 75f3570d8e8c08624b69d8254e156829030a36a7c4aa4b783d895e7c209b2a46b6b9ce822e6d9e9f649b171cf64988f0ad18ce0a55eb39c50d68a7880568078a + +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO aws/aws-sdk-cpp + REF 1.2.4 + SHA512 dc96e40fe72e4b115607245f536cd13414e33a8f754153fd137f1391af14b9793fc8a07f9f984490e0783e385c2c7b9a421878b63ea793012f53fefe7ec4d368 + HEAD_REF master ) -vcpkg_extract_source_archive(${ARCHIVE}) vcpkg_apply_patches( SOURCE_PATH ${SOURCE_PATH} @@ -30,6 +31,34 @@ vcpkg_configure_cmake( vcpkg_install_cmake() +file(GLOB CMAKE_FILES ${CURRENT_PACKAGES_DIR}/lib/cmake/*) + +file(MAKE_DIRECTORY ${CURRENT_PACKAGES_DIR}/share) + +file(COPY ${CMAKE_FILES} DESTINATION ${CURRENT_PACKAGES_DIR}/share) + +vcpkg_copy_pdbs() + +file(GLOB AWS_TARGETS "${CURRENT_PACKAGES_DIR}/share/aws-cpp-sdk-*/aws-cpp-sdk-*targets.cmake") +foreach(AWS_TARGETS ${AWS_TARGETS}) + file(READ ${AWS_TARGETS} _contents) + string(REGEX REPLACE + "get_filename_component\\(_IMPORT_PREFIX \"\\\${CMAKE_CURRENT_LIST_FILE}\" PATH\\)(\nget_filename_component\\(_IMPORT_PREFIX \"\\\${_IMPORT_PREFIX}\" PATH\\))*" + "get_filename_component(_IMPORT_PREFIX \"\${CMAKE_CURRENT_LIST_FILE}\" PATH)\nget_filename_component(_IMPORT_PREFIX \"\${_IMPORT_PREFIX}\" PATH)\nget_filename_component(_IMPORT_PREFIX \"\${_IMPORT_PREFIX}\" PATH)" + _contents "${_contents}") + file(WRITE ${AWS_TARGETS} "${_contents}") +endforeach() + +file(GLOB AWS_TARGETS_RELEASE "${CURRENT_PACKAGES_DIR}/share/aws-cpp-sdk-*/aws-cpp-sdk-*targets-release.cmake") +foreach(AWS_TARGETS_RELEASE ${AWS_TARGETS_RELEASE}) + file(READ ${AWS_TARGETS_RELEASE} _contents) + string(REGEX REPLACE + "bin\\/([A-Za-z0-9_.-]+lib)" + "lib/\\1" + _contents "${_contents}") + file(WRITE ${AWS_TARGETS_RELEASE} "${_contents}") +endforeach() + file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include ${CURRENT_PACKAGES_DIR}/lib/cmake -- cgit v1.2.3 From fcbb90b9a4e06b7c09925c4826f8c46794de3564 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 29 Sep 2017 17:45:41 -0700 Subject: Add winsock2 as a port --- ports/winsock2/CONTROL | 3 +++ ports/winsock2/portfile.cmake | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 ports/winsock2/CONTROL create mode 100644 ports/winsock2/portfile.cmake diff --git a/ports/winsock2/CONTROL b/ports/winsock2/CONTROL new file mode 100644 index 000000000..4b56e50bf --- /dev/null +++ b/ports/winsock2/CONTROL @@ -0,0 +1,3 @@ +Source: winsock2 +Version: 0.0 +Description: Windows Sockets. \ No newline at end of file diff --git a/ports/winsock2/portfile.cmake b/ports/winsock2/portfile.cmake new file mode 100644 index 000000000..81fd38992 --- /dev/null +++ b/ports/winsock2/portfile.cmake @@ -0,0 +1,40 @@ +include(vcpkg_common_functions) + +vcpkg_get_program_files_32_bit(PROGRAM_FILES_32_BIT) +vcpkg_get_windows_sdk(WINDOWS_SDK) + +if (WINDOWS_SDK MATCHES "10.") + set(LIBFILEPATH "${PROGRAM_FILES_32_BIT}\\Windows Kits\\10\\Lib\\${WINDOWS_SDK}\\um\\${TRIPLET_SYSTEM_ARCH}\\Ws2_32.Lib") + set(LICENSEPATH "${PROGRAM_FILES_32_BIT}\\Windows Kits\\10\\Licenses\\${WINDOWS_SDK}\\sdk_license.rtf") + set(HEADERSPATH "${PROGRAM_FILES_32_BIT}\\Windows Kits\\10\\Include\\${WINDOWS_SDK}\\um") +elseif(WINDOWS_SDK MATCHES "8.") + set(LIBFILEPATH "${PROGRAM_FILES_32_BIT}\\Windows Kits\\8.1\\Lib\\winv6.3\\um\\${TRIPLET_SYSTEM_ARCH}\\Ws2_32.Lib") + set(HEADERSPATH "${PROGRAM_FILES_32_BIT}\\Windows Kits\\8.1\\Include\\um") +else() + message(FATAL_ERROR "Portfile not yet configured for Windows SDK with version: ${WINDOWS_SDK}") +endif() + +if (NOT EXISTS "${LIBFILEPATH}") + message(FATAL_ERROR "Cannot find Windows ${WINDOWS_SDK} SDK. File does not exist: ${LIBFILEPATH}") +endif() + +file(MAKE_DIRECTORY + ${CURRENT_PACKAGES_DIR}/include + ${CURRENT_PACKAGES_DIR}/lib + ${CURRENT_PACKAGES_DIR}/debug/lib + ${CURRENT_PACKAGES_DIR}/share/winsock2 +) + +file(COPY + "${HEADERSPATH}\\Winsock2.h" + DESTINATION ${CURRENT_PACKAGES_DIR}/include + ) +file(COPY ${LIBFILEPATH} DESTINATION ${CURRENT_PACKAGES_DIR}/lib) +file(COPY ${LIBFILEPATH} DESTINATION ${CURRENT_PACKAGES_DIR}/debug/lib) + +if (DEFINED LICENSEPATH) + file(COPY ${LICENSEPATH} DESTINATION ${CURRENT_PACKAGES_DIR}/share/winsock2) + file(WRITE ${CURRENT_PACKAGES_DIR}/share/winsock2/copyright "See the accompanying sdk_license.rtf") +else() + file(WRITE ${CURRENT_PACKAGES_DIR}/share/winsock2/copyright "See https://developer.microsoft.com/en-us/windows/downloads/windows-8-1-sdk for the Windows 8.1 SDK license") +endif() \ No newline at end of file -- cgit v1.2.3 From 901014edfce6b7c73f44daad835d8acab85af686 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 29 Sep 2017 17:51:24 -0700 Subject: Add wincrypt as a port --- ports/wincrypt/CONTROL | 3 +++ ports/wincrypt/portfile.cmake | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 ports/wincrypt/CONTROL create mode 100644 ports/wincrypt/portfile.cmake diff --git a/ports/wincrypt/CONTROL b/ports/wincrypt/CONTROL new file mode 100644 index 000000000..78803229c --- /dev/null +++ b/ports/wincrypt/CONTROL @@ -0,0 +1,3 @@ +Source: wincrypt +Version: 0.0 +Description: Windows Cryptography. \ No newline at end of file diff --git a/ports/wincrypt/portfile.cmake b/ports/wincrypt/portfile.cmake new file mode 100644 index 000000000..8ded1cdc4 --- /dev/null +++ b/ports/wincrypt/portfile.cmake @@ -0,0 +1,40 @@ +include(vcpkg_common_functions) + +vcpkg_get_program_files_32_bit(PROGRAM_FILES_32_BIT) +vcpkg_get_windows_sdk(WINDOWS_SDK) + +if (WINDOWS_SDK MATCHES "10.") + set(LIBFILEPATH "${PROGRAM_FILES_32_BIT}\\Windows Kits\\10\\Lib\\${WINDOWS_SDK}\\um\\${TRIPLET_SYSTEM_ARCH}\\Crypt32.Lib") + set(LICENSEPATH "${PROGRAM_FILES_32_BIT}\\Windows Kits\\10\\Licenses\\${WINDOWS_SDK}\\sdk_license.rtf") + set(HEADERSPATH "${PROGRAM_FILES_32_BIT}\\Windows Kits\\10\\Include\\${WINDOWS_SDK}\\um") +elseif(WINDOWS_SDK MATCHES "8.") + set(LIBFILEPATH "${PROGRAM_FILES_32_BIT}\\Windows Kits\\8.1\\Lib\\winv6.3\\um\\${TRIPLET_SYSTEM_ARCH}\\Crypt32.Lib") + set(HEADERSPATH "${PROGRAM_FILES_32_BIT}\\Windows Kits\\8.1\\Include\\um") +else() + message(FATAL_ERROR "Portfile not yet configured for Windows SDK with version: ${WINDOWS_SDK}") +endif() + +if (NOT EXISTS "${LIBFILEPATH}") + message(FATAL_ERROR "Cannot find Windows ${WINDOWS_SDK} SDK. File does not exist: ${LIBFILEPATH}") +endif() + +file(MAKE_DIRECTORY + ${CURRENT_PACKAGES_DIR}/include + ${CURRENT_PACKAGES_DIR}/lib + ${CURRENT_PACKAGES_DIR}/debug/lib + ${CURRENT_PACKAGES_DIR}/share/wincrypt +) + +file(COPY + "${HEADERSPATH}\\Wincrypt.h" + DESTINATION ${CURRENT_PACKAGES_DIR}/include + ) +file(COPY ${LIBFILEPATH} DESTINATION ${CURRENT_PACKAGES_DIR}/lib) +file(COPY ${LIBFILEPATH} DESTINATION ${CURRENT_PACKAGES_DIR}/debug/lib) + +if (DEFINED LICENSEPATH) + file(COPY ${LICENSEPATH} DESTINATION ${CURRENT_PACKAGES_DIR}/share/wincrypt) + file(WRITE ${CURRENT_PACKAGES_DIR}/share/wincrypt/copyright "See the accompanying sdk_license.rtf") +else() + file(WRITE ${CURRENT_PACKAGES_DIR}/share/wincrypt/copyright "See https://developer.microsoft.com/en-us/windows/downloads/windows-8-1-sdk for the Windows 8.1 SDK license") +endif() \ No newline at end of file -- cgit v1.2.3 From b3e06443eab560d5de848f2a066e1baa477fa57b Mon Sep 17 00:00:00 2001 From: Maria Tavlaki Date: Sun, 1 Oct 2017 22:17:33 +0300 Subject: Create stub autocomplete function --- toolsrc/include/vcpkg_Commands.h | 5 +++++ toolsrc/src/commands_autocomplete.cpp | 22 ++++++++++++++++++++++ toolsrc/src/commands_available_commands.cpp | 2 +- toolsrc/vcpkglib/vcpkglib.vcxproj | 1 + toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 3 +++ 5 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 toolsrc/src/commands_autocomplete.cpp diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h index 590f0208c..7cfa2760e 100644 --- a/toolsrc/include/vcpkg_Commands.h +++ b/toolsrc/include/vcpkg_Commands.h @@ -194,6 +194,11 @@ namespace vcpkg::Commands void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } + namespace Autocomplete + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + namespace Help { void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp new file mode 100644 index 000000000..71154445d --- /dev/null +++ b/toolsrc/src/commands_autocomplete.cpp @@ -0,0 +1,22 @@ +#include "pch.h" + +#include "Paragraphs.h" +#include "SortedVector.h" +#include "vcpkg_Commands.h" +#include "vcpkg_Maps.h" +#include "vcpkg_System.h" + +namespace vcpkg::Commands::Autocomplete +{ + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = + Strings::format("The argument should be a command line to autocomplete.\n%s", + Commands::Help::create_example_string("autocomplete install z")); + + args.check_max_arg_count(1, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/commands_available_commands.cpp b/toolsrc/src/commands_available_commands.cpp index 87cc43dca..d3280e6d7 100644 --- a/toolsrc/src/commands_available_commands.cpp +++ b/toolsrc/src/commands_available_commands.cpp @@ -34,7 +34,7 @@ namespace vcpkg::Commands {"import", &Import::perform_and_exit}, {"cache", &Cache::perform_and_exit}, {"portsdiff", &PortsDiff::perform_and_exit}, - }; + {"autocomplete", &Autocomplete::perform_and_exit}}; return t; } diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index edecd7720..0c3c7105d 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -181,6 +181,7 @@ + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 2fbf3d929..668aa48d6 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -180,6 +180,9 @@ Source Files + + Source Files + -- cgit v1.2.3 From fe89e72e9565f0515834b925f015fe19324c38da Mon Sep 17 00:00:00 2001 From: Maria Tavlaki Date: Sun, 1 Oct 2017 23:26:36 +0300 Subject: Autocomplete: handle arguments --- toolsrc/src/commands_autocomplete.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp index 71154445d..a67113aff 100644 --- a/toolsrc/src/commands_autocomplete.cpp +++ b/toolsrc/src/commands_autocomplete.cpp @@ -14,9 +14,34 @@ namespace vcpkg::Commands::Autocomplete Strings::format("The argument should be a command line to autocomplete.\n%s", Commands::Help::create_example_string("autocomplete install z")); - args.check_max_arg_count(1, EXAMPLE); + args.check_min_arg_count(1, EXAMPLE); + args.check_max_arg_count(2, EXAMPLE); args.check_and_get_optional_command_arguments({}); + const std::string requested_command = args.command_arguments.at(0); + const std::string start_with = + args.command_arguments.size() > 1 ? args.command_arguments.at(1) : Strings::EMPTY; + + auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + auto& source_paragraphs = sources_and_errors.paragraphs; + + const auto& istartswith = Strings::case_insensitive_ascii_starts_with; + + std::vector results; + for (const auto& source_control_file : source_paragraphs) + { + auto&& sp = *source_control_file->core_paragraph; + + if (istartswith(sp.name, start_with)) + { + results.push_back(sp.name); + } + } + + System::println(Strings::join(" ", results)); + + auto all_ports = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + Checks::exit_success(VCPKG_LINE_INFO); } } -- cgit v1.2.3 From 7c2239f980197096a13e8fb4b96297b08616eb78 Mon Sep 17 00:00:00 2001 From: Maria Tavlaki Date: Mon, 2 Oct 2017 00:03:39 +0300 Subject: Autocomplete: check if first argument is "install" --- toolsrc/src/commands_autocomplete.cpp | 37 ++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp index a67113aff..013cea320 100644 --- a/toolsrc/src/commands_autocomplete.cpp +++ b/toolsrc/src/commands_autocomplete.cpp @@ -8,6 +8,23 @@ namespace vcpkg::Commands::Autocomplete { + std::vector autocomplete_install( + const std::vector>& source_paragraphs, const std::string& start_with) + { + std::vector results; + const auto& istartswith = Strings::case_insensitive_ascii_starts_with; + + for (const auto& source_control_file : source_paragraphs) + { + auto&& sp = *source_control_file->core_paragraph; + + if (istartswith(sp.name, start_with)) + { + results.push_back(sp.name); + } + } + return results; + } void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { static const std::string EXAMPLE = @@ -21,27 +38,15 @@ namespace vcpkg::Commands::Autocomplete const std::string requested_command = args.command_arguments.at(0); const std::string start_with = args.command_arguments.size() > 1 ? args.command_arguments.at(1) : Strings::EMPTY; - - auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); - auto& source_paragraphs = sources_and_errors.paragraphs; - - const auto& istartswith = Strings::case_insensitive_ascii_starts_with; - std::vector results; - for (const auto& source_control_file : source_paragraphs) + if (requested_command == "install") { - auto&& sp = *source_control_file->core_paragraph; + auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + auto& source_paragraphs = sources_and_errors.paragraphs; - if (istartswith(sp.name, start_with)) - { - results.push_back(sp.name); - } + results = autocomplete_install(source_paragraphs, start_with); } - System::println(Strings::join(" ", results)); - - auto all_ports = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); - Checks::exit_success(VCPKG_LINE_INFO); } } -- cgit v1.2.3 From 016c53e231f353bdfa35f8e265b281e8d56031ed Mon Sep 17 00:00:00 2001 From: Maria Tavlaki Date: Mon, 2 Oct 2017 00:38:53 +0300 Subject: Autocomplete: remove --- toolsrc/src/commands_autocomplete.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp index 013cea320..3963f904b 100644 --- a/toolsrc/src/commands_autocomplete.cpp +++ b/toolsrc/src/commands_autocomplete.cpp @@ -5,6 +5,7 @@ #include "vcpkg_Commands.h" #include "vcpkg_Maps.h" #include "vcpkg_System.h" +#include "vcpkglib.h" namespace vcpkg::Commands::Autocomplete { @@ -25,6 +26,25 @@ namespace vcpkg::Commands::Autocomplete } return results; } + + std::vector autocomplete_remove(std::vector installed_packages, + const std::string& start_with) + { + std::vector results; + const auto& istartswith = Strings::case_insensitive_ascii_starts_with; + + for (const auto& installed_package : installed_packages) + { + auto sp = installed_package->package.displayname(); + + if (istartswith(sp, start_with)) + { + results.push_back(sp); + } + } + return results; + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { static const std::string EXAMPLE = @@ -46,6 +66,13 @@ namespace vcpkg::Commands::Autocomplete results = autocomplete_install(source_paragraphs, start_with); } + else if (requested_command == "remove") + { + const StatusParagraphs status_db = database_load_check(paths); + std::vector installed_packages = get_installed_ports(status_db); + results = autocomplete_remove(installed_packages, start_with); + } + System::println(Strings::join(" ", results)); Checks::exit_success(VCPKG_LINE_INFO); } -- cgit v1.2.3 From 4e6801093986e53d2e88cc02a8875585e4e418b0 Mon Sep 17 00:00:00 2001 From: Tsukasa Sugiura Date: Tue, 3 Oct 2017 22:31:21 +0900 Subject: Extract WiX installer using Dark Extract WiX installer using Dark. It will be standalone extract files from installer of Kinect SDK 2.x even if Kinect SDK 2.x is not installed in user system. --- ports/kinectsdk2/portfile.cmake | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/ports/kinectsdk2/portfile.cmake b/ports/kinectsdk2/portfile.cmake index 5795825dd..05aa1fd2e 100644 --- a/ports/kinectsdk2/portfile.cmake +++ b/ports/kinectsdk2/portfile.cmake @@ -16,10 +16,35 @@ if(VCPKG_TARGET_ARCHITECTURE STREQUAL "arm") message(FATAL_ERROR "This port does not currently support architecture: ${VCPKG_TARGET_ARCHITECTURE}") endif() -get_filename_component(KINECTSDK20_DIR "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Kinect\\v2.0;SDKInstallPath]" ABSOLUTE CACHE) -if(NOT EXISTS "${KINECTSDK20_DIR}") - message(FATAL_ERROR "Error: Could not find Kinect for Windows SDK v2.x. It can be downloaded from https://www.microsoft.com/en-us/download/details.aspx?id=44561.") -endif() +set(KINECTSDK20_VERSION "v2.0_1409") +vcpkg_download_distfile(KINECTSDK20_INSTALLER + URLS "https://download.microsoft.com/download/F/2/D/F2D1012E-3BC6-49C5-B8B3-5ACFF58AF7B8/KinectSDK-${KINECTSDK20_VERSION}-Setup.exe" + FILENAME "KinectSDK-${KINECTSDK20_VERSION}-Setup.exe" + SHA512 ae3b00f45282ab2ed6ea36c09e42e1b274074f41546ecfbe00facf1fffa2e5a762ffeffb9ba2194f716e8122e0fbd9a8ef63c62be68d2b50a40e4f8c5a821f5f +) + +vcpkg_find_acquire_program(DARK) + +set(KINECTSDK20_WIX_INSTALLER "${KINECTSDK20_INSTALLER}") +set(KINECTSDK20_WIX_EXTRACT_DIR "${CURRENT_BUILDTREES_DIR}/src/installer/wix") +vcpkg_execute_required_process( + COMMAND ${DARK} -x ${KINECTSDK20_WIX_EXTRACT_DIR} ${KINECTSDK20_WIX_INSTALLER} + WORKING_DIRECTORY ${CURRENT_BUILDTREES_DIR} + LOGNAME extract_wix_installer +) + +file(TO_NATIVE_PATH "${KINECTSDK20_WIX_EXTRACT_DIR}/AttachedContainer/KinectSDK-${KINECTSDK20_VERSION}-x64.msi" KINECTSDK20_MSI_INSTALLER) +file(TO_NATIVE_PATH "${CURRENT_BUILDTREES_DIR}/src/installer/msi" KINECTSDK20_MSI_EXTRACT_DIR) +file(TO_NATIVE_PATH "${CURRENT_BUILDTREES_DIR}/msiexec.log" MSIEXEC_LOG_PATH) +set(BATCH_FILE ${CURRENT_BUILDTREES_DIR}/msiextract-msmpi.bat) +file(WRITE ${BATCH_FILE} "msiexec.exe /a \"${KINECTSDK20_MSI_INSTALLER}\" /qn /log \"${MSIEXEC_LOG_PATH}\" TARGETDIR=\"${KINECTSDK20_MSI_EXTRACT_DIR}\"") +vcpkg_execute_required_process( + COMMAND ${BATCH_FILE} + WORKING_DIRECTORY ${CURRENT_BUILDTREES_DIR} + LOGNAME extract_msi_installer +) + +set(KINECTSDK20_DIR "${CURRENT_BUILDTREES_DIR}/src/installer/msi/Microsoft SDKs/Kinect/${KINECTSDK20_VERSION}") file( INSTALL -- cgit v1.2.3 From 322e9254c1c4362ea30e1106fb44c087cbbe62e8 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Tue, 3 Oct 2017 17:03:17 -0700 Subject: [gtest] Silence TR1 deprecation warning --- ports/gtest/portfile.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ports/gtest/portfile.cmake b/ports/gtest/portfile.cmake index 0bfe4e60c..333dc8ae3 100644 --- a/ports/gtest/portfile.cmake +++ b/ports/gtest/portfile.cmake @@ -28,6 +28,8 @@ vcpkg_configure_cmake( OPTIONS -Dgtest_force_shared_crt=${gtest_force_shared_crt} ) +set(ENV{_CL_} "/D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING") + vcpkg_install_cmake() file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include) -- cgit v1.2.3 From 0ba3c166d76a4484fd4d378dc7367f2794577a20 Mon Sep 17 00:00:00 2001 From: Jens Frederich Date: Wed, 4 Oct 2017 08:19:57 +0200 Subject: Get proxy credentials behind web proxy --- scripts/bootstrap.ps1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/bootstrap.ps1 b/scripts/bootstrap.ps1 index b7bc5afab..fa51de404 100644 --- a/scripts/bootstrap.ps1 +++ b/scripts/bootstrap.ps1 @@ -4,6 +4,10 @@ param( [string]$disableMetrics = "0" ) +$webclient=New-Object System.Net.WebClient +$creds=Get-Credential +$webclient.Proxy.Credentials=$creds + $scriptsDir = split-path -parent $MyInvocation.MyCommand.Definition $vcpkgRootDir = & $scriptsDir\findFileRecursivelyUp.ps1 $scriptsDir .vcpkg-root -- cgit v1.2.3 From bf84f929d818c21d004b6f8a67a926adce9f4d87 Mon Sep 17 00:00:00 2001 From: atkawa7 Date: Wed, 4 Oct 2017 05:36:30 -0700 Subject: [geos] remove build_cmake --- ports/geos/portfile.cmake | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ports/geos/portfile.cmake b/ports/geos/portfile.cmake index ec88a0f57..68b4ab9f7 100644 --- a/ports/geos/portfile.cmake +++ b/ports/geos/portfile.cmake @@ -33,8 +33,6 @@ vcpkg_configure_cmake( SOURCE_PATH ${SOURCE_PATH} OPTIONS -DGEOS_ENABLE_TESTS=False ) - -vcpkg_build_cmake() vcpkg_install_cmake() file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include) # Handle copyright @@ -49,4 +47,4 @@ else() endif() -vcpkg_copy_pdbs() \ No newline at end of file +vcpkg_copy_pdbs() -- cgit v1.2.3 From 66fdeb47760420f2de14d2fbcb72d44afc8c3f83 Mon Sep 17 00:00:00 2001 From: atkawa7 Date: Wed, 4 Oct 2017 05:39:16 -0700 Subject: [geos] bump version --- ports/geos/CONTROL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/geos/CONTROL b/ports/geos/CONTROL index 3d2ed4565..2b192d088 100644 --- a/ports/geos/CONTROL +++ b/ports/geos/CONTROL @@ -1,3 +1,3 @@ Source: geos -Version: 3.6.2-1 +Version: 3.6.2-2 Description: Geometry Engine Open Source -- cgit v1.2.3 From c6ac9bd7f0bb229ec1107ad45ecae9cfbdb048d5 Mon Sep 17 00:00:00 2001 From: alex85k Date: Wed, 4 Oct 2017 20:34:13 +0500 Subject: [spatialite-tools] initial port (spatialite.exe and other tools) --- ports/spatialite-tools/CONTROL | 4 + ports/spatialite-tools/fix-makefiles.patch | 128 +++++++++++++++++++++++++++++ ports/spatialite-tools/portfile.cmake | 118 ++++++++++++++++++++++++++ 3 files changed, 250 insertions(+) create mode 100644 ports/spatialite-tools/CONTROL create mode 100644 ports/spatialite-tools/fix-makefiles.patch create mode 100644 ports/spatialite-tools/portfile.cmake diff --git a/ports/spatialite-tools/CONTROL b/ports/spatialite-tools/CONTROL new file mode 100644 index 000000000..ecbf681c6 --- /dev/null +++ b/ports/spatialite-tools/CONTROL @@ -0,0 +1,4 @@ +Source: spatialite-tools +Version: 4.3.0 +Description: Contains spatialite.exe and other command line tools to work with SpatiaLite databases (import, export, SQL queries) +Build-Depends: sqlite3, libspatialite, geos, readosm, proj4, zlib, libiconv, expat diff --git a/ports/spatialite-tools/fix-makefiles.patch b/ports/spatialite-tools/fix-makefiles.patch new file mode 100644 index 000000000..ff6e0ad0d --- /dev/null +++ b/ports/spatialite-tools/fix-makefiles.patch @@ -0,0 +1,128 @@ +diff --git a/makefile.vc b/makefile.vc +index 33c85d2..c811e7d 100644 +--- a/makefile.vc ++++ b/makefile.vc +@@ -15,7 +15,7 @@ SPATIALITE_OSM_RAW_EXE = spatialite_osm_raw.exe + SPATIALITE_OSM_FILTER_EXE = spatialite_osm_filter.exe + SPATIALITE_GML_EXE = spatialite_gml.exe + +-CFLAGS = /nologo -IC:\OSGeo4W\include $(OPTFLAGS) ++CFLAGS = /nologo -I$(INSTALLED_ROOT)\include $(OPTFLAGS) + + default: all + +@@ -26,89 +26,58 @@ all: $(SPATIALITE_EXE) $(SHP_DOCTOR_EXE) $(SPATIALITE_TOOL_EXE) \ + $(SPATIALITE_OSM_FILTER_EXE) + + $(SPATIALITE_EXE): shell.obj +- cl shell.obj C:\OSGeo4W\lib\proj_i.lib \ +- C:\OSGeo4W\lib\iconv.lib C:\OSGeo4W\lib\geos_c.lib \ +- C:\OSGeo4W\lib\spatialite_i.lib C:\OSGeo4W\lib\sqlite3_i.lib \ +- /Fe$(SPATIALITE_EXE) ++ cl shell.obj $(LIBS_ALL) /Fe$(SPATIALITE_EXE) + if exist $(SPATIALITE_EXE).manifest mt -manifest \ + $(SPATIALITE_EXE).manifest -outputresource:$(SPATIALITE_EXE);1 + + $(EXIF_LOADER_EXE): exif_loader.obj +- cl exif_loader.obj C:\OSGeo4W\lib\proj_i.lib \ +- C:\OSGeo4W\lib\iconv.lib C:\OSGeo4W\lib\geos_c.lib \ +- C:\OSGeo4W\lib\spatialite_i.lib C:\OSGeo4W\lib\sqlite3_i.lib ++ cl exif_loader.obj $(LIBS_ALL) + if exist $(EXIF_LOADER_EXE).manifest mt -manifest \ + $(EXIF_LOADER_EXE).manifest -outputresource:$(EXIF_LOADER_EXE);1 + + $(SHP_DOCTOR_EXE): shp_doctor.obj +- cl shp_doctor.obj C:\OSGeo4W\lib\proj_i.lib \ +- C:\OSGeo4W\lib\iconv.lib C:\OSGeo4W\lib\geos_c.lib \ +- C:\OSGeo4W\lib\spatialite_i.lib C:\OSGeo4W\lib\sqlite3_i.lib ++ cl shp_doctor.obj $(LIBS_ALL) + if exist $(SHP_DOCTOR_EXE).manifest mt -manifest \ + $(SHP_DOCTOR_EXE).manifest -outputresource:$(SHP_DOCTOR_EXE);1 + + $(SPATIALITE_NETWORK_EXE): spatialite_network.obj +- cl spatialite_network.obj C:\OSGeo4W\lib\proj_i.lib \ +- C:\OSGeo4W\lib\iconv.lib \ +- C:\OSGeo4W\lib\spatialite_i.lib C:\OSGeo4W\lib\sqlite3_i.lib ++ cl spatialite_network.obj $(LIBS_ALL) + if exist $(SPATIALITE_NETWORK_EXE).manifest mt -manifest \ + $(SPATIALITE_TOOL_EXE).manifest \ + -outputresource:$(SPATIALITE_TOOL_EXE);1 + + $(SPATIALITE_TOOL_EXE): spatialite_tool.obj +- cl spatialite_tool.obj C:\OSGeo4W\lib\proj_i.lib \ +- C:\OSGeo4W\lib\iconv.lib C:\OSGeo4W\lib\geos_c.lib \ +- C:\OSGeo4W\lib\spatialite_i.lib C:\OSGeo4W\lib\sqlite3_i.lib ++ cl spatialite_tool.obj $(LIBS_ALL) + if exist $(SPATIALITE_TOOL_EXE).manifest mt -manifest \ + $(SPATIALITE_TOOL_EXE).manifest \ + -outputresource:$(SPATIALITE_TOOL_EXE);1 + + $(SPATIALITE_OSM_NET_EXE): spatialite_osm_net.obj +- cl spatialite_osm_net.obj C:\OSGeo4W\lib\proj_i.lib \ +- C:\OSGeo4W\lib\iconv.lib \ +- C:\OSGeo4W\lib\readosm_i.lib \ +- C:\OSGeo4W\lib\libexpat.lib \ +- C:\OSGeo4W\lib\zlib.lib \ +- C:\OSGeo4W\lib\spatialite_i.lib C:\OSGeo4W\lib\sqlite3_i.lib ++ cl spatialite_osm_net.obj $(LIBS_ALL) + if exist $(SPATIALITE_OSM_EXE).manifest mt -manifest \ + $(SPATIALITE_OSM_EXE).manifest \ + -outputresource:$(SPATIALITE_OSM_NET_EXE);1 + + $(SPATIALITE_OSM_MAP_EXE): spatialite_osm_map.obj +- cl spatialite_osm_map.obj C:\OSGeo4W\lib\proj_i.lib \ +- C:\OSGeo4W\lib\iconv.lib \ +- C:\OSGeo4W\lib\readosm_i.lib \ +- C:\OSGeo4W\lib\libexpat.lib \ +- C:\OSGeo4W\lib\zlib.lib \ +- C:\OSGeo4W\lib\spatialite_i.lib C:\OSGeo4W\lib\sqlite3_i.lib ++ cl spatialite_osm_map.obj $(LIBS_ALL) + if exist $(SPATIALITE_OSM_MAP_EXE).manifest mt -manifest \ + $(SPATIALITE_OSM_MAP_EXE).manifest \ + -outputresource:$(SPATIALITE_OSM_MAP_EXE);1 + + $(SPATIALITE_GML_EXE): spatialite_gml.obj +- cl spatialite_gml.obj C:\OSGeo4W\lib\proj_i.lib \ +- C:\OSGeo4W\lib\iconv.lib \ +- C:\OSGeo4W\lib\libexpat.lib \ +- C:\OSGeo4W\lib\spatialite_i.lib C:\OSGeo4W\lib\sqlite3_i.lib ++ cl spatialite_gml.obj $(LIBS_ALL) + if exist $(SPATIALITE_GML_EXE).manifest mt -manifest \ + $(SPATIALITE_GML_EXE).manifest \ + -outputresource:$(SPATIALITE_GML_EXE);1 + + $(SPATIALITE_OSM_RAW_EXE): spatialite_osm_raw.obj +- cl spatialite_osm_raw.obj C:\OSGeo4W\lib\proj_i.lib \ +- C:\OSGeo4W\lib\iconv.lib \ +- C:\OSGeo4W\lib\readosm_i.lib \ +- C:\OSGeo4W\lib\libexpat.lib \ +- C:\OSGeo4W\lib\zlib.lib \ +- C:\OSGeo4W\lib\spatialite_i.lib C:\OSGeo4W\lib\sqlite3_i.lib ++ cl spatialite_osm_raw.obj $(LIBS_ALL) + if exist $(SPATIALITE_OSM_RAW_EXE).manifest mt -manifest \ + $(SPATIALITE_OSM_RAW_EXE).manifest \ + -outputresource:$(SPATIALITE_OSM_RAW_EXE);1 + + $(SPATIALITE_OSM_FILTER_EXE): spatialite_osm_filter.obj +- cl spatialite_osm_filter.obj C:\OSGeo4W\lib\proj_i.lib \ +- C:\OSGeo4W\lib\iconv.lib \ +- C:\OSGeo4W\lib\spatialite_i.lib C:\OSGeo4W\lib\sqlite3_i.lib ++ cl spatialite_osm_filter.obj $(LIBS_ALL) + if exist $(SPATIALITE_OSM_FILTER_EXE).manifest mt -manifest \ + $(SPATIALITE_OSM_FILTER_EXE).manifest \ + -outputresource:$(SPATIALITE_OSM_FILTER_EXE);1 +diff --git a/nmake.opt b/nmake.opt +index 4f4a953..d9efecf 100644 +--- a/nmake.opt ++++ b/nmake.opt +@@ -1,8 +1,8 @@ + # Directory tree where SpatiaLite will be installed. +-INSTDIR=C:\OSGeo4W ++INSTDIR=$(INST_DIR) + + # Uncomment the first for an optimized build, or the second for debug. +-OPTFLAGS= /nologo /Ox /fp:precise /W3 /MD /D_CRT_SECURE_NO_WARNINGS \ ++OPTFLAGS= /nologo /fp:precise /W3 $(CL_FLAGS) /D_CRT_SECURE_NO_WARNINGS \ + /D_LARGE_FILE=1 /D_FILE_OFFSET_BITS=64 /D_LARGEFILE_SOURCE=1 + #OPTFLAGS= /nologo /Zi /MD /Fdspatialite.pdb + diff --git a/ports/spatialite-tools/portfile.cmake b/ports/spatialite-tools/portfile.cmake new file mode 100644 index 000000000..f42227a12 --- /dev/null +++ b/ports/spatialite-tools/portfile.cmake @@ -0,0 +1,118 @@ +include(vcpkg_common_functions) + +option(BUILD_DEBUG_TOOLS "Build debug version of tools" OFF) + +set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/spatialite-tools-4.3.0) +vcpkg_download_distfile(ARCHIVE + URLS "http://www.gaia-gis.it/gaia-sins/spatialite-tools-4.3.0.tar.gz" + FILENAME "spatialite-tools-4.3.0.tar.gz" + SHA512 e1de27c1c65ff2ff0b08583113517bea74edf33fff59ad6e9c77492ea3ae87d9c0f17d7670ee6602b32eea73ad3678bb5410ef2c6fac6e213bf2e341a907db88 +) +vcpkg_extract_source_archive(${ARCHIVE}) + +find_program(NMAKE nmake) + +vcpkg_apply_patches( + SOURCE_PATH ${SOURCE_PATH} + PATCHES ${CMAKE_CURRENT_LIST_DIR}/fix-makefiles.patch +) + +set(LDIR "\"${CURRENT_INSTALLED_DIR}\"") + +if(VCPKG_CRT_LINKAGE STREQUAL dynamic) + set(CL_FLAGS_DBG "/MDd /Zi") + set(CL_FLAGS_REL "/MD /Ox") + set(GEOS_LIBS_REL "${LDIR}/lib/geos_c.lib") + set(GEOS_LIBS_DBG "${LDIR}/debug/lib/geos_c.lib") + set(LIBXML2_LIBS_REL "${LDIR}/lib/libxml2.lib") + set(LIBXML2_LIBS_DBG "${LDIR}/debug/lib/libxml2.lib") + set(SPATIALITE_LIBS_REL "${LDIR}/lib/spatialite.lib") + set(SPATIALITE_LIBS_DBG "${LDIR}/debug/lib/spatialite.lib") + set(ICONV_LIBS_REL "${LDIR}/lib/libiconv.lib") + set(ICONV_LIBS_DBG "${LDIR}/debug/lib/libiconv.lib") +else() + set(CL_FLAGS_DBG "/MTd /Zi") + set(CL_FLAGS_REL "/MT /Ox") + set(GEOS_LIBS_REL "${LDIR}/lib/libgeos_c.lib ${LDIR}/lib/libgeos.lib") + set(GEOS_LIBS_DBG "${LDIR}/debug/lib/libgeos_c.lib ${LDIR}/debug/lib/libgeos.lib") + set(LIBXML2_LIBS_REL "${LDIR}/lib/libxml2.lib ${LDIR}/lib/lzma.lib ws2_32.lib") + set(LIBXML2_LIBS_DBG "${LDIR}/debug/lib/libxml2.lib ${LDIR}/debug/lib/lzma.lib ws2_32.lib") + set(SPATIALITE_LIBS_REL "${LDIR}/lib/spatialite.lib ${LDIR}/lib/freexl.lib") + set(SPATIALITE_LIBS_DBG "${LDIR}/debug/lib/spatialite.lib ${LDIR}/debug/lib/freexl.lib") + set(ICONV_LIBS_REL "${LDIR}/lib/libiconv.lib ${LDIR}/lib/libcharset.lib") + set(ICONV_LIBS_DBG "${LDIR}/debug/lib/libiconv.lib ${LDIR}/debug/lib/libcharset.lib ") +endif() + +set(LIBS_ALL_DBG + "${ICONV_LIBS_DBG} \ + ${LDIR}/debug/lib/sqlite3.lib \ + ${SPATIALITE_LIBS_DBG} \ + ${LIBXML2_LIBS_DBG} \ + ${GEOS_LIBS_DBG} \ + ${LDIR}/debug/lib/readosm.lib \ + ${LDIR}/debug/lib/expat.lib \ + ${LDIR}/debug/lib/zlibd.lib \ + ${LDIR}/debug/lib/projd.lib" + ) +set(LIBS_ALL_REL + "${ICONV_LIBS_REL} \ + ${LDIR}/lib/sqlite3.lib \ + ${SPATIALITE_LIBS_REL} \ + ${LIBXML2_LIBS_REL} \ + ${GEOS_LIBS_REL} \ + ${LDIR}/lib/readosm.lib \ + ${LDIR}/lib/expat.lib \ + ${LDIR}/lib/zlib.lib \ + ${LDIR}/lib/proj.lib" + ) + +if(BUILD_DEBUG_TOOLS) + ################ + # Debug build + ################ + message(STATUS "Building ${TARGET_TRIPLET}-dgb") + + file(TO_NATIVE_PATH "${CURRENT_PACKAGES_DIR}" INST_DIR_REL) + vcpkg_execute_required_process( + COMMAND ${NMAKE} -f makefile.vc clean install + "INST_DIR=\"${INST_DIR_REL}\"" "INSTALLED_ROOT=${LDIR}" "CL_FLAGS=${CL_FLAGS_DBG}" "LIBS_ALL=${LIBS_ALL_DBG}" + WORKING_DIRECTORY ${SOURCE_PATH} + LOGNAME nmake-build-${TARGET_TRIPLET}-debug + ) + message(STATUS "Building ${TARGET_TRIPLET}-dbg done") + set(EXE_FOLDER ${CURRENT_PACKAGES_DIR}/bin/) +else() + ################ + # Release build + ################ + message(STATUS "Building ${TARGET_TRIPLET}-rel") + + file(TO_NATIVE_PATH "${CURRENT_PACKAGES_DIR}" INST_DIR_REL) + vcpkg_execute_required_process( + COMMAND ${NMAKE} -f makefile.vc clean install + "INST_DIR=\"${INST_DIR_REL}\"" "INSTALLED_ROOT=${LDIR}" "CL_FLAGS=${CL_FLAGS_REL}" "LIBS_ALL=${LIBS_ALL_REL}" + WORKING_DIRECTORY ${SOURCE_PATH} + LOGNAME nmake-build-${TARGET_TRIPLET}-release + ) + message(STATUS "Building ${TARGET_TRIPLET}-rel done") + set(EXE_FOLDER ${CURRENT_PACKAGES_DIR}/bin/) +endif() + +file(INSTALL ${SOURCE_PATH}/COPYING DESTINATION ${CURRENT_PACKAGES_DIR}/share/${PORT} RENAME copyright) + +file(MAKE_DIRECTORY ${CURRENT_PACKAGES_DIR}/tools/${PORT}/) +file(GLOB EXES "${EXE_FOLDER}/*.exe") +file(COPY ${EXES} DESTINATION ${CURRENT_PACKAGES_DIR}/tools/${PORT}) +file(REMOVE ${EXES}) + +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/bin) +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/include) + +if(NOT BUILD_DEBUG_TOOLS AND VCPKG_CRT_LINKAGE STREQUAL dynamic) + vcpkg_copy_tool_dependencies(${CURRENT_PACKAGES_DIR}/tools/${PORT}) +endif() + +message(STATUS "Packaging ${TARGET_TRIPLET} done") + +# Allow empty include directory +set(VCPKG_POLICY_EMPTY_INCLUDE_FOLDER enabled) -- cgit v1.2.3 From 81a72bbfbb23ff4a95366cfc486ca4db0035d7a3 Mon Sep 17 00:00:00 2001 From: Tsukasa Sugiura Date: Thu, 5 Oct 2017 00:50:13 +0900 Subject: Extract WiX installer using Dark Extract WiX installer using Dark. It will be standalone extract files from installer of Kinect SDK 1.x even if Kinect SDK 1.x is not installed in user system. --- ports/kinectsdk1/CONTROL | 2 +- ports/kinectsdk1/portfile.cmake | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/ports/kinectsdk1/CONTROL b/ports/kinectsdk1/CONTROL index 3d4c83fd2..9764fb69a 100644 --- a/ports/kinectsdk1/CONTROL +++ b/ports/kinectsdk1/CONTROL @@ -1,3 +1,3 @@ Source: kinectsdk1 -Version: 1.8-1 +Version: 1.8-2 Description: Kinect for Windows SDK for Kinect v1 sensor. diff --git a/ports/kinectsdk1/portfile.cmake b/ports/kinectsdk1/portfile.cmake index aef4cd1c2..5aec50119 100644 --- a/ports/kinectsdk1/portfile.cmake +++ b/ports/kinectsdk1/portfile.cmake @@ -1,10 +1,39 @@ include(vcpkg_common_functions) -get_filename_component(KINECTSDK10_DIR "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Kinect;SDKInstallPath]" ABSOLUTE CACHE) -if(NOT EXISTS "${KINECTSDK10_DIR}") - message(FATAL_ERROR "Error: Could not find Kinect for Windows SDK v1.x. It can be downloaded from https://www.microsoft.com/en-us/download/details.aspx?id=40278.") +if(VCPKG_TARGET_ARCHITECTURE STREQUAL "arm") + message(FATAL_ERROR "This port does not currently support architecture: ${VCPKG_TARGET_ARCHITECTURE}") endif() +set(KINECTSDK10_VERSION "v1.8") +vcpkg_download_distfile(KINECTSDK10_INSTALLER + URLS "https://download.microsoft.com/download/E/1/D/E1DEC243-0389-4A23-87BF-F47DE869FC1A/KinectSDK-${KINECTSDK10_VERSION}-Setup.exe" + FILENAME "KinectSDK-${KINECTSDK10_VERSION}-Setup.exe" + SHA512 ee8a0f70c86aad80fe214108e315e4550a90ed39f278ce00a7137532174ee5bf3bdeb1d0b499fc5ffdb5e176adecfd68963ee3731e1d2f00d69d32d1b8a3c555 +) + +vcpkg_find_acquire_program(DARK) + +set(KINECTSDK10_WIX_INSTALLER "${KINECTSDK10_INSTALLER}") +set(KINECTSDK10_WIX_EXTRACT_DIR "${CURRENT_BUILDTREES_DIR}/src/installer/wix") +vcpkg_execute_required_process( + COMMAND ${DARK} -x ${KINECTSDK10_WIX_EXTRACT_DIR} ${KINECTSDK10_WIX_INSTALLER} + WORKING_DIRECTORY ${CURRENT_BUILDTREES_DIR} + LOGNAME extract_wix_installer +) + +file(TO_NATIVE_PATH "${KINECTSDK10_WIX_EXTRACT_DIR}/AttachedContainer/KinectSDK-${KINECTSDK10_VERSION}-${VCPKG_TARGET_ARCHITECTURE}.msi" KINECTSDK10_MSI_INSTALLER) +file(TO_NATIVE_PATH "${CURRENT_BUILDTREES_DIR}/src/installer/msi/${VCPKG_TARGET_ARCHITECTURE}" KINECTSDK10_MSI_EXTRACT_DIR) +file(TO_NATIVE_PATH "${CURRENT_BUILDTREES_DIR}/msiexec.log" MSIEXEC_LOG_PATH) +set(BATCH_FILE ${CURRENT_BUILDTREES_DIR}/msiextract-msmpi.bat) +file(WRITE ${BATCH_FILE} "msiexec.exe /a \"${KINECTSDK10_MSI_INSTALLER}\" /qn /log \"${MSIEXEC_LOG_PATH}\" TARGETDIR=\"${KINECTSDK10_MSI_EXTRACT_DIR}\"") +vcpkg_execute_required_process( + COMMAND ${BATCH_FILE} + WORKING_DIRECTORY ${CURRENT_BUILDTREES_DIR} + LOGNAME extract_msi_installer_${VCPKG_TARGET_ARCHITECTURE} +) + +set(KINECTSDK10_DIR "${CURRENT_BUILDTREES_DIR}/src/installer/msi/${VCPKG_TARGET_ARCHITECTURE}/Microsoft SDKs/Kinect/${KINECTSDK10_VERSION}") + file( INSTALL "${KINECTSDK10_DIR}/inc/NuiApi.h" -- cgit v1.2.3 From 6f0f196a1a675823de3dae25bdc46978b29dcd68 Mon Sep 17 00:00:00 2001 From: Tsukasa Sugiura Date: Thu, 5 Oct 2017 01:02:36 +0900 Subject: Change to refer Kinect SDK 1.x that installed using vcpkg port Fix according to changes of Kinect SDK 1.x port. Change to refer Kinect SDK 1.x that installed using vcpkg port. It will be always generate the Kinect SDK 1.x driver, even when Kinect SDK 1.x is not installed in user system. --- ports/openni2/CONTROL | 3 +- ports/openni2/portfile.cmake | 47 +++------------------- .../openni2/replace_environment_variable.patch.in | 16 ++++---- ports/openni2/upgrade_projects.patch | 11 ++++- 4 files changed, 25 insertions(+), 52 deletions(-) diff --git a/ports/openni2/CONTROL b/ports/openni2/CONTROL index 2f0e010e0..72de4e877 100644 --- a/ports/openni2/CONTROL +++ b/ports/openni2/CONTROL @@ -1,3 +1,4 @@ Source: openni2 -Version: 2.2.0.33-1 +Version: 2.2.0.33-2 +Build-Depends: kinectsdk1 Description: OpenNI is open source library for access to Natural Interaction (NI) devices such as RGB-D camera. diff --git a/ports/openni2/portfile.cmake b/ports/openni2/portfile.cmake index 7c15b40ec..2e91bac3f 100644 --- a/ports/openni2/portfile.cmake +++ b/ports/openni2/portfile.cmake @@ -36,13 +36,7 @@ vcpkg_download_distfile(ARCHIVE ) vcpkg_extract_source_archive(${ARCHIVE}) -get_filename_component(KINECTSDK10_DIR "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Kinect;SDKInstallPath]" ABSOLUTE CACHE) -set(KINECTSDK10_INSTALLED FALSE) -if(EXISTS "${KINECTSDK10_DIR}") - set(KINECTSDK10_INSTALLED TRUE) -endif() - -file(TO_NATIVE_PATH ${KINECTSDK10_DIR} KINECTSDK10_DIR) +file(TO_NATIVE_PATH ${VCPKG_ROOT_DIR} NATIVE_VCPKG_ROOT_DIR) configure_file("${CMAKE_CURRENT_LIST_DIR}/replace_environment_variable.patch.in" "${CMAKE_CURRENT_LIST_DIR}/replace_environment_variable.patch" @ONLY) vcpkg_apply_patches( @@ -52,13 +46,6 @@ vcpkg_apply_patches( "${CMAKE_CURRENT_LIST_DIR}/replace_environment_variable.patch" ) -if(NOT ${KINECTSDK10_INSTALLED}) - vcpkg_apply_patches( - SOURCE_PATH ${SOURCE_PATH} - PATCHES "${CMAKE_CURRENT_LIST_DIR}/disable_kinect.patch" - ) -endif() - # Build OpenNI2 vcpkg_build_msbuild( PROJECT_PATH "${SOURCE_PATH}/OpenNI.sln" @@ -154,6 +141,7 @@ file( file( INSTALL + "${SOURCE_BIN_PATH_RELEASE}/OpenNI2/Drivers/Kinect.dll" "${SOURCE_BIN_PATH_RELEASE}/OpenNI2/Drivers/OniFile.dll" "${SOURCE_BIN_PATH_RELEASE}/OpenNI2/Drivers/PS1080.dll" "${SOURCE_CONFIG_PATH}/OpenNI2/Drivers/PS1080.ini" @@ -163,15 +151,6 @@ file( ${CURRENT_PACKAGES_DIR}/bin/OpenNI2/Drivers ) -if(${KINECTSDK10_INSTALLED}) - file( - INSTALL - "${SOURCE_BIN_PATH_RELEASE}/OpenNI2/Drivers/Kinect.dll" - DESTINATION - ${CURRENT_PACKAGES_DIR}/bin/OpenNI2/Drivers - ) -endif() - file( INSTALL "${SOURCE_CONFIG_PATH}/OpenNI.ini" @@ -182,6 +161,7 @@ file( file( INSTALL + "${SOURCE_BIN_PATH_DEBUG}/OpenNI2/Drivers/Kinect.dll" "${SOURCE_BIN_PATH_DEBUG}/OpenNI2/Drivers/OniFile.dll" "${SOURCE_BIN_PATH_DEBUG}/OpenNI2/Drivers/PS1080.dll" "${SOURCE_CONFIG_PATH}/OpenNI2/Drivers/PS1080.ini" @@ -191,15 +171,6 @@ file( ${CURRENT_PACKAGES_DIR}/debug/bin/OpenNI2/Drivers ) -if(${KINECTSDK10_INSTALLED}) - file( - INSTALL - "${SOURCE_BIN_PATH_DEBUG}/OpenNI2/Drivers/Kinect.dll" - DESTINATION - ${CURRENT_PACKAGES_DIR}/debug/bin/OpenNI2/Drivers - ) -endif() - file( INSTALL "${SOURCE_CONFIG_PATH}/OpenNI.ini" @@ -210,6 +181,7 @@ file( file( INSTALL + "${SOURCE_BIN_PATH_RELEASE}/OpenNI2/Drivers/Kinect.dll" "${SOURCE_BIN_PATH_RELEASE}/OpenNI2/Drivers/OniFile.dll" "${SOURCE_BIN_PATH_RELEASE}/OpenNI2/Drivers/PS1080.dll" "${SOURCE_CONFIG_PATH}/OpenNI2/Drivers/PS1080.ini" @@ -219,15 +191,6 @@ file( ${CURRENT_PACKAGES_DIR}/tools/openni2/OpenNI2/Drivers ) -if(${KINECTSDK10_INSTALLED}) - file( - INSTALL - "${SOURCE_BIN_PATH_RELEASE}/OpenNI2/Drivers/Kinect.dll" - DESTINATION - ${CURRENT_PACKAGES_DIR}/tools/openni2/OpenNI2/Drivers - ) -endif() - if(VCPKG_TARGET_ARCHITECTURE STREQUAL "x86") set(NUMBEROFBIT 32) elseif(VCPKG_TARGET_ARCHITECTURE STREQUAL "x64") @@ -248,4 +211,4 @@ file( # Handle copyright file(COPY ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/openni2) -file(RENAME ${CURRENT_PACKAGES_DIR}/share/openni2/LICENSE ${CURRENT_PACKAGES_DIR}/share/openni2/copyright) +file(RENAME ${CURRENT_PACKAGES_DIR}/share/openni2/LICENSE ${CURRENT_PACKAGES_DIR}/share/openni2/copyright) \ No newline at end of file diff --git a/ports/openni2/replace_environment_variable.patch.in b/ports/openni2/replace_environment_variable.patch.in index 25abe7edf..ac5cf017c 100644 --- a/ports/openni2/replace_environment_variable.patch.in +++ b/ports/openni2/replace_environment_variable.patch.in @@ -7,7 +7,7 @@ index 08a49fe..7fd8620 100644 Level3 Disabled - ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; -+ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@KINECTSDK10_DIR@\inc; ++ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x86-windows\include _WINDLL;%(PreprocessorDefinitions);_WINDOWS false false @@ -16,7 +16,7 @@ index 08a49fe..7fd8620 100644 true Kinect10.lib;XnLib.lib;%(AdditionalDependencies) - $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\x86; -+ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@KINECTSDK10_DIR@\lib\x86; ++ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x86-windows\debug\lib true @@ -25,7 +25,7 @@ index 08a49fe..7fd8620 100644 Level3 Disabled - ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; -+ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@KINECTSDK10_DIR@\inc; ++ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x64-windows\include _WINDLL;%(PreprocessorDefinitions);_WINDOWS false false @@ -34,7 +34,7 @@ index 08a49fe..7fd8620 100644 true Kinect10.lib;XnLib.lib;%(AdditionalDependencies) - $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\amd64; -+ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@KINECTSDK10_DIR@\lib\amd64; ++ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x64-windows\debug\lib @@ -43,7 +43,7 @@ index 08a49fe..7fd8620 100644 true true - ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; -+ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@KINECTSDK10_DIR@\inc; ++ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x86-windows\include false @@ -52,7 +52,7 @@ index 08a49fe..7fd8620 100644 true Kinect10.lib;XnLib.lib;%(AdditionalDependencies) - $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\x86; -+ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@KINECTSDK10_DIR@\lib\x86; ++ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x86-windows\lib true @@ -61,7 +61,7 @@ index 08a49fe..7fd8620 100644 true true - ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; -+ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@KINECTSDK10_DIR@\inc; ++ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x64-windows\include false @@ -70,7 +70,7 @@ index 08a49fe..7fd8620 100644 true Kinect10.lib;XnLib.lib;%(AdditionalDependencies) - $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\amd64; -+ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@KINECTSDK10_DIR@\lib\amd64; ++ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x64-windows\lib true diff --git a/ports/openni2/upgrade_projects.patch b/ports/openni2/upgrade_projects.patch index 1a44381b0..86dee5794 100644 --- a/ports/openni2/upgrade_projects.patch +++ b/ports/openni2/upgrade_projects.patch @@ -837,7 +837,7 @@ index 56c5944..0401f3d 100644 AnySuitable Speed diff --git a/Source/Drivers/Kinect/Kinect.vcxproj b/Source/Drivers/Kinect/Kinect.vcxproj -index f54e8b2..7f54d04 100644 +index f54e8b2..6ea2656 100644 --- a/Source/Drivers/Kinect/Kinect.vcxproj +++ b/Source/Drivers/Kinect/Kinect.vcxproj @@ -2,4 +2,4 @@ @@ -895,6 +895,15 @@ index f54e8b2..7f54d04 100644 true +@@ -125,7 +129,7 @@ + + + +- true ++ false + + + @@ -135,7 +139,7 @@ true true -- cgit v1.2.3 From ddbd57f5058b78e7df27497af844a41a1c79b986 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 4 Oct 2017 15:58:05 -0700 Subject: [vcpkg] Reformat and fix headers. --- toolsrc/include/vcpkg_Commands_Export.h | 8 +------- toolsrc/include/vcpkg_Commands_Export_IFW.h | 11 +++++++++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/toolsrc/include/vcpkg_Commands_Export.h b/toolsrc/include/vcpkg_Commands_Export.h index 31003422d..6e698c1b4 100644 --- a/toolsrc/include/vcpkg_Commands_Export.h +++ b/toolsrc/include/vcpkg_Commands_Export.h @@ -1,14 +1,8 @@ #pragma once -#include "StatusParagraphs.h" -#include "VcpkgCmdArguments.h" #include "VcpkgPaths.h" -#include "VersionT.h" -#include "vcpkg_Build.h" -#include "vcpkg_Dependencies.h" -#include namespace vcpkg::Commands::Export { - void export_integration_files(const fs::path &raw_exported_dir_path, const VcpkgPaths& paths); + void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths); } diff --git a/toolsrc/include/vcpkg_Commands_Export_IFW.h b/toolsrc/include/vcpkg_Commands_Export_IFW.h index c066ca021..7bee45eaf 100644 --- a/toolsrc/include/vcpkg_Commands_Export_IFW.h +++ b/toolsrc/include/vcpkg_Commands_Export_IFW.h @@ -1,7 +1,11 @@ #pragma once -#include "vcpkg_Files.h" +#include "VcpkgPaths.h" #include "vcpkg_Dependencies.h" +#include "vcpkg_Files.h" + +#include +#include namespace vcpkg::Commands::Export::IFW { @@ -14,5 +18,8 @@ namespace vcpkg::Commands::Export::IFW Optional maybe_installer_file_path; }; - void do_export(const std::vector &export_plan, const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths); + void do_export(const std::vector& export_plan, + const std::string& export_id, + const Options& ifw_options, + const VcpkgPaths& paths); } -- cgit v1.2.3 From 1b71053ad9954ffb0cb3c2955f42a86f62f66372 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 4 Oct 2017 16:01:29 -0700 Subject: [vcpkg] Reformat and refactor to reduce function size --- toolsrc/src/VcpkgPaths.cpp | 24 ++- toolsrc/src/commands_export.cpp | 324 ++++++++++++++++++++---------------- toolsrc/src/commands_export_ifw.cpp | 167 ++++++++++--------- 3 files changed, 278 insertions(+), 237 deletions(-) diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 19210facf..9f85992be 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -175,18 +175,21 @@ namespace vcpkg static fs::path get_ifw_installerbase_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { - static constexpr std::array EXPECTED_VERSION = { 3, 1, 81 }; + static constexpr std::array EXPECTED_VERSION = {3, 1, 81}; static const std::wstring VERSION_CHECK_ARGUMENTS = L"--framework-version"; - const fs::path downloaded_copy = downloads_folder / "QtInstallerFramework-win-x86" / "bin" / "installerbase.exe"; + const fs::path downloaded_copy = + downloads_folder / "QtInstallerFramework-win-x86" / "bin" / "installerbase.exe"; std::vector candidate_paths; candidate_paths.push_back(downloaded_copy); // TODO: Uncomment later - //const std::vector from_path = Files::find_from_PATH(L"installerbase"); - //candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - //candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe"); - //candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / "QtIFW-3.1.0" / "bin" / "installerbase.exe"); + // const std::vector from_path = Files::find_from_PATH(L"installerbase"); + // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / + // "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe"); + // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / + // "QtIFW-3.1.0" / "bin" / "installerbase.exe"); const Optional path = find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); @@ -283,17 +286,20 @@ namespace vcpkg const fs::path& VcpkgPaths::get_ifw_installerbase_exe() const { - return this->ifw_installerbase_exe.get_lazy([this]() { return get_ifw_installerbase_path(this->downloads, this->scripts); }); + return this->ifw_installerbase_exe.get_lazy( + [this]() { return get_ifw_installerbase_path(this->downloads, this->scripts); }); } const fs::path& VcpkgPaths::get_ifw_binarycreator_exe() const { - return this->ifw_binarycreator_exe.get_lazy([this]() { return get_ifw_installerbase_exe().parent_path() / "binarycreator.exe"; }); + return this->ifw_binarycreator_exe.get_lazy( + [this]() { return get_ifw_installerbase_exe().parent_path() / "binarycreator.exe"; }); } const fs::path& VcpkgPaths::get_ifw_repogen_exe() const { - return this->ifw_repogen_exe.get_lazy([this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; }); + return this->ifw_repogen_exe.get_lazy( + [this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; }); } static std::vector get_vs2017_installation_instances(const VcpkgPaths& paths) diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index 3662a46d8..a24f2eac7 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -211,17 +211,17 @@ namespace vcpkg::Commands::Export return nullopt; } - void export_integration_files(const fs::path &raw_exported_dir_path, const VcpkgPaths& paths) + void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths) { const std::vector integration_files_relative_to_root = { - { ".vcpkg-root" }, - { fs::path{ "scripts" } / "buildsystems" / "msbuild" / "applocal.ps1" }, - { fs::path{ "scripts" } / "buildsystems" / "msbuild" / "vcpkg.targets" }, - { fs::path{ "scripts" } / "buildsystems" / "vcpkg.cmake" }, - { fs::path{ "scripts" } / "cmake" / "vcpkg_get_windows_sdk.cmake" }, - { fs::path{ "scripts" } / "getWindowsSDK.ps1" }, - { fs::path{ "scripts" } / "getProgramFilesPlatformBitness.ps1" }, - { fs::path{ "scripts" } / "getProgramFiles32bit.ps1" }, + {".vcpkg-root"}, + {fs::path{"scripts"} / "buildsystems" / "msbuild" / "applocal.ps1"}, + {fs::path{"scripts"} / "buildsystems" / "msbuild" / "vcpkg.targets"}, + {fs::path{"scripts"} / "buildsystems" / "vcpkg.cmake"}, + {fs::path{"scripts"} / "cmake" / "vcpkg_get_windows_sdk.cmake"}, + {fs::path{"scripts"} / "getWindowsSDK.ps1"}, + {fs::path{"scripts"} / "getProgramFilesPlatformBitness.ps1"}, + {fs::path{"scripts"} / "getProgramFiles32bit.ps1"}, }; for (const fs::path& file : integration_files_relative_to_root) @@ -237,8 +237,27 @@ namespace vcpkg::Commands::Export } } - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + struct ExportArguments + { + bool dry_run; + bool raw; + bool nuget; + bool ifw; + bool zip; + bool seven_zip; + + Optional maybe_nuget_id; + Optional maybe_nuget_version; + + IFW::Options ifw_options; + std::vector specs; + }; + + static ExportArguments handle_export_command_arguments(const VcpkgCmdArguments& args, + const Triplet& default_triplet) { + ExportArguments ret; + static const std::string OPTION_DRY_RUN = "--dry-run"; static const std::string OPTION_RAW = "--raw"; static const std::string OPTION_NUGET = "--nuget"; @@ -258,11 +277,9 @@ namespace vcpkg::Commands::Export Commands::Help::create_example_string("export zlib zlib:x64-windows boost --nuget"); args.check_min_arg_count(1, EXAMPLE); - const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + ret.specs = Util::fmap(args.command_arguments, [&](auto&& arg) { return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE); }); - for (auto&& spec : specs) - Input::check_triplet(spec.triplet(), paths); const auto options = args.check_and_get_optional_command_arguments( { @@ -280,16 +297,16 @@ namespace vcpkg::Commands::Export OPTION_IFW_PACKAGES_DIR_PATH, OPTION_IFW_REPOSITORY_DIR_PATH, OPTION_IFW_CONFIG_FILE_PATH, - OPTION_IFW_INSTALLER_FILE_PATH + OPTION_IFW_INSTALLER_FILE_PATH, }); - const bool dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); - const bool raw = options.switches.find(OPTION_RAW) != options.switches.cend(); - const bool nuget = options.switches.find(OPTION_NUGET) != options.switches.cend(); - const bool ifw = options.switches.find(OPTION_IFW) != options.switches.cend(); - const bool zip = options.switches.find(OPTION_ZIP) != options.switches.cend(); - const bool seven_zip = options.switches.find(OPTION_SEVEN_ZIP) != options.switches.cend(); - - if (!raw && !nuget && !ifw && !zip && !seven_zip && !dry_run) + ret.dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); + ret.raw = options.switches.find(OPTION_RAW) != options.switches.cend(); + ret.nuget = options.switches.find(OPTION_NUGET) != options.switches.cend(); + ret.ifw = options.switches.find(OPTION_IFW) != options.switches.cend(); + ret.zip = options.switches.find(OPTION_ZIP) != options.switches.cend(); + ret.seven_zip = options.switches.find(OPTION_SEVEN_ZIP) != options.switches.cend(); + + if (!ret.raw && !ret.nuget && !ret.ifw && !ret.zip && !ret.seven_zip && !ret.dry_run) { System::println(System::Color::error, "Must provide at least one export type: --raw --nuget --ifw --zip --7zip"); @@ -297,38 +314,152 @@ namespace vcpkg::Commands::Export Checks::exit_fail(VCPKG_LINE_INFO); } - auto maybe_nuget_id = maybe_lookup(options.settings, OPTION_NUGET_ID); - auto maybe_nuget_version = maybe_lookup(options.settings, OPTION_NUGET_VERSION); + ret.maybe_nuget_id = maybe_lookup(options.settings, OPTION_NUGET_ID); + ret.maybe_nuget_version = maybe_lookup(options.settings, OPTION_NUGET_VERSION); - Checks::check_exit(VCPKG_LINE_INFO, !maybe_nuget_id || nuget, "--nuget-id is only valid with --nuget"); + Checks::check_exit(VCPKG_LINE_INFO, !ret.maybe_nuget_id || ret.nuget, "--nuget-id is only valid with --nuget"); Checks::check_exit( - VCPKG_LINE_INFO, !maybe_nuget_version || nuget, "--nuget-version is only valid with --nuget"); + VCPKG_LINE_INFO, !ret.maybe_nuget_version || ret.nuget, "--nuget-version is only valid with --nuget"); - IFW::Options ifw_options; + ret.ifw_options.maybe_repository_url = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_URL); + Checks::check_exit(VCPKG_LINE_INFO, + !ret.ifw_options.maybe_repository_url || ret.ifw, + "--ifw-repository-url is only valid with --ifw"); - ifw_options.maybe_repository_url = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_URL); - Checks::check_exit( - VCPKG_LINE_INFO, !ifw_options.maybe_repository_url || ifw, "--ifw-repository-url is only valid with --ifw"); + ret.ifw_options.maybe_packages_dir_path = maybe_lookup(options.settings, OPTION_IFW_PACKAGES_DIR_PATH); + Checks::check_exit(VCPKG_LINE_INFO, + !ret.ifw_options.maybe_packages_dir_path || ret.ifw, + "--ifw-packages-directory-path is only valid with --ifw"); - ifw_options.maybe_packages_dir_path = maybe_lookup(options.settings, OPTION_IFW_PACKAGES_DIR_PATH); - Checks::check_exit( - VCPKG_LINE_INFO, !ifw_options.maybe_packages_dir_path || ifw, "--ifw-packages-directory-path is only valid with --ifw"); + ret.ifw_options.maybe_repository_dir_path = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_DIR_PATH); + Checks::check_exit(VCPKG_LINE_INFO, + !ret.ifw_options.maybe_repository_dir_path || ret.ifw, + "--ifw-repository-directory-path is only valid with --ifw"); - ifw_options.maybe_repository_dir_path = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_DIR_PATH); - Checks::check_exit( - VCPKG_LINE_INFO, !ifw_options.maybe_repository_dir_path || ifw, "--ifw-repository-directory-path is only valid with --ifw"); + ret.ifw_options.maybe_config_file_path = maybe_lookup(options.settings, OPTION_IFW_CONFIG_FILE_PATH); + Checks::check_exit(VCPKG_LINE_INFO, + !ret.ifw_options.maybe_config_file_path || ret.ifw, + "--ifw-configuration-file-path is only valid with --ifw"); - ifw_options.maybe_config_file_path = maybe_lookup(options.settings, OPTION_IFW_CONFIG_FILE_PATH); - Checks::check_exit( - VCPKG_LINE_INFO, !ifw_options.maybe_config_file_path || ifw, "--ifw-configuration-file-path is only valid with --ifw"); + ret.ifw_options.maybe_installer_file_path = maybe_lookup(options.settings, OPTION_IFW_INSTALLER_FILE_PATH); + Checks::check_exit(VCPKG_LINE_INFO, + !ret.ifw_options.maybe_installer_file_path || ret.ifw, + "--ifw-installer-file-path is only valid with --ifw"); + return ret; + } - ifw_options.maybe_installer_file_path = maybe_lookup(options.settings, OPTION_IFW_INSTALLER_FILE_PATH); - Checks::check_exit( - VCPKG_LINE_INFO, !ifw_options.maybe_installer_file_path || ifw, "--ifw-installer-file-path is only valid with --ifw"); + static void print_next_step_info(const fs::path& prefix) + { + const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; + const CMakeVariable cmake_variable = CMakeVariable(L"CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); + System::println("\n" + "To use the exported libraries in CMake projects use:" + "\n" + " %s" + "\n", + Strings::to_utf8(cmake_variable.s)); + }; + + static void handle_raw_based_export(Span export_plan, + const ExportArguments& opts, + const std::string& export_id, + const VcpkgPaths& paths) + { + Files::Filesystem& fs = paths.get_filesystem(); + const fs::path export_to_path = paths.root; + const fs::path raw_exported_dir_path = export_to_path / export_id; + std::error_code ec; + fs.remove_all(raw_exported_dir_path, ec); + fs.create_directory(raw_exported_dir_path, ec); + + // execute the plan + for (const ExportPlanAction& action : export_plan) + { + if (action.plan_type != ExportPlanType::ALREADY_BUILT) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + const std::string display_name = action.spec.to_string(); + System::println("Exporting package %s... ", display_name); + + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + const InstallDir dirs = InstallDir::from_destination_root( + raw_exported_dir_path / "installed", + action.spec.triplet().to_string(), + raw_exported_dir_path / "installed" / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); + + Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); + System::println(System::Color::success, "Exporting package %s... done", display_name); + } + + // Copy files needed for integration + export_integration_files(raw_exported_dir_path, paths); + + if (opts.raw) + { + System::println( + System::Color::success, R"(Files exported at: "%s")", raw_exported_dir_path.generic_string()); + print_next_step_info(export_to_path); + } + + if (opts.nuget) + { + System::println("Creating nuget package... "); + + const std::string nuget_id = opts.maybe_nuget_id.value_or(raw_exported_dir_path.filename().string()); + const std::string nuget_version = opts.maybe_nuget_version.value_or("1.0.0"); + const fs::path output_path = + do_nuget_export(paths, nuget_id, nuget_version, raw_exported_dir_path, export_to_path); + System::println(System::Color::success, "Creating nuget package... done"); + System::println(System::Color::success, "NuGet package exported at: %s", output_path.generic_string()); + + System::println(R"( +With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: + Install-Package %s -Source "%s" +)" + "\n", + nuget_id, + output_path.parent_path().u8string()); + } + + if (opts.zip) + { + System::println("Creating zip archive... "); + const fs::path output_path = + do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::ZIP); + System::println(System::Color::success, "Creating zip archive... done"); + System::println(System::Color::success, "Zip archive exported at: %s", output_path.generic_string()); + print_next_step_info("[...]"); + } + + if (opts.seven_zip) + { + System::println("Creating 7zip archive... "); + const fs::path output_path = + do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::SEVEN_ZIP); + System::println(System::Color::success, "Creating 7zip archive... done"); + System::println(System::Color::success, "7zip archive exported at: %s", output_path.generic_string()); + print_next_step_info("[...]"); + } + + if (!opts.raw) + { + fs.remove_all(raw_exported_dir_path, ec); + } + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + const auto opts = handle_export_command_arguments(args, default_triplet); + for (auto&& spec : opts.specs) + Input::check_triplet(spec.triplet(), paths); // create the plan const StatusParagraphs status_db = database_load_check(paths); - std::vector export_plan = Dependencies::create_export_plan(paths, specs, status_db); + std::vector export_plan = Dependencies::create_export_plan(paths, opts.specs, status_db); Checks::check_exit(VCPKG_LINE_INFO, !export_plan.empty(), "Export plan cannot be empty"); std::map> group_by_plan_type; @@ -363,118 +494,21 @@ namespace vcpkg::Commands::Export Checks::exit_fail(VCPKG_LINE_INFO); } - if (dry_run) + if (opts.dry_run) { Checks::exit_success(VCPKG_LINE_INFO); } std::string export_id = create_export_id(); - const auto print_next_step_info = [](const fs::path& prefix) { - const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; - const CMakeVariable cmake_variable = - CMakeVariable(L"CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); - System::println("\n" - "To use the exported libraries in CMake projects use:" - "\n" - " %s" - "\n", - Strings::to_utf8(cmake_variable.s)); - }; - - // Main loop - if (raw || nuget || zip || seven_zip) + if (opts.raw || opts.nuget || opts.zip || opts.seven_zip) { - Files::Filesystem& fs = paths.get_filesystem(); - const fs::path export_to_path = paths.root; - const fs::path raw_exported_dir_path = export_to_path / export_id; - std::error_code ec; - fs.remove_all(raw_exported_dir_path, ec); - fs.create_directory(raw_exported_dir_path, ec); - - // execute the plan - for (const ExportPlanAction& action : export_plan) - { - if (action.plan_type != ExportPlanType::ALREADY_BUILT) - { - Checks::unreachable(VCPKG_LINE_INFO); - } - - const std::string display_name = action.spec.to_string(); - System::println("Exporting package %s... ", display_name); - - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; - - const InstallDir dirs = InstallDir::from_destination_root( - raw_exported_dir_path / "installed", - action.spec.triplet().to_string(), - raw_exported_dir_path / "installed" / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); - - Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); - System::println(System::Color::success, "Exporting package %s... done", display_name); - } - - // Copy files needed for integration - export_integration_files(raw_exported_dir_path, paths); - - if (raw) - { - System::println( - System::Color::success, R"(Files exported at: "%s")", raw_exported_dir_path.generic_string()); - print_next_step_info(export_to_path); - } - - if (nuget) - { - System::println("Creating nuget package... "); - - const std::string nuget_id = maybe_nuget_id.value_or(raw_exported_dir_path.filename().string()); - const std::string nuget_version = maybe_nuget_version.value_or("1.0.0"); - const fs::path output_path = - do_nuget_export(paths, nuget_id, nuget_version, raw_exported_dir_path, export_to_path); - System::println(System::Color::success, "Creating nuget package... done"); - System::println(System::Color::success, "NuGet package exported at: %s", output_path.generic_string()); - - System::println(R"( -With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: - Install-Package %s -Source "%s" -)" - "\n", - nuget_id, - output_path.parent_path().u8string()); - } - - if (zip) - { - System::println("Creating zip archive... "); - const fs::path output_path = - do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::ZIP); - System::println(System::Color::success, "Creating zip archive... done"); - System::println(System::Color::success, "Zip archive exported at: %s", output_path.generic_string()); - print_next_step_info("[...]"); - } - - if (seven_zip) - { - System::println("Creating 7zip archive... "); - const fs::path output_path = - do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::SEVEN_ZIP); - System::println(System::Color::success, "Creating 7zip archive... done"); - System::println(System::Color::success, "7zip archive exported at: %s", output_path.generic_string()); - print_next_step_info("[...]"); - } - - if (!raw) - { - fs.remove_all(raw_exported_dir_path, ec); - } + handle_raw_based_export(export_plan, opts, export_id, paths); } - // IFW loop - if (ifw) + if (opts.ifw) { - IFW::do_export(export_plan, export_id, ifw_options, paths); + IFW::do_export(export_plan, export_id, opts.ifw_options, paths); print_next_step_info("@RootDir@/src/vcpkg"); } diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index a0692c11e..0dc8a7d31 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -19,39 +19,39 @@ namespace vcpkg::Commands::Export::IFW char mbstr[11]; const size_t bytes_written = std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d", &date_time); Checks::check_exit(VCPKG_LINE_INFO, - bytes_written == 10, - "Expected 10 bytes to be written, but %u were written", - bytes_written); + bytes_written == 10, + "Expected 10 bytes to be written, but %u were written", + bytes_written); const std::string date_time_as_string(mbstr); return date_time_as_string; } - fs::path get_packages_dir_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + fs::path get_packages_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { - return ifw_options.maybe_packages_dir_path.has_value() ? - fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-packages"); + return ifw_options.maybe_packages_dir_path.has_value() + ? fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-packages"); } - fs::path get_repository_dir_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + fs::path get_repository_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { - return ifw_options.maybe_repository_dir_path.has_value() ? - fs::path(ifw_options.maybe_repository_dir_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-repository"); + return ifw_options.maybe_repository_dir_path.has_value() + ? fs::path(ifw_options.maybe_repository_dir_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-repository"); } - fs::path get_config_file_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + fs::path get_config_file_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { - return ifw_options.maybe_config_file_path.has_value() ? - fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-configuration.xml"); + return ifw_options.maybe_config_file_path.has_value() + ? fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-configuration.xml"); } - fs::path get_installer_file_path(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + fs::path get_installer_file_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { - return ifw_options.maybe_installer_file_path.has_value() ? - fs::path(ifw_options.maybe_installer_file_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-installer.exe"); + return ifw_options.maybe_installer_file_path.has_value() + ? fs::path(ifw_options.maybe_installer_file_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-installer.exe"); } fs::path export_real_package(const fs::path& ifw_packages_dir_path, @@ -82,7 +82,7 @@ namespace vcpkg::Commands::Export::IFW fs.write_contents(package_xml_file_path, Strings::format( -R"###( + R"###( %s %s @@ -91,12 +91,12 @@ R"###( true )###", - action.spec.to_string(), - binary_paragraph.version, - create_release_date(), - action.spec.name(), - action.spec.triplet().canonical_name(), - deps)); + action.spec.to_string(), + binary_paragraph.version, + create_release_date(), + action.spec.name(), + action.spec.triplet().canonical_name(), + deps)); // Return dir path for export package data return ifw_packages_dir_path / @@ -119,15 +119,16 @@ R"###( !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, Strings::format( -R"###( + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( Packages 1.0.0 %s )###", - create_release_date())); + create_release_date())); for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) { @@ -146,7 +147,7 @@ R"###( fs.write_contents(package_xml_file_path, Strings::format( -R"###( + R"###( %s %s @@ -154,10 +155,10 @@ R"###( %s )###", - action.spec.name(), - binary_paragraph.description, - binary_paragraph.version, - create_release_date())); + action.spec.name(), + binary_paragraph.description, + binary_paragraph.version, + create_release_date())); } } @@ -176,15 +177,16 @@ R"###( !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, Strings::format( -R"###( + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( Triplets 1.0.0 %s )###", - create_release_date())); + create_release_date())); for (const std::string& triplet : unique_triplets) { @@ -196,16 +198,17 @@ R"###( !ec, "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, Strings::format( -R"###( + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( %s 1.0.0 %s )###", - triplet, - create_release_date())); + triplet, + create_release_date())); } } @@ -222,18 +225,19 @@ R"###( "Could not create directory for package file %s", package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, Strings::format( -R"###( + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( Integration 1.0.0 %s )###", - create_release_date())); + create_release_date())); } - void export_config(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + void export_config(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { std::error_code ec; Files::Filesystem& fs = paths.get_filesystem(); @@ -257,21 +261,22 @@ R"###( %s )###", - ifw_repo_url); + ifw_repo_url); } - fs.write_contents(config_xml_file_path, Strings::format( -R"###( + fs.write_contents(config_xml_file_path, + Strings::format( + R"###( vcpkg 1.0.0 @RootDir@/src/vcpkg%s )###", - formatted_repo_url)); + formatted_repo_url)); } - void do_repository(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + void do_repository(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { const fs::path& repogen_exe = paths.get_ifw_repogen_exe(); const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); @@ -283,16 +288,13 @@ R"###( Files::Filesystem& fs = paths.get_filesystem(); fs.remove_all(repository_dir, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not remove outdated repository directory %s", - repository_dir.generic_string()); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not remove outdated repository directory %s", repository_dir.generic_string()); - const std::wstring cmd_line = - Strings::wformat(LR"("%s" --packages "%s" "%s" > nul)", - repogen_exe.native(), - packages_dir.native(), - repository_dir.native()); + const std::wstring cmd_line = Strings::wformat(LR"("%s" --packages "%s" "%s" > nul)", + repogen_exe.native(), + packages_dir.native(), + repository_dir.native()); const int exit_code = System::cmd_execute_clean(cmd_line); Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW repository generating failed"); @@ -300,7 +302,7 @@ R"###( System::println(System::Color::success, "Generating repository %s... done.", repository_dir.generic_string()); } - void do_installer(const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + void do_installer(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { const fs::path& binarycreator_exe = paths.get_ifw_binarycreator_exe(); const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); @@ -315,21 +317,19 @@ R"###( std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); if (!ifw_repo_url.empty()) { - cmd_line = - Strings::wformat(LR"("%s" --online-only --config "%s" --repository "%s" "%s" > nul)", - binarycreator_exe.native(), - config_file.native(), - repository_dir.native(), - installer_file.native()); + cmd_line = Strings::wformat(LR"("%s" --online-only --config "%s" --repository "%s" "%s" > nul)", + binarycreator_exe.native(), + config_file.native(), + repository_dir.native(), + installer_file.native()); } else { - cmd_line = - Strings::wformat(LR"("%s" --config "%s" --packages "%s" "%s" > nul)", - binarycreator_exe.native(), - config_file.native(), - packages_dir.native(), - installer_file.native()); + cmd_line = Strings::wformat(LR"("%s" --config "%s" --packages "%s" "%s" > nul)", + binarycreator_exe.native(), + config_file.native(), + packages_dir.native(), + installer_file.native()); } const int exit_code = System::cmd_execute_clean(cmd_line); @@ -338,7 +338,10 @@ R"###( System::println(System::Color::success, "Generating installer %s... done.", installer_file.generic_string()); } - void do_export(const std::vector &export_plan, const std::string &export_id, const Options &ifw_options, const VcpkgPaths& paths) + void do_export(const std::vector& export_plan, + const std::string& export_id, + const Options& ifw_options, + const VcpkgPaths& paths) { const fs::path ifw_packages_dir_path = get_packages_dir_path(export_id, ifw_options, paths); const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); @@ -350,15 +353,13 @@ R"###( fs.remove_all(ifw_packages_dir_path, ec); Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not remove outdated packages directory %s", - ifw_packages_dir_path.generic_string()); + !ec, + "Could not remove outdated packages directory %s", + ifw_packages_dir_path.generic_string()); fs.create_directory(ifw_packages_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create packages directory %s", - ifw_packages_dir_path.generic_string()); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create packages directory %s", ifw_packages_dir_path.generic_string()); // execute the plan std::map unique_packages; @@ -384,9 +385,9 @@ R"###( // Copy package data const InstallDir dirs = InstallDir::from_destination_root(ifw_package_dir_path, - action.spec.triplet().to_string(), - ifw_package_dir_path / "vcpkg" / "info" / - (binary_paragraph.fullstem() + ".list")); + action.spec.triplet().to_string(), + ifw_package_dir_path / "vcpkg" / "info" / + (binary_paragraph.fullstem() + ".list")); Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); System::println("Exporting package %s... done", display_name); -- cgit v1.2.3 From c98db7541594eadccf6823d4fdde2ff8c53c5fe9 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Wed, 4 Oct 2017 16:24:03 -0700 Subject: [vcpkg] Refactor out implication in option parsing for export --- toolsrc/include/Span.h | 2 ++ toolsrc/src/commands_export.cpp | 70 +++++++++++++++++++++++------------------ 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/toolsrc/include/Span.h b/toolsrc/include/Span.h index b2c9acdbc..a43e8f992 100644 --- a/toolsrc/include/Span.h +++ b/toolsrc/include/Span.h @@ -2,6 +2,7 @@ #include #include +#include #include template @@ -17,6 +18,7 @@ public: constexpr Span(std::nullptr_t) noexcept : Span() {} constexpr Span(T* ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) {} constexpr Span(T* ptr_begin, T* ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) {} + constexpr Span(std::initializer_list l) noexcept : m_ptr(l.begin()), m_count(l.size()) {} template constexpr Span(T (&arr)[N]) noexcept : Span(arr, N) diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp index a24f2eac7..20838f5a5 100644 --- a/toolsrc/src/commands_export.cpp +++ b/toolsrc/src/commands_export.cpp @@ -314,37 +314,45 @@ namespace vcpkg::Commands::Export Checks::exit_fail(VCPKG_LINE_INFO); } - ret.maybe_nuget_id = maybe_lookup(options.settings, OPTION_NUGET_ID); - ret.maybe_nuget_version = maybe_lookup(options.settings, OPTION_NUGET_VERSION); - - Checks::check_exit(VCPKG_LINE_INFO, !ret.maybe_nuget_id || ret.nuget, "--nuget-id is only valid with --nuget"); - Checks::check_exit( - VCPKG_LINE_INFO, !ret.maybe_nuget_version || ret.nuget, "--nuget-version is only valid with --nuget"); - - ret.ifw_options.maybe_repository_url = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_URL); - Checks::check_exit(VCPKG_LINE_INFO, - !ret.ifw_options.maybe_repository_url || ret.ifw, - "--ifw-repository-url is only valid with --ifw"); - - ret.ifw_options.maybe_packages_dir_path = maybe_lookup(options.settings, OPTION_IFW_PACKAGES_DIR_PATH); - Checks::check_exit(VCPKG_LINE_INFO, - !ret.ifw_options.maybe_packages_dir_path || ret.ifw, - "--ifw-packages-directory-path is only valid with --ifw"); - - ret.ifw_options.maybe_repository_dir_path = maybe_lookup(options.settings, OPTION_IFW_REPOSITORY_DIR_PATH); - Checks::check_exit(VCPKG_LINE_INFO, - !ret.ifw_options.maybe_repository_dir_path || ret.ifw, - "--ifw-repository-directory-path is only valid with --ifw"); - - ret.ifw_options.maybe_config_file_path = maybe_lookup(options.settings, OPTION_IFW_CONFIG_FILE_PATH); - Checks::check_exit(VCPKG_LINE_INFO, - !ret.ifw_options.maybe_config_file_path || ret.ifw, - "--ifw-configuration-file-path is only valid with --ifw"); - - ret.ifw_options.maybe_installer_file_path = maybe_lookup(options.settings, OPTION_IFW_INSTALLER_FILE_PATH); - Checks::check_exit(VCPKG_LINE_INFO, - !ret.ifw_options.maybe_installer_file_path || ret.ifw, - "--ifw-installer-file-path is only valid with --ifw"); + struct OptionPair + { + const std::string& name; + Optional& out_opt; + }; + const auto options_implies = + [&](const std::string& main_opt_name, bool main_opt, Span implying_opts) { + if (main_opt) + { + for (auto&& opt : implying_opts) + opt.out_opt = maybe_lookup(options.settings, opt.name); + } + else + { + for (auto&& opt : implying_opts) + Checks::check_exit(VCPKG_LINE_INFO, + !maybe_lookup(options.settings, opt.name), + "%s is only valid with %s", + opt.name, + main_opt_name); + } + }; + + options_implies(OPTION_NUGET, + ret.nuget, + { + {OPTION_NUGET_ID, ret.maybe_nuget_id}, + {OPTION_NUGET_VERSION, ret.maybe_nuget_version}, + }); + + options_implies(OPTION_IFW, + ret.ifw, + { + {OPTION_IFW_REPOSITORY_URL, ret.ifw_options.maybe_repository_url}, + {OPTION_IFW_PACKAGES_DIR_PATH, ret.ifw_options.maybe_packages_dir_path}, + {OPTION_IFW_REPOSITORY_DIR_PATH, ret.ifw_options.maybe_repository_dir_path}, + {OPTION_IFW_CONFIG_FILE_PATH, ret.ifw_options.maybe_config_file_path}, + {OPTION_IFW_INSTALLER_FILE_PATH, ret.ifw_options.maybe_installer_file_path}, + }); return ret; } -- cgit v1.2.3 From 887466dfc1ff8ed20d3b9268f76da987f7d53635 Mon Sep 17 00:00:00 2001 From: LazyHamster Date: Thu, 5 Oct 2017 15:56:49 +0300 Subject: Added port for librtmp 2.3 --- ports/librtmp/CMakeLists.txt | 57 ++++++++++++++++++ ports/librtmp/CONTROL | 4 ++ ports/librtmp/fix_strncasecmp.patch | 16 ++++++ ports/librtmp/hide_netstackdump.patch | 22 +++++++ ports/librtmp/librtmp.def | 105 ++++++++++++++++++++++++++++++++++ ports/librtmp/portfile.cmake | 36 ++++++++++++ 6 files changed, 240 insertions(+) create mode 100644 ports/librtmp/CMakeLists.txt create mode 100644 ports/librtmp/CONTROL create mode 100644 ports/librtmp/fix_strncasecmp.patch create mode 100644 ports/librtmp/hide_netstackdump.patch create mode 100644 ports/librtmp/librtmp.def create mode 100644 ports/librtmp/portfile.cmake diff --git a/ports/librtmp/CMakeLists.txt b/ports/librtmp/CMakeLists.txt new file mode 100644 index 000000000..c12ddc0ef --- /dev/null +++ b/ports/librtmp/CMakeLists.txt @@ -0,0 +1,57 @@ +cmake_minimum_required(VERSION 3.8) + +project(librtmp C) + +find_package(zlib REQUIRED) +find_package(openssl REQUIRED) + +include_directories(${ZLIB_INCLUDE_DIRS}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) + +set(CMAKE_DEBUG_POSTFIX "d") + +if(MSVC) + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) + add_definitions(-D_WINSOCK_DEPRECATED_NO_WARNINGS) +endif() + +add_definitions(-DLIBRTMP_ONLY) + +# List the header files +set(HEADERS librtmp/amf.h + librtmp/bytes.h + librtmp/dh.h + librtmp/dhgroups.h + librtmp/handshake.h + librtmp/http.h + librtmp/log.h + librtmp/rtmp.h + librtmp/rtmp_sys.h +) + +# List the source files +set(SRCS librtmp/amf.c + librtmp/hashswf.c + librtmp/log.c + librtmp/parseurl.c + librtmp/rtmp.c + librtmp/librtmp.def +) + +if(MSVC) + set(SRCS_MSVC "librtmp/librtmp.def") +endif() + +add_library(librtmp ${SRCS} ${HEADERS} ${SRCS_MSVC}) + +target_include_directories(librtmp PRIVATE ./librtmp) +target_link_libraries(librtmp PRIVATE ${ZLIB_LIBRARIES} ${OPENSSL_LIBRARIES}) +target_link_libraries(librtmp PRIVATE Ws2_32.lib Winmm.lib) + +install(TARGETS librtmp + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib) + +install(FILES librtmp/rtmp.h librtmp/amf.h DESTINATION include/librtmp) \ No newline at end of file diff --git a/ports/librtmp/CONTROL b/ports/librtmp/CONTROL new file mode 100644 index 000000000..d26541d91 --- /dev/null +++ b/ports/librtmp/CONTROL @@ -0,0 +1,4 @@ +Source: librtmp +Version: 2.3 +Build-Depends: zlib, openssl +Description: RTMPDump Real-Time Messaging Protocol API diff --git a/ports/librtmp/fix_strncasecmp.patch b/ports/librtmp/fix_strncasecmp.patch new file mode 100644 index 000000000..c1cadc4ac --- /dev/null +++ b/ports/librtmp/fix_strncasecmp.patch @@ -0,0 +1,16 @@ +diff --git a/librtmp/rtmp_sys.h b/librtmp/rtmp_sys.h +index 0874cbe..b43d587 100644 +--- a/librtmp/rtmp_sys.h ++++ b/librtmp/rtmp_sys.h +@@ -37,6 +37,11 @@ + #include + #endif + ++#ifdef _MSC_VER ++#define strncasecmp _strnicmp ++#define strcasecmp _stricmp ++#endif ++ + #define GetSockError() WSAGetLastError() + #define SetSockError(e) WSASetLastError(e) + #define setsockopt(a,b,c,d,e) (setsockopt)(a,b,c,(const char *)d,(int)e) diff --git a/ports/librtmp/hide_netstackdump.patch b/ports/librtmp/hide_netstackdump.patch new file mode 100644 index 000000000..e2a5e4207 --- /dev/null +++ b/ports/librtmp/hide_netstackdump.patch @@ -0,0 +1,22 @@ +diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c +index f152648..0bf3f7d 100644 +--- a/librtmp/rtmp.c ++++ b/librtmp/rtmp.c +@@ -1316,7 +1316,7 @@ ReadN(RTMP *r, char *buffer, int n) + SendBytesReceived(r); + } + /*RTMP_Log(RTMP_LOGDEBUG, "%s: %d bytes\n", __FUNCTION__, nBytes); */ +-#ifdef _DEBUG ++#if defined(_DEBUG) && !defined(LIBRTMP_ONLY) + fwrite(ptr, 1, nBytes, netstackdump_read); + #endif + +@@ -3527,7 +3527,7 @@ RTMPSockBuf_Send(RTMPSockBuf *sb, const char *buf, int len) + { + int rc; + +-#ifdef _DEBUG ++#if defined(_DEBUG) && !defined(LIBRTMP_ONLY) + fwrite(buf, 1, len, netstackdump); + #endif + diff --git a/ports/librtmp/librtmp.def b/ports/librtmp/librtmp.def new file mode 100644 index 000000000..d9f8b9136 --- /dev/null +++ b/ports/librtmp/librtmp.def @@ -0,0 +1,105 @@ +EXPORTS + AMF_AddProp + AMF_CountProp + AMF_Decode + AMF_DecodeArray + AMF_DecodeBoolean + AMF_DecodeInt16 + AMF_DecodeInt24 + AMF_DecodeInt32 + AMF_DecodeLongString + AMF_DecodeNumber + AMF_DecodeString + AMF_Dump + AMF_Encode + AMF_EncodeBoolean + AMF_EncodeInt16 + AMF_EncodeInt24 + AMF_EncodeInt32 + AMF_EncodeNamedBoolean + AMF_EncodeNamedNumber + AMF_EncodeNamedString + AMF_EncodeNumber + AMF_EncodeString + AMF_GetProp + AMF_Reset + + AMF3_Decode + AMF3CD_AddProp + AMF3CD_GetProp + AMF3Prop_Decode + AMF3ReadInteger + AMF3ReadString + + AMFProp_Decode + AMFProp_Dump + AMFProp_Encode + AMFProp_GetBoolean + AMFProp_GetName + AMFProp_GetNumber + AMFProp_GetObject + AMFProp_GetString + AMFProp_GetType + AMFProp_IsValid + AMFProp_Reset + AMFProp_SetName + + RTMP_Alloc + RTMP_ClientPacket + RTMP_Close + RTMP_Connect + RTMP_Connect0 + RTMP_Connect1 + RTMP_ConnectStream + RTMP_ctrlC + RTMP_debuglevel + RTMP_DefaultFlashVer + RTMP_DeleteStream + RTMP_DropRequest + RTMP_EnableWrite + RTMP_FindFirstMatchingProperty + RTMP_FindPrefixProperty + RTMP_Free + RTMP_GetDuration + RTMP_GetNextMediaPacket + RTMP_GetTime + RTMP_HashSWF + RTMP_Init + RTMP_IsConnected + RTMP_IsTimedout + RTMP_LibVersion + RTMP_Log + RTMP_LogGetLevel + RTMP_LogHex + RTMP_LogHexString + RTMP_LogPrintf + RTMP_LogSetCallback + RTMP_LogSetLevel + RTMP_LogSetOutput + RTMP_LogStatus + RTMP_ParsePlaypath + RTMP_ParseURL + RTMP_Pause + RTMP_Read + RTMP_ReadPacket + RTMP_ReconnectStream + RTMP_SendChunk + RTMP_SendClientBW + RTMP_SendCreateStream + RTMP_SendCtrl + RTMP_SendPacket + RTMP_SendPause + RTMP_SendSeek + RTMP_SendServerBW + RTMP_Serve + RTMP_SetBufferMS + RTMP_SetOpt + RTMP_SetupStream + RTMP_SetupURL + RTMP_Socket + RTMP_TLS_ctx + RTMP_TLS_Init + RTMP_ToggleStream + RTMP_UpdateBufferMS + RTMP_UserInterrupt + RTMP_Write diff --git a/ports/librtmp/portfile.cmake b/ports/librtmp/portfile.cmake new file mode 100644 index 000000000..18423f152 --- /dev/null +++ b/ports/librtmp/portfile.cmake @@ -0,0 +1,36 @@ +include(vcpkg_common_functions) + +set(RTMPDUMP_VERSION 2.3) +set(RTMPDUMP_FILENAME rtmpdump-${RTMPDUMP_VERSION}.tgz) +set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/rtmpdump-${RTMPDUMP_VERSION}) + +vcpkg_download_distfile(ARCHIVE + URLS "http://rtmpdump.mplayerhq.hu/download/${RTMPDUMP_FILENAME}" + FILENAME "${RTMPDUMP_FILENAME}" + SHA512 d8240ba372a704231286b81bbf75716d8b76874840538c4e1527f7f8b6ca66eeaba6b03167fe6fab06bf80f20f07d89ecb84cc428b3196234174a43f3328ec2a +) +vcpkg_extract_source_archive(${ARCHIVE}) + +file(COPY ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt DESTINATION ${SOURCE_PATH}) +file(COPY ${CMAKE_CURRENT_LIST_DIR}/librtmp.def DESTINATION ${SOURCE_PATH}/librtmp) + +vcpkg_apply_patches( + SOURCE_PATH ${SOURCE_PATH} + PATCHES + ${CMAKE_CURRENT_LIST_DIR}/fix_strncasecmp.patch + ${CMAKE_CURRENT_LIST_DIR}/hide_netstackdump.patch +) + +vcpkg_configure_cmake( + SOURCE_PATH ${SOURCE_PATH} +) + +vcpkg_install_cmake() + +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include) + +# License and man +file(INSTALL ${SOURCE_PATH}/librtmp/COPYING DESTINATION ${CURRENT_PACKAGES_DIR}/share/librtmp RENAME copyright) +file(INSTALL ${SOURCE_PATH}/librtmp/librtmp.3.html DESTINATION ${CURRENT_PACKAGES_DIR}/share/librtmp) + +vcpkg_copy_pdbs() -- cgit v1.2.3 From 13a225c6ab4c20e7f62c3463be64b3075ffb9c50 Mon Sep 17 00:00:00 2001 From: glachancecmaisonneuve Date: Thu, 5 Oct 2017 12:15:42 -0400 Subject: mozjpeg initial port --- ports/mozjpeg/CONTROL | 3 +++ ports/mozjpeg/portfile.cmake | 49 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 ports/mozjpeg/CONTROL create mode 100644 ports/mozjpeg/portfile.cmake diff --git a/ports/mozjpeg/CONTROL b/ports/mozjpeg/CONTROL new file mode 100644 index 000000000..8afc065b3 --- /dev/null +++ b/ports/mozjpeg/CONTROL @@ -0,0 +1,3 @@ +Source: mozjpeg +Version: 3.2 +Description: MozJPEG reduces file sizes of JPEG images while retaining quality and compatibility with the vast majority of the world's deployed decoders. It's compatible with libjpeg API and ABI, and can be used as a drop-in replacement for libjpeg. diff --git a/ports/mozjpeg/portfile.cmake b/ports/mozjpeg/portfile.cmake new file mode 100644 index 000000000..d95f83ff8 --- /dev/null +++ b/ports/mozjpeg/portfile.cmake @@ -0,0 +1,49 @@ +include(vcpkg_common_functions) +set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/mozjpeg-3.2) +vcpkg_download_distfile(ARCHIVE + URLS "https://github.com/mozilla/mozjpeg/archive/v3.2.zip" + FILENAME "mozjpeg.zip" + SHA512 a1ba53dea3e04add46616918b5e96f2c8102ef65856596f1794df29c8be27db3d9fb13e7ffc864d23626f98dff5a6b47315903cae9ae41f9905aef2cc91af0c5 +) + +vcpkg_find_acquire_program(NASM) +get_filename_component(NASM_EXE_PATH ${NASM} DIRECTORY) +set(ENV{PATH} "$ENV{PATH};${NASM_EXE_PATH}") + +vcpkg_extract_source_archive(${ARCHIVE}) + +if (${VCPKG_LIBRARY_LINKAGE} STREQUAL static) + set(OPTIONS "-DENABLE_SHARED=FALSE") +else() + set(OPTIONS "-DENABLE_STATIC=FALSE") +endif() + +vcpkg_configure_cmake( + SOURCE_PATH ${SOURCE_PATH} + PREFER_NINJA + OPTIONS ${OPTIONS} +) + +vcpkg_install_cmake() + +#remove extra debug files +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include) +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/doc) +file(GLOB DEBUGEXES ${CURRENT_PACKAGES_DIR}/debug/bin/*.exe) +file(REMOVE ${DEBUGEXES}) + +#move exes to tools +file(GLOB EXES ${CURRENT_PACKAGES_DIR}/bin/*.exe) +file(MAKE_DIRECTORY ${CURRENT_PACKAGES_DIR}/tools) +file(COPY ${EXES} DESTINATION ${CURRENT_PACKAGES_DIR}/tools) +file(REMOVE ${EXES}) + +#remove empty fodlers after static build +if (${VCPKG_LIBRARY_LINKAGE} STREQUAL static) + file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/bin) + file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/bin) +endif() + +# Handle copyright +file(INSTALL ${SOURCE_PATH}/LICENSE.md DESTINATION ${CURRENT_PACKAGES_DIR}/share/mozjpeg RENAME copyright) +vcpkg_copy_pdbs() \ No newline at end of file -- cgit v1.2.3 From 6f763c5ca830c9e461e106c63959a60d33eb5e5b Mon Sep 17 00:00:00 2001 From: Konstantin Podsvirov Date: Thu, 5 Oct 2017 21:24:32 +0300 Subject: [vcpkg-export-ifw] Maintenance Tool Install maintenance tool and create Start menu shortcuts to manage, update and uninstall packages. --- scripts/ifw/maintenance.qs | 46 +++++++++++++++++++++++++ toolsrc/src/commands_export_ifw.cpp | 69 ++++++++++++++++++++++++++++++++++--- 2 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 scripts/ifw/maintenance.qs diff --git a/scripts/ifw/maintenance.qs b/scripts/ifw/maintenance.qs new file mode 100644 index 000000000..5cdad7225 --- /dev/null +++ b/scripts/ifw/maintenance.qs @@ -0,0 +1,46 @@ +// constructor +function Component() +{ + installer.installationStarted.connect(this, Component.prototype.onInstallationStarted); +} + +Component.prototype.onInstallationStarted = function() +{ + if (component.updateRequested() || component.installationRequested()) { + if (installer.value("os") == "win") + component.installerbaseBinaryPath = "@TargetDir@/tempmaintenancetool.exe"; + installer.setInstallerBaseBinary(component.installerbaseBinaryPath); + } +} + +Component.prototype.createOperations = function() +{ + // call the base createOperations + component.createOperations(); + + // only for windows online installer + if ( installer.value("os") == "win" && !installer.isOfflineOnly() ) + { + // shortcut to add or remove packages + component.addOperation( "CreateShortcut", + "@TargetDir@/maintenancetool.exe", + "@StartMenuDir@/Manage vcpkg.lnk", + " --manage-packages"); + // shortcut to update packages + component.addOperation( "CreateShortcut", + "@TargetDir@/maintenancetool.exe", + "@StartMenuDir@/Update vcpkg.lnk", + " --updater"); + } + + // create uninstall link only for windows + if (installer.value("os") == "win") + { + // shortcut to uninstaller + component.addOperation( "CreateShortcut", + "@TargetDir@/maintenancetool.exe", + "@StartMenuDir@/Uninstall vcpkg.lnk", + " --uninstall"); + } +} + diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index 0dc8a7d31..4ab0ae537 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -270,12 +270,66 @@ namespace vcpkg::Commands::Export::IFW vcpkg 1.0.0 + vcpkg @RootDir@/src/vcpkg%s )###", formatted_repo_url)); } + void export_maintenance_tool(const fs::path& ifw_packages_dir_path, const VcpkgPaths& paths) + { + System::println("Exporting maintenance tool... "); + + std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + const fs::path& installerbase_exe = paths.get_ifw_installerbase_exe(); + fs::path tempmaintenancetool = ifw_packages_dir_path / "maintenance" / "data" / "tempmaintenancetool.exe"; + fs.create_directories(tempmaintenancetool.parent_path(), ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + tempmaintenancetool.generic_string()); + fs.copy_file(installerbase_exe, tempmaintenancetool, fs::copy_options::overwrite_existing, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not write package file %s", + tempmaintenancetool.generic_string()); + + fs::path package_xml_file_path = ifw_packages_dir_path / "maintenance" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + Maintenance Tool + Maintenance Tool + 1.0.0 + %s + + true + true + true + +)###", +create_release_date())); + const fs::path script_source = paths.root / "scripts" / "ifw" / "maintenance.qs"; + const fs::path script_destination = ifw_packages_dir_path / "maintenance" / "meta" / "maintenance.qs"; + fs.copy_file(script_source, script_destination, fs::copy_options::overwrite_existing, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not write package file %s", + script_destination.generic_string()); + + System::println("Exporting maintenance tool... done"); + } + void do_repository(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { const fs::path& repogen_exe = paths.get_ifw_repogen_exe(); @@ -343,14 +397,12 @@ namespace vcpkg::Commands::Export::IFW const Options& ifw_options, const VcpkgPaths& paths) { - const fs::path ifw_packages_dir_path = get_packages_dir_path(export_id, ifw_options, paths); - const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); - - System::println("Exporting packages %s... ", ifw_packages_dir_path.generic_string()); - std::error_code ec; Files::Filesystem& fs = paths.get_filesystem(); + // Prepare packages directory + const fs::path ifw_packages_dir_path = get_packages_dir_path(export_id, ifw_options, paths); + fs.remove_all(ifw_packages_dir_path, ec); Checks::check_exit(VCPKG_LINE_INFO, !ec, @@ -361,6 +413,11 @@ namespace vcpkg::Commands::Export::IFW Checks::check_exit( VCPKG_LINE_INFO, !ec, "Could not create packages directory %s", ifw_packages_dir_path.generic_string()); + // Export maintenance tool + export_maintenance_tool(ifw_packages_dir_path, paths); + + System::println("Exporting packages %s... ", ifw_packages_dir_path.generic_string()); + // execute the plan std::map unique_packages; std::set unique_triplets; @@ -395,6 +452,8 @@ namespace vcpkg::Commands::Export::IFW System::println("Exporting packages %s... done", ifw_packages_dir_path.generic_string()); + const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); + System::println("Generating configuration %s...", config_file.generic_string()); // Unique packages -- cgit v1.2.3 From a518ded266259141edd278e3f4025a3ab3211215 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 5 Oct 2017 14:36:29 -0700 Subject: [vcpkg] Check size and don't perform stripping if string is too small. --- toolsrc/src/vcpkg_System.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 4d2e88b73..7a6e7f028 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -179,6 +179,7 @@ namespace vcpkg::System // On Win7, output from powershell calls contain a byte order mark, so we strip it out if it is present static void remove_byte_order_mark(std::wstring* s) { + if (s->size() < 3) return; const wchar_t* a = s->c_str(); // This is the UTF-8 byte-order mark if (a[0] == 0xEF && a[1] == 0xBB && a[2] == 0xBF) -- cgit v1.2.3 From 2c9ee072da34a925f0faf22596e532d378930582 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 5 Oct 2017 17:49:28 -0700 Subject: [vcpkg_build_cmake] Refactor _build_ and _install_ into a single cmake script. Regenerate documentation. Remove MSVC_64_TOOLSET option because it's obsolete. --- docs/maintainers/portfile-functions.md | 2 + docs/maintainers/vcpkg_acquire_msys.md | 2 +- docs/maintainers/vcpkg_build_cmake.md | 31 ++++++++++++ docs/maintainers/vcpkg_find_acquire_program.md | 2 +- docs/maintainers/vcpkg_from_bitbucket.md | 53 +++++++++++++++++++++ docs/maintainers/vcpkg_from_github.md | 6 ++- docs/maintainers/vcpkg_install_cmake.md | 8 ++-- ports/folly/portfile.cmake | 2 +- ports/protobuf/portfile.cmake | 3 +- scripts/cmake/vcpkg_build_cmake.cmake | 65 ++++++++++++++------------ scripts/cmake/vcpkg_configure_cmake.cmake | 2 + scripts/cmake/vcpkg_install_cmake.cmake | 50 ++------------------ 12 files changed, 141 insertions(+), 85 deletions(-) create mode 100644 docs/maintainers/vcpkg_build_cmake.md create mode 100644 docs/maintainers/vcpkg_from_bitbucket.md diff --git a/docs/maintainers/portfile-functions.md b/docs/maintainers/portfile-functions.md index 705d65b7e..e16147f7d 100644 --- a/docs/maintainers/portfile-functions.md +++ b/docs/maintainers/portfile-functions.md @@ -3,6 +3,7 @@ # Portfile helper functions - [vcpkg\_acquire\_msys](vcpkg_acquire_msys.md) - [vcpkg\_apply\_patches](vcpkg_apply_patches.md) +- [vcpkg\_build\_cmake](vcpkg_build_cmake.md) - [vcpkg\_build\_msbuild](vcpkg_build_msbuild.md) - [vcpkg\_configure\_cmake](vcpkg_configure_cmake.md) - [vcpkg\_copy\_pdbs](vcpkg_copy_pdbs.md) @@ -11,5 +12,6 @@ - [vcpkg\_execute\_required\_process](vcpkg_execute_required_process.md) - [vcpkg\_extract\_source\_archive](vcpkg_extract_source_archive.md) - [vcpkg\_find\_acquire\_program](vcpkg_find_acquire_program.md) +- [vcpkg\_from\_bitbucket](vcpkg_from_bitbucket.md) - [vcpkg\_from\_github](vcpkg_from_github.md) - [vcpkg\_install\_cmake](vcpkg_install_cmake.md) diff --git a/docs/maintainers/vcpkg_acquire_msys.md b/docs/maintainers/vcpkg_acquire_msys.md index 46cda81fd..53aa6532e 100644 --- a/docs/maintainers/vcpkg_acquire_msys.md +++ b/docs/maintainers/vcpkg_acquire_msys.md @@ -32,7 +32,7 @@ message(STATUS "Installing MSYS Packages") vcpkg_execute_required_process( COMMAND ${BASH} --noprofile --norc -c - "pacman -Sy --noconfirm --needed make" + 'PATH=/usr/bin:\$PATH pacman -Sy --noconfirm --needed make' WORKING_DIRECTORY ${MSYS_ROOT} LOGNAME pacman-${TARGET_TRIPLET}) ``` diff --git a/docs/maintainers/vcpkg_build_cmake.md b/docs/maintainers/vcpkg_build_cmake.md new file mode 100644 index 000000000..ddfa46f6b --- /dev/null +++ b/docs/maintainers/vcpkg_build_cmake.md @@ -0,0 +1,31 @@ +# vcpkg_build_cmake + +Build a cmake project. + +## Usage: +```cmake +vcpkg_build_cmake([DISABLE_PARALLEL] [TARGET ]) +``` + +## Parameters: +### DISABLE_PARALLEL +The underlying buildsystem will be instructed to not parallelize + +### TARGET +The target passed to the cmake build command (`cmake --build . --target `). If not specified, no target will +be passed. + +## Notes: +This command should be preceeded by a call to [`vcpkg_configure_cmake()`](vcpkg_configure_cmake.md). +You can use the alias [`vcpkg_install_cmake()`](vcpkg_configure_cmake.md) function if your CMake script supports the +"install" target + +## Examples: + +* [zlib](https://github.com/Microsoft/vcpkg/blob/master/ports/zlib/portfile.cmake) +* [cpprestsdk](https://github.com/Microsoft/vcpkg/blob/master/ports/cpprestsdk/portfile.cmake) +* [poco](https://github.com/Microsoft/vcpkg/blob/master/ports/poco/portfile.cmake) +* [opencv](https://github.com/Microsoft/vcpkg/blob/master/ports/opencv/portfile.cmake) + +## Source +[scripts/cmake/vcpkg_build_cmake.cmake](https://github.com/Microsoft/vcpkg/blob/master/scripts/cmake/vcpkg_build_cmake.cmake) diff --git a/docs/maintainers/vcpkg_find_acquire_program.md b/docs/maintainers/vcpkg_find_acquire_program.md index bc50ef4c8..8107c8dd2 100644 --- a/docs/maintainers/vcpkg_find_acquire_program.md +++ b/docs/maintainers/vcpkg_find_acquire_program.md @@ -16,6 +16,7 @@ The current list of programs includes: - 7Z - BISON - FLEX +- GASPREPROCESSOR - PERL - PYTHON2 - PYTHON3 @@ -24,7 +25,6 @@ The current list of programs includes: - NASM - NINJA - YASM -- GASPREPROCESSOR Note that msys2 has a dedicated helper function: [`vcpkg_acquire_msys`](vcpkg_acquire_msys.md). diff --git a/docs/maintainers/vcpkg_from_bitbucket.md b/docs/maintainers/vcpkg_from_bitbucket.md new file mode 100644 index 000000000..c8850b725 --- /dev/null +++ b/docs/maintainers/vcpkg_from_bitbucket.md @@ -0,0 +1,53 @@ +# vcpkg_from_bitbucket + +Download and extract a project from Bitbucket. +Enables support for installing HEAD `vcpkg.exe install --head `. + +## Usage: +```cmake +vcpkg_from_bitbucket( + OUT_SOURCE_PATH + REPO + [REF ] + [SHA512 <45d0d7f8cc350...>] + [HEAD_REF ] +) +``` + +## Parameters: +### OUT_SOURCE_PATH +Specifies the out-variable that will contain the extracted location. + +This should be set to `SOURCE_PATH` by convention. + +### REPO +The organization or user and repository on GitHub. + +### REF +A stable git commit-ish (ideally a tag) that will not change contents. **This should not be a branch.** + +For repositories without official releases, this can be set to the full commit id of the current latest master. + +If `REF` is specified, `SHA512` must also be specified. + +### SHA512 +The SHA512 hash that should match the archive (https://bitbucket.com/${REPO}/get/${REF}.tar.gz). + +This is most easily determined by first setting it to `1`, then trying to build the port. The error message will contain the full hash, which can be copied back into the portfile. + +### HEAD_REF +The unstable git commit-ish (ideally a branch) to pull for `--head` builds. + +For most projects, this should be `master`. The chosen branch should be one that is expected to be always buildable on all supported platforms. + +## Notes: +At least one of `REF` and `HEAD_REF` must be specified, however it is preferable for both to be present. + +This exports the `VCPKG_HEAD_VERSION` variable during head builds. + +## Examples: + +* [blaze](https://github.com/Microsoft/vcpkg/blob/master/ports/blaze/portfile.cmake) + +## Source +[scripts/cmake/vcpkg_from_bitbucket.cmake](https://github.com/Microsoft/vcpkg/blob/master/scripts/cmake/vcpkg_from_bitbucket.cmake) diff --git a/docs/maintainers/vcpkg_from_github.md b/docs/maintainers/vcpkg_from_github.md index cb7849fcc..cf50dc445 100644 --- a/docs/maintainers/vcpkg_from_github.md +++ b/docs/maintainers/vcpkg_from_github.md @@ -23,7 +23,9 @@ This should be set to `SOURCE_PATH` by convention. The organization or user and repository on GitHub. ### REF -A stable git commit-ish (ideally a tag) that will not change contents. +A stable git commit-ish (ideally a tag) that will not change contents. **This should not be a branch.** + +For repositories without official releases, this can be set to the full commit id of the current latest master. If `REF` is specified, `SHA512` must also be specified. @@ -38,7 +40,7 @@ The unstable git commit-ish (ideally a branch) to pull for `--head` builds. For most projects, this should be `master`. The chosen branch should be one that is expected to be always buildable on all supported platforms. ## Notes: -At least one of `REF` and `HEAD_REF` must be specified. +At least one of `REF` and `HEAD_REF` must be specified, however it is preferable for both to be present. This exports the `VCPKG_HEAD_VERSION` variable during head builds. diff --git a/docs/maintainers/vcpkg_install_cmake.md b/docs/maintainers/vcpkg_install_cmake.md index e199d1292..1b132b4f1 100644 --- a/docs/maintainers/vcpkg_install_cmake.md +++ b/docs/maintainers/vcpkg_install_cmake.md @@ -4,15 +4,15 @@ Build and install a cmake project. ## Usage: ```cmake -vcpkg_install_cmake([MSVC_64_TOOLSET]) +vcpkg_install_cmake(...) ``` ## Parameters: -### MSVC_64_TOOLSET -This adds the `/p:PreferredToolArchitecture=x64` switch if the underlying buildsystem is MSBuild. Some large projects can run out of memory when linking if they use the 32-bit hosted tools. +See [`vcpkg_build_cmake()`](vcpkg_build_cmake.md). ## Notes: -This command should be preceeded by a call to [`vcpkg_configure_cmake()`](vcpkg_configure_cmake.md). +This command transparently forwards to [`vcpkg_build_cmake()`](vcpkg_build_cmake.md), adding a `TARGET install` +parameter. ## Examples: diff --git a/ports/folly/portfile.cmake b/ports/folly/portfile.cmake index 919e799d5..1b30ad86c 100644 --- a/ports/folly/portfile.cmake +++ b/ports/folly/portfile.cmake @@ -38,7 +38,7 @@ vcpkg_configure_cmake( # Folly runs built executables during the build, so they need access to the installed DLLs. set(ENV{PATH} "$ENV{PATH};${CURRENT_INSTALLED_DIR}/bin;${CURRENT_INSTALLED_DIR}/debug/bin") -vcpkg_install_cmake(MSVC_64_TOOLSET) +vcpkg_install_cmake() vcpkg_copy_pdbs() diff --git a/ports/protobuf/portfile.cmake b/ports/protobuf/portfile.cmake index e3cae639c..e7f45c36c 100644 --- a/ports/protobuf/portfile.cmake +++ b/ports/protobuf/portfile.cmake @@ -58,8 +58,7 @@ vcpkg_configure_cmake( -DCMAKE_INSTALL_CMAKEDIR=share/protobuf ) -# Using 64-bit toolset to avoid occassional Linker Out-of-Memory issues. -vcpkg_install_cmake(MSVC_64_TOOLSET) +vcpkg_install_cmake() # It appears that at this point the build hasn't actually finished. There is probably # a process spawned by the build, therefore we need to wait a bit. diff --git a/scripts/cmake/vcpkg_build_cmake.cmake b/scripts/cmake/vcpkg_build_cmake.cmake index 546071a36..5dc81ec09 100644 --- a/scripts/cmake/vcpkg_build_cmake.cmake +++ b/scripts/cmake/vcpkg_build_cmake.cmake @@ -4,19 +4,21 @@ ## ## ## Usage: ## ```cmake -## vcpkg_build_cmake([MSVC_64_TOOLSET] [DISABLE_PARALLEL]) +## vcpkg_build_cmake([DISABLE_PARALLEL] [TARGET ]) ## ``` ## ## ## Parameters: -## ### MSVC_64_TOOLSET -## This adds the `/p:PreferredToolArchitecture=x64` switch to the underlying buildsystem parameters. Some large projects can run out of memory when linking if they use the 32-bit hosted tools. -## ## ### DISABLE_PARALLEL -## The /m parameter will not be added to the underlying buildsystem parameters +## The underlying buildsystem will be instructed to not parallelize +## +## ### TARGET +## The target passed to the cmake build command (`cmake --build . --target `). If not specified, no target will +## be passed. ## ## ## Notes: ## This command should be preceeded by a call to [`vcpkg_configure_cmake()`](vcpkg_configure_cmake.md). -## Use [`vcpkg_install_cmake()`](vcpkg_configure_cmake.md) function if your CMake script supports the "install" target +## You can use the alias [`vcpkg_install_cmake()`](vcpkg_configure_cmake.md) function if your CMake script supports the +## "install" target ## ## ## Examples: ## @@ -25,45 +27,50 @@ ## * [poco](https://github.com/Microsoft/vcpkg/blob/master/ports/poco/portfile.cmake) ## * [opencv](https://github.com/Microsoft/vcpkg/blob/master/ports/opencv/portfile.cmake) function(vcpkg_build_cmake) - cmake_parse_arguments(_bc "MSVC_64_TOOLSET;DISABLE_PARALLEL" "" "" ${ARGN}) - - set(MSVC_EXTRA_ARGS - "/p:VCPkgLocalAppDataDisabled=true" - "/p:UseIntelMKL=No" - ) + cmake_parse_arguments(_bc "DISABLE_PARALLEL" "TARGET;LOGFILE_ROOT" "" ${ARGN}) - # Specifies the architecture of the toolset, NOT the architecture of the produced binary - # This can help libraries that cause the linker to run out of memory. - # https://support.microsoft.com/en-us/help/2891057/linker-fatal-error-lnk1102-out-of-memory - if (_bc_MSVC_64_TOOLSET) - list(APPEND MSVC_EXTRA_ARGS "/p:PreferredToolArchitecture=x64") + if(NOT _bc_LOGFILE_ROOT) + set(_bc_LOGFILE_ROOT "build") endif() - if (NOT _bc_DISABLE_PARALLEL) - list(APPEND MSVC_EXTRA_ARGS "/m") + if(_VCPKG_CMAKE_GENERATOR MATCHES "Ninja") + set(BUILD_ARGS "-v") # verbose output + if (_bc_DISABLE_PARALLEL) + list(APPEND BUILD_ARGS "-j1") + endif() + elseif(_VCPKG_CMAKE_GENERATOR MATCHES "Visual Studio") + set(BUILD_ARGS + "/p:VCPkgLocalAppDataDisabled=true" + "/p:UseIntelMKL=No" + ) + if (NOT _bc_DISABLE_PARALLEL) + list(APPEND BUILD_ARGS "/m") + endif() + elseif(_VCPKG_CMAKE_GENERATOR MATCHES "NMake") + # No options are currently added for nmake builds + else() + message(FATAL_ERROR "Unrecognized GENERATOR setting from vcpkg_configure_cmake(). Valid generators are: Ninja, Visual Studio, and NMake Makefiles") endif() - if(EXISTS ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel/build.ninja) - set(BUILD_ARGS -v) # verbose output - endif() - - if(_bc_MSVC_64_TOOLSET) - set(BUILD_ARGS ${MSVC_EXTRA_ARGS}) + if(_bc_TARGET) + set(TARGET_PARAM "--target" ${_bc_TARGET}) + else() + set(TARGET_PARAM) endif() message(STATUS "Build ${TARGET_TRIPLET}-rel") vcpkg_execute_required_process( - COMMAND ${CMAKE_COMMAND} --build . --config Release -- ${BUILD_ARGS} + COMMAND ${CMAKE_COMMAND} --build . --config Release ${TARGET_PARAM} -- ${BUILD_ARGS} WORKING_DIRECTORY ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel - LOGNAME build-${TARGET_TRIPLET}-rel + LOGNAME ${_bc_LOGFILE_ROOT}-${TARGET_TRIPLET}-rel ) message(STATUS "Build ${TARGET_TRIPLET}-rel done") message(STATUS "Build ${TARGET_TRIPLET}-dbg") vcpkg_execute_required_process( - COMMAND ${CMAKE_COMMAND} --build . --config Debug -- ${BUILD_ARGS} + COMMAND ${CMAKE_COMMAND} --build . --config Debug ${TARGET_PARAM} -- ${BUILD_ARGS} WORKING_DIRECTORY ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-dbg - LOGNAME build-${TARGET_TRIPLET}-dbg + LOGNAME ${_bc_LOGFILE_ROOT}-${TARGET_TRIPLET}-dbg ) message(STATUS "Build ${TARGET_TRIPLET}-dbg done") endfunction() diff --git a/scripts/cmake/vcpkg_configure_cmake.cmake b/scripts/cmake/vcpkg_configure_cmake.cmake index fecea8f1c..fe8c97c52 100644 --- a/scripts/cmake/vcpkg_configure_cmake.cmake +++ b/scripts/cmake/vcpkg_configure_cmake.cmake @@ -188,4 +188,6 @@ function(vcpkg_configure_cmake) LOGNAME config-${TARGET_TRIPLET}-dbg ) message(STATUS "Configuring ${TARGET_TRIPLET}-dbg done") + + set(_VCPKG_CMAKE_GENERATOR "${GENERATOR}" PARENT_SCOPE) endfunction() \ No newline at end of file diff --git a/scripts/cmake/vcpkg_install_cmake.cmake b/scripts/cmake/vcpkg_install_cmake.cmake index 34ac15fe6..ab72d054e 100644 --- a/scripts/cmake/vcpkg_install_cmake.cmake +++ b/scripts/cmake/vcpkg_install_cmake.cmake @@ -4,15 +4,15 @@ ## ## ## Usage: ## ```cmake -## vcpkg_install_cmake([MSVC_64_TOOLSET]) +## vcpkg_install_cmake(...) ## ``` ## ## ## Parameters: -## ### MSVC_64_TOOLSET -## This adds the `/p:PreferredToolArchitecture=x64` switch to the underlying buildsystem parameters. Some large projects can run out of memory when linking if they use the 32-bit hosted tools. +## See [`vcpkg_build_cmake()`](vcpkg_build_cmake.md). ## ## ## Notes: -## This command should be preceeded by a call to [`vcpkg_configure_cmake()`](vcpkg_configure_cmake.md). +## This command transparently forwards to [`vcpkg_build_cmake()`](vcpkg_build_cmake.md), adding a `TARGET install` +## parameter. ## ## ## Examples: ## @@ -21,45 +21,5 @@ ## * [poco](https://github.com/Microsoft/vcpkg/blob/master/ports/poco/portfile.cmake) ## * [opencv](https://github.com/Microsoft/vcpkg/blob/master/ports/opencv/portfile.cmake) function(vcpkg_install_cmake) - cmake_parse_arguments(_bc "MSVC_64_TOOLSET;DISABLE_PARALLEL" "" "" ${ARGN}) - - set(MSVC_EXTRA_ARGS - "/p:VCPkgLocalAppDataDisabled=true" - "/p:UseIntelMKL=No" - ) - - # Specifies the architecture of the toolset, NOT the architecture of the produced binary - # This can help libraries that cause the linker to run out of memory. - # https://support.microsoft.com/en-us/help/2891057/linker-fatal-error-lnk1102-out-of-memory - if (_bc_MSVC_64_TOOLSET) - list(APPEND MSVC_EXTRA_ARGS "/p:PreferredToolArchitecture=x64") - endif() - - if (NOT _bc_DISABLE_PARALLEL) - list(APPEND MSVC_EXTRA_ARGS "/m") - endif() - - if(EXISTS ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel/build.ninja) - set(BUILD_ARGS -v) # verbose output - endif() - - if(_bc_MSVC_64_TOOLSET) - set(BUILD_ARGS ${MSVC_EXTRA_ARGS}) - endif() - - message(STATUS "Package ${TARGET_TRIPLET}-rel") - vcpkg_execute_required_process( - COMMAND ${CMAKE_COMMAND} --build . --config Release --target install -- ${BUILD_ARGS} - WORKING_DIRECTORY ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-rel - LOGNAME package-${TARGET_TRIPLET}-rel - ) - message(STATUS "Package ${TARGET_TRIPLET}-rel done") - - message(STATUS "Package ${TARGET_TRIPLET}-dbg") - vcpkg_execute_required_process( - COMMAND ${CMAKE_COMMAND} --build . --config Debug --target install -- ${BUILD_ARGS} - WORKING_DIRECTORY ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}-dbg - LOGNAME package-${TARGET_TRIPLET}-dbg - ) - message(STATUS "Package ${TARGET_TRIPLET}-dbg done") + vcpkg_build_cmake(LOGFILE_ROOT install TARGET install ${ARGN}) endfunction() -- cgit v1.2.3 From 9b0c2cb2524ef3fa1e8e7e8f2512c32e40eb5815 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 5 Oct 2017 18:07:29 -0700 Subject: [vcpkg] Remove multiple byte order marks --- toolsrc/src/vcpkg_System.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 7a6e7f028..3b4c440d8 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -177,12 +177,11 @@ namespace vcpkg::System } // On Win7, output from powershell calls contain a byte order mark, so we strip it out if it is present - static void remove_byte_order_mark(std::wstring* s) + static void remove_byte_order_marks(std::wstring* s) { - if (s->size() < 3) return; const wchar_t* a = s->c_str(); // This is the UTF-8 byte-order mark - if (a[0] == 0xEF && a[1] == 0xBB && a[2] == 0xBF) + while (s->size() >= 3 && a[0] == 0xEF && a[1] == 0xBB && a[2] == 0xBF) { s->erase(0, 3); } @@ -214,7 +213,7 @@ namespace vcpkg::System const auto ec = _pclose(pipe); Debug::println("_pclose() returned %d", ec); - remove_byte_order_mark(&output); + remove_byte_order_marks(&output); return {ec, Strings::to_utf8(output)}; } -- cgit v1.2.3 From 13385293e62561166c490671630e92458e630b1b Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 5 Oct 2017 18:14:08 -0700 Subject: [vcpkg] Clang-format on commands_export_ifw --- toolsrc/src/commands_export_ifw.cpp | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index 4ab0ae537..191dbb763 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -288,25 +288,23 @@ namespace vcpkg::Commands::Export::IFW fs::path tempmaintenancetool = ifw_packages_dir_path / "maintenance" / "data" / "tempmaintenancetool.exe"; fs.create_directories(tempmaintenancetool.parent_path(), ec); Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - tempmaintenancetool.generic_string()); + !ec, + "Could not create directory for package file %s", + tempmaintenancetool.generic_string()); fs.copy_file(installerbase_exe, tempmaintenancetool, fs::copy_options::overwrite_existing, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not write package file %s", - tempmaintenancetool.generic_string()); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not write package file %s", tempmaintenancetool.generic_string()); fs::path package_xml_file_path = ifw_packages_dir_path / "maintenance" / "meta" / "package.xml"; fs::path package_xml_dir_path = package_xml_file_path.parent_path(); fs.create_directories(package_xml_dir_path, ec); Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); fs.write_contents(package_xml_file_path, - Strings::format( - R"###( + Strings::format( + R"###( Maintenance Tool Maintenance Tool @@ -318,14 +316,12 @@ namespace vcpkg::Commands::Export::IFW true )###", -create_release_date())); + create_release_date())); const fs::path script_source = paths.root / "scripts" / "ifw" / "maintenance.qs"; const fs::path script_destination = ifw_packages_dir_path / "maintenance" / "meta" / "maintenance.qs"; fs.copy_file(script_source, script_destination, fs::copy_options::overwrite_existing, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not write package file %s", - script_destination.generic_string()); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not write package file %s", script_destination.generic_string()); System::println("Exporting maintenance tool... done"); } -- cgit v1.2.3 From 7f68aa6630f96f474e85cd332dbbdc1ce6226d50 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 4 Oct 2017 15:50:48 -0700 Subject: Introduce Util::stable_keep_if() --- toolsrc/include/vcpkg_Util.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index c76ca01ac..e5ead6d3a 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -37,6 +37,12 @@ namespace vcpkg::Util return ret; } + template + void stable_keep_if(Container& cont, Pred pred) + { + cont.erase(std::stable_partition(cont.begin(), cont.end(), pred), cont.end()); + } + template void unstable_keep_if(Container& cont, Pred pred) { -- cgit v1.2.3 From 9a963f7eff1981d4e894ea8b297d092cda60b764 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Oct 2017 13:51:28 -0700 Subject: Overhaul VS selection. Add triplet option to specify VS instance --- scripts/get_triplet_environment.cmake | 3 +- toolsrc/include/VcpkgPaths.h | 5 +- toolsrc/include/vcpkg_Build.h | 3 +- toolsrc/include/vcpkg_Util.h | 15 +++++ toolsrc/src/PostBuildLint.cpp | 2 +- toolsrc/src/VcpkgPaths.cpp | 120 ++++++++++++++++++---------------- toolsrc/src/commands_env.cpp | 4 +- toolsrc/src/vcpkg_Build.cpp | 12 +++- 8 files changed, 97 insertions(+), 67 deletions(-) diff --git a/scripts/get_triplet_environment.cmake b/scripts/get_triplet_environment.cmake index 69e06bf97..b32f840d2 100644 --- a/scripts/get_triplet_environment.cmake +++ b/scripts/get_triplet_environment.cmake @@ -5,4 +5,5 @@ message("c35112b6-d1ba-415b-aa5d-81de856ef8eb") message("VCPKG_TARGET_ARCHITECTURE=${VCPKG_TARGET_ARCHITECTURE}") message("VCPKG_CMAKE_SYSTEM_NAME=${VCPKG_CMAKE_SYSTEM_NAME}") message("VCPKG_CMAKE_SYSTEM_VERSION=${VCPKG_CMAKE_SYSTEM_VERSION}") -message("VCPKG_PLATFORM_TOOLSET=${VCPKG_PLATFORM_TOOLSET}") \ No newline at end of file +message("VCPKG_PLATFORM_TOOLSET=${VCPKG_PLATFORM_TOOLSET}") +message("VCPKG_VISUAL_STUDIO_PATH=${VCPKG_VISUAL_STUDIO_PATH}") \ No newline at end of file diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index 4b4527434..d4640fba2 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -17,6 +17,7 @@ namespace vcpkg struct Toolset { + fs::path visual_studio_root_path; fs::path dumpbin; fs::path vcvarsall; std::vector vcvarsall_options; @@ -66,7 +67,8 @@ namespace vcpkg /// /// Valid version strings are "v140", "v141", and "". Empty string gets the latest. /// - const Toolset& get_toolset(const std::string& toolset_version) const; + const Toolset& VcpkgPaths::get_toolset(const Optional& toolset_version, + const Optional& visual_studio_path) const; Files::Filesystem& get_filesystem() const; @@ -78,6 +80,5 @@ namespace vcpkg Lazy ifw_binarycreator_exe; Lazy ifw_repogen_exe; Lazy> toolsets; - Lazy> toolsets_vs2017_v140; }; } diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h index 78e89d4de..5ba675757 100644 --- a/toolsrc/include/vcpkg_Build.h +++ b/toolsrc/include/vcpkg_Build.h @@ -79,7 +79,8 @@ namespace vcpkg::Build std::string target_architecture; std::string cmake_system_name; std::string cmake_system_version; - std::string platform_toolset; + Optional platform_toolset; + Optional visual_studio_path; }; std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset); diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index e5ead6d3a..a87045d73 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -67,6 +67,21 @@ namespace vcpkg::Util return std::find_if(cont.cbegin(), cont.cend(), pred); } + template + using ToVectorOfConstPointersT = std::decay_t()))>; + + template> + std::vector to_vector_of_const_pointers(const Container& cont) + { + std::vector output; + for (auto i = cont.cbegin(), cend = cont.end(); i != cend; ++i) + { + output.push_back(&(*i)); + } + + return output; + } + template auto find_if_not(const Container& cont, Pred pred) { diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index 416d4a636..a0699e15c 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -722,7 +722,7 @@ namespace vcpkg::PostBuildLint const auto& fs = paths.get_filesystem(); // for dumpbin - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset); + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); const fs::path package_dir = paths.package_dir(spec); size_t error_count = 0; diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 9f85992be..f080783c4 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -337,14 +337,14 @@ namespace vcpkg // VS2015 const Optional vs_2015_installation_instance = get_vs2015_installation_instance(); - if (const auto v = vs_2015_installation_instance.get()) + if (const auto vs_2015_root_path = vs_2015_installation_instance.get()) { - const fs::path vs2015_vcvarsall_bat = *v / "VC" / "vcvarsall.bat"; + const fs::path vs2015_vcvarsall_bat = *vs_2015_root_path / "VC" / "vcvarsall.bat"; paths_examined.push_back(vs2015_vcvarsall_bat); if (fs.exists(vs2015_vcvarsall_bat)) { - const fs::path vs2015_dumpbin_exe = *v / "VC" / "bin" / "dumpbin.exe"; + const fs::path vs2015_dumpbin_exe = *vs_2015_root_path / "VC" / "bin" / "dumpbin.exe"; paths_examined.push_back(vs2015_dumpbin_exe); const fs::path vs2015_bin_dir = vs2015_vcvarsall_bat.parent_path() / "bin"; @@ -364,19 +364,25 @@ namespace vcpkg if (fs.exists(vs2015_dumpbin_exe)) { - found_toolsets.push_back( - {vs2015_dumpbin_exe, vs2015_vcvarsall_bat, {}, V_140, supported_architectures}); + found_toolsets.push_back({*vs_2015_root_path, + vs2015_dumpbin_exe, + vs2015_vcvarsall_bat, + {}, + V_140, + supported_architectures}); } } } + const bool v140_is_available = !found_toolsets.empty(); + const std::vector vs2017_installation_instances = get_vs2017_installation_instances(paths); // VS2017 - Optional vs2017_toolset; for (const std::string& instance : vs2017_installation_instances) { - const fs::path vc_dir = fs::path{instance} / "VC"; + const fs::path vs_root_path = fs::path{instance}; + const fs::path vc_dir = vs_root_path / "VC"; // Skip any instances that do not have vcvarsall. const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build"; @@ -415,14 +421,22 @@ namespace vcpkg paths_examined.push_back(dumpbin_path); if (fs.exists(dumpbin_path)) { - vs2017_toolset = Toolset{dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}; + found_toolsets.push_back( + Toolset{vs_root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}); + + if (v140_is_available) + { + found_toolsets.push_back(Toolset{vs_root_path, + dumpbin_path, + vcvarsall_bat, + {L"-vcvars_ver=14.0"}, + V_140, + supported_architectures}); + } + break; } } - if (const auto value = vs2017_toolset.get()) - { - found_toolsets.push_back(*value); - } } if (found_toolsets.empty()) @@ -439,64 +453,54 @@ namespace vcpkg return found_toolsets; } - static std::vector create_vs2017_v140_toolset_instances(const std::vector& vs_toolsets) - { - std::vector vs2017_v140_toolsets; - - // In constrast to v141 and above, there can only be a single instance of v140 (VS2017 vs VS2015). - const auto it = Util::find_if(vs_toolsets, [&](const Toolset& t) { return t.version == V_140; }); - - // If v140 is not available, then VS2017 cant use them. Return empty. - if (it == vs_toolsets.cend()) - { - return vs2017_v140_toolsets; - } - - // If it does exist, then create a matching v140 toolset for each v141 toolset - const Toolset v140_toolset = *it; - for (const Toolset& toolset : vs_toolsets) - { - if (toolset.version != V_141) - { - continue; - } - - Toolset t = Toolset{ - toolset.dumpbin, toolset.vcvarsall, {L"-vcvars_ver=14.0"}, V_140, toolset.supported_architectures}; - vs2017_v140_toolsets.push_back(std::move(t)); - } - - return vs2017_v140_toolsets; - } - - const Toolset& VcpkgPaths::get_toolset(const std::string& toolset_version) const + const Toolset& VcpkgPaths::get_toolset(const Optional& toolset_version, + const Optional& visual_studio_path) const { - const std::wstring& w_toolset_version = Strings::to_utf16(toolset_version); - // Invariant: toolsets are non-empty and sorted with newest at back() const std::vector& vs_toolsets = this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); - if (w_toolset_version.empty()) + std::vector candidates = Util::to_vector_of_const_pointers(vs_toolsets); + const auto tsv = toolset_version.get(); + const auto vsp = visual_studio_path.get(); + + if (tsv && vsp) { - return vs_toolsets.back(); + const std::wstring w_toolset_version = Strings::to_utf16(*tsv); + const fs::path vs_root_path = *vsp; + Util::stable_keep_if(candidates, [&](const Toolset* t) { + return w_toolset_version == t->version && vs_root_path == t->visual_studio_root_path; + }); + Checks::check_exit(VCPKG_LINE_INFO, + !candidates.empty(), + "Could not find Visual Studio instace at %s with %s toolset.", + vs_root_path.generic_string(), + *tsv); + + Checks::check_exit(VCPKG_LINE_INFO, candidates.size() == 1); + return *candidates.back(); } - const auto toolset = - Util::find_if(vs_toolsets, [&](const Toolset& t) { return w_toolset_version == t.version; }); - Checks::check_exit( - VCPKG_LINE_INFO, toolset != vs_toolsets.end(), "Could not find toolset '%s'", toolset_version); + if (tsv) + { + const std::wstring w_toolset_version = Strings::to_utf16(*tsv); + Util::stable_keep_if(candidates, [&](const Toolset* t) { return w_toolset_version == t->version; }); + Checks::check_exit( + VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instace with %s toolset.", *tsv); + } - // If v140 is the selected toolset and VS2017 is available, then use VS2017's vcvarsall with the - // -vcvars_ver=14.0 option - const std::vector& vs2017_v140_toolsets = this->toolsets_vs2017_v140.get_lazy( - [&vs_toolsets]() { return create_vs2017_v140_toolset_instances(vs_toolsets); }); - if (w_toolset_version == V_140 && !vs2017_v140_toolsets.empty()) + if (vsp) { - return vs2017_v140_toolsets.back(); + const fs::path vs_root_path = *vsp; + Util::stable_keep_if(candidates, + [&](const Toolset* t) { return vs_root_path == t->visual_studio_root_path; }); + Checks::check_exit(VCPKG_LINE_INFO, + !candidates.empty(), + "Could not find Visual Studio instace at %s.", + vs_root_path.generic_string()); } - return *toolset; + return *candidates.back(); } Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); } diff --git a/toolsrc/src/commands_env.cpp b/toolsrc/src/commands_env.cpp index 073c501f5..6dad3e882 100644 --- a/toolsrc/src/commands_env.cpp +++ b/toolsrc/src/commands_env.cpp @@ -13,8 +13,8 @@ namespace vcpkg::Commands::Env args.check_and_get_optional_command_arguments({}); const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); - System::cmd_execute_clean( - Build::make_build_env_cmd(pre_build_info, paths.get_toolset(pre_build_info.platform_toolset)) + L" && cmd"); + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); + System::cmd_execute_clean(Build::make_build_env_cmd(pre_build_info, toolset) + L" && cmd"); Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp index 853f84998..9be20629d 100644 --- a/toolsrc/src/vcpkg_Build.cpp +++ b/toolsrc/src/vcpkg_Build.cpp @@ -138,7 +138,7 @@ namespace vcpkg::Build const fs::path ports_cmake_script_path = paths.ports_cmake; const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset); + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); std::string features; @@ -386,7 +386,15 @@ namespace vcpkg::Build if (variable_name == "VCPKG_PLATFORM_TOOLSET") { - pre_build_info.platform_toolset = variable_value; + pre_build_info.platform_toolset = + variable_value.empty() ? nullopt : Optional{variable_value}; + continue; + } + + if (variable_name == "VCPKG_VISUAL_STUDIO_PATH") + { + pre_build_info.visual_studio_path = + variable_value.empty() ? nullopt : Optional{variable_value}; continue; } -- cgit v1.2.3 From eca5a8b8d48d24c1a50fac58797af45dc5e83110 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Oct 2017 14:27:36 -0700 Subject: Add vswhere in fetchDependency.ps1 --- scripts/fetchDependency.ps1 | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/fetchDependency.ps1 b/scripts/fetchDependency.ps1 index 25447c19b..80d6d2abb 100644 --- a/scripts/fetchDependency.ps1 +++ b/scripts/fetchDependency.ps1 @@ -119,11 +119,21 @@ function SelectProgram([Parameter(Mandatory=$true)][string]$Dependency) $requiredVersion = "4.1.0" $downloadVersion = "4.1.0" $url = "https://dist.nuget.org/win-x86-commandline/v4.1.0/nuget.exe" - $downloadPath = "$downloadsDir\nuget-4.1.0\nuget.exe" + $downloadPath = "$downloadsDir\nuget-$downloadVersion\nuget.exe" $expectedDownloadedFileHash = "4c1de9b026e0c4ab087302ff75240885742c0faa62bd2554f913bbe1f6cb63a0" $executableFromDownload = $downloadPath $extractionType = $ExtractionType_NO_EXTRACTION_REQUIRED } + elseif($Dependency -eq "vswhere") + { + $requiredVersion = "2.1.4" + $downloadVersion = "2.1.4" + $url = "https://github.com/Microsoft/vswhere/releases/download/2.1.4/vswhere.exe" + $downloadPath = "$downloadsDir\vswhere-$downloadVersion\vswhere.exe" + $expectedDownloadedFileHash = "548fb9dfeed59bc4ddcce739a5729e9c8dd5932cd60ff6f74727ee069e7da458" + $executableFromDownload = $downloadPath + $extractionType = $ExtractionType_NO_EXTRACTION_REQUIRED + } elseif($Dependency -eq "git") { $requiredVersion = "2.14.1" -- cgit v1.2.3 From 86f3a9dbbdc360db3716b878dd37f2dbec8e983c Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Oct 2017 18:12:17 -0700 Subject: Fix Strings::split() to handle delimiters of arbitrary size --- toolsrc/src/vcpkg_Strings.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp index 21df2c309..bbe6b29cd 100644 --- a/toolsrc/src/vcpkg_Strings.cpp +++ b/toolsrc/src/vcpkg_Strings.cpp @@ -154,11 +154,13 @@ namespace vcpkg::Strings return output; } + const size_t delimiter_length = delimiter.length(); size_t i = 0; for (size_t pos = s.find(delimiter); pos != std::string::npos; pos = s.find(delimiter, pos)) { output.push_back(s.substr(i, pos - i)); - i = ++pos; + pos += delimiter_length; + i = pos; } // Add the rest of the string after the last delimiter, unless there is nothing after it -- cgit v1.2.3 From f0c23aeb6b238ee0ba2dc272ee4c193f2f777460 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Oct 2017 18:25:34 -0700 Subject: Completely rework Visual Studio detection - Now using vswhere.exe to detect all VS instance (2015 + 2017) - Default version preference order is now: stable, prerelease, legacy - Within each preference weight, the latest one is chosen - findVisualStudioInstallationInstances.ps1 now has a parameter to choose VS instance --- scripts/findAnyMSBuildWithCppPlatformToolset.ps1 | 172 +++--------------- scripts/findVisualStudioInstallationInstances.ps1 | 49 ++--- toolsrc/include/vcpkg_Util.h | 14 +- toolsrc/src/VcpkgPaths.cpp | 209 ++++++++++++---------- 4 files changed, 172 insertions(+), 272 deletions(-) diff --git a/scripts/findAnyMSBuildWithCppPlatformToolset.ps1 b/scripts/findAnyMSBuildWithCppPlatformToolset.ps1 index f72491e5d..632cc2cdf 100644 --- a/scripts/findAnyMSBuildWithCppPlatformToolset.ps1 +++ b/scripts/findAnyMSBuildWithCppPlatformToolset.ps1 @@ -1,164 +1,50 @@ [CmdletBinding()] param( [Parameter(Mandatory=$False)] - [switch]$DisableVS2017 = $False, - - [Parameter(Mandatory=$False)] - [switch]$DisableVS2015 = $False + [string]$explicitlyRequestedVSPath = "" ) -if ($DisableVS2017 -and $DisableVS2015) -{ - throw "Both VS2015 and VS2017 were disabled." -} - -function New-MSBuildInstance() -{ - param ($msbuildExePath, $toolsetVersion) - - $instance = new-object PSObject - $instance | add-member -type NoteProperty -Name msbuildExePath -Value $msbuildExePath - $instance | add-member -type NoteProperty -Name toolsetVersion -Value $toolsetVersion +$explicitlyRequestedVSPath = $explicitlyRequestedVSPath -replace "\\$" # Remove potential trailing backslash - return $instance -} - -Write-Verbose "Executing $($MyInvocation.MyCommand.Name) with DisableVS2017=$DisableVS2017, DisableVS2015=$DisableVS2015" $scriptsDir = split-path -parent $MyInvocation.MyCommand.Definition - -$validInstances = New-Object System.Collections.ArrayList - -# VS2017 -Write-Verbose "`n`n" -Write-Verbose "Checking for MSBuild from VS2017 instances..." -$VisualStudio2017InstallationInstances = & $scriptsDir\findVisualStudioInstallationInstances.ps1 -Write-Verbose "VS2017 Candidates: $([system.String]::Join(',', $VisualStudio2017InstallationInstances))" -foreach ($instanceCandidate in $VisualStudio2017InstallationInstances) -{ - $VCFolder= "$instanceCandidate\VC\Tools\MSVC\" - - if (Test-Path $VCFolder) - { - $instance = New-MSBuildInstance "$instanceCandidate\MSBuild\15.0\Bin\MSBuild.exe" "v141" - Write-Verbose "Found $instance" - $validInstances.Add($instance) > $null - } -} - -# VS2015 - in Program Files -Write-Verbose "`n`n" -Write-Verbose "Checking for MSBuild from VS2015 in Program Files..." -$CandidateProgramFiles = $(& $scriptsDir\getProgramFiles32bit.ps1), $(& $scriptsDir\getProgramFilesPlatformBitness.ps1) -Write-Verbose "Program Files Candidate locations: $([system.String]::Join(',', $CandidateProgramFiles))" -foreach ($ProgramFiles in $CandidateProgramFiles) -{ - $clExe= "$ProgramFiles\Microsoft Visual Studio 14.0\VC\bin\cl.exe" - - if (!(Test-Path $clExe)) - { - Write-Verbose "$clExe - Not Found" - continue - } - - Write-Verbose "$clExe - Found" - $instance = New-MSBuildInstance "$ProgramFiles\MSBuild\14.0\Bin\MSBuild.exe" "v140" - Write-Verbose "Found $instance" - $validInstances.Add($instance) > $null -} - -# VS2015 - through the registry -function NewCppRegistryPair() -{ - param ($visualStudioEntry, $msBuildEntry) - - $instance = new-object PSObject - $instance | add-member -type NoteProperty -Name visualStudioEntry -Value $visualStudioEntry - $instance | add-member -type NoteProperty -Name msBuildEntry -Value $msBuildEntry - - return $instance -} - -Write-Verbose "`n`n" -Write-Verbose "Checking for MSBuild from VS2015 through the registry..." - -$registryPairs = -$(NewCppRegistryPair "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\visualstudio\14.0" "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\msbuild\toolsversions\14.0"), -$(NewCppRegistryPair "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\visualstudio\14.0" "Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\msbuild\toolsversions\14.0") - -foreach ($pair in $registryPairs) +$VisualStudioInstallationInstances = & $scriptsDir\findVisualStudioInstallationInstances.ps1 +Write-Verbose "VS Candidates:`n`r$([system.String]::Join([Environment]::NewLine, $VisualStudioInstallationInstances))" +foreach ($instanceCandidate in $VisualStudioInstallationInstances) { - $vsEntry = $pair.visualStudioEntry - try - { - $VS14InstallDir = $(gp $vsEntry InstallDir -erroraction Stop | % { $_.InstallDir }) - Write-Verbose "$vsEntry\InstallDir - Found" - } - catch - { - Write-Verbose "$vsEntry\InstallDir - Not Found" - continue - } - - Write-Verbose "$VS14InstallDir - Obtained from registry" - # We want "${VS14InstallDir}..\..\VC\bin\cl.exe" - # Doing Split-path to avoid the ..\.. from appearing in the output - $clExePath = Split-path $VS14InstallDir -Parent - $clExePath = Split-path $clExePath -Parent - $clExePath = "$clExePath\VC\bin\cl.exe" - - if (!(Test-Path $clExePath)) - { - Write-Verbose "$clExePath - Not Found" - continue - } + Write-Verbose "Inspecting: $instanceCandidate" + $split = $instanceCandidate -split "::" + # $preferenceWeight = $split[0] + # $releaseType = $split[1] + $version = $split[2] + $path = $split[3] - Write-Verbose "$clExePath - Found" - - $msbuildEntry = $pair.msBuildEntry - try - { - $MSBuild14 = $(gp $msbuildEntry MSBuildToolsPath -erroraction Stop | % { $_.MSBuildToolsPath }) - Write-Verbose "$msbuildEntry\MSBuildToolsPath - Found" - } - catch - { - Write-Verbose "$msbuildEntry\MSBuildToolsPath - Not Found" - continue - } - - Write-Verbose "${MSBuild14} - Obtained from registry" - $msbuildPath = "${MSBuild14}MSBuild.exe" - if (!(Test-Path $msbuildPath)) + if ($explicitlyRequestedVSPath -ne "" -and $explicitlyRequestedVSPath -ne $path) { - Write-Verbose "$msbuildPath - Not Found" + Write-Verbose "Skipping: $instanceCandidate" continue } - $instance = New-MSBuildInstance $msbuildPath "v140" - Write-Verbose "Found $instance" - $validInstances.Add($instance) > $null -} - -Write-Verbose "`n`n`n" -Write-Verbose "The following MSBuild instances were found:" -foreach ($instance in $validInstances) -{ - Write-Verbose $instance -} - -# Selecting -foreach ($instance in $validInstances) -{ - if (!$DisableVS2017 -and $instance.toolsetVersion -eq "v141") + $majorVersion = $version.Substring(0,2); + if ($majorVersion -eq "15") { - return $instance.msbuildExePath, $instance.toolsetVersion + $VCFolder= "$path\VC\Tools\MSVC\" + if (Test-Path $VCFolder) + { + Write-Verbose "Picking: $instanceCandidate" + return "$path\MSBuild\15.0\Bin\MSBuild.exe", "v141" + } } - if (!$DisableVS2015 -and $instance.toolsetVersion -eq "v140") + if ($majorVersion -eq "14") { - return $instance.msbuildExePath, $instance.toolsetVersion + $clExe= "$path\VC\bin\cl.exe" + if (Test-Path $clExe) + { + Write-Verbose "Picking: $instanceCandidate" + $programFilesPath = split-path -parent $path + return "$programFilesPath\MSBuild\14.0\Bin\MSBuild.exe", "v140" + } } } - throw "Could not find MSBuild version with C++ support. VS2015 or VS2017 (with C++) needs to be installed." \ No newline at end of file diff --git a/scripts/findVisualStudioInstallationInstances.ps1 b/scripts/findVisualStudioInstallationInstances.ps1 index ca807980c..8c67ef6d6 100644 --- a/scripts/findVisualStudioInstallationInstances.ps1 +++ b/scripts/findVisualStudioInstallationInstances.ps1 @@ -4,32 +4,35 @@ param( ) $scriptsDir = split-path -parent $MyInvocation.MyCommand.Definition -$vcpkgRootDir = & $scriptsDir\findFileRecursivelyUp.ps1 $scriptsDir .vcpkg-root +$vswhereExe = & $scriptsDir\fetchDependency.ps1 "vswhere" -$downloadsDir = "$vcpkgRootDir\downloads" +$output = & $vswhereExe -prerelease -legacy -format xml +[xml]$asXml = $output -$nugetexe = & $scriptsDir\fetchDependency.ps1 "nuget" -$nugetPackageDir = "$downloadsDir\nuget-packages" - -$SetupAPIVersion = "1.8.24" -Write-Verbose "Fetching Microsoft.VisualStudio.Setup.Configuration.Native@$SetupAPIVersion from NuGet." -$nugetOutput = & $nugetexe install Microsoft.VisualStudio.Setup.Configuration.Native -Version $SetupAPIVersion -OutputDirectory $nugetPackageDir -Source "https://api.nuget.org/v3/index.json" -nocache 2>&1 -Write-Verbose "Fetching Microsoft.VisualStudio.Setup.Configuration.Native@$SetupAPIVersion from NuGet. Done." - -$SetupConsoleExe = "$nugetPackageDir\Microsoft.VisualStudio.Setup.Configuration.Native.$SetupAPIVersion\tools\x86\Microsoft.VisualStudio.Setup.Configuration.Console.exe" - -if (!(Test-Path $SetupConsoleExe)) +$results = New-Object System.Collections.ArrayList +foreach ($instance in $asXml.instances.instance) { - throw $nugetOutput + $installationPath = $instance.InstallationPath -replace "\\$" # Remove potential trailing backslash + $installationVersion = $instance.InstallationVersion + $isPrerelease = $instance.IsPrerelease + if ($isPrerelease -eq 0) + { + $releaseType = "PreferenceWeight3::StableRelease" + } + elseif ($isPrerelease -eq 1) + { + $releaseType = "PreferenceWeight2::PreRelease" + } + else + { + $releaseType = "PreferenceWeight1::Legacy" + } + + # Placed like that for easy sorting according to preference + $results.Add("${releaseType}::${installationVersion}::${installationPath}") > $null } -$instances = & $SetupConsoleExe -nologo -value InstallationPath 2>&1 -$instanceCount = $instances.Length - -# The last item can be empty -if ($instanceCount -gt 0 -and $instances[$instanceCount - 1] -eq "") -{ - $instances = $instances[0..($instanceCount - 2)] -} +$results.Sort() +$results.Reverse() -return $instances +return $results \ No newline at end of file diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index a87045d73..facb7dd26 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -68,18 +68,12 @@ namespace vcpkg::Util } template - using ToVectorOfConstPointersT = std::decay_t()))>; + using ElementT = std::remove_reference_t()))>; - template> - std::vector to_vector_of_const_pointers(const Container& cont) + template> + std::vector element_pointers(Container&& cont) { - std::vector output; - for (auto i = cont.cbegin(), cend = cont.end(); i != cend; ++i) - { - output.push_back(&(*i)); - } - - return output; + return fmap(cont, [](auto&& x) { return &x; }); } template diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index f080783c4..8264ec293 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -302,26 +302,33 @@ namespace vcpkg [this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; }); } - static std::vector get_vs2017_installation_instances(const VcpkgPaths& paths) + struct VisualStudioInstance + { + fs::path root_path; + std::string version; + std::string release_type; + std::string preference_weight; // Mostly unused, just for verification that order is as intended + + std::string major_version() const { return version.substr(0, 2); } + }; + + static std::vector get_visual_studio_instances(const VcpkgPaths& paths) { const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; const std::wstring cmd = System::create_powershell_script_cmd(script); const System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd); - Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect VS 2017 instances"); - return Strings::split(ec_data.output, "\n"); - } + Checks::check_exit( + VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect Visual Studio instances"); - static Optional get_vs2015_installation_instance() - { - const Optional vs2015_cmntools_optional = System::get_environment_variable(L"VS140COMNTOOLS"); - if (const auto v = vs2015_cmntools_optional.get()) + const std::vector instances_as_strings = Strings::split(ec_data.output, "\n"); + std::vector output; + for (const std::string& instance_as_string : instances_as_strings) { - const fs::path vs2015_cmntools = fs::path(*v).parent_path(); // The call to parent_path() is needed because - // the env variable has a trailing backslash - return vs2015_cmntools.parent_path().parent_path(); + const std::vector split = Strings::split(instance_as_string, "::"); + output.push_back({split.at(3), split.at(2), split.at(1), split.at(0)}); } - return nullopt; + return output; } static std::vector find_toolset_instances(const VcpkgPaths& paths) @@ -335,108 +342,118 @@ namespace vcpkg std::vector found_toolsets; - // VS2015 - const Optional vs_2015_installation_instance = get_vs2015_installation_instance(); - if (const auto vs_2015_root_path = vs_2015_installation_instance.get()) - { - const fs::path vs2015_vcvarsall_bat = *vs_2015_root_path / "VC" / "vcvarsall.bat"; + const std::vector vs_instances = get_visual_studio_instances(paths); + const bool v140_is_available = Util::find_if(vs_instances, [&](const VisualStudioInstance& vs_instance) { + return vs_instance.major_version() == "14"; + }) != vs_instances.cend(); - paths_examined.push_back(vs2015_vcvarsall_bat); - if (fs.exists(vs2015_vcvarsall_bat)) + // VS2017 + for (const VisualStudioInstance& vs_instance : vs_instances) + { + const std::string major_version = vs_instance.major_version(); + if (major_version == "15") { - const fs::path vs2015_dumpbin_exe = *vs_2015_root_path / "VC" / "bin" / "dumpbin.exe"; - paths_examined.push_back(vs2015_dumpbin_exe); + const fs::path vc_dir = vs_instance.root_path / "VC"; + + // Skip any instances that do not have vcvarsall. + const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build"; + const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat"; + paths_examined.push_back(vcvarsall_bat); + if (!fs.exists(vcvarsall_bat)) continue; - const fs::path vs2015_bin_dir = vs2015_vcvarsall_bat.parent_path() / "bin"; + // Get all supported architectures std::vector supported_architectures; - if (fs.exists(vs2015_bin_dir / "vcvars32.bat")) + if (fs.exists(vcvarsall_dir / "vcvars32.bat")) supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); - if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat")) - supported_architectures.push_back({L"x64", CPU::X64, CPU::X64}); - if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) + if (fs.exists(vcvarsall_dir / "vcvars64.bat")) + supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64}); + if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); - if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) + if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); - if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) + if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); - if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) + if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); - if (fs.exists(vs2015_dumpbin_exe)) + // Locate the "best" MSVC toolchain version + const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; + std::vector msvc_subdirectories = fs.get_files_non_recursive(msvc_path); + Util::unstable_keep_if(msvc_subdirectories, + [&fs](const fs::path& path) { return fs.is_directory(path); }); + + // Sort them so that latest comes first + std::sort( + msvc_subdirectories.begin(), + msvc_subdirectories.end(), + [](const fs::path& left, const fs::path& right) { return left.filename() > right.filename(); }); + + for (const fs::path& subdir : msvc_subdirectories) { - found_toolsets.push_back({*vs_2015_root_path, - vs2015_dumpbin_exe, - vs2015_vcvarsall_bat, - {}, - V_140, - supported_architectures}); + const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe"; + paths_examined.push_back(dumpbin_path); + if (fs.exists(dumpbin_path)) + { + found_toolsets.push_back(Toolset{ + vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}); + + if (v140_is_available) + { + found_toolsets.push_back(Toolset{vs_instance.root_path, + dumpbin_path, + vcvarsall_bat, + {L"-vcvars_ver=14.0"}, + V_140, + supported_architectures}); + } + + break; + } } - } - } - const bool v140_is_available = !found_toolsets.empty(); - - const std::vector vs2017_installation_instances = get_vs2017_installation_instances(paths); + continue; + } - // VS2017 - for (const std::string& instance : vs2017_installation_instances) - { - const fs::path vs_root_path = fs::path{instance}; - const fs::path vc_dir = vs_root_path / "VC"; - - // Skip any instances that do not have vcvarsall. - const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build"; - const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat"; - paths_examined.push_back(vcvarsall_bat); - if (!fs.exists(vcvarsall_bat)) continue; - - // Get all supported architectures - std::vector supported_architectures; - if (fs.exists(vcvarsall_dir / "vcvars32.bat")) - supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); - if (fs.exists(vcvarsall_dir / "vcvars64.bat")) - supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64}); - if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) - supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); - if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) - supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); - if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) - supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); - if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) - supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); - - // Locate the "best" MSVC toolchain version - const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; - std::vector msvc_subdirectories = fs.get_files_non_recursive(msvc_path); - Util::unstable_keep_if(msvc_subdirectories, [&fs](const fs::path& path) { return fs.is_directory(path); }); - - // Sort them so that latest comes first - std::sort(msvc_subdirectories.begin(), - msvc_subdirectories.end(), - [](const fs::path& left, const fs::path& right) { return left.filename() > right.filename(); }); - - for (const fs::path& subdir : msvc_subdirectories) + if (major_version == "14") { - const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe"; - paths_examined.push_back(dumpbin_path); - if (fs.exists(dumpbin_path)) - { - found_toolsets.push_back( - Toolset{vs_root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}); + const fs::path vcvarsall_bat = vs_instance.root_path / "VC" / "vcvarsall.bat"; - if (v140_is_available) + paths_examined.push_back(vcvarsall_bat); + if (fs.exists(vcvarsall_bat)) + { + const fs::path vs2015_dumpbin_exe = vs_instance.root_path / "VC" / "bin" / "dumpbin.exe"; + paths_examined.push_back(vs2015_dumpbin_exe); + + const fs::path vs2015_bin_dir = vcvarsall_bat.parent_path() / "bin"; + std::vector supported_architectures; + if (fs.exists(vs2015_bin_dir / "vcvars32.bat")) + supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); + if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat")) + supported_architectures.push_back({L"x64", CPU::X64, CPU::X64}); + if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) + supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); + if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) + supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); + if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) + supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); + if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) + supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + + if (fs.exists(vs2015_dumpbin_exe)) { - found_toolsets.push_back(Toolset{vs_root_path, - dumpbin_path, - vcvarsall_bat, - {L"-vcvars_ver=14.0"}, - V_140, - supported_architectures}); + found_toolsets.push_back({vs_instance.root_path, + vs2015_dumpbin_exe, + vcvarsall_bat, + {}, + V_140, + supported_architectures}); } - - break; } + + continue; } + + Checks::exit_with_message(VCPKG_LINE_INFO, "Expected major version 14 or 15 but got: %s", major_version); } if (found_toolsets.empty()) @@ -460,7 +477,7 @@ namespace vcpkg const std::vector& vs_toolsets = this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); - std::vector candidates = Util::to_vector_of_const_pointers(vs_toolsets); + std::vector candidates = Util::element_pointers(vs_toolsets); const auto tsv = toolset_version.get(); const auto vsp = visual_studio_path.get(); @@ -500,7 +517,7 @@ namespace vcpkg vs_root_path.generic_string()); } - return *candidates.back(); + return *candidates.front(); } Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); } -- cgit v1.2.3 From 9ae4b9f885c6bb3ede212d42c51f2b96fbfc86dd Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Oct 2017 19:01:48 -0700 Subject: Update CHANGELOG and bump version to v0.0.91 --- CHANGELOG.md | 42 ++++++++++++++++++++++++++++++++++++++++++ toolsrc/VERSION.txt | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75d89f6ac..5a2b0e336 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,45 @@ +vcpkg (0.0.91) +-------------- + * Add ports: + - abseil 2017-09-28 + - enet 1.3.13 + - exiv2 4f4add2cdcbe73af7098122a509dff0739d15908 + - freexl 1.0.4 + - gts 0.7.6 + - kinectsdk2 2.0 + - libexif 0.6.21-1 + - libfreenect2 0.2.0 + - librtmp 2.3 + - libspatialite 4.3.0a + - libxmp-lite 4.4.1 + - proj4 4.9.3-1 + - readosm 1.1.0 + - spirit-po 1.1.2 + - telnetpp 1.2.4 + - wildmidi 0.4.1 + * Update ports: + - anax 2.1.0-2 -> 2.1.0-3 + - aws-sdk-cpp 1.0.61-1 -> 1.2.4 + - geos 3.5.0-1 -> 3.6.2-2 + - kinectsdk1 1.8-1 -> 1.8-2 + - lua 5.3.4-1 -> 5.3.4-2 + - openni2 2.2.0.33 -> 2.2.0.33-2 + - openssl 1.0.2l-2 -> 1.0.2l-3 + - pangolin 0.5-1 -> 0.5-2 + - proj 4.9.3-1 -> 0 + - sdl2 2.0.5-4 -> 2.0.6-1 + - zlib 1.2.11-2 -> 1.2.11-3 + * `vcpkg export`: Add new option `--ifw` which creates a standalone GUI installer for the exported packages. More information and screenshots [here](https://github.com/Microsoft/vcpkg/pull/1734) + * Complete rework of Visual Studio detection & selection: + - Use [`vswhere.exe`](https://github.com/Microsoft/vswhere) to detect Visual Studio installation instances + - Add the ability to specify the Visual Studio instance to use in the triplet file with the `VCPKG_VISUAL_STUDIO_PATH` variable + - Automatic selection now picks instances in order: stable, prerelease, legacy. Within each group, newer versions are preferred over old versions + - Fix issue where v140 toolset would not work if VS2017 (with v140) was installed but VS2015 was not installed + * Add message when downloading a `vcpkg` dependency (e.g. `cmake`) + +-- vcpkg team THU, 05 Oct 2017 19:00:00 -0800 + + vcpkg (0.0.90) -------------- * Add ports: diff --git a/toolsrc/VERSION.txt b/toolsrc/VERSION.txt index c47961221..04ab0d2c9 100644 --- a/toolsrc/VERSION.txt +++ b/toolsrc/VERSION.txt @@ -1 +1 @@ -"0.0.90" \ No newline at end of file +"0.0.91" \ No newline at end of file -- cgit v1.2.3 From 0643bd6581182a537b23c885b1c6b27e33e61dc4 Mon Sep 17 00:00:00 2001 From: Daniel Strommen Date: Thu, 5 Oct 2017 19:47:41 -0700 Subject: Fix Win10SDK detection during Bootstrap When multiple Win10 SDK's are installed, like Insider previews, depending on the SDK installation, it may not contain the um headers. There is already a loop for trying to find the newest Win10 SDK that has full headers, but it's returning at the first failure, rather than continuing the loop to the next iteration. Also, use Join-Path instead of manual path appending, to normalize the extra \ at the end of the sdk root value. In some cases paths with double backslashes can be interpreted as a fallback syntax for UNC paths. Join-Path normalizes the path appropriately. --- scripts/getWindowsSDK.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/getWindowsSDK.ps1 b/scripts/getWindowsSDK.ps1 index 9aebae8e3..f4537ddc3 100644 --- a/scripts/getWindowsSDK.ps1 +++ b/scripts/getWindowsSDK.ps1 @@ -20,7 +20,7 @@ $validInstances = New-Object System.Collections.ArrayList # Windows 10 SDK function CheckWindows10SDK($path) { - $folder = "$path\Include" + $folder = (Join-Path $path "Include") if (!(Test-Path $folder)) { Write-Verbose "$folder - Not Found" @@ -37,7 +37,7 @@ function CheckWindows10SDK($path) if (!(Test-Path $windowsheader)) { Write-Verbose "$windowsheader - Not Found" - return + continue } Write-Verbose "$windowsheader - Found" @@ -45,7 +45,7 @@ function CheckWindows10SDK($path) if (!(Test-Path $ddkheader)) { Write-Verbose "$ddkheader - Not Found" - return + continue } Write-Verbose "$ddkheader - Found" @@ -106,4 +106,4 @@ foreach ($instance in $validInstances) } } -throw "Could not detect a Windows SDK / TargetPlatformVersion" \ No newline at end of file +throw "Could not detect a Windows SDK / TargetPlatformVersion" -- cgit v1.2.3 From 540046b564f95d262f5e4d2a4f988485e6469742 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 5 Oct 2017 22:16:43 -0700 Subject: [vcpkg] Remove assert that vswhere returns only 14 or 15. --- toolsrc/src/VcpkgPaths.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 8264ec293..d84a2d281 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -452,8 +452,6 @@ namespace vcpkg continue; } - - Checks::exit_with_message(VCPKG_LINE_INFO, "Expected major version 14 or 15 but got: %s", major_version); } if (found_toolsets.empty()) -- cgit v1.2.3 From e3527b23ea291489fae1363528ecde07c9191f95 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Oct 2017 22:44:49 -0700 Subject: Don't assume VS2015 is in C:\Program Files (x86)\ --- scripts/findAnyMSBuildWithCppPlatformToolset.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/findAnyMSBuildWithCppPlatformToolset.ps1 b/scripts/findAnyMSBuildWithCppPlatformToolset.ps1 index 632cc2cdf..e9fb60cb2 100644 --- a/scripts/findAnyMSBuildWithCppPlatformToolset.ps1 +++ b/scripts/findAnyMSBuildWithCppPlatformToolset.ps1 @@ -41,7 +41,7 @@ foreach ($instanceCandidate in $VisualStudioInstallationInstances) if (Test-Path $clExe) { Write-Verbose "Picking: $instanceCandidate" - $programFilesPath = split-path -parent $path + $programFilesPath = & $scriptsDir\getProgramFiles32bit.ps1 return "$programFilesPath\MSBuild\14.0\Bin\MSBuild.exe", "v140" } } -- cgit v1.2.3 From 3a6e34804a878ce0c3f74b208f9a5c0bdc75ec7b Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Oct 2017 22:46:55 -0700 Subject: Remove stray comment --- toolsrc/src/VcpkgPaths.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index d84a2d281..08f21df34 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -347,7 +347,6 @@ namespace vcpkg return vs_instance.major_version() == "14"; }) != vs_instances.cend(); - // VS2017 for (const VisualStudioInstance& vs_instance : vs_instances) { const std::string major_version = vs_instance.major_version(); -- cgit v1.2.3 From 03c17e20268bb8bdbfec8710be80fd1310d38dff Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 5 Oct 2017 22:47:45 -0700 Subject: Remove unneeded "continue" --- toolsrc/src/VcpkgPaths.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index 08f21df34..e3e83af30 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -448,8 +448,6 @@ namespace vcpkg supported_architectures}); } } - - continue; } } -- cgit v1.2.3 From cf7762a82ea044b33ddadd6b1d01a4035af3bf9d Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 6 Oct 2017 00:49:41 -0700 Subject: [vcpkg-internal-ci] Remove chakracore due to dependency on cor.h --- scripts/internalCI.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/internalCI.ps1 b/scripts/internalCI.ps1 index 67871acc1..887eb7bea 100644 --- a/scripts/internalCI.ps1 +++ b/scripts/internalCI.ps1 @@ -14,7 +14,7 @@ if (-not $?) { throw $? } ./vcpkg.exe install azure-storage-cpp cpprestsdk:x64-windows-static cpprestsdk:x86-uwp if (-not $?) { throw $? } -./vcpkg.exe install bond chakracore cryptopp zlib expat sdl2 curl sqlite3 libuv protobuf:x64-windows sfml opencv:x64-windows uwebsockets uwebsockets:x64-windows-static +./vcpkg.exe install bond cryptopp zlib expat sdl2 curl sqlite3 libuv protobuf:x64-windows sfml opencv:x64-windows uwebsockets uwebsockets:x64-windows-static if (-not $?) { throw $? } ./vcpkg.exe install opencv:x86-uwp boost:x86-uwp -- cgit v1.2.3 From f0f25b1cb714e07766b998bb205314498f891416 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Oct 2017 02:04:04 -0700 Subject: Remove unused variable --- scripts/getWindowsSDK.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/getWindowsSDK.ps1 b/scripts/getWindowsSDK.ps1 index f4537ddc3..8ef26a436 100644 --- a/scripts/getWindowsSDK.ps1 +++ b/scripts/getWindowsSDK.ps1 @@ -13,7 +13,6 @@ if ($DisableWin10SDK -and $DisableWin81SDK) } Write-Verbose "Executing $($MyInvocation.MyCommand.Name)" -$scriptsDir = split-path -parent $MyInvocation.MyCommand.Definition $validInstances = New-Object System.Collections.ArrayList -- cgit v1.2.3 From 3a7a18a53db623c970887b325b53005660df0ede Mon Sep 17 00:00:00 2001 From: John Farrier Date: Fri, 6 Oct 2017 13:53:48 -0400 Subject: #1930 Celero Initial Port --- ports/celero/CONTROL | 3 +++ ports/celero/portfile.cmake | 49 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 ports/celero/CONTROL create mode 100644 ports/celero/portfile.cmake diff --git a/ports/celero/CONTROL b/ports/celero/CONTROL new file mode 100644 index 000000000..852e9b4f9 --- /dev/null +++ b/ports/celero/CONTROL @@ -0,0 +1,3 @@ +Source: celero +Version: 2.1.0 +Description: Celero is a modern cross-platform (Windows, Linux, MacOS) Microbenchmarking library for C++. diff --git a/ports/celero/portfile.cmake b/ports/celero/portfile.cmake new file mode 100644 index 000000000..6fdb04285 --- /dev/null +++ b/ports/celero/portfile.cmake @@ -0,0 +1,49 @@ +# Common Ambient Variables: +# CURRENT_BUILDTREES_DIR = ${VCPKG_ROOT_DIR}\buildtrees\${PORT} +# CURRENT_PACKAGES_DIR = ${VCPKG_ROOT_DIR}\packages\${PORT}_${TARGET_TRIPLET} +# CURRENT_PORT_DIR = ${VCPKG_ROOT_DIR}\ports\${PORT} +# PORT = current port name (zlib, etc) +# TARGET_TRIPLET = current triplet (x86-windows, x64-windows-static, etc) +# VCPKG_CRT_LINKAGE = C runtime linkage type (static, dynamic) +# VCPKG_LIBRARY_LINKAGE = target library linkage type (static, dynamic) +# VCPKG_ROOT_DIR = +# VCPKG_TARGET_ARCHITECTURE = target architecture (x64, x86, arm) +# + +include(vcpkg_common_functions) +set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/Celero-master) +vcpkg_download_distfile(ARCHIVE + URLS "https://github.com/DigitalInBlue/Celero/archive/master.zip" + FILENAME "celero-v2.1.0.zip" + SHA512 d3971b102bd1785cf21712bcf2e39193e47d5faaa39421cb1cc788340bb67aed4c32343d3b45042813fcf503d48068bc2a2d26808e2e12d8515e29c60ef40c5c +) +vcpkg_extract_source_archive(${ARCHIVE}) + +# Disable building of the examples +set(CELEROExperiment_celeroDemoDoNotOptizeAway OFF) +set(CELEROExperiment_celeroDemoFileWrite OFF) +set(CELEROExperiment_celeroDemoMultithread OFF) +set(CELEROExperiment_celeroDemoSimple OFF) +set(CELEROExperiment_celeroDemoSimpleJUnit OFF) +set(CELEROExperiment_celeroDemoSleep OFF) +set(CELEROExperiment_celeroDemoToString OFF) +set(CELEROExperiment_celeroDemoTransform OFF) +set(CELEROExperiment_celeroExperimentCompressBools OFF) +set(CELEROExperiment_celeroExperimentCostOfPimpl OFF) +set(CELEROExperiment_celeroExperimentParameterPassing OFF) +set(CELEROExperiment_celeroExperimentParticles OFF) +set(CELEROExperiment_celeroExperimentSimpleComparison OFF) +set(CELEROExperiment_celeroExperimentSortingRandomInts OFF) + +vcpkg_configure_cmake( + SOURCE_PATH ${SOURCE_PATH} + # PREFER_NINJA Disable this option if project cannot be built with Ninja + # OPTIONS -DUSE_THIS_IN_ALL_BUILDS=1 -DUSE_THIS_TOO=2 + # OPTIONS_RELEASE -DOPTIMIZE=1 + # OPTIONS_DEBUG -DDEBUGGABLE=1 +) + +vcpkg_install_cmake() + +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include) +file(INSTALL ${SOURCE_PATH}/license.txt DESTINATION ${CURRENT_PACKAGES_DIR}/share/celero RENAME copyright) -- cgit v1.2.3 From 52352d25e6164cc2cab6d1a03e44eb22ef2e8b98 Mon Sep 17 00:00:00 2001 From: John Farrier Date: Fri, 6 Oct 2017 14:18:02 -0400 Subject: #1930 Improved build control to exclude demo applications. --- ports/celero/portfile.cmake | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/ports/celero/portfile.cmake b/ports/celero/portfile.cmake index 6fdb04285..ef66131e7 100644 --- a/ports/celero/portfile.cmake +++ b/ports/celero/portfile.cmake @@ -20,20 +20,9 @@ vcpkg_download_distfile(ARCHIVE vcpkg_extract_source_archive(${ARCHIVE}) # Disable building of the examples -set(CELEROExperiment_celeroDemoDoNotOptizeAway OFF) -set(CELEROExperiment_celeroDemoFileWrite OFF) -set(CELEROExperiment_celeroDemoMultithread OFF) -set(CELEROExperiment_celeroDemoSimple OFF) -set(CELEROExperiment_celeroDemoSimpleJUnit OFF) -set(CELEROExperiment_celeroDemoSleep OFF) -set(CELEROExperiment_celeroDemoToString OFF) -set(CELEROExperiment_celeroDemoTransform OFF) -set(CELEROExperiment_celeroExperimentCompressBools OFF) -set(CELEROExperiment_celeroExperimentCostOfPimpl OFF) -set(CELEROExperiment_celeroExperimentParameterPassing OFF) -set(CELEROExperiment_celeroExperimentParticles OFF) -set(CELEROExperiment_celeroExperimentSimpleComparison OFF) -set(CELEROExperiment_celeroExperimentSortingRandomInts OFF) +set(CELERO_ENABLE_EXPERIMENTS OFF) +set(CELERO_ENABLE_TESTS OFF) +set(CELERO_RUN_EXAMPLE_ON_BUILD OFF) vcpkg_configure_cmake( SOURCE_PATH ${SOURCE_PATH} -- cgit v1.2.3 From cd4142d3cac144c6f4e558cdfe8403e1987ff833 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Oct 2017 14:06:02 -0700 Subject: Bump version of nuget to 4.3.0 (was 4.1.0) --- scripts/fetchDependency.ps1 | 8 ++++---- toolsrc/src/VcpkgPaths.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/fetchDependency.ps1 b/scripts/fetchDependency.ps1 index 80d6d2abb..665376baf 100644 --- a/scripts/fetchDependency.ps1 +++ b/scripts/fetchDependency.ps1 @@ -116,11 +116,11 @@ function SelectProgram([Parameter(Mandatory=$true)][string]$Dependency) } elseif($Dependency -eq "nuget") { - $requiredVersion = "4.1.0" - $downloadVersion = "4.1.0" - $url = "https://dist.nuget.org/win-x86-commandline/v4.1.0/nuget.exe" + $requiredVersion = "4.3.0" + $downloadVersion = "4.3.0" + $url = "https://dist.nuget.org/win-x86-commandline/v4.3.0/nuget.exe" $downloadPath = "$downloadsDir\nuget-$downloadVersion\nuget.exe" - $expectedDownloadedFileHash = "4c1de9b026e0c4ab087302ff75240885742c0faa62bd2554f913bbe1f6cb63a0" + $expectedDownloadedFileHash = "386da77a8cf2b63d1260b7020feeedabfe3b65ab31d20e6a313a530865972f3a" $executableFromDownload = $downloadPath $extractionType = $ExtractionType_NO_EXTRACTION_REQUIRED } diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index e3e83af30..d14002e47 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -130,10 +130,10 @@ namespace vcpkg fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder) { - static constexpr std::array EXPECTED_VERSION = {4, 1, 0}; + static constexpr std::array EXPECTED_VERSION = {4, 3, 0}; static const std::wstring VERSION_CHECK_ARGUMENTS = Strings::WEMPTY; - const fs::path downloaded_copy = downloads_folder / "nuget-4.1.0" / "nuget.exe"; + const fs::path downloaded_copy = downloads_folder / "nuget-4.3.0" / "nuget.exe"; const std::vector from_path = Files::find_from_PATH(L"nuget"); std::vector candidate_paths; -- cgit v1.2.3 From 049ad42779176fba38a79ec4c1344fcd2d058dbc Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 6 Oct 2017 14:06:43 -0700 Subject: [mozjpeg] Use vcpkg_from_github and vcpkg_copy_tool_dependencies --- ports/mozjpeg/CONTROL | 2 +- ports/mozjpeg/portfile.cmake | 33 +++++++++++++++++++-------------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/ports/mozjpeg/CONTROL b/ports/mozjpeg/CONTROL index 8afc065b3..9e3f19b4c 100644 --- a/ports/mozjpeg/CONTROL +++ b/ports/mozjpeg/CONTROL @@ -1,3 +1,3 @@ Source: mozjpeg -Version: 3.2 +Version: 3.2-1 Description: MozJPEG reduces file sizes of JPEG images while retaining quality and compatibility with the vast majority of the world's deployed decoders. It's compatible with libjpeg API and ABI, and can be used as a drop-in replacement for libjpeg. diff --git a/ports/mozjpeg/portfile.cmake b/ports/mozjpeg/portfile.cmake index d95f83ff8..52011d394 100644 --- a/ports/mozjpeg/portfile.cmake +++ b/ports/mozjpeg/portfile.cmake @@ -1,27 +1,30 @@ include(vcpkg_common_functions) -set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/mozjpeg-3.2) -vcpkg_download_distfile(ARCHIVE - URLS "https://github.com/mozilla/mozjpeg/archive/v3.2.zip" - FILENAME "mozjpeg.zip" - SHA512 a1ba53dea3e04add46616918b5e96f2c8102ef65856596f1794df29c8be27db3d9fb13e7ffc864d23626f98dff5a6b47315903cae9ae41f9905aef2cc91af0c5 + +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO mozilla/mozjpeg + REF v3.2 + SHA512 d14789827a9f4f78139a3945d3169d37eb891758b5ab40ef19e99ebebb2fb6d7c3a05495de245bba54cfd913b153af352159aa9fc0218127f97819137e0f1ab8 + HEAD_REF master ) vcpkg_find_acquire_program(NASM) get_filename_component(NASM_EXE_PATH ${NASM} DIRECTORY) set(ENV{PATH} "$ENV{PATH};${NASM_EXE_PATH}") -vcpkg_extract_source_archive(${ARCHIVE}) - -if (${VCPKG_LIBRARY_LINKAGE} STREQUAL static) +if(VCPKG_LIBRARY_LINKAGE STREQUAL static) set(OPTIONS "-DENABLE_SHARED=FALSE") else() set(OPTIONS "-DENABLE_STATIC=FALSE") endif() +string(COMPARE EQUAL "${VCPKG_CRT_LINKAGE}" "dynamic" WITH_CRT_DLL) + vcpkg_configure_cmake( SOURCE_PATH ${SOURCE_PATH} - PREFER_NINJA - OPTIONS ${OPTIONS} + OPTIONS + ${OPTIONS} + -DWITH_CRT_DLL=${WITH_CRT_DLL} ) vcpkg_install_cmake() @@ -34,12 +37,14 @@ file(REMOVE ${DEBUGEXES}) #move exes to tools file(GLOB EXES ${CURRENT_PACKAGES_DIR}/bin/*.exe) -file(MAKE_DIRECTORY ${CURRENT_PACKAGES_DIR}/tools) -file(COPY ${EXES} DESTINATION ${CURRENT_PACKAGES_DIR}/tools) +file(MAKE_DIRECTORY ${CURRENT_PACKAGES_DIR}/tools/mozjpeg) +file(COPY ${EXES} DESTINATION ${CURRENT_PACKAGES_DIR}/tools/mozjpeg) file(REMOVE ${EXES}) -#remove empty fodlers after static build -if (${VCPKG_LIBRARY_LINKAGE} STREQUAL static) +vcpkg_copy_tool_dependencies(${CURRENT_PACKAGES_DIR}/tools/mozjpeg) + +#remove empty folders after static build +if (VCPKG_LIBRARY_LINKAGE STREQUAL static) file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/bin) file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/bin) endif() -- cgit v1.2.3 From bc18ea6622a852e9bd883051cd8503b9640cab59 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Oct 2017 18:23:11 -0700 Subject: [cpprestsdk] Patch to allow building with openssl 1.1.0 --- ports/cpprestsdk/0003_openssl_110.patch | 14 ++++++++++++++ ports/cpprestsdk/CONTROL | 2 +- ports/cpprestsdk/portfile.cmake | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 ports/cpprestsdk/0003_openssl_110.patch diff --git a/ports/cpprestsdk/0003_openssl_110.patch b/ports/cpprestsdk/0003_openssl_110.patch new file mode 100644 index 000000000..b2b361187 --- /dev/null +++ b/ports/cpprestsdk/0003_openssl_110.patch @@ -0,0 +1,14 @@ +diff --git a/Release/src/websockets/client/ws_client_wspp.cpp b/Release/src/websockets/client/ws_client_wspp.cpp +index 9f91d68..4b5d506 100644 +--- a/Release/src/websockets/client/ws_client_wspp.cpp ++++ b/Release/src/websockets/client/ws_client_wspp.cpp +@@ -76,7 +76,9 @@ static struct ASIO_SSL_memory_leak_suppress + { + ~ASIO_SSL_memory_leak_suppress() + { ++#if OPENSSL_VERSION_NUMBER < 0x10100000L + ::SSL_COMP_free_compression_methods(); ++#endif + } + } ASIO_SSL_memory_leak_suppressor; + diff --git a/ports/cpprestsdk/CONTROL b/ports/cpprestsdk/CONTROL index f22ee9854..9831af585 100644 --- a/ports/cpprestsdk/CONTROL +++ b/ports/cpprestsdk/CONTROL @@ -1,5 +1,5 @@ Source: cpprestsdk -Version: 2.9.0-3 +Version: 2.9.0-4 Build-Depends: zlib (windows), openssl (windows), boost (windows), websocketpp (windows) Description: C++11 JSON, REST, and OAuth library The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services. diff --git a/ports/cpprestsdk/portfile.cmake b/ports/cpprestsdk/portfile.cmake index 7482760d3..83b38a92d 100644 --- a/ports/cpprestsdk/portfile.cmake +++ b/ports/cpprestsdk/portfile.cmake @@ -13,6 +13,7 @@ if(NOT VCPKG_USE_HEAD_VERSION) PATCHES ${CMAKE_CURRENT_LIST_DIR}/0001_cmake.patch ${CMAKE_CURRENT_LIST_DIR}/0002_no_websocketpp_in_uwp.patch + ${CMAKE_CURRENT_LIST_DIR}/0003_openssl_110.patch ) endif() -- cgit v1.2.3 From 1fb5313a881fe0fcfd90dff5255045c8367ee00b Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 6 Oct 2017 18:32:59 -0700 Subject: [websocketpp] Add patch for openssl 1.1.0 compatibility --- ports/websocketpp/CONTROL | 2 +- ports/websocketpp/openssl_110.patch | 19 +++++++++++++++++++ ports/websocketpp/portfile.cmake | 6 ++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 ports/websocketpp/openssl_110.patch diff --git a/ports/websocketpp/CONTROL b/ports/websocketpp/CONTROL index f812dc565..f15164de2 100644 --- a/ports/websocketpp/CONTROL +++ b/ports/websocketpp/CONTROL @@ -1,4 +1,4 @@ Source: websocketpp -Version: 0.7.0 +Version: 0.7.0-1 Build-Depends: zlib, openssl, boost Description: Library that implements RFC6455 The WebSocket Protocol \ No newline at end of file diff --git a/ports/websocketpp/openssl_110.patch b/ports/websocketpp/openssl_110.patch new file mode 100644 index 000000000..93f4302e0 --- /dev/null +++ b/ports/websocketpp/openssl_110.patch @@ -0,0 +1,19 @@ +diff --git a/websocketpp/transport/asio/security/tls.hpp b/websocketpp/transport/asio/security/tls.hpp +index 7b32db8..37173b7 100644 +--- a/websocketpp/transport/asio/security/tls.hpp ++++ b/websocketpp/transport/asio/security/tls.hpp +@@ -355,7 +355,13 @@ protected: + template + lib::error_code translate_ec(ErrorCodeType ec) { + if (ec.category() == lib::asio::error::get_ssl_category()) { +- if (ERR_GET_REASON(ec.value()) == SSL_R_SHORT_READ) { ++ if ( ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ ERR_GET_REASON(ec.value()) == SSL_R_SHORT_READ ++#else ++ false ++#endif ++ ) { + return make_error_code(transport::error::tls_short_read); + } else { + // We know it is a TLS related error, but otherwise don't know diff --git a/ports/websocketpp/portfile.cmake b/ports/websocketpp/portfile.cmake index 98a4d52e6..8531edd7d 100644 --- a/ports/websocketpp/portfile.cmake +++ b/ports/websocketpp/portfile.cmake @@ -9,6 +9,12 @@ vcpkg_download_distfile(ARCHIVE ) vcpkg_extract_source_archive(${ARCHIVE}) +vcpkg_apply_patches( + SOURCE_PATH ${SOURCE_PATH} + PATCHES + ${CMAKE_CURRENT_LIST_DIR}/openssl_110.patch +) + file(MAKE_DIRECTORY ${CURRENT_PACKAGES_DIR}/share) # Put the license file where vcpkg expects it -- cgit v1.2.3 From e30466b08cff9749a197774390e2cd00f62eb9b2 Mon Sep 17 00:00:00 2001 From: pravic Date: Wed, 4 Oct 2017 07:12:43 +0300 Subject: [sciter] Update to 4.0.4.5413 --- ports/sciter/CONTROL | 2 +- ports/sciter/portfile.cmake | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ports/sciter/CONTROL b/ports/sciter/CONTROL index 54d72ec3c..5583c626d 100644 --- a/ports/sciter/CONTROL +++ b/ports/sciter/CONTROL @@ -1,4 +1,4 @@ Source: sciter -Version: 4.0.3 +Version: 4.0.4 Description: Sciter is an embeddable HTML/CSS/scripting engine. Maintainer: andrew.fedoniouk@gmail.com, ehysta@gmail.com diff --git a/ports/sciter/portfile.cmake b/ports/sciter/portfile.cmake index 063b318e3..1622379ac 100644 --- a/ports/sciter/portfile.cmake +++ b/ports/sciter/portfile.cmake @@ -12,9 +12,9 @@ include(vcpkg_common_functions) # header-only library set(VCPKG_POLICY_DLLS_WITHOUT_LIBS enabled) -set(SCITER_VERSION 4.0.3) -set(SCITER_REVISION 1209528289b8c8369352d648f4ba0c67826cbd8b) -set(SCITER_SHA 9fc72dd44b22c69715b4b08c5af7a65e0bb48d849191002b2ae45ca6f5ea058fb8c64cc7f6c176215afce682af6166a1579efd8cc2ca0fb9e844ceba1160f10f) +set(SCITER_VERSION 4.0.4) +set(SCITER_REVISION 172e04dc1b8527a6f7ea8b6e9388238f9568cc93) +set(SCITER_SHA 07db84fe560450b32477a35fd63d6d9ba5a5df1cc4bccba6e0f74cde56f16a2708f58b7f27482a97e4264e7069096128a591c886f19e56fc2fd8d16ddcbcf73e) if(VCPKG_TARGET_ARCHITECTURE STREQUAL x64) set(SCITER_ARCH 64) -- cgit v1.2.3 From a958a8b50a1eacbf2d908d4428da6637f375a8bd Mon Sep 17 00:00:00 2001 From: pravic Date: Sun, 8 Oct 2017 07:32:30 +0300 Subject: [sciter] Update to 4.0.4.5428 --- ports/sciter/portfile.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/sciter/portfile.cmake b/ports/sciter/portfile.cmake index 1622379ac..ac3020144 100644 --- a/ports/sciter/portfile.cmake +++ b/ports/sciter/portfile.cmake @@ -13,8 +13,8 @@ include(vcpkg_common_functions) set(VCPKG_POLICY_DLLS_WITHOUT_LIBS enabled) set(SCITER_VERSION 4.0.4) -set(SCITER_REVISION 172e04dc1b8527a6f7ea8b6e9388238f9568cc93) -set(SCITER_SHA 07db84fe560450b32477a35fd63d6d9ba5a5df1cc4bccba6e0f74cde56f16a2708f58b7f27482a97e4264e7069096128a591c886f19e56fc2fd8d16ddcbcf73e) +set(SCITER_REVISION 9b5954df34ac0094e6037ac8aa6e00fb883185f9) +set(SCITER_SHA a87b05aec6c99f56926b005eb1303b2b68f901fe2658433ca11d704b50308e6d291026404b86320fae0f1b12ca257a35338464f21d94ebeaa6e40cfec64a9201) if(VCPKG_TARGET_ARCHITECTURE STREQUAL x64) set(SCITER_ARCH 64) -- cgit v1.2.3 From 86f6485078b2eac0999c8eef631862afc863c3d3 Mon Sep 17 00:00:00 2001 From: Tsukasa Sugiura Date: Sat, 7 Oct 2017 00:24:59 +0900 Subject: Add support custom triplets Add support custom triplets. --- ports/openni2/CONTROL | 2 +- ports/openni2/replace_environment_variable.patch.in | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ports/openni2/CONTROL b/ports/openni2/CONTROL index 72de4e877..bf012ff8e 100644 --- a/ports/openni2/CONTROL +++ b/ports/openni2/CONTROL @@ -1,4 +1,4 @@ Source: openni2 -Version: 2.2.0.33-2 +Version: 2.2.0.33-3 Build-Depends: kinectsdk1 Description: OpenNI is open source library for access to Natural Interaction (NI) devices such as RGB-D camera. diff --git a/ports/openni2/replace_environment_variable.patch.in b/ports/openni2/replace_environment_variable.patch.in index ac5cf017c..31e7cb951 100644 --- a/ports/openni2/replace_environment_variable.patch.in +++ b/ports/openni2/replace_environment_variable.patch.in @@ -7,7 +7,7 @@ index 08a49fe..7fd8620 100644 Level3 Disabled - ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; -+ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x86-windows\include ++ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\include _WINDLL;%(PreprocessorDefinitions);_WINDOWS false false @@ -16,7 +16,7 @@ index 08a49fe..7fd8620 100644 true Kinect10.lib;XnLib.lib;%(AdditionalDependencies) - $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\x86; -+ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x86-windows\debug\lib ++ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\debug\lib true @@ -25,7 +25,7 @@ index 08a49fe..7fd8620 100644 Level3 Disabled - ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; -+ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x64-windows\include ++ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\include _WINDLL;%(PreprocessorDefinitions);_WINDOWS false false @@ -34,7 +34,7 @@ index 08a49fe..7fd8620 100644 true Kinect10.lib;XnLib.lib;%(AdditionalDependencies) - $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\amd64; -+ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x64-windows\debug\lib ++ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\debug\lib @@ -43,7 +43,7 @@ index 08a49fe..7fd8620 100644 true true - ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; -+ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x86-windows\include ++ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\include false @@ -52,7 +52,7 @@ index 08a49fe..7fd8620 100644 true Kinect10.lib;XnLib.lib;%(AdditionalDependencies) - $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\x86; -+ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x86-windows\lib ++ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\lib true @@ -61,7 +61,7 @@ index 08a49fe..7fd8620 100644 true true - ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; -+ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x64-windows\include ++ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\include false @@ -70,7 +70,7 @@ index 08a49fe..7fd8620 100644 true Kinect10.lib;XnLib.lib;%(AdditionalDependencies) - $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\amd64; -+ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_x64-windows\lib ++ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\lib true -- cgit v1.2.3 From a3f68f5d01deb65becea0e93b95512559f47d31a Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Fri, 6 Oct 2017 23:17:35 -0700 Subject: [string_theory] Initial port --- ports/string-theory/CONTROL | 3 +++ ports/string-theory/portfile.cmake | 42 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 ports/string-theory/CONTROL create mode 100644 ports/string-theory/portfile.cmake diff --git a/ports/string-theory/CONTROL b/ports/string-theory/CONTROL new file mode 100644 index 000000000..63bc5b656 --- /dev/null +++ b/ports/string-theory/CONTROL @@ -0,0 +1,3 @@ +Source: string-theory +Version: 1.6 +Description: Flexible C++11 string library with type-safe formatting. diff --git a/ports/string-theory/portfile.cmake b/ports/string-theory/portfile.cmake new file mode 100644 index 000000000..8a6cb1fd1 --- /dev/null +++ b/ports/string-theory/portfile.cmake @@ -0,0 +1,42 @@ +include(vcpkg_common_functions) + +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO zrax/string_theory + REF 1.6 + SHA512 5bc99b6dfc2ab43d2812ee47dfbbeeb68106da39b2349799ab924f009270166ebb5508f87a37e634fbfa5495dd263697a582404650eedc5393722761c5ce2028 + HEAD_REF master +) + +if(VCPKG_LIBRARY_LINKAGE STREQUAL static) + set(ST_BUILD_STATIC ON) +else() + set(ST_BUILD_STATIC OFF) +endif() + +vcpkg_configure_cmake( + SOURCE_PATH ${SOURCE_PATH} + PREFER_NINJA + OPTIONS + -DST_BUILD_STATIC=${ST_BUILD_STATIC} +) + +vcpkg_install_cmake() + +vcpkg_fixup_cmake_targets(CONFIG_PATH "lib/cmake/string_theory") + +file(RENAME ${CURRENT_PACKAGES_DIR}/share/string-theory ${CURRENT_PACKAGES_DIR}/share/string_theory) + +if(VCPKG_LIBRARY_LINKAGE STREQUAL static) + file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/bin) + file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/bin) +endif() + +vcpkg_copy_pdbs() + +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include) + +# Handle copyright +file(COPY ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/string-theory) +file(RENAME ${CURRENT_PACKAGES_DIR}/share/string-theory/LICENSE ${CURRENT_PACKAGES_DIR}/share/string-theory/copyright) +file(COPY ${CURRENT_PACKAGES_DIR}/share/string-theory/copyright DESTINATION ${CURRENT_PACKAGES_DIR}/share/string_theory/copyright) -- cgit v1.2.3 From ab7a1abc93473dc1b7fcb341a4d104e3a77afd87 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 9 Oct 2017 16:38:21 -0700 Subject: [VS detection] Add -products * flag to vswhere. This includes Express and BuildTools SKUs --- scripts/findVisualStudioInstallationInstances.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/findVisualStudioInstallationInstances.ps1 b/scripts/findVisualStudioInstallationInstances.ps1 index 8c67ef6d6..b2f186478 100644 --- a/scripts/findVisualStudioInstallationInstances.ps1 +++ b/scripts/findVisualStudioInstallationInstances.ps1 @@ -6,7 +6,7 @@ param( $scriptsDir = split-path -parent $MyInvocation.MyCommand.Definition $vswhereExe = & $scriptsDir\fetchDependency.ps1 "vswhere" -$output = & $vswhereExe -prerelease -legacy -format xml +$output = & $vswhereExe -prerelease -legacy -products * -format xml [xml]$asXml = $output $results = New-Object System.Collections.ArrayList -- cgit v1.2.3 From b6512bace19d6c28cce71a0c2e8e28ab77d3ef56 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 9 Oct 2017 16:40:13 -0700 Subject: [vswhere.exe] Update to vesrion 2.2.3 (was 2.1.4) --- scripts/fetchDependency.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/fetchDependency.ps1 b/scripts/fetchDependency.ps1 index 665376baf..bc58f4436 100644 --- a/scripts/fetchDependency.ps1 +++ b/scripts/fetchDependency.ps1 @@ -126,11 +126,11 @@ function SelectProgram([Parameter(Mandatory=$true)][string]$Dependency) } elseif($Dependency -eq "vswhere") { - $requiredVersion = "2.1.4" - $downloadVersion = "2.1.4" - $url = "https://github.com/Microsoft/vswhere/releases/download/2.1.4/vswhere.exe" + $requiredVersion = "2.2.3" + $downloadVersion = "2.2.3" + $url = "https://github.com/Microsoft/vswhere/releases/download/2.2.3/vswhere.exe" $downloadPath = "$downloadsDir\vswhere-$downloadVersion\vswhere.exe" - $expectedDownloadedFileHash = "548fb9dfeed59bc4ddcce739a5729e9c8dd5932cd60ff6f74727ee069e7da458" + $expectedDownloadedFileHash = "5f19066ac91635ad17d33fe0f79fc63c672a46f98c0358589a90163bcb2733e8" $executableFromDownload = $downloadPath $extractionType = $ExtractionType_NO_EXTRACTION_REQUIRED } -- cgit v1.2.3 From 40bec91c0b19e90e63aec104178c14076259a233 Mon Sep 17 00:00:00 2001 From: Eric Mittelette Date: Mon, 9 Oct 2017 17:00:03 -0700 Subject: adding tiny-dnn port files --- ports/tiny-dnn/CONTROL | 3 +++ ports/tiny-dnn/portfile.cmake | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 ports/tiny-dnn/CONTROL create mode 100644 ports/tiny-dnn/portfile.cmake diff --git a/ports/tiny-dnn/CONTROL b/ports/tiny-dnn/CONTROL new file mode 100644 index 000000000..1423a8695 --- /dev/null +++ b/ports/tiny-dnn/CONTROL @@ -0,0 +1,3 @@ +Source: tiny-dnn +Version: 1.10.8 +Description:a C++14 implementation of deep learning. It is suitable for deep learning on limited computational resource. diff --git a/ports/tiny-dnn/portfile.cmake b/ports/tiny-dnn/portfile.cmake new file mode 100644 index 000000000..423b92aa6 --- /dev/null +++ b/ports/tiny-dnn/portfile.cmake @@ -0,0 +1,16 @@ +#header-only library +include(vcpkg_common_functions) +SET(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/tiny-dnn-dd906fed8c8aff8dc837657c42f9d55f8b793b0e) +vcpkg_download_distfile(ARCHIVE + URLS "https://github.com/tiny-dnn/tiny-dnn/archive/dd906fed8c8aff8dc837657c42f9d55f8b793b0e.zip" + FILENAME "tiny-dnn-1.zip" + SHA512 9881d5a10215e3e2e5fe0e3df6b061ebf4e5c064883bdcff5578f1b635c6a41e8f03bfbcf7e07922f3c477c3bdfb5dea85d616e2cd9d42f07d7ae78e601ffded +) +vcpkg_extract_source_archive(${ARCHIVE}) + +# Copy the asio header files +file(INSTALL ${SOURCE_PATH}/tiny_dnn DESTINATION ${CURRENT_PACKAGES_DIR}/include) + + +file(COPY ${CURRENT_BUILDTREES_DIR}/src/tiny-dnn-dd906fed8c8aff8dc837657c42f9d55f8b793b0e/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/tiny-dnn) + file(RENAME ${CURRENT_PACKAGES_DIR}/share/tiny-dnn/LICENSE ${CURRENT_PACKAGES_DIR}/share/tiny-dnn/copyright) \ No newline at end of file -- cgit v1.2.3 From d3c45b0668e00703facc86aee998cbfb40fde2ff Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Mon, 9 Oct 2017 17:11:34 -0700 Subject: [tiny-dnn] Use vcpkg_from_github() and fix version --- ports/tiny-dnn/CONTROL | 4 ++-- ports/tiny-dnn/portfile.cmake | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/ports/tiny-dnn/CONTROL b/ports/tiny-dnn/CONTROL index 1423a8695..f12cc076f 100644 --- a/ports/tiny-dnn/CONTROL +++ b/ports/tiny-dnn/CONTROL @@ -1,3 +1,3 @@ Source: tiny-dnn -Version: 1.10.8 -Description:a C++14 implementation of deep learning. It is suitable for deep learning on limited computational resource. +Version: 2017-10-09-dd906fed8c8aff8dc837657c42f9d55f8b793b0e +Description: A C++14 implementation of deep learning. It is suitable for deep learning on limited computational resource. diff --git a/ports/tiny-dnn/portfile.cmake b/ports/tiny-dnn/portfile.cmake index 423b92aa6..7e3baa92a 100644 --- a/ports/tiny-dnn/portfile.cmake +++ b/ports/tiny-dnn/portfile.cmake @@ -1,14 +1,13 @@ #header-only library include(vcpkg_common_functions) -SET(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/tiny-dnn-dd906fed8c8aff8dc837657c42f9d55f8b793b0e) -vcpkg_download_distfile(ARCHIVE - URLS "https://github.com/tiny-dnn/tiny-dnn/archive/dd906fed8c8aff8dc837657c42f9d55f8b793b0e.zip" - FILENAME "tiny-dnn-1.zip" - SHA512 9881d5a10215e3e2e5fe0e3df6b061ebf4e5c064883bdcff5578f1b635c6a41e8f03bfbcf7e07922f3c477c3bdfb5dea85d616e2cd9d42f07d7ae78e601ffded +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO tiny-dnn/tiny-dnn + REF dd906fed8c8aff8dc837657c42f9d55f8b793b0e + SHA512 d853db7f49af1bece55337b93631c41191f3abd8287969f230330662fecc612e4e53ab789535fc6f9770ae0c8623d8e020e6036c2c804783d08f176a08c05d1b + HEAD_REF master ) -vcpkg_extract_source_archive(${ARCHIVE}) -# Copy the asio header files file(INSTALL ${SOURCE_PATH}/tiny_dnn DESTINATION ${CURRENT_PACKAGES_DIR}/include) -- cgit v1.2.3 From c7914d34de76b0d45cc0db6019d3331b59340346 Mon Sep 17 00:00:00 2001 From: jasjuang Date: Tue, 10 Oct 2017 23:06:14 -0700 Subject: update mpfr to 3.1.6 --- ports/mpfr/CONTROL | 2 +- ports/mpfr/portfile.cmake | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ports/mpfr/CONTROL b/ports/mpfr/CONTROL index 2d5d4fedd..bec54417d 100644 --- a/ports/mpfr/CONTROL +++ b/ports/mpfr/CONTROL @@ -1,4 +1,4 @@ Source: mpfr -Version: 3.1.5-1 +Version: 3.1.6 Description: The MPFR library is a C library for multiple-precision floating-point computations with correct rounding Build-Depends: mpir diff --git a/ports/mpfr/portfile.cmake b/ports/mpfr/portfile.cmake index 6a61d4038..b71aa0505 100644 --- a/ports/mpfr/portfile.cmake +++ b/ports/mpfr/portfile.cmake @@ -1,9 +1,9 @@ include(vcpkg_common_functions) -set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/mpfr-3.1.5) +set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/mpfr-3.1.6) vcpkg_download_distfile(ARCHIVE - URLS "http://www.mpfr.org/mpfr-current/mpfr-3.1.5.tar.xz" - FILENAME "mpfr-3.1.5.tar.xz" - SHA512 3643469b9099b31e41d6ec9158196cd1c30894030c8864ee5b1b1e91b488bccbf7c263c951b03fe9f4ae6f9d29279e157a7dfed0885467d875f107a3d964f032 + URLS "http://www.mpfr.org/mpfr-current/mpfr-3.1.6.tar.xz" + FILENAME "mpfr-3.1.6.tar.xz" + SHA512 746ee74d5026f267f74ab352d850ed30ff627d530aa840c71b24793e44875f8503946bd7399905dea2b2dd5744326254d7889337fe94cfe58d03c4066e9d8054 ) vcpkg_extract_source_archive(${ARCHIVE}) -- cgit v1.2.3 From 7cd465b8897bd9487db6d990e58dcac472b3d4d6 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Wed, 11 Oct 2017 17:56:01 -0700 Subject: `vcpkg install` Print summary when using the --keep-going flag --- toolsrc/src/commands_install.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp index d815332fe..4411dd3ae 100644 --- a/toolsrc/src/commands_install.cpp +++ b/toolsrc/src/commands_install.cpp @@ -556,6 +556,7 @@ namespace vcpkg::Commands::Install const bool no_downloads = options.find(OPTION_NO_DOWNLOADS) != options.cend(); const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); const KeepGoing keep_going = to_keep_going(options.find(OPTION_KEEP_GOING) != options.cend()); + const PrintSummary print_summary = to_print_summary(keep_going == KeepGoing::YES); // create the plan StatusParagraphs status_db = database_load_check(paths); @@ -606,7 +607,7 @@ namespace vcpkg::Commands::Install Checks::exit_success(VCPKG_LINE_INFO); } - perform_and_exit(action_plan, install_plan_options, keep_going, PrintSummary::NO, paths, status_db); + perform_and_exit(action_plan, install_plan_options, keep_going, print_summary, paths, status_db); Checks::exit_success(VCPKG_LINE_INFO); } -- cgit v1.2.3 From 00d89dbd66a658174233920d6be2a85f282ef29f Mon Sep 17 00:00:00 2001 From: Mikhail Paulyshka Date: Sun, 24 Sep 2017 16:01:37 +0300 Subject: vcpkg: initial ARM64 support --- scripts/cmake/vcpkg_configure_cmake.cmake | 16 ++++++++++++++-- toolsrc/src/PostBuildLint.cpp | 1 + toolsrc/src/VcpkgPaths.cpp | 4 ++++ triplets/arm64-uwp.cmake | 6 ++++++ 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 triplets/arm64-uwp.cmake diff --git a/scripts/cmake/vcpkg_configure_cmake.cmake b/scripts/cmake/vcpkg_configure_cmake.cmake index fe8c97c52..bfb6a19fd 100644 --- a/scripts/cmake/vcpkg_configure_cmake.cmake +++ b/scripts/cmake/vcpkg_configure_cmake.cmake @@ -78,14 +78,20 @@ function(vcpkg_configure_cmake) set(GENERATOR "Visual Studio 15 2017") elseif(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" AND TRIPLET_SYSTEM_ARCH MATCHES "x64" AND VCPKG_PLATFORM_TOOLSET MATCHES "v141") set(GENERATOR "Visual Studio 15 2017 Win64") - elseif(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" AND TRIPLET_SYSTEM_ARCH MATCHES "arm" AND VCPKG_PLATFORM_TOOLSET MATCHES "v141") + elseif(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" AND TRIPLET_SYSTEM_ARCH STREQUAL "arm" AND VCPKG_PLATFORM_TOOLSET MATCHES "v141") set(GENERATOR "Visual Studio 15 2017 ARM") + elseif(VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" AND TRIPLET_SYSTEM_ARCH STREQUAL "arm64" AND VCPKG_PLATFORM_TOOLSET MATCHES "v141") + set(GENERATOR "Visual Studio 15 2017") + set(ARCH "ARM64") elseif(TRIPLET_SYSTEM_ARCH MATCHES "x86" AND VCPKG_PLATFORM_TOOLSET MATCHES "v141") set(GENERATOR "Visual Studio 15 2017") elseif(TRIPLET_SYSTEM_ARCH MATCHES "x64" AND VCPKG_PLATFORM_TOOLSET MATCHES "v141") set(GENERATOR "Visual Studio 15 2017 Win64") - elseif(TRIPLET_SYSTEM_ARCH MATCHES "arm" AND VCPKG_PLATFORM_TOOLSET MATCHES "v141") + elseif(TRIPLET_SYSTEM_ARCH STREQUAL "arm" AND VCPKG_PLATFORM_TOOLSET MATCHES "v141") set(GENERATOR "Visual Studio 15 2017 ARM") + elseif(TRIPLET_SYSTEM_ARCH STREQUAL "arm64" AND VCPKG_PLATFORM_TOOLSET MATCHES "v141") + set(GENERATOR "Visual Studio 15 2017") + set(ARCH "ARM64") endif() # If we use Ninja, make sure it's on PATH @@ -139,6 +145,12 @@ function(vcpkg_configure_cmake) "-DCMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION=ON" ) + if(DEFINED ARCH) + list(APPEND _csc_OPTIONS + "-A${ARCH}" + ) + endif() + if(DEFINED VCPKG_CRT_LINKAGE AND VCPKG_CRT_LINKAGE STREQUAL dynamic) list(APPEND _csc_OPTIONS_DEBUG "-DCMAKE_CXX_FLAGS_DEBUG=/D_DEBUG /MDd /Z7 /Ob0 /Od /RTC1 ${VCPKG_CXX_FLAGS_DEBUG}" diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp index a0699e15c..6d9a0da73 100644 --- a/toolsrc/src/PostBuildLint.cpp +++ b/toolsrc/src/PostBuildLint.cpp @@ -361,6 +361,7 @@ namespace vcpkg::PostBuildLint case MachineType::I386: return "x86"; case MachineType::ARM: case MachineType::ARMNT: return "arm"; + case MachineType::ARM64: return "arm64"; default: return "Machine Type Code = " + std::to_string(static_cast(machine_type)); } } diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp index d14002e47..dac9e40e7 100644 --- a/toolsrc/src/VcpkgPaths.cpp +++ b/toolsrc/src/VcpkgPaths.cpp @@ -370,10 +370,14 @@ namespace vcpkg supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); + if (fs.exists(vcvarsall_dir / "vcvarsx86_arm64.bat")) + supported_architectures.push_back({L"x86_arm64", CPU::X86, CPU::ARM64}); if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm64.bat")) + supported_architectures.push_back({L"amd64_arm64", CPU::X64, CPU::ARM64}); // Locate the "best" MSVC toolchain version const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; diff --git a/triplets/arm64-uwp.cmake b/triplets/arm64-uwp.cmake new file mode 100644 index 000000000..b37c34e87 --- /dev/null +++ b/triplets/arm64-uwp.cmake @@ -0,0 +1,6 @@ +set(VCPKG_TARGET_ARCHITECTURE arm64) +set(VCPKG_CRT_LINKAGE dynamic) +set(VCPKG_LIBRARY_LINKAGE dynamic) + +set(VCPKG_CMAKE_SYSTEM_NAME WindowsStore) +set(VCPKG_CMAKE_SYSTEM_VERSION 10.0) -- cgit v1.2.3 From dcfb9d45c13ba3adc22a47d62642f6acd2ee239b Mon Sep 17 00:00:00 2001 From: jasjuang Date: Thu, 12 Oct 2017 04:09:52 -0700 Subject: add NVCUDASAMPLES_ROOT to whitelist --- toolsrc/src/vcpkg_System.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp index 3b4c440d8..5293638e3 100644 --- a/toolsrc/src/vcpkg_System.cpp +++ b/toolsrc/src/vcpkg_System.cpp @@ -106,6 +106,8 @@ namespace vcpkg::System L"HTTPS_PROXY", // Enables find_package(CUDA) in CMake L"CUDA_PATH", + // Environmental variable generated automatically by CUDA after installation + L"NVCUDASAMPLES_ROOT", }; // Flush stdout before launching external process -- cgit v1.2.3 From d2c728e0bca834e9d30fe1d21c8921cdd4d188b8 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 12 Oct 2017 07:52:48 -0700 Subject: [several ports] Remove CMake double expansions inside if() directives --- ports/antlr4/portfile.cmake | 4 ++-- ports/bond/portfile.cmake | 4 ++-- ports/freeimage/CMakeLists.txt | 6 +++--- ports/libnice/CMakeLists.txt | 2 +- ports/libtheora/CMakeLists.txt | 2 +- ports/msmpi/portfile.cmake | 10 +++++----- ports/shaderc/CMakeLists.txt | 2 +- ports/shaderc/CMakeLists_spirv.txt | 2 +- ports/zziplib/CMakeLists.txt | 2 +- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/ports/antlr4/portfile.cmake b/ports/antlr4/portfile.cmake index 78266b6eb..868efcdbe 100644 --- a/ports/antlr4/portfile.cmake +++ b/ports/antlr4/portfile.cmake @@ -24,7 +24,7 @@ vcpkg_apply_patches( ${CMAKE_CURRENT_LIST_DIR}/Fix-building-in-Visual-Studio-2017.patch ) -if (${VCPKG_LIBRARY_LINKAGE} STREQUAL static) +if (VCPKG_LIBRARY_LINKAGE STREQUAL "static") set(DEBUG_CONFIG "Debug Static") set(RELEASE_CONFIG "Release Static") else() @@ -53,7 +53,7 @@ file(COPY ${SOURCE_PATH}/bin/vs-2015/${TRIPLET_SYSTEM_ARCH}/${DEBUG_CONFIG file(COPY ${SOURCE_PATH}/bin/vs-2015/${TRIPLET_SYSTEM_ARCH}/${RELEASE_CONFIG}/antlr4-runtime.lib DESTINATION ${CURRENT_PACKAGES_DIR}/lib) -if (${VCPKG_LIBRARY_LINKAGE} STREQUAL static) +if (VCPKG_LIBRARY_LINKAGE STREQUAL "static") vcpkg_apply_patches( SOURCE_PATH ${CURRENT_PACKAGES_DIR}/include PATCHES ${CMAKE_CURRENT_LIST_DIR}/static.patch diff --git a/ports/bond/portfile.cmake b/ports/bond/portfile.cmake index f3664da8c..147ebeea8 100644 --- a/ports/bond/portfile.cmake +++ b/ports/bond/portfile.cmake @@ -1,4 +1,4 @@ -if (VCPKG_LIBRARY_LINKAGE STREQUAL dynamic) +if (VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic") message(STATUS "Warning: Dynamic building not supported yet. Building static.") set(VCPKG_LIBRARY_LINKAGE static) endif() @@ -23,7 +23,7 @@ vcpkg_extract_source_archive(${ARCHIVE}) vcpkg_extract_source_archive(${GBC_ARCHIVE} ${CURRENT_BUILDTREES_DIR}/tools/) set(FETCHED_GBC_PATH ${CURRENT_BUILDTREES_DIR}/tools/gbc-6.0.0-amd64.exe) -if (NOT EXISTS ${FETCHED_GBC_PATH}) +if (NOT EXISTS "${FETCHED_GBC_PATH}") message(FATAL_ERROR "Fetching GBC failed. Expected '${FETCHED_GBC_PATH}' to exists, but it doesn't.") endif() diff --git a/ports/freeimage/CMakeLists.txt b/ports/freeimage/CMakeLists.txt index f385f508c..9f4f1677b 100644 --- a/ports/freeimage/CMakeLists.txt +++ b/ports/freeimage/CMakeLists.txt @@ -72,7 +72,7 @@ set(SRCS ${DEPRECATION_SRCS} # define (to nothing instead of _declspec(dllimport) ) the DLL_API macro. # For this purpouse we include (depending on the BUILD_SHARED_LIBS ) # the appropriate FreeImageConfig.h . -if(${BUILD_SHARED_LIBS}) +if(BUILD_SHARED_LIBS) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/FreeImageConfig-dynamic.h ${CMAKE_CURRENT_BINARY_DIR}/FreeImageConfig.h) else() configure_file(${CMAKE_CURRENT_SOURCE_DIR}/FreeImageConfig-static.h ${CMAKE_CURRENT_BINARY_DIR}/FreeImageConfig.h) @@ -81,7 +81,7 @@ list(APPEND PUBLIC_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/FreeImageConfig.h) add_library(FreeImage ${SRCS} ${PRIVATE_HEADERS} ${PUBLIC_HEADERS}) -if(${BUILD_SHARED_LIBS}) +if(BUILD_SHARED_LIBS) target_compile_definitions(FreeImage PRIVATE -DFREEIMAGE_EXPORTS) else() target_compile_definitions(FreeImage PRIVATE -DFREEIMAGE_LIB) @@ -119,7 +119,7 @@ add_library(FreeImagePlus ${CMAKE_CURRENT_SOURCE_DIR}/Wrapper/FreeImagePlus/FreeImagePlus.h ${CMAKE_CURRENT_SOURCE_DIR}/Wrapper/FreeImagePlus/FreeImagePlus.rc) -if(${BUILD_SHARED_LIBS}) +if(BUILD_SHARED_LIBS) target_compile_definitions(FreeImagePlus PRIVATE -DFIP_EXPORTS) else() target_compile_definitions(FreeImagePlus PRIVATE -DFREEIMAGE_LIB) diff --git a/ports/libnice/CMakeLists.txt b/ports/libnice/CMakeLists.txt index c631d3317..7454a0046 100644 --- a/ports/libnice/CMakeLists.txt +++ b/ports/libnice/CMakeLists.txt @@ -119,7 +119,7 @@ RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib) -if (${CMAKE_BUILD_TYPE} STREQUAL "Release") +if (CMAKE_BUILD_TYPE STREQUAL "Release") install(FILES agent/address.h DESTINATION include/nice) install(FILES agent/agent.h DESTINATION include/nice) install(FILES agent/candidate.h DESTINATION include/nice) diff --git a/ports/libtheora/CMakeLists.txt b/ports/libtheora/CMakeLists.txt index 24ecbccf4..cf8799e5d 100644 --- a/ports/libtheora/CMakeLists.txt +++ b/ports/libtheora/CMakeLists.txt @@ -66,7 +66,7 @@ if(USE_X86) add_definitions(-DOC_X86_ASM) endif() -if (${BUILD_SHARED_LIBS}) +if (BUILD_SHARED_LIBS) add_definitions(-DLIBTHEORA_EXPORTS) endif() diff --git a/ports/msmpi/portfile.cmake b/ports/msmpi/portfile.cmake index ca841313e..893e6f124 100644 --- a/ports/msmpi/portfile.cmake +++ b/ports/msmpi/portfile.cmake @@ -22,7 +22,7 @@ vcpkg_get_program_files_platform_bitness(PROGRAM_FILES_PLATFORM_BITNESS) set(SYSTEM_MPIEXEC_FILEPATH "${PROGRAM_FILES_PLATFORM_BITNESS}/Microsoft MPI/Bin/mpiexec.exe") set(MSMPI_EXPECTED_FULL_VERSION "8.1.12438.1084") -if(EXISTS ${SYSTEM_MPIEXEC_FILEPATH}) +if(EXISTS "${SYSTEM_MPIEXEC_FILEPATH}") set(MPIEXEC_VERSION_LOGNAME "mpiexec-version") vcpkg_execute_required_process( COMMAND ${SYSTEM_MPIEXEC_FILEPATH} @@ -31,8 +31,8 @@ if(EXISTS ${SYSTEM_MPIEXEC_FILEPATH}) ) file(READ ${CURRENT_BUILDTREES_DIR}/${MPIEXEC_VERSION_LOGNAME}-out.log MPIEXEC_OUTPUT) - if(${MPIEXEC_OUTPUT} MATCHES "\\[Version ([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)\\]") - if(NOT ${CMAKE_MATCH_1} STREQUAL ${MSMPI_EXPECTED_FULL_VERSION}) + if(MPIEXEC_OUTPUT MATCHES "\\[Version ([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)\\]") + if(NOT CMAKE_MATCH_1 STREQUAL MSMPI_EXPECTED_FULL_VERSION) download_msmpi_redistributable_package() message(FATAL_ERROR @@ -102,7 +102,7 @@ file(INSTALL DESTINATION ${CURRENT_PACKAGES_DIR}/lib ) -if(${TRIPLET_SYSTEM_ARCH} STREQUAL "x86") +if(TRIPLET_SYSTEM_ARCH STREQUAL "x86") file(INSTALL "${SOURCE_LIB_PATH}/${TRIPLET_SYSTEM_ARCH}/msmpifes.lib" "${SOURCE_LIB_PATH}/${TRIPLET_SYSTEM_ARCH}/msmpifms.lib" @@ -121,7 +121,7 @@ file(INSTALL DESTINATION ${CURRENT_PACKAGES_DIR}/debug/lib ) -if(${TRIPLET_SYSTEM_ARCH} STREQUAL "x86") +if(TRIPLET_SYSTEM_ARCH STREQUAL "x86") file(INSTALL "${SOURCE_LIB_PATH}/${TRIPLET_SYSTEM_ARCH}/msmpifes.lib" "${SOURCE_LIB_PATH}/${TRIPLET_SYSTEM_ARCH}/msmpifms.lib" diff --git a/ports/shaderc/CMakeLists.txt b/ports/shaderc/CMakeLists.txt index f4e0830c6..580ffa1d1 100644 --- a/ports/shaderc/CMakeLists.txt +++ b/ports/shaderc/CMakeLists.txt @@ -1,5 +1,5 @@ option(SUFFIX_D "Add d Suffix to lib" ${SUFFIX_D}) -if(NOT ${SUFFIX_D}) +if(NOT SUFFIX_D) find_library(GLSLANG glslang) find_library(OSDEPENDENT OSDependent) find_library(OGLCOMPILER OGLCompiler) diff --git a/ports/shaderc/CMakeLists_spirv.txt b/ports/shaderc/CMakeLists_spirv.txt index 6aa738b1f..618177fa6 100644 --- a/ports/shaderc/CMakeLists_spirv.txt +++ b/ports/shaderc/CMakeLists_spirv.txt @@ -1,5 +1,5 @@ option(SUFFIX_D "Add d Suffix to lib" ${SUFFIX_D}) -if(NOT ${SUFFIX_D}) +if(NOT SUFFIX_D) find_library(SPIRVTOOLSOPT spirv-tools-opt) find_library(SPIRVTOOLS spirv-tools) ELSE() diff --git a/ports/zziplib/CMakeLists.txt b/ports/zziplib/CMakeLists.txt index 7f46079e9..c99bc0ddd 100644 --- a/ports/zziplib/CMakeLists.txt +++ b/ports/zziplib/CMakeLists.txt @@ -55,7 +55,7 @@ set(SRCS zzip/dir.c add_library(zziplib ${SRCS} ${HEADERS}) -if(${BUILD_SHARED_LIBS}) +if(BUILD_SHARED_LIBS) target_compile_definitions(zziplib PRIVATE -DZZIPLIB_EXPORTS) endif() -- cgit v1.2.3 From 5c66f301b9d7aa27a11059cee970e579f039c66c Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 12 Oct 2017 08:22:50 -0700 Subject: [vcpkg-scripts] Remove double expansions --- scripts/cmake/vcpkg_acquire_depot_tools.cmake | 2 +- scripts/cmake/vcpkg_download_distfile.cmake | 2 +- scripts/cmake/vcpkg_find_acquire_program.cmake | 11 +++++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/scripts/cmake/vcpkg_acquire_depot_tools.cmake b/scripts/cmake/vcpkg_acquire_depot_tools.cmake index 1cc375725..009ba40f1 100644 --- a/scripts/cmake/vcpkg_acquire_depot_tools.cmake +++ b/scripts/cmake/vcpkg_acquire_depot_tools.cmake @@ -26,7 +26,7 @@ function(vcpkg_acquire_depot_tools PATH_TO_ROOT_OUT) set(download_success 1) endif() - if (NOT ${download_success}) + if (NOT download_success) message(FATAL_ERROR "\n" " Failed to download file.\n" diff --git a/scripts/cmake/vcpkg_download_distfile.cmake b/scripts/cmake/vcpkg_download_distfile.cmake index 006570195..b8acfc823 100644 --- a/scripts/cmake/vcpkg_download_distfile.cmake +++ b/scripts/cmake/vcpkg_download_distfile.cmake @@ -78,7 +78,7 @@ function(vcpkg_download_distfile VAR) endif() endforeach(url) - if (NOT ${download_success}) + if (NOT download_success) message(FATAL_ERROR "\n" " Failed to download file.\n" diff --git a/scripts/cmake/vcpkg_find_acquire_program.cmake b/scripts/cmake/vcpkg_find_acquire_program.cmake index 3c6dfae08..8d167e1c2 100644 --- a/scripts/cmake/vcpkg_find_acquire_program.cmake +++ b/scripts/cmake/vcpkg_find_acquire_program.cmake @@ -34,7 +34,8 @@ ## * [openssl](https://github.com/Microsoft/vcpkg/blob/master/ports/openssl/portfile.cmake) ## * [qt5](https://github.com/Microsoft/vcpkg/blob/master/ports/qt5/portfile.cmake) function(vcpkg_find_acquire_program VAR) - if(${VAR} AND NOT ${VAR} MATCHES "-NOTFOUND") + set(EXPANDED_VAR ${${VAR}}) + if(EXPANDED_VAR) return() endif() @@ -153,7 +154,8 @@ function(vcpkg_find_acquire_program VAR) macro(do_find) if(NOT DEFINED REQUIRED_INTERPRETER) - find_program(${VAR} ${PROGNAME} PATHS ${PATHS}) + find_program(FOUND_PROG ${PROGNAME} PATHS ${PATHS}) + set(${VAR} ${FOUND_PROG}) else() vcpkg_find_acquire_program(${REQUIRED_INTERPRETER}) find_file(SCRIPT ${SCRIPTNAME} PATHS ${PATHS}) @@ -162,7 +164,8 @@ function(vcpkg_find_acquire_program VAR) endmacro() do_find() - if(${VAR} MATCHES "-NOTFOUND") + set(FOUND_PROG ${${VAR}}) + if(FOUND_PROG MATCHES "-NOTFOUND") file(DOWNLOAD ${URL} ${DOWNLOADS}/${ARCHIVE} EXPECTED_HASH SHA512=${HASH} SHOW_PROGRESS @@ -173,7 +176,7 @@ function(vcpkg_find_acquire_program VAR) else() get_filename_component(ARCHIVE_EXTENSION ${ARCHIVE} EXT) string(TOLOWER "${ARCHIVE_EXTENSION}" ARCHIVE_EXTENSION) - if(${ARCHIVE_EXTENSION} STREQUAL ".msi") + if(ARCHIVE_EXTENSION STREQUAL ".msi") file(TO_NATIVE_PATH "${DOWNLOADS}/${ARCHIVE}" ARCHIVE_NATIVE_PATH) file(TO_NATIVE_PATH "${DOWNLOADS}/tools/${PROGNAME}/${SUBDIR}" DESTINATION_NATIVE_PATH) execute_process( -- cgit v1.2.3 From ae0b277ae3162a99852df9c8ac016394cb506257 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 12 Oct 2017 10:18:29 -0700 Subject: [celero] Update to use vcpkg_from_github and Ninja --- ports/celero/CONTROL | 2 +- ports/celero/portfile.cmake | 45 ++++++++++++++++++--------------------------- 2 files changed, 19 insertions(+), 28 deletions(-) diff --git a/ports/celero/CONTROL b/ports/celero/CONTROL index 852e9b4f9..d40c93783 100644 --- a/ports/celero/CONTROL +++ b/ports/celero/CONTROL @@ -1,3 +1,3 @@ Source: celero -Version: 2.1.0 +Version: 2.1.0-1 Description: Celero is a modern cross-platform (Windows, Linux, MacOS) Microbenchmarking library for C++. diff --git a/ports/celero/portfile.cmake b/ports/celero/portfile.cmake index ef66131e7..c942ca5d8 100644 --- a/ports/celero/portfile.cmake +++ b/ports/celero/portfile.cmake @@ -1,35 +1,26 @@ -# Common Ambient Variables: -# CURRENT_BUILDTREES_DIR = ${VCPKG_ROOT_DIR}\buildtrees\${PORT} -# CURRENT_PACKAGES_DIR = ${VCPKG_ROOT_DIR}\packages\${PORT}_${TARGET_TRIPLET} -# CURRENT_PORT_DIR = ${VCPKG_ROOT_DIR}\ports\${PORT} -# PORT = current port name (zlib, etc) -# TARGET_TRIPLET = current triplet (x86-windows, x64-windows-static, etc) -# VCPKG_CRT_LINKAGE = C runtime linkage type (static, dynamic) -# VCPKG_LIBRARY_LINKAGE = target library linkage type (static, dynamic) -# VCPKG_ROOT_DIR = -# VCPKG_TARGET_ARCHITECTURE = target architecture (x64, x86, arm) -# - include(vcpkg_common_functions) -set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/Celero-master) -vcpkg_download_distfile(ARCHIVE - URLS "https://github.com/DigitalInBlue/Celero/archive/master.zip" - FILENAME "celero-v2.1.0.zip" - SHA512 d3971b102bd1785cf21712bcf2e39193e47d5faaa39421cb1cc788340bb67aed4c32343d3b45042813fcf503d48068bc2a2d26808e2e12d8515e29c60ef40c5c -) -vcpkg_extract_source_archive(${ARCHIVE}) -# Disable building of the examples -set(CELERO_ENABLE_EXPERIMENTS OFF) -set(CELERO_ENABLE_TESTS OFF) -set(CELERO_RUN_EXAMPLE_ON_BUILD OFF) +if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic") + message(STATUS "Celero currently can only be built statically") + set(VCPKG_LIBRARY_LINKAGE static) +endif() + + +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO DigitalInBlue/Celero + REF v2.1.0 + SHA512 30563567255b09a2c810d97896839589ed99d45b6c8d075fd16d1a0068457d70195a199f5c982c84784c2e03284c1eaac565253fa72b81d9e2d4102721b80221 + HEAD_REF master +) vcpkg_configure_cmake( SOURCE_PATH ${SOURCE_PATH} - # PREFER_NINJA Disable this option if project cannot be built with Ninja - # OPTIONS -DUSE_THIS_IN_ALL_BUILDS=1 -DUSE_THIS_TOO=2 - # OPTIONS_RELEASE -DOPTIMIZE=1 - # OPTIONS_DEBUG -DDEBUGGABLE=1 + PREFER_NINJA # Disable this option if project cannot be built with Ninja + OPTIONS + -DCELERO_ENABLE_EXPERIMENTS=OFF + -DCELERO_ENABLE_TESTS=OFF + -DCELERO_RUN_EXAMPLE_ON_BUILD=OFF ) vcpkg_install_cmake() -- cgit v1.2.3 From 57b37aac65eb863e485c8f36a4b4eb95487799b4 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 12 Oct 2017 10:37:14 -0700 Subject: [openni2] Use separate copy of sources to enable building multiple triplets. Use vcpkg_from_github. --- ports/openni2/CONTROL | 2 +- ports/openni2/portfile.cmake | 38 +++++------ .../openni2/replace_environment_variable.patch.in | 76 ---------------------- 3 files changed, 18 insertions(+), 98 deletions(-) delete mode 100644 ports/openni2/replace_environment_variable.patch.in diff --git a/ports/openni2/CONTROL b/ports/openni2/CONTROL index bf012ff8e..b1d60d860 100644 --- a/ports/openni2/CONTROL +++ b/ports/openni2/CONTROL @@ -1,4 +1,4 @@ Source: openni2 -Version: 2.2.0.33-3 +Version: 2.2.0.33-4 Build-Depends: kinectsdk1 Description: OpenNI is open source library for access to Natural Interaction (NI) devices such as RGB-D camera. diff --git a/ports/openni2/portfile.cmake b/ports/openni2/portfile.cmake index 2e91bac3f..cc428ddb7 100644 --- a/ports/openni2/portfile.cmake +++ b/ports/openni2/portfile.cmake @@ -1,15 +1,3 @@ -# Common Ambient Variables: -# CURRENT_BUILDTREES_DIR = ${VCPKG_ROOT_DIR}\buildtrees\${PORT} -# CURRENT_PACKAGES_DIR = ${VCPKG_ROOT_DIR}\packages\${PORT}_${TARGET_TRIPLET} -# CURRENT_PORT_DIR = ${VCPKG_ROOT_DIR}\ports\${PORT} -# PORT = current port name (zlib, etc) -# TARGET_TRIPLET = current triplet (x86-windows, x64-windows-static, etc) -# VCPKG_CRT_LINKAGE = C runtime linkage type (static, dynamic) -# VCPKG_LIBRARY_LINKAGE = target library linkage type (static, dynamic) -# VCPKG_ROOT_DIR = -# VCPKG_TARGET_ARCHITECTURE = target architecture (x64, x86, arm) -# - # UWP Not Support if (VCPKG_CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") message(FATAL_ERROR "Error: UWP builds are currently not supported.") @@ -28,16 +16,13 @@ endif() # Download Source Code include(vcpkg_common_functions) -set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/OpenNI2-2.2-beta2) -vcpkg_download_distfile(ARCHIVE - URLS "https://github.com/OpenNI/OpenNI2/archive/2.2-beta2.zip" - FILENAME "OpenNI2-2.2-beta.zip" - SHA512 9779161493114265745c9eb8b15db95a3ed2322cd75504931d0fb7b6214d7abc8a9eb2ea5f35e309bc4d2748f015eee27ada4974a2e9568b5ecb9d98099c84e9 +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO OpenNI/OpenNI2 + REF 2.2-beta2 + SHA512 60a3a3043679f3069aea869e92dc5881328ce4393d4140ea8d089027321ac501ae27d283657214e2834d216d0d49bf4f29a4b3d3e43df27a6ed21f889cd0083f + HEAD_REF master ) -vcpkg_extract_source_archive(${ARCHIVE}) - -file(TO_NATIVE_PATH ${VCPKG_ROOT_DIR} NATIVE_VCPKG_ROOT_DIR) -configure_file("${CMAKE_CURRENT_LIST_DIR}/replace_environment_variable.patch.in" "${CMAKE_CURRENT_LIST_DIR}/replace_environment_variable.patch" @ONLY) vcpkg_apply_patches( SOURCE_PATH ${SOURCE_PATH} @@ -46,6 +31,17 @@ vcpkg_apply_patches( "${CMAKE_CURRENT_LIST_DIR}/replace_environment_variable.patch" ) +file(REMOVE_RECURSE ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}) +file(MAKE_DIRECTORY ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}) +file(COPY ${SOURCE_PATH} DESTINATION ${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}) +get_filename_component(SOURCE_DIR_NAME "${SOURCE_PATH}" NAME) + +# Use fresh copy of sources for building and modification +set(SOURCE_PATH "${CURRENT_BUILDTREES_DIR}/${TARGET_TRIPLET}/${SOURCE_DIR_NAME}") + +file(TO_NATIVE_PATH ${CURRENT_INSTALLED_DIR} NATIVE_INSTALLED_DIR) +configure_file("${SOURCE_PATH}/Source/Drivers/Kinect/Kinect.vcxproj" "${SOURCE_PATH}/Source/Drivers/Kinect/Kinect.vcxproj" @ONLY) + # Build OpenNI2 vcpkg_build_msbuild( PROJECT_PATH "${SOURCE_PATH}/OpenNI.sln" diff --git a/ports/openni2/replace_environment_variable.patch.in b/ports/openni2/replace_environment_variable.patch.in deleted file mode 100644 index 31e7cb951..000000000 --- a/ports/openni2/replace_environment_variable.patch.in +++ /dev/null @@ -1,76 +0,0 @@ -diff --git a/Source/Drivers/Kinect/Kinect.vcxproj b/Source/Drivers/Kinect/Kinect.vcxproj -index 08a49fe..7fd8620 100644 ---- a/Source/Drivers/Kinect/Kinect.vcxproj -+++ b/Source/Drivers/Kinect/Kinect.vcxproj -@@ -101,7 +101,7 @@ - - Level3 - Disabled -- ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; -+ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\include - _WINDLL;%(PreprocessorDefinitions);_WINDOWS - false - false -@@ -109,7 +109,7 @@ - - true - Kinect10.lib;XnLib.lib;%(AdditionalDependencies) -- $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\x86; -+ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\debug\lib - true - - -@@ -117,7 +117,7 @@ - - Level3 - Disabled -- ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; -+ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\include - _WINDLL;%(PreprocessorDefinitions);_WINDOWS - false - false -@@ -125,7 +125,7 @@ - - true - Kinect10.lib;XnLib.lib;%(AdditionalDependencies) -- $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\amd64; -+ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\debug\lib - - - -@@ -139,7 +139,7 @@ - MaxSpeed - true - true -- ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; -+ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\include - false - - -@@ -147,7 +147,7 @@ - true - true - Kinect10.lib;XnLib.lib;%(AdditionalDependencies) -- $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\x86; -+ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\lib - true - - -@@ -157,7 +157,7 @@ - MaxSpeed - true - true -- ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; -+ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\include - false - - -@@ -165,7 +165,7 @@ - true - true - Kinect10.lib;XnLib.lib;%(AdditionalDependencies) -- $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\amd64; -+ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_VCPKG_ROOT_DIR@\packages\kinectsdk1_@TARGET_TRIPLET@\lib - true - - -- cgit v1.2.3 From 9ddc98988fb8d7c886963fa7568395ecd5785eaa Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 12 Oct 2017 10:52:00 -0700 Subject: [vcpkg-scripts] Detect and prompt for proxy in more cases --- scripts/bootstrap.ps1 | 4 ---- scripts/fetchDependency.ps1 | 20 +++++++++++--------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/scripts/bootstrap.ps1 b/scripts/bootstrap.ps1 index fa51de404..b7bc5afab 100644 --- a/scripts/bootstrap.ps1 +++ b/scripts/bootstrap.ps1 @@ -4,10 +4,6 @@ param( [string]$disableMetrics = "0" ) -$webclient=New-Object System.Net.WebClient -$creds=Get-Credential -$webclient.Proxy.Credentials=$creds - $scriptsDir = split-path -parent $MyInvocation.MyCommand.Definition $vcpkgRootDir = & $scriptsDir\findFileRecursivelyUp.ps1 $scriptsDir .vcpkg-root diff --git a/scripts/fetchDependency.ps1 b/scripts/fetchDependency.ps1 index b6144d581..2ee87bcff 100644 --- a/scripts/fetchDependency.ps1 +++ b/scripts/fetchDependency.ps1 @@ -82,17 +82,19 @@ function SelectProgram([Parameter(Mandatory=$true)][string]$Dependency) New-Item -ItemType directory -Path $downloadDir | Out-Null } + $WC = New-Object System.Net.WebClient + $ProxyAuth = !$WC.Proxy.IsBypassed($url) + if ($ProxyAuth) + { + $ProxyCred = Get-Credential -Message "Enter credentials for Proxy Authentication" + $PSDefaultParameterValues.Add("Start-BitsTransfer:ProxyAuthentication","Basic") + $PSDefaultParameterValues.Add("Start-BitsTransfer:ProxyCredential",$ProxyCred) + $WC.Proxy.Credentials=$ProxyCred + } + if (($PSVersionTable.PSEdition -ne "Core") -and ($Dependency -ne "git")) # git fails with BITS { try { - $WC = New-Object System.Net.WebClient - $ProxyAuth = !$WC.Proxy.IsBypassed($url) - If($ProxyAuth){ - $ProxyCred = Get-Credential -Message "Enter credentials for Proxy Authentication" - $PSDefaultParameterValues.Add("Start-BitsTransfer:ProxyAuthentication","Basic") - $PSDefaultParameterValues.Add("Start-BitsTransfer:ProxyCredential",$ProxyCred) - } - Start-BitsTransfer -Source $url -Destination $downloadPath -ErrorAction Stop } catch [System.Exception] { @@ -106,7 +108,7 @@ function SelectProgram([Parameter(Mandatory=$true)][string]$Dependency) if (!(Test-Path $downloadPath)) { Write-Verbose("Downloading $Dependency...") - (New-Object System.Net.WebClient).DownloadFile($url, $downloadPath) + $WC.DownloadFile($url, $downloadPath) } } -- cgit v1.2.3 From 0179bc051ea1c5d60547b283e8e8c60472b1d2e7 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 12 Oct 2017 10:52:55 -0700 Subject: [openni2] Fixup forgot to commit renamed patch file. --- ports/openni2/replace_environment_variable.patch | 76 ++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 ports/openni2/replace_environment_variable.patch diff --git a/ports/openni2/replace_environment_variable.patch b/ports/openni2/replace_environment_variable.patch new file mode 100644 index 000000000..48978e869 --- /dev/null +++ b/ports/openni2/replace_environment_variable.patch @@ -0,0 +1,76 @@ +diff --git a/Source/Drivers/Kinect/Kinect.vcxproj b/Source/Drivers/Kinect/Kinect.vcxproj +index 08a49fe..7fd8620 100644 +--- a/Source/Drivers/Kinect/Kinect.vcxproj ++++ b/Source/Drivers/Kinect/Kinect.vcxproj +@@ -101,7 +101,7 @@ + + Level3 + Disabled +- ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; ++ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_INSTALLED_DIR@\include + _WINDLL;%(PreprocessorDefinitions);_WINDOWS + false + false +@@ -109,7 +109,7 @@ + + true + Kinect10.lib;XnLib.lib;%(AdditionalDependencies) +- $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\x86; ++ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_INSTALLED_DIR@\debug\lib + true + + +@@ -117,7 +117,7 @@ + + Level3 + Disabled +- ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; ++ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_INSTALLED_DIR@\include + _WINDLL;%(PreprocessorDefinitions);_WINDOWS + false + false +@@ -125,7 +125,7 @@ + + true + Kinect10.lib;XnLib.lib;%(AdditionalDependencies) +- $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\amd64; ++ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_INSTALLED_DIR@\debug\lib + + + +@@ -139,7 +139,7 @@ + MaxSpeed + true + true +- ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; ++ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_INSTALLED_DIR@\include + false + + +@@ -147,7 +147,7 @@ + true + true + Kinect10.lib;XnLib.lib;%(AdditionalDependencies) +- $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\x86; ++ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_INSTALLED_DIR@\lib + true + + +@@ -157,7 +157,7 @@ + MaxSpeed + true + true +- ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;$(KINECTSDK10_DIR)\inc; ++ ..\..\..\Include;..\..\..\ThirdParty\PSCommon\XnLib\Include;@NATIVE_INSTALLED_DIR@\include + false + + +@@ -165,7 +165,7 @@ + true + true + Kinect10.lib;XnLib.lib;%(AdditionalDependencies) +- $(SolutionDir)Bin\$(Platform)-$(Configuration)\;$(KINECTSDK10_DIR)\lib\amd64; ++ $(SolutionDir)Bin\$(Platform)-$(Configuration)\;@NATIVE_INSTALLED_DIR@\lib + true + + -- cgit v1.2.3 From 3efcc3d377750b753d516fd21b9009bfcd6e3877 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 12 Oct 2017 11:45:08 -0700 Subject: Fix #1963 (permissive- issue) --- toolsrc/include/VcpkgPaths.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h index d4640fba2..a38865a3f 100644 --- a/toolsrc/include/VcpkgPaths.h +++ b/toolsrc/include/VcpkgPaths.h @@ -67,8 +67,8 @@ namespace vcpkg /// /// Valid version strings are "v140", "v141", and "". Empty string gets the latest. /// - const Toolset& VcpkgPaths::get_toolset(const Optional& toolset_version, - const Optional& visual_studio_path) const; + const Toolset& get_toolset(const Optional& toolset_version, + const Optional& visual_studio_path) const; Files::Filesystem& get_filesystem() const; -- cgit v1.2.3 From 53ad1402514481c581a7b3bd1b0ffbcea9aaa902 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Thu, 12 Oct 2017 11:54:47 -0700 Subject: [vcpkg-scripts] Hotpatch revert changes to vcpkg_find_acquire_program.cmake. --- scripts/cmake/vcpkg_find_acquire_program.cmake | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/scripts/cmake/vcpkg_find_acquire_program.cmake b/scripts/cmake/vcpkg_find_acquire_program.cmake index 8d167e1c2..51e394bf1 100644 --- a/scripts/cmake/vcpkg_find_acquire_program.cmake +++ b/scripts/cmake/vcpkg_find_acquire_program.cmake @@ -154,8 +154,7 @@ function(vcpkg_find_acquire_program VAR) macro(do_find) if(NOT DEFINED REQUIRED_INTERPRETER) - find_program(FOUND_PROG ${PROGNAME} PATHS ${PATHS}) - set(${VAR} ${FOUND_PROG}) + find_program(${VAR} ${PROGNAME} PATHS ${PATHS}) else() vcpkg_find_acquire_program(${REQUIRED_INTERPRETER}) find_file(SCRIPT ${SCRIPTNAME} PATHS ${PATHS}) @@ -164,8 +163,7 @@ function(vcpkg_find_acquire_program VAR) endmacro() do_find() - set(FOUND_PROG ${${VAR}}) - if(FOUND_PROG MATCHES "-NOTFOUND") + if("${${VAR}}" MATCHES "-NOTFOUND") file(DOWNLOAD ${URL} ${DOWNLOADS}/${ARCHIVE} EXPECTED_HASH SHA512=${HASH} SHOW_PROGRESS @@ -194,5 +192,5 @@ function(vcpkg_find_acquire_program VAR) do_find() endif() - set(${VAR} ${${VAR}} PARENT_SCOPE) + set(${VAR} "${${VAR}}" PARENT_SCOPE) endfunction() -- cgit v1.2.3 From 9e19c24d2911ff1ef648aeed0c596e3987eafebf Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Thu, 12 Oct 2017 14:03:01 -0700 Subject: `vcpkg autocomplete` More work on autocomplete --- toolsrc/src/commands_autocomplete.cpp | 83 +++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 22 deletions(-) diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp index 3963f904b..abad19df7 100644 --- a/toolsrc/src/commands_autocomplete.cpp +++ b/toolsrc/src/commands_autocomplete.cpp @@ -1,9 +1,8 @@ #include "pch.h" #include "Paragraphs.h" -#include "SortedVector.h" +#include "metrics.h" #include "vcpkg_Commands.h" -#include "vcpkg_Maps.h" #include "vcpkg_System.h" #include "vcpkglib.h" @@ -35,7 +34,7 @@ namespace vcpkg::Commands::Autocomplete for (const auto& installed_package : installed_packages) { - auto sp = installed_package->package.displayname(); + const auto sp = installed_package->package.displayname(); if (istartswith(sp, start_with)) { @@ -47,33 +46,73 @@ namespace vcpkg::Commands::Autocomplete void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { - static const std::string EXAMPLE = - Strings::format("The argument should be a command line to autocomplete.\n%s", - Commands::Help::create_example_string("autocomplete install z")); + Metrics::g_metrics.lock()->set_send_metrics(false); - args.check_min_arg_count(1, EXAMPLE); - args.check_max_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}); + if (args.command_arguments.size() != 1) + { + Checks::exit_success(VCPKG_LINE_INFO); + } - const std::string requested_command = args.command_arguments.at(0); - const std::string start_with = - args.command_arguments.size() > 1 ? args.command_arguments.at(1) : Strings::EMPTY; - std::vector results; - if (requested_command == "install") + const std::string to_autocomplete = args.command_arguments.at(0); + const std::vector tokens = Strings::split(to_autocomplete, " "); + if (tokens.size() == 1) { - auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); - auto& source_paragraphs = sources_and_errors.paragraphs; + const std::string requested_command = tokens[0]; + + std::vector valid_commands = {"install", + "search", + "remove", + "list", + "update", + "hash", + "help", + "integrate", + "export", + "edit", + "create", + "owns", + "cache", + "version", + "contact"}; + + Util::unstable_keep_if(valid_commands, [&](const std::string& s) { + return Strings::case_insensitive_ascii_starts_with(s, requested_command); + }); - results = autocomplete_install(source_paragraphs, start_with); + if (valid_commands.size() == 1) + { + System::println(valid_commands[0] + " "); + } + else + { + System::println(Strings::join("\n", valid_commands)); + } + + Checks::exit_success(VCPKG_LINE_INFO); } - else if (requested_command == "remove") + + if (tokens.size() == 2) { - const StatusParagraphs status_db = database_load_check(paths); - std::vector installed_packages = get_installed_ports(status_db); - results = autocomplete_remove(installed_packages, start_with); + const std::string requested_command = tokens[0]; + const std::string start_with = tokens[1]; + std::vector results; + if (requested_command == "install") + { + auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + auto& source_paragraphs = sources_and_errors.paragraphs; + + results = autocomplete_install(source_paragraphs, start_with); + } + else if (requested_command == "remove") + { + const StatusParagraphs status_db = database_load_check(paths); + const std::vector installed_packages = get_installed_ports(status_db); + results = autocomplete_remove(installed_packages, start_with); + } + + System::println(Strings::join("\n", results)); } - System::println(Strings::join(" ", results)); Checks::exit_success(VCPKG_LINE_INFO); } } -- cgit v1.2.3 From 37fba399ef5c57573a1218206cb2c55f5f6bc13c Mon Sep 17 00:00:00 2001 From: Konstantin Podsvirov Date: Fri, 13 Oct 2017 05:33:32 +0300 Subject: [vcpkg-export-ifw] Safe description QtIFW support rich text for component description, bu some port has not safe ampersand symbol in description text (for example 'openexr' package), that should be replaced to '&' symbol name --- toolsrc/src/commands_export_ifw.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp index 191dbb763..c001a93ed 100644 --- a/toolsrc/src/commands_export_ifw.cpp +++ b/toolsrc/src/commands_export_ifw.cpp @@ -26,6 +26,14 @@ namespace vcpkg::Commands::Export::IFW return date_time_as_string; } + std::string safe_rich_from_plain_text(const std::string& text) + { + // match standalone ampersand, no HTML number or name + std::regex standalone_ampersand(R"###(&(?!(#[0-9]+|\w+);))###"); + + return std::regex_replace(text, standalone_ampersand, "&"); + } + fs::path get_packages_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) { return ifw_options.maybe_packages_dir_path.has_value() @@ -156,7 +164,7 @@ namespace vcpkg::Commands::Export::IFW )###", action.spec.name(), - binary_paragraph.description, + safe_rich_from_plain_text(binary_paragraph.description), binary_paragraph.version, create_release_date())); } -- cgit v1.2.3 From f6a0d78c82789af482eb3c885cbbb73aba7dfb38 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 13 Oct 2017 14:54:31 -0700 Subject: `autocomplete` Rework command, fixing a lot of corner cases in the process --- toolsrc/include/vcpkg_Commands.h | 8 ++--- toolsrc/src/commands_autocomplete.cpp | 66 ++++++++++++++++------------------- 2 files changed, 34 insertions(+), 40 deletions(-) diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h index 7cfa2760e..c9a33a8f4 100644 --- a/toolsrc/include/vcpkg_Commands.h +++ b/toolsrc/include/vcpkg_Commands.h @@ -194,10 +194,10 @@ namespace vcpkg::Commands void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } - namespace Autocomplete - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } + namespace Autocomplete + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } namespace Help { diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp index abad19df7..478a3c478 100644 --- a/toolsrc/src/commands_autocomplete.cpp +++ b/toolsrc/src/commands_autocomplete.cpp @@ -5,6 +5,7 @@ #include "vcpkg_Commands.h" #include "vcpkg_System.h" #include "vcpkglib.h" +#include namespace vcpkg::Commands::Autocomplete { @@ -44,20 +45,26 @@ namespace vcpkg::Commands::Autocomplete return results; } + [[noreturn]] static void output_sorted_results_and_exit(const LineInfo& line_info, + std::vector&& results) + { + const SortedVector sorted_results(results); + System::println(Strings::join("\n", sorted_results)); + Checks::exit_success(line_info); + } + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) { Metrics::g_metrics.lock()->set_send_metrics(false); + const std::string to_autocomplete = Strings::join(" ", args.command_arguments); + const std::vector tokens = Strings::split(to_autocomplete, " "); - if (args.command_arguments.size() != 1) - { - Checks::exit_success(VCPKG_LINE_INFO); - } + std::smatch match; - const std::string to_autocomplete = args.command_arguments.at(0); - const std::vector tokens = Strings::split(to_autocomplete, " "); - if (tokens.size() == 1) + // Handles vcpkg + if (std::regex_match(to_autocomplete, match, std::regex{R"###(^(\S*)$)###"})) { - const std::string requested_command = tokens[0]; + const std::string requested_command = match[1].str(); std::vector valid_commands = {"install", "search", @@ -79,38 +86,25 @@ namespace vcpkg::Commands::Autocomplete return Strings::case_insensitive_ascii_starts_with(s, requested_command); }); - if (valid_commands.size() == 1) - { - System::println(valid_commands[0] + " "); - } - else - { - System::println(Strings::join("\n", valid_commands)); - } - - Checks::exit_success(VCPKG_LINE_INFO); + output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(valid_commands)); } - if (tokens.size() == 2) + // Handles vcpkg install + if (std::regex_match(to_autocomplete, match, std::regex{R"###(^install.* (\S*)$)###"})) { - const std::string requested_command = tokens[0]; - const std::string start_with = tokens[1]; - std::vector results; - if (requested_command == "install") - { - auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); - auto& source_paragraphs = sources_and_errors.paragraphs; - - results = autocomplete_install(source_paragraphs, start_with); - } - else if (requested_command == "remove") - { - const StatusParagraphs status_db = database_load_check(paths); - const std::vector installed_packages = get_installed_ports(status_db); - results = autocomplete_remove(installed_packages, start_with); - } + const std::string start_with = match[1].str(); + auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + auto& source_paragraphs = sources_and_errors.paragraphs; + output_sorted_results_and_exit(VCPKG_LINE_INFO, autocomplete_install(source_paragraphs, start_with)); + } - System::println(Strings::join("\n", results)); + // Handles vcpkg remove + if (std::regex_match(to_autocomplete, match, std::regex{R"###(^remove.* (\S*)$)###"})) + { + const std::string start_with = match[1].str(); + const StatusParagraphs status_db = database_load_check(paths); + const std::vector installed_packages = get_installed_ports(status_db); + output_sorted_results_and_exit(VCPKG_LINE_INFO, autocomplete_remove(installed_packages, start_with)); } Checks::exit_success(VCPKG_LINE_INFO); -- cgit v1.2.3 From d46a992b3cbbbf3479ad3906aecd07e73174cd40 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Fri, 13 Oct 2017 15:17:11 -0700 Subject: Don't do function "aliasing" --- toolsrc/src/commands_autocomplete.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp index 478a3c478..6ded74f9b 100644 --- a/toolsrc/src/commands_autocomplete.cpp +++ b/toolsrc/src/commands_autocomplete.cpp @@ -13,13 +13,12 @@ namespace vcpkg::Commands::Autocomplete const std::vector>& source_paragraphs, const std::string& start_with) { std::vector results; - const auto& istartswith = Strings::case_insensitive_ascii_starts_with; for (const auto& source_control_file : source_paragraphs) { auto&& sp = *source_control_file->core_paragraph; - if (istartswith(sp.name, start_with)) + if (Strings::case_insensitive_ascii_starts_with(sp.name, start_with)) { results.push_back(sp.name); } @@ -31,13 +30,12 @@ namespace vcpkg::Commands::Autocomplete const std::string& start_with) { std::vector results; - const auto& istartswith = Strings::case_insensitive_ascii_starts_with; for (const auto& installed_package : installed_packages) { const auto sp = installed_package->package.displayname(); - if (istartswith(sp, start_with)) + if (Strings::case_insensitive_ascii_starts_with(sp, start_with)) { results.push_back(sp); } -- cgit v1.2.3 From e17de99599a2f114faab1bb4821fbaad4d266c95 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 13 Oct 2017 18:37:41 -0700 Subject: [vcpkg] Re-layout all files using new organization scheme. All filenames and directories are lowercase. Use dots for namespace separation. --- toolsrc/include/BinaryParagraph.h | 41 - toolsrc/include/CStringView.h | 96 --- toolsrc/include/LineInfo.h | 19 - toolsrc/include/MachineType.h | 36 - toolsrc/include/PackageSpec.h | 95 --- toolsrc/include/PackageSpecParseResult.h | 32 - toolsrc/include/ParagraphParseResult.h | 32 - toolsrc/include/Paragraphs.h | 38 - toolsrc/include/PostBuildLint.h | 12 - toolsrc/include/PostBuildLint_BuildType.h | 66 -- toolsrc/include/SortedVector.h | 50 -- toolsrc/include/SourceParagraph.h | 96 --- toolsrc/include/Span.h | 52 -- toolsrc/include/StatusParagraph.h | 44 -- toolsrc/include/StatusParagraphs.h | 46 -- toolsrc/include/VcpkgCmdArguments.h | 49 -- toolsrc/include/VcpkgPaths.h | 84 -- toolsrc/include/VersionT.h | 29 - toolsrc/include/coff_file_reader.h | 21 - toolsrc/include/filesystem_fs.h | 16 - toolsrc/include/lazy.h | 26 - toolsrc/include/metrics.h | 28 - toolsrc/include/pch.h | 8 +- toolsrc/include/triplet.h | 43 -- toolsrc/include/vcpkg/base/checks.h | 55 ++ toolsrc/include/vcpkg/base/chrono.h | 28 + toolsrc/include/vcpkg/base/cofffilereader.h | 23 + toolsrc/include/vcpkg/base/cstringview.h | 97 +++ toolsrc/include/vcpkg/base/enums.h | 12 + toolsrc/include/vcpkg/base/expected.h | 115 +++ toolsrc/include/vcpkg/base/files.h | 57 ++ toolsrc/include/vcpkg/base/graphs.h | 161 ++++ toolsrc/include/vcpkg/base/lazy.h | 26 + toolsrc/include/vcpkg/base/lineinfo.h | 19 + toolsrc/include/vcpkg/base/machinetype.h | 37 + toolsrc/include/vcpkg/base/optional.h | 99 +++ toolsrc/include/vcpkg/base/sortedvector.h | 50 ++ toolsrc/include/vcpkg/base/span.h | 60 ++ toolsrc/include/vcpkg/base/strings.h | 114 +++ toolsrc/include/vcpkg/base/system.h | 108 +++ toolsrc/include/vcpkg/base/util.h | 156 ++++ toolsrc/include/vcpkg/binaryparagraph.h | 42 + toolsrc/include/vcpkg/build.h | 205 +++++ toolsrc/include/vcpkg/commands.h | 134 ++++ toolsrc/include/vcpkg/dependencies.h | 149 ++++ toolsrc/include/vcpkg/export.h | 10 + toolsrc/include/vcpkg/export.ifw.h | 26 + toolsrc/include/vcpkg/globalstate.h | 19 + toolsrc/include/vcpkg/help.h | 19 + toolsrc/include/vcpkg/input.h | 15 + toolsrc/include/vcpkg/install.h | 69 ++ toolsrc/include/vcpkg/metrics.h | 28 + toolsrc/include/vcpkg/packagespec.h | 95 +++ toolsrc/include/vcpkg/packagespecparseresult.h | 33 + toolsrc/include/vcpkg/paragraphparseresult.h | 33 + toolsrc/include/vcpkg/paragraphs.h | 38 + toolsrc/include/vcpkg/parse.h | 38 + toolsrc/include/vcpkg/postbuildlint.buildtype.h | 68 ++ toolsrc/include/vcpkg/postbuildlint.h | 13 + toolsrc/include/vcpkg/remove.h | 24 + toolsrc/include/vcpkg/sourceparagraph.h | 97 +++ toolsrc/include/vcpkg/statusparagraph.h | 45 ++ toolsrc/include/vcpkg/statusparagraphs.h | 47 ++ toolsrc/include/vcpkg/triplet.h | 43 ++ toolsrc/include/vcpkg/update.h | 21 + toolsrc/include/vcpkg/vcpkgcmdarguments.h | 50 ++ toolsrc/include/vcpkg/vcpkglib.h | 38 + toolsrc/include/vcpkg/vcpkgpaths.h | 85 +++ toolsrc/include/vcpkg/versiont.h | 29 + toolsrc/include/vcpkg_Build.h | 192 ----- toolsrc/include/vcpkg_Checks.h | 54 -- toolsrc/include/vcpkg_Chrono.h | 28 - toolsrc/include/vcpkg_Commands.h | 258 ------- toolsrc/include/vcpkg_Commands_Export.h | 8 - toolsrc/include/vcpkg_Commands_Export_IFW.h | 25 - toolsrc/include/vcpkg_Dependencies.h | 147 ---- toolsrc/include/vcpkg_Enums.h | 10 - toolsrc/include/vcpkg_Files.h | 43 -- toolsrc/include/vcpkg_GlobalState.h | 19 - toolsrc/include/vcpkg_Graphs.h | 159 ---- toolsrc/include/vcpkg_Input.h | 14 - toolsrc/include/vcpkg_Maps.h | 30 - toolsrc/include/vcpkg_Parse.h | 38 - toolsrc/include/vcpkg_Strings.h | 113 --- toolsrc/include/vcpkg_System.h | 107 --- toolsrc/include/vcpkg_Util.h | 144 ---- toolsrc/include/vcpkg_expected.h | 114 --- toolsrc/include/vcpkg_optional.h | 98 --- toolsrc/include/vcpkglib.h | 38 - toolsrc/src/BinaryParagraph.cpp | 123 --- toolsrc/src/LineInfo.cpp | 9 - toolsrc/src/MachineType.cpp | 41 - toolsrc/src/PackageSpec.cpp | 175 ----- toolsrc/src/PackageSpecParseResult.cpp | 20 - toolsrc/src/ParagraphParseResult.cpp | 34 - toolsrc/src/Paragraphs.cpp | 304 -------- toolsrc/src/PostBuildLint.cpp | 846 --------------------- toolsrc/src/PostBuildLint_BuildType.cpp | 70 -- toolsrc/src/SourceParagraph.cpp | 262 ------- toolsrc/src/StatusParagraph.cpp | 86 --- toolsrc/src/StatusParagraphs.cpp | 90 --- toolsrc/src/VcpkgCmdArguments.cpp | 283 ------- toolsrc/src/VcpkgPaths.cpp | 519 ------------- toolsrc/src/VersionT.cpp | 19 - toolsrc/src/coff_file_reader.cpp | 308 -------- toolsrc/src/commands_autocomplete.cpp | 79 -- toolsrc/src/commands_available_commands.cpp | 50 -- toolsrc/src/commands_build.cpp | 102 --- toolsrc/src/commands_build_external.cpp | 21 - toolsrc/src/commands_cache.cpp | 68 -- toolsrc/src/commands_ci.cpp | 60 -- toolsrc/src/commands_contact.cpp | 22 - toolsrc/src/commands_create.cpp | 38 - toolsrc/src/commands_depends.cpp | 55 -- toolsrc/src/commands_edit.cpp | 86 --- toolsrc/src/commands_env.cpp | 21 - toolsrc/src/commands_export.cpp | 526 ------------- toolsrc/src/commands_export_ifw.cpp | 481 ------------ toolsrc/src/commands_hash.cpp | 55 -- toolsrc/src/commands_help.cpp | 131 ---- toolsrc/src/commands_import.cpp | 119 --- toolsrc/src/commands_install.cpp | 613 --------------- toolsrc/src/commands_integrate.cpp | 342 --------- toolsrc/src/commands_list.cpp | 74 -- toolsrc/src/commands_owns.cpp | 37 - toolsrc/src/commands_portsdiff.cpp | 181 ----- toolsrc/src/commands_remove.cpp | 249 ------ toolsrc/src/commands_search.cpp | 145 ---- toolsrc/src/commands_update.cpp | 73 -- toolsrc/src/commands_version.cpp | 67 -- toolsrc/src/metrics.cpp | 395 ---------- toolsrc/src/test_install_plan.cpp | 486 ------------ toolsrc/src/tests.arguments.cpp | 58 ++ toolsrc/src/tests.dependencies.cpp | 110 +++ toolsrc/src/tests.installplan.cpp | 487 ++++++++++++ toolsrc/src/tests.packagespec.cpp | 120 +++ toolsrc/src/tests.paragraph.cpp | 389 ++++++++++ toolsrc/src/tests_arguments.cpp | 58 -- toolsrc/src/tests_dependencies.cpp | 110 --- toolsrc/src/tests_package_spec.cpp | 119 --- toolsrc/src/tests_paragraph.cpp | 388 ---------- toolsrc/src/triplet.cpp | 55 -- toolsrc/src/vcpkg.cpp | 56 +- toolsrc/src/vcpkg/base/checks.cpp | 81 ++ toolsrc/src/vcpkg/base/chrono.cpp | 61 ++ toolsrc/src/vcpkg/base/cofffilereader.cpp | 308 ++++++++ toolsrc/src/vcpkg/base/enums.cpp | 14 + toolsrc/src/vcpkg/base/files.cpp | 208 +++++ toolsrc/src/vcpkg/base/lineinfo.cpp | 9 + toolsrc/src/vcpkg/base/machinetype.cpp | 41 + toolsrc/src/vcpkg/base/strings.cpp | 174 +++++ toolsrc/src/vcpkg/base/system.cpp | 350 +++++++++ toolsrc/src/vcpkg/binaryparagraph.cpp | 123 +++ toolsrc/src/vcpkg/build.cpp | 533 +++++++++++++ toolsrc/src/vcpkg/commands.autocomplete.cpp | 78 ++ toolsrc/src/vcpkg/commands.buildexternal.cpp | 23 + toolsrc/src/vcpkg/commands.cache.cpp | 69 ++ toolsrc/src/vcpkg/commands.ci.cpp | 62 ++ toolsrc/src/vcpkg/commands.contact.cpp | 22 + toolsrc/src/vcpkg/commands.cpp | 56 ++ toolsrc/src/vcpkg/commands.create.cpp | 39 + toolsrc/src/vcpkg/commands.dependinfo.cpp | 56 ++ toolsrc/src/vcpkg/commands.edit.cpp | 87 +++ toolsrc/src/vcpkg/commands.env.cpp | 22 + toolsrc/src/vcpkg/commands.exportifw.cpp | 482 ++++++++++++ toolsrc/src/vcpkg/commands.hash.cpp | 55 ++ toolsrc/src/vcpkg/commands.import.cpp | 120 +++ toolsrc/src/vcpkg/commands.integrate.cpp | 342 +++++++++ toolsrc/src/vcpkg/commands.list.cpp | 75 ++ toolsrc/src/vcpkg/commands.owns.cpp | 38 + toolsrc/src/vcpkg/commands.portsdiff.cpp | 182 +++++ toolsrc/src/vcpkg/commands.search.cpp | 146 ++++ toolsrc/src/vcpkg/commands.version.cpp | 67 ++ toolsrc/src/vcpkg/dependencies.cpp | 669 ++++++++++++++++ toolsrc/src/vcpkg/export.cpp | 528 +++++++++++++ toolsrc/src/vcpkg/globalstate.cpp | 13 + toolsrc/src/vcpkg/help.cpp | 131 ++++ toolsrc/src/vcpkg/input.cpp | 55 ++ toolsrc/src/vcpkg/install.cpp | 615 +++++++++++++++ toolsrc/src/vcpkg/metrics.cpp | 398 ++++++++++ toolsrc/src/vcpkg/packagespec.cpp | 175 +++++ toolsrc/src/vcpkg/packagespecparseresult.cpp | 21 + toolsrc/src/vcpkg/paragraphparseresult.cpp | 34 + toolsrc/src/vcpkg/paragraphs.cpp | 304 ++++++++ toolsrc/src/vcpkg/parse.cpp | 81 ++ toolsrc/src/vcpkg/postbuildlint.buildtype.cpp | 70 ++ toolsrc/src/vcpkg/postbuildlint.cpp | 846 +++++++++++++++++++++ toolsrc/src/vcpkg/remove.cpp | 251 ++++++ toolsrc/src/vcpkg/sourceparagraph.cpp | 264 +++++++ toolsrc/src/vcpkg/statusparagraph.cpp | 86 +++ toolsrc/src/vcpkg/statusparagraphs.cpp | 89 +++ toolsrc/src/vcpkg/triplet.cpp | 55 ++ toolsrc/src/vcpkg/update.cpp | 75 ++ toolsrc/src/vcpkg/vcpkgcmdarguments.cpp | 284 +++++++ toolsrc/src/vcpkg/vcpkglib.cpp | 247 ++++++ toolsrc/src/vcpkg/vcpkgpaths.cpp | 519 +++++++++++++ toolsrc/src/vcpkg/versiont.cpp | 19 + toolsrc/src/vcpkg_Build.cpp | 406 ---------- toolsrc/src/vcpkg_Build_BuildPolicy.cpp | 40 - toolsrc/src/vcpkg_Checks.cpp | 81 -- toolsrc/src/vcpkg_Chrono.cpp | 61 -- toolsrc/src/vcpkg_Dependencies.cpp | 669 ---------------- toolsrc/src/vcpkg_Enums.cpp | 14 - toolsrc/src/vcpkg_Files.cpp | 209 ----- toolsrc/src/vcpkg_GlobalState.cpp | 13 - toolsrc/src/vcpkg_Input.cpp | 54 -- toolsrc/src/vcpkg_Parse.cpp | 80 -- toolsrc/src/vcpkg_Strings.cpp | 174 ----- toolsrc/src/vcpkg_System.cpp | 349 --------- toolsrc/src/vcpkg_metrics_uploader.cpp | 18 - toolsrc/src/vcpkglib.cpp | 247 ------ toolsrc/src/vcpkgmetricsuploader.cpp | 20 + toolsrc/vcpkglib/vcpkglib.vcxproj | 198 ++--- toolsrc/vcpkglib/vcpkglib.vcxproj.filters | 416 +++++----- .../vcpkgmetricsuploader.vcxproj | 2 +- .../vcpkgmetricsuploader.vcxproj.filters | 2 +- toolsrc/vcpkgtest/vcpkgtest.vcxproj | 10 +- toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters | 10 +- 218 files changed, 14032 insertions(+), 13936 deletions(-) delete mode 100644 toolsrc/include/BinaryParagraph.h delete mode 100644 toolsrc/include/CStringView.h delete mode 100644 toolsrc/include/LineInfo.h delete mode 100644 toolsrc/include/MachineType.h delete mode 100644 toolsrc/include/PackageSpec.h delete mode 100644 toolsrc/include/PackageSpecParseResult.h delete mode 100644 toolsrc/include/ParagraphParseResult.h delete mode 100644 toolsrc/include/Paragraphs.h delete mode 100644 toolsrc/include/PostBuildLint.h delete mode 100644 toolsrc/include/PostBuildLint_BuildType.h delete mode 100644 toolsrc/include/SortedVector.h delete mode 100644 toolsrc/include/SourceParagraph.h delete mode 100644 toolsrc/include/Span.h delete mode 100644 toolsrc/include/StatusParagraph.h delete mode 100644 toolsrc/include/StatusParagraphs.h delete mode 100644 toolsrc/include/VcpkgCmdArguments.h delete mode 100644 toolsrc/include/VcpkgPaths.h delete mode 100644 toolsrc/include/VersionT.h delete mode 100644 toolsrc/include/coff_file_reader.h delete mode 100644 toolsrc/include/filesystem_fs.h delete mode 100644 toolsrc/include/lazy.h delete mode 100644 toolsrc/include/metrics.h delete mode 100644 toolsrc/include/triplet.h create mode 100644 toolsrc/include/vcpkg/base/checks.h create mode 100644 toolsrc/include/vcpkg/base/chrono.h create mode 100644 toolsrc/include/vcpkg/base/cofffilereader.h create mode 100644 toolsrc/include/vcpkg/base/cstringview.h create mode 100644 toolsrc/include/vcpkg/base/enums.h create mode 100644 toolsrc/include/vcpkg/base/expected.h create mode 100644 toolsrc/include/vcpkg/base/files.h create mode 100644 toolsrc/include/vcpkg/base/graphs.h create mode 100644 toolsrc/include/vcpkg/base/lazy.h create mode 100644 toolsrc/include/vcpkg/base/lineinfo.h create mode 100644 toolsrc/include/vcpkg/base/machinetype.h create mode 100644 toolsrc/include/vcpkg/base/optional.h create mode 100644 toolsrc/include/vcpkg/base/sortedvector.h create mode 100644 toolsrc/include/vcpkg/base/span.h create mode 100644 toolsrc/include/vcpkg/base/strings.h create mode 100644 toolsrc/include/vcpkg/base/system.h create mode 100644 toolsrc/include/vcpkg/base/util.h create mode 100644 toolsrc/include/vcpkg/binaryparagraph.h create mode 100644 toolsrc/include/vcpkg/build.h create mode 100644 toolsrc/include/vcpkg/commands.h create mode 100644 toolsrc/include/vcpkg/dependencies.h create mode 100644 toolsrc/include/vcpkg/export.h create mode 100644 toolsrc/include/vcpkg/export.ifw.h create mode 100644 toolsrc/include/vcpkg/globalstate.h create mode 100644 toolsrc/include/vcpkg/help.h create mode 100644 toolsrc/include/vcpkg/input.h create mode 100644 toolsrc/include/vcpkg/install.h create mode 100644 toolsrc/include/vcpkg/metrics.h create mode 100644 toolsrc/include/vcpkg/packagespec.h create mode 100644 toolsrc/include/vcpkg/packagespecparseresult.h create mode 100644 toolsrc/include/vcpkg/paragraphparseresult.h create mode 100644 toolsrc/include/vcpkg/paragraphs.h create mode 100644 toolsrc/include/vcpkg/parse.h create mode 100644 toolsrc/include/vcpkg/postbuildlint.buildtype.h create mode 100644 toolsrc/include/vcpkg/postbuildlint.h create mode 100644 toolsrc/include/vcpkg/remove.h create mode 100644 toolsrc/include/vcpkg/sourceparagraph.h create mode 100644 toolsrc/include/vcpkg/statusparagraph.h create mode 100644 toolsrc/include/vcpkg/statusparagraphs.h create mode 100644 toolsrc/include/vcpkg/triplet.h create mode 100644 toolsrc/include/vcpkg/update.h create mode 100644 toolsrc/include/vcpkg/vcpkgcmdarguments.h create mode 100644 toolsrc/include/vcpkg/vcpkglib.h create mode 100644 toolsrc/include/vcpkg/vcpkgpaths.h create mode 100644 toolsrc/include/vcpkg/versiont.h delete mode 100644 toolsrc/include/vcpkg_Build.h delete mode 100644 toolsrc/include/vcpkg_Checks.h delete mode 100644 toolsrc/include/vcpkg_Chrono.h delete mode 100644 toolsrc/include/vcpkg_Commands.h delete mode 100644 toolsrc/include/vcpkg_Commands_Export.h delete mode 100644 toolsrc/include/vcpkg_Commands_Export_IFW.h delete mode 100644 toolsrc/include/vcpkg_Dependencies.h delete mode 100644 toolsrc/include/vcpkg_Enums.h delete mode 100644 toolsrc/include/vcpkg_Files.h delete mode 100644 toolsrc/include/vcpkg_GlobalState.h delete mode 100644 toolsrc/include/vcpkg_Graphs.h delete mode 100644 toolsrc/include/vcpkg_Input.h delete mode 100644 toolsrc/include/vcpkg_Maps.h delete mode 100644 toolsrc/include/vcpkg_Parse.h delete mode 100644 toolsrc/include/vcpkg_Strings.h delete mode 100644 toolsrc/include/vcpkg_System.h delete mode 100644 toolsrc/include/vcpkg_Util.h delete mode 100644 toolsrc/include/vcpkg_expected.h delete mode 100644 toolsrc/include/vcpkg_optional.h delete mode 100644 toolsrc/include/vcpkglib.h delete mode 100644 toolsrc/src/BinaryParagraph.cpp delete mode 100644 toolsrc/src/LineInfo.cpp delete mode 100644 toolsrc/src/MachineType.cpp delete mode 100644 toolsrc/src/PackageSpec.cpp delete mode 100644 toolsrc/src/PackageSpecParseResult.cpp delete mode 100644 toolsrc/src/ParagraphParseResult.cpp delete mode 100644 toolsrc/src/Paragraphs.cpp delete mode 100644 toolsrc/src/PostBuildLint.cpp delete mode 100644 toolsrc/src/PostBuildLint_BuildType.cpp delete mode 100644 toolsrc/src/SourceParagraph.cpp delete mode 100644 toolsrc/src/StatusParagraph.cpp delete mode 100644 toolsrc/src/StatusParagraphs.cpp delete mode 100644 toolsrc/src/VcpkgCmdArguments.cpp delete mode 100644 toolsrc/src/VcpkgPaths.cpp delete mode 100644 toolsrc/src/VersionT.cpp delete mode 100644 toolsrc/src/coff_file_reader.cpp delete mode 100644 toolsrc/src/commands_autocomplete.cpp delete mode 100644 toolsrc/src/commands_available_commands.cpp delete mode 100644 toolsrc/src/commands_build.cpp delete mode 100644 toolsrc/src/commands_build_external.cpp delete mode 100644 toolsrc/src/commands_cache.cpp delete mode 100644 toolsrc/src/commands_ci.cpp delete mode 100644 toolsrc/src/commands_contact.cpp delete mode 100644 toolsrc/src/commands_create.cpp delete mode 100644 toolsrc/src/commands_depends.cpp delete mode 100644 toolsrc/src/commands_edit.cpp delete mode 100644 toolsrc/src/commands_env.cpp delete mode 100644 toolsrc/src/commands_export.cpp delete mode 100644 toolsrc/src/commands_export_ifw.cpp delete mode 100644 toolsrc/src/commands_hash.cpp delete mode 100644 toolsrc/src/commands_help.cpp delete mode 100644 toolsrc/src/commands_import.cpp delete mode 100644 toolsrc/src/commands_install.cpp delete mode 100644 toolsrc/src/commands_integrate.cpp delete mode 100644 toolsrc/src/commands_list.cpp delete mode 100644 toolsrc/src/commands_owns.cpp delete mode 100644 toolsrc/src/commands_portsdiff.cpp delete mode 100644 toolsrc/src/commands_remove.cpp delete mode 100644 toolsrc/src/commands_search.cpp delete mode 100644 toolsrc/src/commands_update.cpp delete mode 100644 toolsrc/src/commands_version.cpp delete mode 100644 toolsrc/src/metrics.cpp delete mode 100644 toolsrc/src/test_install_plan.cpp create mode 100644 toolsrc/src/tests.arguments.cpp create mode 100644 toolsrc/src/tests.dependencies.cpp create mode 100644 toolsrc/src/tests.installplan.cpp create mode 100644 toolsrc/src/tests.packagespec.cpp create mode 100644 toolsrc/src/tests.paragraph.cpp delete mode 100644 toolsrc/src/tests_arguments.cpp delete mode 100644 toolsrc/src/tests_dependencies.cpp delete mode 100644 toolsrc/src/tests_package_spec.cpp delete mode 100644 toolsrc/src/tests_paragraph.cpp delete mode 100644 toolsrc/src/triplet.cpp create mode 100644 toolsrc/src/vcpkg/base/checks.cpp create mode 100644 toolsrc/src/vcpkg/base/chrono.cpp create mode 100644 toolsrc/src/vcpkg/base/cofffilereader.cpp create mode 100644 toolsrc/src/vcpkg/base/enums.cpp create mode 100644 toolsrc/src/vcpkg/base/files.cpp create mode 100644 toolsrc/src/vcpkg/base/lineinfo.cpp create mode 100644 toolsrc/src/vcpkg/base/machinetype.cpp create mode 100644 toolsrc/src/vcpkg/base/strings.cpp create mode 100644 toolsrc/src/vcpkg/base/system.cpp create mode 100644 toolsrc/src/vcpkg/binaryparagraph.cpp create mode 100644 toolsrc/src/vcpkg/build.cpp create mode 100644 toolsrc/src/vcpkg/commands.autocomplete.cpp create mode 100644 toolsrc/src/vcpkg/commands.buildexternal.cpp create mode 100644 toolsrc/src/vcpkg/commands.cache.cpp create mode 100644 toolsrc/src/vcpkg/commands.ci.cpp create mode 100644 toolsrc/src/vcpkg/commands.contact.cpp create mode 100644 toolsrc/src/vcpkg/commands.cpp create mode 100644 toolsrc/src/vcpkg/commands.create.cpp create mode 100644 toolsrc/src/vcpkg/commands.dependinfo.cpp create mode 100644 toolsrc/src/vcpkg/commands.edit.cpp create mode 100644 toolsrc/src/vcpkg/commands.env.cpp create mode 100644 toolsrc/src/vcpkg/commands.exportifw.cpp create mode 100644 toolsrc/src/vcpkg/commands.hash.cpp create mode 100644 toolsrc/src/vcpkg/commands.import.cpp create mode 100644 toolsrc/src/vcpkg/commands.integrate.cpp create mode 100644 toolsrc/src/vcpkg/commands.list.cpp create mode 100644 toolsrc/src/vcpkg/commands.owns.cpp create mode 100644 toolsrc/src/vcpkg/commands.portsdiff.cpp create mode 100644 toolsrc/src/vcpkg/commands.search.cpp create mode 100644 toolsrc/src/vcpkg/commands.version.cpp create mode 100644 toolsrc/src/vcpkg/dependencies.cpp create mode 100644 toolsrc/src/vcpkg/export.cpp create mode 100644 toolsrc/src/vcpkg/globalstate.cpp create mode 100644 toolsrc/src/vcpkg/help.cpp create mode 100644 toolsrc/src/vcpkg/input.cpp create mode 100644 toolsrc/src/vcpkg/install.cpp create mode 100644 toolsrc/src/vcpkg/metrics.cpp create mode 100644 toolsrc/src/vcpkg/packagespec.cpp create mode 100644 toolsrc/src/vcpkg/packagespecparseresult.cpp create mode 100644 toolsrc/src/vcpkg/paragraphparseresult.cpp create mode 100644 toolsrc/src/vcpkg/paragraphs.cpp create mode 100644 toolsrc/src/vcpkg/parse.cpp create mode 100644 toolsrc/src/vcpkg/postbuildlint.buildtype.cpp create mode 100644 toolsrc/src/vcpkg/postbuildlint.cpp create mode 100644 toolsrc/src/vcpkg/remove.cpp create mode 100644 toolsrc/src/vcpkg/sourceparagraph.cpp create mode 100644 toolsrc/src/vcpkg/statusparagraph.cpp create mode 100644 toolsrc/src/vcpkg/statusparagraphs.cpp create mode 100644 toolsrc/src/vcpkg/triplet.cpp create mode 100644 toolsrc/src/vcpkg/update.cpp create mode 100644 toolsrc/src/vcpkg/vcpkgcmdarguments.cpp create mode 100644 toolsrc/src/vcpkg/vcpkglib.cpp create mode 100644 toolsrc/src/vcpkg/vcpkgpaths.cpp create mode 100644 toolsrc/src/vcpkg/versiont.cpp delete mode 100644 toolsrc/src/vcpkg_Build.cpp delete mode 100644 toolsrc/src/vcpkg_Build_BuildPolicy.cpp delete mode 100644 toolsrc/src/vcpkg_Checks.cpp delete mode 100644 toolsrc/src/vcpkg_Chrono.cpp delete mode 100644 toolsrc/src/vcpkg_Dependencies.cpp delete mode 100644 toolsrc/src/vcpkg_Enums.cpp delete mode 100644 toolsrc/src/vcpkg_Files.cpp delete mode 100644 toolsrc/src/vcpkg_GlobalState.cpp delete mode 100644 toolsrc/src/vcpkg_Input.cpp delete mode 100644 toolsrc/src/vcpkg_Parse.cpp delete mode 100644 toolsrc/src/vcpkg_Strings.cpp delete mode 100644 toolsrc/src/vcpkg_System.cpp delete mode 100644 toolsrc/src/vcpkg_metrics_uploader.cpp delete mode 100644 toolsrc/src/vcpkglib.cpp create mode 100644 toolsrc/src/vcpkgmetricsuploader.cpp diff --git a/toolsrc/include/BinaryParagraph.h b/toolsrc/include/BinaryParagraph.h deleted file mode 100644 index 61e03343a..000000000 --- a/toolsrc/include/BinaryParagraph.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "PackageSpec.h" -#include "SourceParagraph.h" -#include - -namespace vcpkg -{ - /// - /// Built package metadata - /// - struct BinaryParagraph - { - BinaryParagraph(); - explicit BinaryParagraph(std::unordered_map fields); - BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet); - BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet); - - std::string displayname() const; - - std::string fullstem() const; - - std::string dir() const; - - PackageSpec spec; - std::string version; - std::string description; - std::string maintainer; - std::string feature; - std::vector default_features; - std::vector depends; - }; - - struct BinaryControlFile - { - BinaryParagraph core_paragraph; - std::vector features; - }; - - void serialize(const BinaryParagraph& pgh, std::string& out_str); -} \ No newline at end of file diff --git a/toolsrc/include/CStringView.h b/toolsrc/include/CStringView.h deleted file mode 100644 index c1810b4f1..000000000 --- a/toolsrc/include/CStringView.h +++ /dev/null @@ -1,96 +0,0 @@ -#pragma once -#include - -namespace vcpkg -{ - template - struct BasicCStringView - { - constexpr BasicCStringView() : cstr(nullptr) {} - constexpr BasicCStringView(const CharType* cstr) : cstr(cstr) {} - constexpr BasicCStringView(const BasicCStringView&) = default; - BasicCStringView(const std::basic_string& str) : cstr(str.c_str()) {} - - constexpr const CharType* c_str() const { return cstr; } - - private: - const CharType* cstr; - }; - - namespace details - { - inline bool vcpkg_strcmp(const char* l, const char* r) { return strcmp(l, r) == 0; } - inline bool vcpkg_strcmp(const wchar_t* l, const wchar_t* r) { return wcscmp(l, r) == 0; } - } - - template - bool operator==(const BasicCStringView& l, const BasicCStringView& r) - { - return details::vcpkg_strcmp(l.c_str(), r.c_str()); - } - - template - bool operator==(const CharType* l, const BasicCStringView& r) - { - return details::vcpkg_strcmp(l, r.c_str()); - } - - template - bool operator==(const BasicCStringView& r, const CharType* l) - { - return details::vcpkg_strcmp(l, r.c_str()); - } - - template - bool operator==(const std::basic_string& l, const BasicCStringView& r) - { - return l == r.c_str(); - } - - template - bool operator==(const BasicCStringView& r, const std::basic_string& l) - { - return l == r.c_str(); - } - - // notequals - template - bool operator!=(const BasicCStringView& l, const BasicCStringView& r) - { - return !details::vcpkg_strcmp(l.c_str(), r.c_str()); - } - - template - bool operator!=(const CharType* l, const BasicCStringView& r) - { - return !details::vcpkg_strcmp(l, r.c_str()); - } - - template - bool operator!=(const BasicCStringView& r, const CharType* l) - { - return !details::vcpkg_strcmp(l, r.c_str()); - } - - template - bool operator!=(const BasicCStringView& r, const std::basic_string& l) - { - return l != r.c_str(); - } - - template - bool operator!=(const std::basic_string& l, const BasicCStringView& r) - { - return l != r.c_str(); - } - - using CStringView = BasicCStringView; - using CWStringView = BasicCStringView; - - inline const char* to_printf_arg(const CStringView string_view) { return string_view.c_str(); } - - inline const wchar_t* to_wprintf_arg(const CWStringView string_view) { return string_view.c_str(); } - - static_assert(sizeof(CStringView) == sizeof(void*), "CStringView must be a simple wrapper around char*"); - static_assert(sizeof(CWStringView) == sizeof(void*), "CWStringView must be a simple wrapper around wchar_t*"); -} diff --git a/toolsrc/include/LineInfo.h b/toolsrc/include/LineInfo.h deleted file mode 100644 index 62973462a..000000000 --- a/toolsrc/include/LineInfo.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include - -namespace vcpkg -{ - struct LineInfo - { - int line_number; - const char* file_name; - - constexpr LineInfo() : line_number(0), file_name(nullptr) {} - constexpr LineInfo(const int lineno, const char* filename) : line_number(lineno), file_name(filename) {} - - std::string to_string() const; - }; -} - -#define VCPKG_LINE_INFO vcpkg::LineInfo(__LINE__, __FILE__) diff --git a/toolsrc/include/MachineType.h b/toolsrc/include/MachineType.h deleted file mode 100644 index 6f61bbd53..000000000 --- a/toolsrc/include/MachineType.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once -#include - -namespace vcpkg -{ - enum class MachineType : uint16_t - { - UNKNOWN = 0x0, // The contents of this field are assumed to be applicable to any machine type - AM33 = 0x1d3, // Matsushita AM33 - AMD64 = 0x8664, // x64 - ARM = 0x1c0, // ARM little endian - ARM64 = 0xaa64, // ARM64 little endian - ARMNT = 0x1c4, // ARM Thumb-2 little endian - EBC = 0xebc, // EFI byte code - I386 = 0x14c, // Intel 386 or later processors and compatible processors - IA64 = 0x200, // Intel Itanium processor family - M32R = 0x9041, // Mitsubishi M32R little endian - MIPS16 = 0x266, // MIPS16 - MIPSFPU = 0x366, // MIPS with FPU - MIPSFPU16 = 0x466, // MIPS16 with FPU - POWERPC = 0x1f0, // Power PC little endian - POWERPCFP = 0x1f1, // Power PC with floating point support - R4000 = 0x166, // MIPS little endian - RISCV32 = 0x5032, // RISC-V 32-bit address space - RISCV64 = 0x5064, // RISC-V 64-bit address space - RISCV128 = 0x5128, // RISC-V 128-bit address space - SH3 = 0x1a2, // Hitachi SH3 - SH3DSP = 0x1a3, // Hitachi SH3 DSP - SH4 = 0x1a6, // Hitachi SH4 - SH5 = 0x1a8, // Hitachi SH5 - THUMB = 0x1c2, // Thumb - WCEMIPSV2 = 0x169, // MIPS little-endian WCE v2 - }; - - MachineType to_machine_type(const uint16_t value); -} diff --git a/toolsrc/include/PackageSpec.h b/toolsrc/include/PackageSpec.h deleted file mode 100644 index c5ce767f9..000000000 --- a/toolsrc/include/PackageSpec.h +++ /dev/null @@ -1,95 +0,0 @@ -#pragma once - -#include "PackageSpecParseResult.h" -#include "Triplet.h" -#include "vcpkg_expected.h" - -namespace vcpkg -{ - struct ParsedSpecifier - { - std::string name; - std::vector features; - std::string triplet; - - static ExpectedT from_string(const std::string& input); - }; - - struct PackageSpec - { - static ExpectedT from_name_and_triplet(const std::string& name, - const Triplet& triplet); - - const std::string& name() const; - - const Triplet& triplet() const; - - std::string dir() const; - - std::string to_string() const; - - private: - std::string m_name; - Triplet m_triplet; - }; - - struct FeatureSpec - { - FeatureSpec(const PackageSpec& spec, const std::string& feature) : m_spec(spec), m_feature(feature) {} - - const std::string& name() const { return m_spec.name(); } - const std::string& feature() const { return m_feature; } - const Triplet& triplet() const { return m_spec.triplet(); } - - const PackageSpec& spec() const { return m_spec; } - - std::string to_string() const; - - static std::vector from_strings_and_triplet(const std::vector& depends, - const Triplet& t); - - private: - PackageSpec m_spec; - std::string m_feature; - }; - - struct FullPackageSpec - { - PackageSpec package_spec; - std::vector features; - - static std::vector to_feature_specs(const std::vector& specs); - - static ExpectedT from_string(const std::string& spec_as_string, - const Triplet& default_triplet); - }; - - struct Features - { - std::string name; - std::vector features; - - static ExpectedT from_string(const std::string& input); - }; - - bool operator==(const PackageSpec& left, const PackageSpec& right); - bool operator!=(const PackageSpec& left, const PackageSpec& right); -} - -template<> -struct std::hash -{ - size_t operator()(const vcpkg::PackageSpec& value) const - { - size_t hash = 17; - hash = hash * 31 + std::hash()(value.name()); - hash = hash * 31 + std::hash()(value.triplet()); - return hash; - } -}; - -template<> -struct std::equal_to -{ - bool operator()(const vcpkg::PackageSpec& left, const vcpkg::PackageSpec& right) const { return left == right; } -}; diff --git a/toolsrc/include/PackageSpecParseResult.h b/toolsrc/include/PackageSpecParseResult.h deleted file mode 100644 index 1462b8073..000000000 --- a/toolsrc/include/PackageSpecParseResult.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "vcpkg_expected.h" - -namespace vcpkg -{ - enum class PackageSpecParseResult - { - SUCCESS = 0, - TOO_MANY_COLONS, - INVALID_CHARACTERS - }; - - CStringView to_string(PackageSpecParseResult ev) noexcept; - - template<> - struct ErrorHolder - { - ErrorHolder() : m_err(PackageSpecParseResult::SUCCESS) {} - ErrorHolder(PackageSpecParseResult err) : m_err(err) {} - - constexpr bool has_error() const { return m_err != PackageSpecParseResult::SUCCESS; } - - const PackageSpecParseResult& error() const { return m_err; } - PackageSpecParseResult& error() { return m_err; } - - CStringView to_string() const { return vcpkg::to_string(m_err); } - - private: - PackageSpecParseResult m_err; - }; -} diff --git a/toolsrc/include/ParagraphParseResult.h b/toolsrc/include/ParagraphParseResult.h deleted file mode 100644 index eaa7e6327..000000000 --- a/toolsrc/include/ParagraphParseResult.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#include - -namespace vcpkg -{ - enum class ParagraphParseResult - { - SUCCESS = 0, - EXPECTED_ONE_PARAGRAPH - }; - - struct ParagraphParseResultCategoryImpl final : std::error_category - { - virtual const char* name() const noexcept override; - - virtual std::string message(int ev) const noexcept override; - }; - - const std::error_category& paragraph_parse_result_category(); - - std::error_code make_error_code(ParagraphParseResult e); - - ParagraphParseResult to_paragraph_parse_result(int i); - - ParagraphParseResult to_paragraph_parse_result(std::error_code ec); -} - -// Enable implicit conversion to std::error_code -template<> -struct std::is_error_code_enum : ::std::true_type -{ -}; diff --git a/toolsrc/include/Paragraphs.h b/toolsrc/include/Paragraphs.h deleted file mode 100644 index aae46f7da..000000000 --- a/toolsrc/include/Paragraphs.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include - -#include "BinaryParagraph.h" -#include "VcpkgPaths.h" -#include "VersionT.h" -#include "filesystem_fs.h" -#include "vcpkg_Parse.h" -#include "vcpkg_expected.h" - -namespace vcpkg::Paragraphs -{ - using RawParagraph = Parse::RawParagraph; - - Expected get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path); - Expected> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path); - Expected parse_single_paragraph(const std::string& str); - Expected> parse_paragraphs(const std::string& str); - - Parse::ParseExpected try_load_port(const Files::Filesystem& fs, const fs::path& control_path); - - Expected try_load_cached_control_package(const VcpkgPaths& paths, const PackageSpec& spec); - - struct LoadResults - { - std::vector> paragraphs; - std::vector> errors; - }; - - LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); - - std::vector> load_all_ports(const Files::Filesystem& fs, - const fs::path& ports_dir); - - std::map load_all_port_names_and_versions(const Files::Filesystem& fs, - const fs::path& ports_dir); -} diff --git a/toolsrc/include/PostBuildLint.h b/toolsrc/include/PostBuildLint.h deleted file mode 100644 index 69fafc9f7..000000000 --- a/toolsrc/include/PostBuildLint.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "PackageSpec.h" -#include "VcpkgPaths.h" -#include "vcpkg_Build.h" - -namespace vcpkg::PostBuildLint -{ - size_t perform_all_checks(const PackageSpec& spec, - const VcpkgPaths& paths, - const Build::PreBuildInfo& pre_build_info, - const Build::BuildInfo& build_info); -} diff --git a/toolsrc/include/PostBuildLint_BuildType.h b/toolsrc/include/PostBuildLint_BuildType.h deleted file mode 100644 index 38ad3084e..000000000 --- a/toolsrc/include/PostBuildLint_BuildType.h +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once -#include "CStringView.h" -#include "vcpkg_Build.h" -#include -#include - -namespace vcpkg::PostBuildLint -{ - enum class ConfigurationType - { - DEBUG, - RELEASE, - }; - - struct BuildType - { - enum class BackingEnum - { - DEBUG_STATIC = 1, - DEBUG_DYNAMIC, - RELEASE_STATIC, - RELEASE_DYNAMIC - }; - - static BuildType value_of(const ConfigurationType& config, const Build::LinkageType& linkage); - - BuildType() = delete; - - constexpr BuildType(const BackingEnum backing_enum, - const ConfigurationType config, - const Build::LinkageType linkage) - : backing_enum(backing_enum), m_config(config), m_linkage(linkage) - { - } - - constexpr operator BackingEnum() const { return backing_enum; } - - const ConfigurationType& config() const; - const Build::LinkageType& linkage() const; - const std::regex& crt_regex() const; - const std::string& to_string() const; - - private: - BackingEnum backing_enum; - ConfigurationType m_config; - Build::LinkageType m_linkage; - }; - - namespace BuildTypeC - { - using Build::LinkageType; - using BE = BuildType::BackingEnum; - - static constexpr CStringView ENUM_NAME = "vcpkg::PostBuildLint::BuildType"; - - static constexpr BuildType DEBUG_STATIC = {BE::DEBUG_STATIC, ConfigurationType::DEBUG, LinkageType::STATIC}; - static constexpr BuildType DEBUG_DYNAMIC = {BE::DEBUG_DYNAMIC, ConfigurationType::DEBUG, LinkageType::DYNAMIC}; - static constexpr BuildType RELEASE_STATIC = { - BE::RELEASE_STATIC, ConfigurationType::RELEASE, LinkageType::STATIC}; - static constexpr BuildType RELEASE_DYNAMIC = { - BE::RELEASE_DYNAMIC, ConfigurationType::RELEASE, LinkageType::DYNAMIC}; - - static constexpr std::array VALUES = { - DEBUG_STATIC, DEBUG_DYNAMIC, RELEASE_STATIC, RELEASE_DYNAMIC}; - } -} diff --git a/toolsrc/include/SortedVector.h b/toolsrc/include/SortedVector.h deleted file mode 100644 index 62808cc2f..000000000 --- a/toolsrc/include/SortedVector.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include -#include - -// Add more forwarding functions to the m_data std::vector as needed. -namespace vcpkg -{ - template - class SortedVector - { - public: - using size_type = typename std::vector::size_type; - using iterator = typename std::vector::const_iterator; - - SortedVector() : m_data() {} - - explicit SortedVector(std::vector v) : m_data(std::move(v)) - { - if (!std::is_sorted(m_data.begin(), m_data.end())) - { - std::sort(m_data.begin(), m_data.end()); - } - } - - template - SortedVector(std::vector v, Compare comp) : m_data(std::move(v)) - { - if (!std::is_sorted(m_data.cbegin(), m_data.cend(), comp)) - { - std::sort(m_data.begin(), m_data.end(), comp); - } - } - - iterator begin() const { return this->m_data.cbegin(); } - - iterator end() const { return this->m_data.cend(); } - - iterator cbegin() const { return this->m_data.cbegin(); } - - iterator cend() const { return this->m_data.cend(); } - - bool empty() const { return this->m_data.empty(); } - - size_type size() const { return this->m_data.size(); } - - private: - std::vector m_data; - }; -} diff --git a/toolsrc/include/SourceParagraph.h b/toolsrc/include/SourceParagraph.h deleted file mode 100644 index ccf9faf4f..000000000 --- a/toolsrc/include/SourceParagraph.h +++ /dev/null @@ -1,96 +0,0 @@ -#pragma once - -#include "PackageSpec.h" -#include "Span.h" -#include "vcpkg_Parse.h" -#include "vcpkg_System.h" -#include "vcpkg_expected.h" - -#include -#include - -namespace vcpkg -{ - struct Dependency - { - Features depend; - std::string qualifier; - - std::string name() const; - static Dependency parse_dependency(std::string name, std::string qualifier); - }; - - std::vector filter_dependencies(const std::vector& deps, const Triplet& t); - std::vector filter_dependencies_to_specs(const std::vector& deps, const Triplet& t); - - // zlib[uwp] becomes Dependency{"zlib", "uwp"} - std::vector expand_qualified_dependencies(const std::vector& depends); - - std::string to_string(const Dependency& dep); - - struct FeatureParagraph - { - std::string name; - std::string description; - std::vector depends; - }; - - /// - /// Port metadata (CONTROL file) - /// - struct SourceParagraph - { - std::string name; - std::string version; - std::string description; - std::string maintainer; - std::vector supports; - std::vector depends; - std::vector default_features; - }; - struct SourceControlFile - { - static Parse::ParseExpected parse_control_file( - std::vector&& control_paragraphs); - - std::unique_ptr core_paragraph; - std::vector> feature_paragraphs; - }; - - void print_error_message(Span> error_info_list); - inline void print_error_message(const std::unique_ptr& error_info_list) - { - return print_error_message({&error_info_list, 1}); - } - - struct Supports - { - static ExpectedT> parse(const std::vector& strs); - - using Architecture = System::CPUArchitecture; - - enum class Platform - { - WINDOWS, - UWP, - }; - enum class Linkage - { - DYNAMIC, - STATIC, - }; - enum class ToolsetVersion - { - V140, - V141, - }; - - bool is_supported(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools); - - private: - std::vector architectures; - std::vector platforms; - std::vector crt_linkages; - std::vector toolsets; - }; -} diff --git a/toolsrc/include/Span.h b/toolsrc/include/Span.h deleted file mode 100644 index a43e8f992..000000000 --- a/toolsrc/include/Span.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -template -struct Span -{ -public: - using element_type = T; - using pointer = T*; - using reference = T&; - using iterator = T*; - - constexpr Span() noexcept : m_ptr(nullptr), m_count(0) {} - constexpr Span(std::nullptr_t) noexcept : Span() {} - constexpr Span(T* ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) {} - constexpr Span(T* ptr_begin, T* ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) {} - constexpr Span(std::initializer_list l) noexcept : m_ptr(l.begin()), m_count(l.size()) {} - - template - constexpr Span(T (&arr)[N]) noexcept : Span(arr, N) - { - } - - Span(std::vector& v) noexcept : Span(v.data(), v.size()) {} - Span(const std::vector>& v) noexcept : Span(v.data(), v.size()) {} - - constexpr iterator begin() const { return m_ptr; } - constexpr iterator end() const { return m_ptr + m_count; } - - constexpr reference operator[](size_t i) const { return m_ptr[i]; } - constexpr size_t size() const { return m_count; } - -private: - pointer m_ptr; - size_t m_count; -}; - -template -Span make_span(std::vector& v) -{ - return {v.data(), v.size()}; -} - -template -Span make_span(const std::vector& v) -{ - return {v.data(), v.size()}; -} diff --git a/toolsrc/include/StatusParagraph.h b/toolsrc/include/StatusParagraph.h deleted file mode 100644 index b56533d65..000000000 --- a/toolsrc/include/StatusParagraph.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "BinaryParagraph.h" -#include - -namespace vcpkg -{ - enum class InstallState - { - ERROR_STATE, - NOT_INSTALLED, - HALF_INSTALLED, - INSTALLED, - }; - - enum class Want - { - ERROR_STATE, - UNKNOWN, - INSTALL, - HOLD, - DEINSTALL, - PURGE - }; - - /// - /// Installed package metadata - /// - struct StatusParagraph - { - StatusParagraph(); - explicit StatusParagraph(std::unordered_map&& fields); - - BinaryParagraph package; - Want want; - InstallState state; - }; - - void serialize(const StatusParagraph& pgh, std::string& out_str); - - std::string to_string(InstallState f); - - std::string to_string(Want f); -} diff --git a/toolsrc/include/StatusParagraphs.h b/toolsrc/include/StatusParagraphs.h deleted file mode 100644 index 1a9ee6a03..000000000 --- a/toolsrc/include/StatusParagraphs.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once -#include "StatusParagraph.h" -#include -#include - -namespace vcpkg -{ - struct StatusParagraphs - { - StatusParagraphs(); - explicit StatusParagraphs(std::vector>&& ps); - - using container = std::vector>; - using iterator = container::reverse_iterator; - using const_iterator = container::const_reverse_iterator; - - const_iterator find(const PackageSpec& spec) const { return find(spec.name(), spec.triplet()); } - const_iterator find(const std::string& name, const Triplet& triplet) const; - iterator find(const std::string& name, const Triplet& triplet); - std::vector*> find_all(const std::string& name, const Triplet& triplet); - iterator find(const std::string& name, const Triplet& triplet, const std::string& feature); - - const_iterator find_installed(const PackageSpec& spec) const - { - return find_installed(spec.name(), spec.triplet()); - } - const_iterator find_installed(const std::string& name, const Triplet& triplet) const; - - iterator insert(std::unique_ptr); - - friend void serialize(const StatusParagraphs& pgh, std::string& out_str); - - iterator end() { return paragraphs.rend(); } - - const_iterator end() const { return paragraphs.rend(); } - - iterator begin() { return paragraphs.rbegin(); } - - const_iterator begin() const { return paragraphs.rbegin(); } - - private: - std::vector> paragraphs; - }; - - void serialize(const StatusParagraphs& pgh, std::string& out_str); -} diff --git a/toolsrc/include/VcpkgCmdArguments.h b/toolsrc/include/VcpkgCmdArguments.h deleted file mode 100644 index 0de5747b1..000000000 --- a/toolsrc/include/VcpkgCmdArguments.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "vcpkg_optional.h" -#include -#include -#include -#include - -namespace vcpkg -{ - struct ParsedArguments - { - std::unordered_set switches; - std::unordered_map settings; - }; - - struct VcpkgCmdArguments - { - static VcpkgCmdArguments create_from_command_line(const int argc, const wchar_t* const* const argv); - static VcpkgCmdArguments create_from_arg_sequence(const std::string* arg_begin, const std::string* arg_end); - - std::unique_ptr vcpkg_root_dir; - std::unique_ptr triplet; - Optional debug = nullopt; - Optional sendmetrics = nullopt; - Optional printmetrics = nullopt; - - std::string command; - std::vector command_arguments; - std::unordered_set check_and_get_optional_command_arguments( - const std::vector& valid_options) const - { - return std::move(check_and_get_optional_command_arguments(valid_options, {}).switches); - } - - ParsedArguments check_and_get_optional_command_arguments(const std::vector& valid_switches, - const std::vector& valid_settings) const; - - void check_max_arg_count(const size_t expected_arg_count) const; - void check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const; - void check_min_arg_count(const size_t expected_arg_count) const; - void check_min_arg_count(const size_t expected_arg_count, const std::string& example_text) const; - void check_exact_arg_count(const size_t expected_arg_count) const; - void check_exact_arg_count(const size_t expected_arg_count, const std::string& example_text) const; - - private: - std::unordered_map> optional_command_arguments; - }; -} diff --git a/toolsrc/include/VcpkgPaths.h b/toolsrc/include/VcpkgPaths.h deleted file mode 100644 index d4640fba2..000000000 --- a/toolsrc/include/VcpkgPaths.h +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once -#include "BinaryParagraph.h" -#include "Lazy.h" -#include "PackageSpec.h" -#include "filesystem_fs.h" -#include "vcpkg_Files.h" -#include "vcpkg_expected.h" - -namespace vcpkg -{ - struct ToolsetArchOption - { - CWStringView name; - System::CPUArchitecture host_arch; - System::CPUArchitecture target_arch; - }; - - struct Toolset - { - fs::path visual_studio_root_path; - fs::path dumpbin; - fs::path vcvarsall; - std::vector vcvarsall_options; - CWStringView version; - std::vector supported_architectures; - }; - - struct VcpkgPaths - { - static Expected create(const fs::path& vcpkg_root_dir); - - fs::path package_dir(const PackageSpec& spec) const; - fs::path port_dir(const PackageSpec& spec) const; - fs::path port_dir(const std::string& name) const; - fs::path build_info_file_path(const PackageSpec& spec) const; - fs::path listfile_path(const BinaryParagraph& pgh) const; - - bool is_valid_triplet(const Triplet& t) const; - - fs::path root; - fs::path packages; - fs::path buildtrees; - fs::path downloads; - fs::path ports; - fs::path installed; - fs::path triplets; - fs::path scripts; - - fs::path buildsystems; - fs::path buildsystems_msbuild_targets; - - fs::path vcpkg_dir; - fs::path vcpkg_dir_status_file; - fs::path vcpkg_dir_info; - fs::path vcpkg_dir_updates; - - fs::path ports_cmake; - - const fs::path& get_cmake_exe() const; - const fs::path& get_git_exe() const; - const fs::path& get_nuget_exe() const; - const fs::path& get_ifw_installerbase_exe() const; - const fs::path& get_ifw_binarycreator_exe() const; - const fs::path& get_ifw_repogen_exe() const; - - /// Retrieve a toolset matching a VS version - /// - /// Valid version strings are "v140", "v141", and "". Empty string gets the latest. - /// - const Toolset& VcpkgPaths::get_toolset(const Optional& toolset_version, - const Optional& visual_studio_path) const; - - Files::Filesystem& get_filesystem() const; - - private: - Lazy cmake_exe; - Lazy git_exe; - Lazy nuget_exe; - Lazy ifw_installerbase_exe; - Lazy ifw_binarycreator_exe; - Lazy ifw_repogen_exe; - Lazy> toolsets; - }; -} diff --git a/toolsrc/include/VersionT.h b/toolsrc/include/VersionT.h deleted file mode 100644 index 67efd8da3..000000000 --- a/toolsrc/include/VersionT.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once -#include - -namespace vcpkg -{ - struct VersionT - { - VersionT(); - VersionT(const std::string& value); - - std::string to_string() const; - - std::string value; - }; - - bool operator==(const VersionT& left, const VersionT& right); - bool operator!=(const VersionT& left, const VersionT& right); - - struct VersionDiff - { - VersionT left; - VersionT right; - - VersionDiff(); - VersionDiff(const VersionT& left, const VersionT& right); - - std::string to_string() const; - }; -} diff --git a/toolsrc/include/coff_file_reader.h b/toolsrc/include/coff_file_reader.h deleted file mode 100644 index 7287211a1..000000000 --- a/toolsrc/include/coff_file_reader.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include "MachineType.h" -#include "filesystem_fs.h" -#include - -namespace vcpkg::CoffFileReader -{ - struct DllInfo - { - MachineType machine_type; - }; - - struct LibInfo - { - std::vector machine_types; - }; - - DllInfo read_dll(const fs::path& path); - - LibInfo read_lib(const fs::path& path); -} diff --git a/toolsrc/include/filesystem_fs.h b/toolsrc/include/filesystem_fs.h deleted file mode 100644 index 0651ebf25..000000000 --- a/toolsrc/include/filesystem_fs.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include - -namespace fs -{ - namespace stdfs = std::experimental::filesystem; - - using stdfs::path; - using stdfs::copy_options; - using stdfs::file_status; - - inline bool is_regular_file(file_status s) { return stdfs::is_regular_file(s); } - inline bool is_directory(file_status s) { return stdfs::is_directory(s); } - inline bool status_known(file_status s) { return stdfs::status_known(s); } -} \ No newline at end of file diff --git a/toolsrc/include/lazy.h b/toolsrc/include/lazy.h deleted file mode 100644 index 58c11c002..000000000 --- a/toolsrc/include/lazy.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -namespace vcpkg -{ - template - class Lazy - { - public: - Lazy() : value(T()), initialized(false) {} - - template - T const& get_lazy(const F& f) const - { - if (!initialized) - { - value = f(); - initialized = true; - } - return value; - } - - private: - mutable T value; - mutable bool initialized; - }; -} diff --git a/toolsrc/include/metrics.h b/toolsrc/include/metrics.h deleted file mode 100644 index 8eae426de..000000000 --- a/toolsrc/include/metrics.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include - -#include "vcpkg_Util.h" - -namespace vcpkg::Metrics -{ - struct Metrics : Util::ResourceBase - { - void set_send_metrics(bool should_send_metrics); - void set_print_metrics(bool should_print_metrics); - void set_user_information(const std::string& user_id, const std::string& first_use_time); - void init_user_information(std::string& user_id, std::string& first_use_time); - - void track_metric(const std::string& name, double value); - void track_property(const std::string& name, const std::string& value); - void track_property(const std::string& name, const std::wstring& value); - - void upload(const std::string& payload); - void flush(); - }; - - extern Util::LockGuarded g_metrics; - - std::wstring get_SQM_user(); - bool get_compiled_metrics_enabled(); -} diff --git a/toolsrc/include/pch.h b/toolsrc/include/pch.h index 0f34063f8..8333eb927 100644 --- a/toolsrc/include/pch.h +++ b/toolsrc/include/pch.h @@ -2,9 +2,13 @@ #define NOMINMAX #define WIN32_LEAN_AND_MEAN + #pragma warning(suppress : 4768) #include +#pragma warning(suppress : 4768) +#include + #include #include #include @@ -28,10 +32,6 @@ #include #include #include -#pragma warning(push) -#pragma warning(disable : 4768) -#include -#pragma warning(pop) #include #include #include diff --git a/toolsrc/include/triplet.h b/toolsrc/include/triplet.h deleted file mode 100644 index 46a52f8e6..000000000 --- a/toolsrc/include/triplet.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include - -namespace vcpkg -{ - struct TripletInstance; - - struct Triplet - { - public: - constexpr Triplet() : m_instance(&DEFAULT_INSTANCE) {} - - static Triplet from_canonical_name(const std::string& triplet_as_string); - - static const Triplet X86_WINDOWS; - static const Triplet X64_WINDOWS; - static const Triplet X86_UWP; - static const Triplet X64_UWP; - static const Triplet ARM_UWP; - - const std::string& canonical_name() const; - const std::string& to_string() const; - size_t hash_code() const; - - bool operator==(const Triplet& other) const; - - private: - static const TripletInstance DEFAULT_INSTANCE; - - constexpr Triplet(const TripletInstance* ptr) : m_instance(ptr) {} - - const TripletInstance* m_instance; - }; - - bool operator!=(const Triplet& left, const Triplet& right); -} - -template<> -struct std::hash -{ - size_t operator()(const vcpkg::Triplet& t) const { return t.hash_code(); } -}; diff --git a/toolsrc/include/vcpkg/base/checks.h b/toolsrc/include/vcpkg/base/checks.h new file mode 100644 index 000000000..fb162c897 --- /dev/null +++ b/toolsrc/include/vcpkg/base/checks.h @@ -0,0 +1,55 @@ +#pragma once + +#include +#include +#include + +namespace vcpkg::Checks +{ + void register_console_ctrl_handler(); + + // Indicate that an internal error has occurred and exit the tool. This should be used when invariants have been + // broken. + [[noreturn]] void unreachable(const LineInfo& line_info); + + [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code); + + // Exit the tool without an error message. + [[noreturn]] inline void exit_fail(const LineInfo& line_info) { exit_with_code(line_info, EXIT_FAILURE); } + + // Exit the tool successfully. + [[noreturn]] inline void exit_success(const LineInfo& line_info) { exit_with_code(line_info, EXIT_SUCCESS); } + + // Display an error message to the user and exit the tool. + [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message); + + template + // Display an error message to the user and exit the tool. + [[noreturn]] void exit_with_message(const LineInfo& line_info, + const char* error_message_template, + const Arg1 error_message_arg1, + const Args&... error_message_args) + { + exit_with_message(line_info, + Strings::format(error_message_template, error_message_arg1, error_message_args...)); + } + + void check_exit(const LineInfo& line_info, bool expression); + + void check_exit(const LineInfo& line_info, bool expression, const CStringView error_message); + + template + void check_exit(const LineInfo& line_info, + Conditional&& expression, + const char* error_message_template, + const Arg1 error_message_arg1, + const Args&... error_message_args) + { + if (!expression) + { + // Only create the string if the expression is false + exit_with_message(line_info, + Strings::format(error_message_template, error_message_arg1, error_message_args...)); + } + } +} diff --git a/toolsrc/include/vcpkg/base/chrono.h b/toolsrc/include/vcpkg/base/chrono.h new file mode 100644 index 000000000..b525852f2 --- /dev/null +++ b/toolsrc/include/vcpkg/base/chrono.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +namespace vcpkg::Chrono +{ + class ElapsedTime + { + public: + static ElapsedTime create_started(); + + constexpr ElapsedTime() : m_start_tick() {} + + template + TimeUnit elapsed() const + { + return std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - this->m_start_tick); + } + + double microseconds() const { return elapsed>().count(); } + + std::string to_string() const; + + private: + std::chrono::high_resolution_clock::time_point m_start_tick; + }; +} diff --git a/toolsrc/include/vcpkg/base/cofffilereader.h b/toolsrc/include/vcpkg/base/cofffilereader.h new file mode 100644 index 000000000..ad2cc7b12 --- /dev/null +++ b/toolsrc/include/vcpkg/base/cofffilereader.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +#include + +namespace vcpkg::CoffFileReader +{ + struct DllInfo + { + MachineType machine_type; + }; + + struct LibInfo + { + std::vector machine_types; + }; + + DllInfo read_dll(const fs::path& path); + + LibInfo read_lib(const fs::path& path); +} diff --git a/toolsrc/include/vcpkg/base/cstringview.h b/toolsrc/include/vcpkg/base/cstringview.h new file mode 100644 index 000000000..341830f05 --- /dev/null +++ b/toolsrc/include/vcpkg/base/cstringview.h @@ -0,0 +1,97 @@ +#pragma once + +#include + +namespace vcpkg +{ + template + struct BasicCStringView + { + constexpr BasicCStringView() : cstr(nullptr) {} + constexpr BasicCStringView(const CharType* cstr) : cstr(cstr) {} + constexpr BasicCStringView(const BasicCStringView&) = default; + BasicCStringView(const std::basic_string& str) : cstr(str.c_str()) {} + + constexpr const CharType* c_str() const { return cstr; } + + private: + const CharType* cstr; + }; + + namespace details + { + inline bool vcpkg_strcmp(const char* l, const char* r) { return strcmp(l, r) == 0; } + inline bool vcpkg_strcmp(const wchar_t* l, const wchar_t* r) { return wcscmp(l, r) == 0; } + } + + template + bool operator==(const BasicCStringView& l, const BasicCStringView& r) + { + return details::vcpkg_strcmp(l.c_str(), r.c_str()); + } + + template + bool operator==(const CharType* l, const BasicCStringView& r) + { + return details::vcpkg_strcmp(l, r.c_str()); + } + + template + bool operator==(const BasicCStringView& r, const CharType* l) + { + return details::vcpkg_strcmp(l, r.c_str()); + } + + template + bool operator==(const std::basic_string& l, const BasicCStringView& r) + { + return l == r.c_str(); + } + + template + bool operator==(const BasicCStringView& r, const std::basic_string& l) + { + return l == r.c_str(); + } + + // notequals + template + bool operator!=(const BasicCStringView& l, const BasicCStringView& r) + { + return !details::vcpkg_strcmp(l.c_str(), r.c_str()); + } + + template + bool operator!=(const CharType* l, const BasicCStringView& r) + { + return !details::vcpkg_strcmp(l, r.c_str()); + } + + template + bool operator!=(const BasicCStringView& r, const CharType* l) + { + return !details::vcpkg_strcmp(l, r.c_str()); + } + + template + bool operator!=(const BasicCStringView& r, const std::basic_string& l) + { + return l != r.c_str(); + } + + template + bool operator!=(const std::basic_string& l, const BasicCStringView& r) + { + return l != r.c_str(); + } + + using CStringView = BasicCStringView; + using CWStringView = BasicCStringView; + + inline const char* to_printf_arg(const CStringView string_view) { return string_view.c_str(); } + + inline const wchar_t* to_wprintf_arg(const CWStringView string_view) { return string_view.c_str(); } + + static_assert(sizeof(CStringView) == sizeof(void*), "CStringView must be a simple wrapper around char*"); + static_assert(sizeof(CWStringView) == sizeof(void*), "CWStringView must be a simple wrapper around wchar_t*"); +} diff --git a/toolsrc/include/vcpkg/base/enums.h b/toolsrc/include/vcpkg/base/enums.h new file mode 100644 index 000000000..6eca2cfe1 --- /dev/null +++ b/toolsrc/include/vcpkg/base/enums.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +#include + +namespace vcpkg::Enums +{ + std::string nullvalue_to_string(const CStringView enum_name); + + [[noreturn]] void nullvalue_used(const LineInfo& line_info, const CStringView enum_name); +} diff --git a/toolsrc/include/vcpkg/base/expected.h b/toolsrc/include/vcpkg/base/expected.h new file mode 100644 index 000000000..a946c442e --- /dev/null +++ b/toolsrc/include/vcpkg/base/expected.h @@ -0,0 +1,115 @@ +#pragma once + +#include + +#include + +namespace vcpkg +{ + template + struct ErrorHolder + { + ErrorHolder() : m_is_error(false) {} + template + ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward(err)) + { + } + + constexpr bool has_error() const { return m_is_error; } + + const Err& error() const { return m_err; } + Err& error() { return m_err; } + + CStringView to_string() const { return "value was error"; } + + private: + bool m_is_error; + Err m_err; + }; + + template<> + struct ErrorHolder + { + ErrorHolder() = default; + ErrorHolder(const std::error_code& err) : m_err(err) {} + + constexpr bool has_error() const { return bool(m_err); } + + const std::error_code& error() const { return m_err; } + std::error_code& error() { return m_err; } + + CStringView to_string() const { return "value was error"; } + + private: + std::error_code m_err; + }; + + template + class ExpectedT + { + public: + constexpr ExpectedT() = default; + + // Constructors are intentionally implicit + + ExpectedT(const S& s) : m_s(s) {} + ExpectedT(S&& s) : m_s(std::move(s)) {} + + ExpectedT(const T& t) : m_t(t) {} + ExpectedT(T&& t) : m_t(std::move(t)) {} + + ExpectedT(const ExpectedT&) = default; + ExpectedT(ExpectedT&&) = default; + ExpectedT& operator=(const ExpectedT&) = default; + ExpectedT& operator=(ExpectedT&&) = default; + + explicit constexpr operator bool() const noexcept { return !m_s.has_error(); } + constexpr bool has_value() const noexcept { return !m_s.has_error(); } + + T&& value_or_exit(const LineInfo& line_info) && + { + exit_if_error(line_info); + return std::move(this->m_t); + } + + const T& value_or_exit(const LineInfo& line_info) const& + { + exit_if_error(line_info); + return this->m_t; + } + + const S& error() const& { return this->m_s.error(); } + + S&& error() && { return std::move(this->m_s.error()); } + + const T* get() const + { + if (!this->has_value()) + { + return nullptr; + } + return &this->m_t; + } + + T* get() + { + if (!this->has_value()) + { + return nullptr; + } + return &this->m_t; + } + + private: + void exit_if_error(const LineInfo& line_info) const + { + Checks::check_exit(line_info, !m_s.has_error(), m_s.to_string()); + } + + ErrorHolder m_s; + T m_t; + }; + + template + using Expected = ExpectedT; +} diff --git a/toolsrc/include/vcpkg/base/files.h b/toolsrc/include/vcpkg/base/files.h new file mode 100644 index 000000000..f4bcf742c --- /dev/null +++ b/toolsrc/include/vcpkg/base/files.h @@ -0,0 +1,57 @@ +#pragma once + +#include + +#include + +namespace fs +{ + namespace stdfs = std::experimental::filesystem; + + using stdfs::copy_options; + using stdfs::file_status; + using stdfs::path; + + inline bool is_regular_file(file_status s) { return stdfs::is_regular_file(s); } + inline bool is_directory(file_status s) { return stdfs::is_directory(s); } + inline bool status_known(file_status s) { return stdfs::status_known(s); } +} + +namespace vcpkg::Files +{ + __interface Filesystem + { + virtual Expected read_contents(const fs::path& file_path) const = 0; + virtual Expected> read_lines(const fs::path& file_path) const = 0; + virtual fs::path find_file_recursively_up(const fs::path& starting_dir, const std::string& filename) const = 0; + virtual std::vector get_files_recursive(const fs::path& dir) const = 0; + virtual std::vector get_files_non_recursive(const fs::path& dir) const = 0; + + virtual void write_lines(const fs::path& file_path, const std::vector& lines) = 0; + virtual void write_contents(const fs::path& file_path, const std::string& data) = 0; + virtual void rename(const fs::path& oldpath, const fs::path& newpath) = 0; + virtual bool remove(const fs::path& path) = 0; + virtual bool remove(const fs::path& path, std::error_code& ec) = 0; + virtual std::uintmax_t remove_all(const fs::path& path, std::error_code& ec) = 0; + virtual bool exists(const fs::path& path) const = 0; + virtual bool is_directory(const fs::path& path) const = 0; + virtual bool is_regular_file(const fs::path& path) const = 0; + virtual bool is_empty(const fs::path& path) const = 0; + virtual bool create_directory(const fs::path& path, std::error_code& ec) = 0; + virtual bool create_directories(const fs::path& path, std::error_code& ec) = 0; + virtual void copy(const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts) = 0; + virtual bool copy_file( + const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts, std::error_code& ec) = 0; + virtual fs::file_status status(const fs::path& path, std::error_code& ec) const = 0; + }; + + Filesystem& get_real_filesystem(); + + static const char* FILESYSTEM_INVALID_CHARACTERS = R"(\/:*?"<>|)"; + + bool has_invalid_chars_for_filesystem(const std::string& s); + + void print_paths(const std::vector& paths); + + std::vector find_from_PATH(const std::wstring& name); +} diff --git a/toolsrc/include/vcpkg/base/graphs.h b/toolsrc/include/vcpkg/base/graphs.h new file mode 100644 index 000000000..ff56cb298 --- /dev/null +++ b/toolsrc/include/vcpkg/base/graphs.h @@ -0,0 +1,161 @@ +#pragma once + +#include +#include + +#include + +namespace vcpkg::Graphs +{ + enum class ExplorationStatus + { + // We have not visited this vertex + NOT_EXPLORED, + + // We have visited this vertex but haven't visited all vertices in its subtree + PARTIALLY_EXPLORED, + + // We have visited this vertex and all vertices in its subtree + FULLY_EXPLORED + }; + + template + __interface AdjacencyProvider + { + std::vector adjacency_list(const U& vertex) const; + + U load_vertex_data(const V& vertex) const; + }; + + template + static void topological_sort_internal(const V& vertex, + const AdjacencyProvider& f, + std::unordered_map& exploration_status, + std::vector& sorted) + { + ExplorationStatus& status = exploration_status[vertex]; + switch (status) + { + case ExplorationStatus::FULLY_EXPLORED: return; + case ExplorationStatus::PARTIALLY_EXPLORED: Checks::exit_with_message(VCPKG_LINE_INFO, "cycle in graph"); + case ExplorationStatus::NOT_EXPLORED: + { + status = ExplorationStatus::PARTIALLY_EXPLORED; + U vertex_data = f.load_vertex_data(vertex); + for (const V& neighbour : f.adjacency_list(vertex_data)) + topological_sort_internal(neighbour, f, exploration_status, sorted); + + sorted.push_back(std::move(vertex_data)); + status = ExplorationStatus::FULLY_EXPLORED; + return; + } + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + template + std::vector topological_sort(const std::vector& starting_vertices, const AdjacencyProvider& f) + { + std::vector sorted; + std::unordered_map exploration_status; + + for (auto& vertex : starting_vertices) + { + topological_sort_internal(vertex, f, exploration_status, sorted); + } + + return sorted; + } + + template + struct GraphAdjacencyProvider final : AdjacencyProvider + { + const std::unordered_map>& vertices; + + GraphAdjacencyProvider(const std::unordered_map>& vertices) : vertices(vertices) {} + + std::vector adjacency_list(const V& vertex) const override + { + const std::unordered_set& as_set = this->vertices.at(vertex); + return std::vector(as_set.cbegin(), as_set.cend()); // TODO: Avoid redundant copy + } + + V load_vertex_data(const V& vertex) const override { return vertex; } + }; + + template + struct Graph + { + public: + void add_vertex(V v) { this->vertices[v]; } + + // TODO: Change with iterators + void add_vertices(const std::vector& vs) + { + for (const V& v : vs) + { + this->vertices[v]; + } + } + + void add_edge(V u, V v) + { + this->vertices[v]; + this->vertices[u].insert(v); + } + + std::vector topological_sort() const + { + GraphAdjacencyProvider adjacency_provider{this->vertices}; + std::unordered_map indegrees = count_indegrees(); + + std::vector sorted; + sorted.reserve(indegrees.size()); + + std::unordered_map exploration_status; + exploration_status.reserve(indegrees.size()); + + for (auto& pair : indegrees) + { + if (pair.second == 0) // Starting from vertices with indegree == 0. Not required. + { + V vertex = pair.first; + topological_sort_internal(vertex, adjacency_provider, exploration_status, sorted); + } + } + + return sorted; + } + + std::unordered_map count_indegrees() const + { + std::unordered_map indegrees; + + for (auto& pair : this->vertices) + { + indegrees[pair.first]; + for (V neighbour : pair.second) + { + ++indegrees[neighbour]; + } + } + + return indegrees; + } + + const std::unordered_map>& adjacency_list() const { return this->vertices; } + std::vector vertex_list() const + { + // why no &? it returns 0 + std::vector vertex_list; + for (const auto& vertex : this->vertices) + { + vertex_list.emplace_back(vertex.first); + } + return vertex_list; + } + + private: + std::unordered_map> vertices; + }; +} diff --git a/toolsrc/include/vcpkg/base/lazy.h b/toolsrc/include/vcpkg/base/lazy.h new file mode 100644 index 000000000..58c11c002 --- /dev/null +++ b/toolsrc/include/vcpkg/base/lazy.h @@ -0,0 +1,26 @@ +#pragma once + +namespace vcpkg +{ + template + class Lazy + { + public: + Lazy() : value(T()), initialized(false) {} + + template + T const& get_lazy(const F& f) const + { + if (!initialized) + { + value = f(); + initialized = true; + } + return value; + } + + private: + mutable T value; + mutable bool initialized; + }; +} diff --git a/toolsrc/include/vcpkg/base/lineinfo.h b/toolsrc/include/vcpkg/base/lineinfo.h new file mode 100644 index 000000000..62973462a --- /dev/null +++ b/toolsrc/include/vcpkg/base/lineinfo.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +namespace vcpkg +{ + struct LineInfo + { + int line_number; + const char* file_name; + + constexpr LineInfo() : line_number(0), file_name(nullptr) {} + constexpr LineInfo(const int lineno, const char* filename) : line_number(lineno), file_name(filename) {} + + std::string to_string() const; + }; +} + +#define VCPKG_LINE_INFO vcpkg::LineInfo(__LINE__, __FILE__) diff --git a/toolsrc/include/vcpkg/base/machinetype.h b/toolsrc/include/vcpkg/base/machinetype.h new file mode 100644 index 000000000..b85cdbb0b --- /dev/null +++ b/toolsrc/include/vcpkg/base/machinetype.h @@ -0,0 +1,37 @@ +#pragma once + +#include + +namespace vcpkg +{ + enum class MachineType : uint16_t + { + UNKNOWN = 0x0, // The contents of this field are assumed to be applicable to any machine type + AM33 = 0x1d3, // Matsushita AM33 + AMD64 = 0x8664, // x64 + ARM = 0x1c0, // ARM little endian + ARM64 = 0xaa64, // ARM64 little endian + ARMNT = 0x1c4, // ARM Thumb-2 little endian + EBC = 0xebc, // EFI byte code + I386 = 0x14c, // Intel 386 or later processors and compatible processors + IA64 = 0x200, // Intel Itanium processor family + M32R = 0x9041, // Mitsubishi M32R little endian + MIPS16 = 0x266, // MIPS16 + MIPSFPU = 0x366, // MIPS with FPU + MIPSFPU16 = 0x466, // MIPS16 with FPU + POWERPC = 0x1f0, // Power PC little endian + POWERPCFP = 0x1f1, // Power PC with floating point support + R4000 = 0x166, // MIPS little endian + RISCV32 = 0x5032, // RISC-V 32-bit address space + RISCV64 = 0x5064, // RISC-V 64-bit address space + RISCV128 = 0x5128, // RISC-V 128-bit address space + SH3 = 0x1a2, // Hitachi SH3 + SH3DSP = 0x1a3, // Hitachi SH3 DSP + SH4 = 0x1a6, // Hitachi SH4 + SH5 = 0x1a8, // Hitachi SH5 + THUMB = 0x1c2, // Thumb + WCEMIPSV2 = 0x169, // MIPS little-endian WCE v2 + }; + + MachineType to_machine_type(const uint16_t value); +} diff --git a/toolsrc/include/vcpkg/base/optional.h b/toolsrc/include/vcpkg/base/optional.h new file mode 100644 index 000000000..ff7a210c7 --- /dev/null +++ b/toolsrc/include/vcpkg/base/optional.h @@ -0,0 +1,99 @@ +#pragma once + +#include + +namespace vcpkg +{ + struct NullOpt + { + explicit constexpr NullOpt(int) {} + }; + + const static constexpr NullOpt nullopt{0}; + + template + class Optional + { + public: + constexpr Optional() : m_is_present(false), m_t() {} + + // Constructors are intentionally implicit + constexpr Optional(NullOpt) : m_is_present(false), m_t() {} + + Optional(const T& t) : m_is_present(true), m_t(t) {} + + Optional(T&& t) : m_is_present(true), m_t(std::move(t)) {} + + T&& value_or_exit(const LineInfo& line_info) && + { + this->exit_if_null(line_info); + return std::move(this->m_t); + } + + const T& value_or_exit(const LineInfo& line_info) const& + { + this->exit_if_null(line_info); + return this->m_t; + } + + constexpr explicit operator bool() const { return this->m_is_present; } + + constexpr bool has_value() const { return m_is_present; } + + template + T value_or(U&& default_value) const& + { + return bool(*this) ? this->m_t : static_cast(std::forward(default_value)); + } + + template + T value_or(U&& default_value) && + { + return bool(*this) ? std::move(this->m_t) : static_cast(std::forward(default_value)); + } + + const T* get() const { return bool(*this) ? &this->m_t : nullptr; } + + T* get() { return bool(*this) ? &this->m_t : nullptr; } + + private: + void exit_if_null(const LineInfo& line_info) const + { + Checks::check_exit(line_info, this->m_is_present, "Value was null"); + } + + bool m_is_present; + T m_t; + }; + + template + Optional> make_optional(U&& u) + { + return Optional>(std::forward(u)); + } + + template + bool operator==(const Optional& o, const T& t) + { + if (auto p = o.get()) return *p == t; + return false; + } + template + bool operator==(const T& t, const Optional& o) + { + if (auto p = o.get()) return t == *p; + return false; + } + template + bool operator!=(const Optional& o, const T& t) + { + if (auto p = o.get()) return *p != t; + return true; + } + template + bool operator!=(const T& t, const Optional& o) + { + if (auto p = o.get()) return t != *p; + return true; + } +} diff --git a/toolsrc/include/vcpkg/base/sortedvector.h b/toolsrc/include/vcpkg/base/sortedvector.h new file mode 100644 index 000000000..62808cc2f --- /dev/null +++ b/toolsrc/include/vcpkg/base/sortedvector.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include + +// Add more forwarding functions to the m_data std::vector as needed. +namespace vcpkg +{ + template + class SortedVector + { + public: + using size_type = typename std::vector::size_type; + using iterator = typename std::vector::const_iterator; + + SortedVector() : m_data() {} + + explicit SortedVector(std::vector v) : m_data(std::move(v)) + { + if (!std::is_sorted(m_data.begin(), m_data.end())) + { + std::sort(m_data.begin(), m_data.end()); + } + } + + template + SortedVector(std::vector v, Compare comp) : m_data(std::move(v)) + { + if (!std::is_sorted(m_data.cbegin(), m_data.cend(), comp)) + { + std::sort(m_data.begin(), m_data.end(), comp); + } + } + + iterator begin() const { return this->m_data.cbegin(); } + + iterator end() const { return this->m_data.cend(); } + + iterator cbegin() const { return this->m_data.cbegin(); } + + iterator cend() const { return this->m_data.cend(); } + + bool empty() const { return this->m_data.empty(); } + + size_type size() const { return this->m_data.size(); } + + private: + std::vector m_data; + }; +} diff --git a/toolsrc/include/vcpkg/base/span.h b/toolsrc/include/vcpkg/base/span.h new file mode 100644 index 000000000..6be546351 --- /dev/null +++ b/toolsrc/include/vcpkg/base/span.h @@ -0,0 +1,60 @@ +#pragma once + +#include +#include +#include +#include + +namespace vcpkg +{ + template + struct Span + { + public: + using element_type = T; + using pointer = T*; + using reference = T&; + using iterator = T*; + + constexpr Span() noexcept : m_ptr(nullptr), m_count(0) {} + constexpr Span(std::nullptr_t) noexcept : Span() {} + constexpr Span(T* ptr, size_t count) noexcept : m_ptr(ptr), m_count(count) {} + constexpr Span(T* ptr_begin, T* ptr_end) noexcept : m_ptr(ptr_begin), m_count(ptr_end - ptr_begin) {} + constexpr Span(std::initializer_list l) noexcept : m_ptr(l.begin()), m_count(l.size()) {} + + template + constexpr Span(T (&arr)[N]) noexcept : Span(arr, N) + { + } + + template + constexpr Span(const std::array, N>& arr) noexcept : Span(arr.data(), arr.size()) + { + } + + Span(std::vector& v) noexcept : Span(v.data(), v.size()) {} + Span(const std::vector>& v) noexcept : Span(v.data(), v.size()) {} + + constexpr iterator begin() const { return m_ptr; } + constexpr iterator end() const { return m_ptr + m_count; } + + constexpr reference operator[](size_t i) const { return m_ptr[i]; } + constexpr size_t size() const { return m_count; } + + private: + pointer m_ptr; + size_t m_count; + }; + + template + Span make_span(std::vector& v) + { + return {v.data(), v.size()}; + } + + template + Span make_span(const std::vector& v) + { + return {v.data(), v.size()}; + } +} \ No newline at end of file diff --git a/toolsrc/include/vcpkg/base/strings.h b/toolsrc/include/vcpkg/base/strings.h new file mode 100644 index 000000000..59823deb8 --- /dev/null +++ b/toolsrc/include/vcpkg/base/strings.h @@ -0,0 +1,114 @@ +#pragma once + +#include + +#include + +namespace vcpkg::Strings::details +{ + template + auto to_printf_arg(const T& t) -> decltype(t.to_string()) + { + return t.to_string(); + } + + inline const char* to_printf_arg(const std::string& s) { return s.c_str(); } + + inline const char* to_printf_arg(const char* s) { return s; } + + inline int to_printf_arg(const int s) { return s; } + + inline long long to_printf_arg(const long long s) { return s; } + + inline unsigned long to_printf_arg(const unsigned long s) { return s; } + + inline size_t to_printf_arg(const size_t s) { return s; } + + inline double to_printf_arg(const double s) { return s; } + + std::string format_internal(const char* fmtstr, ...); + + inline const wchar_t* to_wprintf_arg(const std::wstring& s) { return s.c_str(); } + + inline const wchar_t* to_wprintf_arg(const wchar_t* s) { return s; } + + std::wstring wformat_internal(const wchar_t* fmtstr, ...); +} + +namespace vcpkg::Strings +{ + static constexpr const char* EMPTY = ""; + static constexpr const wchar_t* WEMPTY = L""; + + template + std::string format(const char* fmtstr, const Args&... args) + { + using vcpkg::Strings::details::to_printf_arg; + return details::format_internal(fmtstr, to_printf_arg(to_printf_arg(args))...); + } + + template + std::wstring wformat(const wchar_t* fmtstr, const Args&... args) + { + using vcpkg::Strings::details::to_wprintf_arg; + return details::wformat_internal(fmtstr, to_wprintf_arg(to_wprintf_arg(args))...); + } + + std::wstring to_utf16(const CStringView s); + + std::string to_utf8(const CWStringView w); + + std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern); + + bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern); + + bool case_insensitive_ascii_compare(const CStringView left, const CStringView right); + + std::string ascii_to_lowercase(const std::string& input); + + bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern); + + template + std::basic_string join(const CharType* delimiter, const Container& v, Transformer transformer) + { + const auto begin = v.begin(); + const auto end = v.end(); + + if (begin == end) + { + return std::basic_string(); + } + + std::basic_string output; + output.append(transformer(*begin)); + for (auto it = std::next(begin); it != end; ++it) + { + output.append(delimiter); + output.append(transformer(*it)); + } + + return output; + } + template + std::basic_string join(const CharType* delimiter, const Container& v) + { + using Element = decltype(*v.begin()); + return join(delimiter, v, [](const Element& x) -> const Element& { return x; }); + } + + void trim(std::string* s); + + std::string trimmed(const std::string& s); + + void trim_all_and_remove_whitespace_strings(std::vector* strings); + + std::vector split(const std::string& s, const std::string& delimiter); + + template + std::string serialize(const T& t) + { + std::string ret; + serialize(t, ret); + return ret; + } +} diff --git a/toolsrc/include/vcpkg/base/system.h b/toolsrc/include/vcpkg/base/system.h new file mode 100644 index 000000000..a2e8f3f45 --- /dev/null +++ b/toolsrc/include/vcpkg/base/system.h @@ -0,0 +1,108 @@ +#pragma once + +#include +#include +#include + +#include + +namespace vcpkg::System +{ + tm get_current_date_time(); + + fs::path get_exe_path_of_current_process(); + + struct ExitCodeAndOutput + { + int exit_code; + std::string output; + }; + + int cmd_execute_clean(const CWStringView cmd_line); + + int cmd_execute(const CWStringView cmd_line); + + ExitCodeAndOutput cmd_execute_and_capture_output(const CWStringView cmd_line); + + std::wstring create_powershell_script_cmd(const fs::path& script_path, const CWStringView args = Strings::WEMPTY); + + enum class Color + { + success = 10, + error = 12, + warning = 14, + }; + + void println(); + void print(const CStringView message); + void println(const CStringView message); + void print(const Color c, const CStringView message); + void println(const Color c, const CStringView message); + + template + void print(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) + { + return System::print(Strings::format(messageTemplate, messageArg1, messageArgs...)); + } + + template + void print(const Color c, const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) + { + return System::print(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); + } + + template + void println(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) + { + return System::println(Strings::format(messageTemplate, messageArg1, messageArgs...)); + } + + template + void println(const Color c, const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) + { + return System::println(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); + } + + Optional get_environment_variable(const CWStringView varname) noexcept; + + Optional get_registry_string(HKEY base, const CWStringView subkey, const CWStringView valuename); + + enum class CPUArchitecture + { + X86, + X64, + ARM, + ARM64, + }; + + Optional to_cpu_architecture(CStringView arch); + + CPUArchitecture get_host_processor(); + + std::vector get_supported_host_architectures(); + + const fs::path& get_program_files_32_bit(); + + const fs::path& get_program_files_platform_bitness(); +} + +namespace vcpkg::Debug +{ + void println(const CStringView message); + void println(const System::Color c, const CStringView message); + + template + void println(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) + { + return Debug::println(Strings::format(messageTemplate, messageArg1, messageArgs...)); + } + + template + void println(const System::Color c, + const char* messageTemplate, + const Arg1& messageArg1, + const Args&... messageArgs) + { + return Debug::println(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); + } +} diff --git a/toolsrc/include/vcpkg/base/util.h b/toolsrc/include/vcpkg/base/util.h new file mode 100644 index 000000000..3834580b6 --- /dev/null +++ b/toolsrc/include/vcpkg/base/util.h @@ -0,0 +1,156 @@ +#pragma once + +#include +#include +#include +#include + +namespace vcpkg::Util +{ + template + using FmapOut = decltype(std::declval()(*begin(std::declval()))); + + template> + std::vector fmap(Cont&& xs, Func&& f) + { + std::vector ret; + ret.reserve(xs.size()); + + for (auto&& x : xs) + ret.push_back(f(x)); + + return ret; + } + + template + using FmapFlattenOut = std::decay_t()(*begin(std::declval()))))>; + + template> + std::vector fmap_flatten(Cont&& xs, Func&& f) + { + std::vector ret; + + for (auto&& x : xs) + for (auto&& y : f(x)) + ret.push_back(std::move(y)); + + return ret; + } + + template + void stable_keep_if(Container& cont, Pred pred) + { + cont.erase(std::stable_partition(cont.begin(), cont.end(), pred), cont.end()); + } + + template + void unstable_keep_if(Container& cont, Pred pred) + { + cont.erase(std::partition(cont.begin(), cont.end(), pred), cont.end()); + } + + template + void erase_remove_if(Container& cont, Pred pred) + { + cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); + } + + template + auto find(Container&& cont, V&& v) + { + using std::begin; + using std::end; + return std::find(begin(cont), end(cont), v); + } + + template + auto find_if(Container&& cont, Pred pred) + { + using std::begin; + using std::end; + return std::find_if(begin(cont), end(cont), pred); + } + + template + using ElementT = std::remove_reference_t()))>; + + template> + std::vector element_pointers(Container&& cont) + { + return fmap(cont, [](auto&& x) { return &x; }); + } + + template + auto find_if_not(Container&& cont, Pred pred) + { + using std::begin; + using std::end; + return std::find_if_not(begin(cont), end(cont), pred); + } + + template + void group_by(const Container& cont, _Inout_ std::map>* output, Func&& f) + { + for (const V& element : cont) + { + K key = f(element); + (*output)[key].push_back(&element); + } + } + + template())->first)>> + std::vector extract_keys(AssocContainer&& input_map) + { + return fmap(input_map, [](auto&& p) { return p.first; }); + } + + struct MoveOnlyBase + { + MoveOnlyBase() = default; + MoveOnlyBase(const MoveOnlyBase&) = delete; + MoveOnlyBase(MoveOnlyBase&&) = default; + + MoveOnlyBase& operator=(const MoveOnlyBase&) = delete; + MoveOnlyBase& operator=(MoveOnlyBase&&) = default; + }; + + struct ResourceBase + { + ResourceBase() = default; + ResourceBase(const ResourceBase&) = delete; + ResourceBase(ResourceBase&&) = delete; + + ResourceBase& operator=(const ResourceBase&) = delete; + ResourceBase& operator=(ResourceBase&&) = delete; + }; + + template + struct LockGuardPtr; + + template + struct LockGuarded + { + friend struct LockGuardPtr; + + LockGuardPtr lock() { return *this; } + + private: + std::mutex m_mutex; + T m_t; + }; + + template + struct LockGuardPtr + { + T& operator*() { return m_ptr; } + T* operator->() { return &m_ptr; } + + T* get() { return &m_ptr; } + + LockGuardPtr(LockGuarded& sync) : m_lock(sync.m_mutex), m_ptr(sync.m_t) {} + + private: + std::unique_lock m_lock; + T& m_ptr; + }; +} \ No newline at end of file diff --git a/toolsrc/include/vcpkg/binaryparagraph.h b/toolsrc/include/vcpkg/binaryparagraph.h new file mode 100644 index 000000000..7eb50a6d7 --- /dev/null +++ b/toolsrc/include/vcpkg/binaryparagraph.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include + +#include + +namespace vcpkg +{ + /// + /// Built package metadata + /// + struct BinaryParagraph + { + BinaryParagraph(); + explicit BinaryParagraph(std::unordered_map fields); + BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet); + BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet); + + std::string displayname() const; + + std::string fullstem() const; + + std::string dir() const; + + PackageSpec spec; + std::string version; + std::string description; + std::string maintainer; + std::string feature; + std::vector default_features; + std::vector depends; + }; + + struct BinaryControlFile + { + BinaryParagraph core_paragraph; + std::vector features; + }; + + void serialize(const BinaryParagraph& pgh, std::string& out_str); +} \ No newline at end of file diff --git a/toolsrc/include/vcpkg/build.h b/toolsrc/include/vcpkg/build.h new file mode 100644 index 000000000..f146e9951 --- /dev/null +++ b/toolsrc/include/vcpkg/build.h @@ -0,0 +1,205 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +namespace vcpkg::Build +{ + namespace Command + { + void perform_and_exit(const FullPackageSpec& full_spec, + const fs::path& port_dir, + const std::unordered_set& options, + const VcpkgPaths& paths); + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); + } + + enum class UseHeadVersion + { + NO = 0, + YES + }; + + inline UseHeadVersion to_use_head_version(const bool value) + { + return value ? UseHeadVersion::YES : UseHeadVersion::NO; + } + + inline bool to_bool(const UseHeadVersion value) { return value == UseHeadVersion::YES; } + + enum class AllowDownloads + { + NO = 0, + YES + }; + + inline AllowDownloads to_allow_downloads(const bool value) + { + return value ? AllowDownloads::YES : AllowDownloads::NO; + } + + inline bool to_bool(const AllowDownloads value) { return value == AllowDownloads::YES; } + + struct BuildPackageOptions + { + UseHeadVersion use_head_version; + AllowDownloads allow_downloads; + }; + + enum class BuildResult + { + NULLVALUE = 0, + SUCCEEDED, + BUILD_FAILED, + POST_BUILD_CHECKS_FAILED, + FILE_CONFLICTS, + CASCADED_DUE_TO_MISSING_DEPENDENCIES + }; + + static constexpr std::array BUILD_RESULT_VALUES = { + BuildResult::SUCCEEDED, + BuildResult::BUILD_FAILED, + BuildResult::POST_BUILD_CHECKS_FAILED, + BuildResult::FILE_CONFLICTS, + BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES}; + + const std::string& to_string(const BuildResult build_result); + std::string create_error_message(const BuildResult build_result, const PackageSpec& spec); + std::string create_user_troubleshooting_message(const PackageSpec& spec); + + /// + /// Settings from the triplet file which impact the build environment and post-build checks + /// + struct PreBuildInfo + { + /// + /// Runs the triplet file in a "capture" mode to create a PreBuildInfo + /// + static PreBuildInfo from_triplet_file(const VcpkgPaths& paths, const Triplet& triplet); + + std::string target_architecture; + std::string cmake_system_name; + std::string cmake_system_version; + Optional platform_toolset; + Optional visual_studio_path; + }; + + std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset); + + struct ExtendedBuildResult + { + BuildResult code; + std::vector unmet_dependencies; + }; + + struct BuildPackageConfig + { + BuildPackageConfig(const SourceParagraph& src, + const Triplet& triplet, + fs::path&& port_dir, + const BuildPackageOptions& build_package_options) + : src(src) + , scf(nullptr) + , triplet(triplet) + , port_dir(std::move(port_dir)) + , build_package_options(build_package_options) + , feature_list(nullptr) + { + } + + BuildPackageConfig(const SourceControlFile& src, + const Triplet& triplet, + fs::path&& port_dir, + const BuildPackageOptions& build_package_options, + const std::unordered_set& feature_list) + : src(*src.core_paragraph) + , scf(&src) + , triplet(triplet) + , port_dir(std::move(port_dir)) + , build_package_options(build_package_options) + , feature_list(&feature_list) + { + } + + const SourceParagraph& src; + const SourceControlFile* scf; + const Triplet& triplet; + fs::path port_dir; + const BuildPackageOptions& build_package_options; + const std::unordered_set* feature_list; + }; + + ExtendedBuildResult build_package(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const StatusParagraphs& status_db); + + enum class BuildPolicy + { + EMPTY_PACKAGE, + DLLS_WITHOUT_LIBS, + ONLY_RELEASE_CRT, + EMPTY_INCLUDE_FOLDER, + ALLOW_OBSOLETE_MSVCRT, + // Must be last + COUNT, + }; + + constexpr std::array G_ALL_POLICIES = { + BuildPolicy::EMPTY_PACKAGE, + BuildPolicy::DLLS_WITHOUT_LIBS, + BuildPolicy::ONLY_RELEASE_CRT, + BuildPolicy::EMPTY_INCLUDE_FOLDER, + BuildPolicy::ALLOW_OBSOLETE_MSVCRT, + }; + + const std::string& to_string(BuildPolicy policy); + CStringView to_cmake_variable(BuildPolicy policy); + + struct BuildPolicies + { + BuildPolicies() = default; + BuildPolicies(std::map&& map) : m_policies(std::move(map)) {} + + bool is_enabled(BuildPolicy policy) const + { + const auto it = m_policies.find(policy); + if (it != m_policies.cend()) return it->second; + return false; + } + + private: + std::map m_policies; + }; + + enum class LinkageType : char + { + DYNAMIC, + STATIC, + }; + + Optional to_linkage_type(const std::string& str); + + struct BuildInfo + { + LinkageType crt_linkage; + LinkageType library_linkage; + + Optional version; + + BuildPolicies policies; + }; + + BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath); +} diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h new file mode 100644 index 000000000..64b2118ce --- /dev/null +++ b/toolsrc/include/vcpkg/commands.h @@ -0,0 +1,134 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include + +namespace vcpkg::Commands +{ + using CommandTypeA = void (*)(const VcpkgCmdArguments& args, + const VcpkgPaths& paths, + const Triplet& default_triplet); + using CommandTypeB = void (*)(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + using CommandTypeC = void (*)(const VcpkgCmdArguments& args); + + namespace BuildExternal + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); + } + + namespace CI + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); + } + + namespace Env + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); + } + + namespace Create + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Edit + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace DependInfo + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Search + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace List + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Owns + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Cache + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Import + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Integrate + { + extern const char* const INTEGRATE_COMMAND_HELPSTRING; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace PortsDiff + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Autocomplete + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + } + + namespace Version + { + const std::string& version(); + void warn_if_vcpkg_version_mismatch(const VcpkgPaths& paths); + void perform_and_exit(const VcpkgCmdArguments& args); + } + + namespace Contact + { + const std::string& email(); + void perform_and_exit(const VcpkgCmdArguments& args); + } + + namespace Hash + { + void perform_and_exit(const VcpkgCmdArguments& args); + } + + template + struct PackageNameAndFunction + { + std::string name; + T function; + }; + + Span> get_available_commands_type_a(); + Span> get_available_commands_type_b(); + Span> get_available_commands_type_c(); + + template + T find(const std::string& command_name, const std::vector> available_commands) + { + for (const PackageNameAndFunction& cmd : available_commands) + { + if (cmd.name == command_name) + { + return cmd.function; + } + } + + // not found + return nullptr; + } +} diff --git a/toolsrc/include/vcpkg/dependencies.h b/toolsrc/include/vcpkg/dependencies.h new file mode 100644 index 000000000..2301dbc36 --- /dev/null +++ b/toolsrc/include/vcpkg/dependencies.h @@ -0,0 +1,149 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include + +namespace vcpkg::Dependencies +{ + enum class RequestType + { + UNKNOWN, + USER_REQUESTED, + AUTO_SELECTED + }; + + std::string to_output_string(RequestType request_type, const CStringView s); + + struct AnyParagraph + { + std::vector dependencies(const Triplet& triplet) const; + + Optional status_paragraph; + Optional binary_control_file; + Optional source_paragraph; + Optional source_control_file; + }; +} + +namespace vcpkg::Dependencies +{ + enum class InstallPlanType + { + UNKNOWN, + BUILD_AND_INSTALL, + INSTALL, + ALREADY_INSTALLED + }; + + struct InstallPlanAction : Util::MoveOnlyBase + { + static bool compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right); + + InstallPlanAction(); + + InstallPlanAction(const PackageSpec& spec, + const std::unordered_set& features, + const RequestType& request_type); + InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); + InstallPlanAction(const PackageSpec& spec, + const SourceControlFile& any_paragraph, + const std::unordered_set& features, + const RequestType& request_type); + + std::string displayname() const; + + PackageSpec spec; + AnyParagraph any_paragraph; + InstallPlanType plan_type; + RequestType request_type; + std::unordered_set feature_list; + }; + + enum class RemovePlanType + { + UNKNOWN, + NOT_INSTALLED, + REMOVE + }; + + struct RemovePlanAction : Util::MoveOnlyBase + { + static bool compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right); + + RemovePlanAction(); + RemovePlanAction(const PackageSpec& spec, const RemovePlanType& plan_type, const RequestType& request_type); + + PackageSpec spec; + RemovePlanType plan_type; + RequestType request_type; + }; + + struct AnyAction + { + AnyAction(InstallPlanAction&& iplan) : install_plan(std::move(iplan)) {} + AnyAction(RemovePlanAction&& rplan) : remove_plan(std::move(rplan)) {} + + Optional install_plan; + Optional remove_plan; + + const PackageSpec& spec() const; + }; + + enum class ExportPlanType + { + UNKNOWN, + PORT_AVAILABLE_BUT_NOT_BUILT, + ALREADY_BUILT + }; + + struct ExportPlanAction : Util::MoveOnlyBase + { + static bool compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right); + + ExportPlanAction(); + ExportPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); + + PackageSpec spec; + AnyParagraph any_paragraph; + ExportPlanType plan_type; + RequestType request_type; + }; + + __interface PortFileProvider { virtual const SourceControlFile& get_control_file(const std::string& spec) const; }; + + struct MapPortFile : Util::ResourceBase, PortFileProvider + { + const std::unordered_map& ports; + explicit MapPortFile(const std::unordered_map& map); + const SourceControlFile& get_control_file(const std::string& spec) const override; + }; + + struct PathsPortFile : Util::ResourceBase, PortFileProvider + { + const VcpkgPaths& ports; + mutable std::unordered_map cache; + explicit PathsPortFile(const VcpkgPaths& paths); + const SourceControlFile& get_control_file(const std::string& spec) const override; + }; + + std::vector create_install_plan(const PortFileProvider& port_file_provider, + const std::vector& specs, + const StatusParagraphs& status_db); + + std::vector create_remove_plan(const std::vector& specs, + const StatusParagraphs& status_db); + + std::vector create_export_plan(const VcpkgPaths& paths, + const std::vector& specs, + const StatusParagraphs& status_db); + + std::vector create_feature_install_plan(const std::unordered_map& map, + const std::vector& specs, + const StatusParagraphs& status_db); +} diff --git a/toolsrc/include/vcpkg/export.h b/toolsrc/include/vcpkg/export.h new file mode 100644 index 000000000..f3285e187 --- /dev/null +++ b/toolsrc/include/vcpkg/export.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace vcpkg::Export +{ + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); + + void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths); +} diff --git a/toolsrc/include/vcpkg/export.ifw.h b/toolsrc/include/vcpkg/export.ifw.h new file mode 100644 index 000000000..d28a4436d --- /dev/null +++ b/toolsrc/include/vcpkg/export.ifw.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include + +#include + +#include +#include + +namespace vcpkg::Export::IFW +{ + struct Options + { + Optional maybe_repository_url; + Optional maybe_packages_dir_path; + Optional maybe_repository_dir_path; + Optional maybe_config_file_path; + Optional maybe_installer_file_path; + }; + + void do_export(const std::vector& export_plan, + const std::string& export_id, + const Options& ifw_options, + const VcpkgPaths& paths); +} diff --git a/toolsrc/include/vcpkg/globalstate.h b/toolsrc/include/vcpkg/globalstate.h new file mode 100644 index 000000000..7cea361cf --- /dev/null +++ b/toolsrc/include/vcpkg/globalstate.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +#include + +namespace vcpkg +{ + struct GlobalState + { + static Util::LockGuarded timer; + static std::atomic debugging; + static std::atomic feature_packages; + + static std::atomic g_init_console_cp; + static std::atomic g_init_console_output_cp; + }; +} \ No newline at end of file diff --git a/toolsrc/include/vcpkg/help.h b/toolsrc/include/vcpkg/help.h new file mode 100644 index 000000000..39ad6912d --- /dev/null +++ b/toolsrc/include/vcpkg/help.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include + +#include + +namespace vcpkg::Help +{ + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + + void help_topic_valid_triplet(const VcpkgPaths& paths); + + void print_usage(); + + void print_example(const std::string& command_and_arguments); + + std::string create_example_string(const std::string& command_and_arguments); +} diff --git a/toolsrc/include/vcpkg/input.h b/toolsrc/include/vcpkg/input.h new file mode 100644 index 000000000..621139427 --- /dev/null +++ b/toolsrc/include/vcpkg/input.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace vcpkg::Input +{ + PackageSpec check_and_get_package_spec(const std::string& package_spec_as_string, + const Triplet& default_triplet, + CStringView example_text); + FullPackageSpec check_and_get_full_package_spec(const std::string& full_package_spec_as_string, + const Triplet& default_triplet, + CStringView example_text); + + void check_triplet(const Triplet& t, const VcpkgPaths& paths); +} diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h new file mode 100644 index 000000000..02600b7f5 --- /dev/null +++ b/toolsrc/include/vcpkg/install.h @@ -0,0 +1,69 @@ +#pragma once + +#include +#include +#include +#include + +#include + +namespace vcpkg::Install +{ + enum class KeepGoing + { + NO = 0, + YES + }; + + inline KeepGoing to_keep_going(const bool value) { return value ? KeepGoing::YES : KeepGoing::NO; } + + enum class PrintSummary + { + NO = 0, + YES + }; + + inline PrintSummary to_print_summary(const bool value) { return value ? PrintSummary::YES : PrintSummary::NO; } + + struct InstallDir + { + static InstallDir from_destination_root(const fs::path& destination_root, + const std::string& destination_subdirectory, + const fs::path& listfile); + + private: + fs::path m_destination; + std::string m_destination_subdirectory; + fs::path m_listfile; + + public: + const fs::path& destination() const; + const std::string& destination_subdirectory() const; + const fs::path& listfile() const; + }; + + Build::BuildResult perform_install_plan_action(const VcpkgPaths& paths, + const Dependencies::InstallPlanAction& action, + const Build::BuildPackageOptions& install_plan_options, + StatusParagraphs& status_db); + + enum class InstallResult + { + FILE_CONFLICTS, + SUCCESS, + }; + + void install_files_and_write_listfile(Files::Filesystem& fs, const fs::path& source_dir, const InstallDir& dirs); + InstallResult install_package(const VcpkgPaths& paths, + const BinaryControlFile& binary_paragraph, + StatusParagraphs* status_db); + + void perform_and_exit_ex(const std::vector& action_plan, + const Build::BuildPackageOptions& install_plan_options, + const KeepGoing keep_going, + const PrintSummary print_summary, + const VcpkgPaths& paths, + StatusParagraphs& status_db); + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); +} diff --git a/toolsrc/include/vcpkg/metrics.h b/toolsrc/include/vcpkg/metrics.h new file mode 100644 index 000000000..41be5002d --- /dev/null +++ b/toolsrc/include/vcpkg/metrics.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include + +namespace vcpkg::Metrics +{ + struct Metrics : Util::ResourceBase + { + void set_send_metrics(bool should_send_metrics); + void set_print_metrics(bool should_print_metrics); + void set_user_information(const std::string& user_id, const std::string& first_use_time); + void init_user_information(std::string& user_id, std::string& first_use_time); + + void track_metric(const std::string& name, double value); + void track_property(const std::string& name, const std::string& value); + void track_property(const std::string& name, const std::wstring& value); + + void upload(const std::string& payload); + void flush(); + }; + + extern Util::LockGuarded g_metrics; + + std::wstring get_SQM_user(); + bool get_compiled_metrics_enabled(); +} diff --git a/toolsrc/include/vcpkg/packagespec.h b/toolsrc/include/vcpkg/packagespec.h new file mode 100644 index 000000000..ee34f14a3 --- /dev/null +++ b/toolsrc/include/vcpkg/packagespec.h @@ -0,0 +1,95 @@ +#pragma once + +#include +#include +#include + +namespace vcpkg +{ + struct ParsedSpecifier + { + std::string name; + std::vector features; + std::string triplet; + + static ExpectedT from_string(const std::string& input); + }; + + struct PackageSpec + { + static ExpectedT from_name_and_triplet(const std::string& name, + const Triplet& triplet); + + const std::string& name() const; + + const Triplet& triplet() const; + + std::string dir() const; + + std::string to_string() const; + + private: + std::string m_name; + Triplet m_triplet; + }; + + struct FeatureSpec + { + FeatureSpec(const PackageSpec& spec, const std::string& feature) : m_spec(spec), m_feature(feature) {} + + const std::string& name() const { return m_spec.name(); } + const std::string& feature() const { return m_feature; } + const Triplet& triplet() const { return m_spec.triplet(); } + + const PackageSpec& spec() const { return m_spec; } + + std::string to_string() const; + + static std::vector from_strings_and_triplet(const std::vector& depends, + const Triplet& t); + + private: + PackageSpec m_spec; + std::string m_feature; + }; + + struct FullPackageSpec + { + PackageSpec package_spec; + std::vector features; + + static std::vector to_feature_specs(const std::vector& specs); + + static ExpectedT from_string(const std::string& spec_as_string, + const Triplet& default_triplet); + }; + + struct Features + { + std::string name; + std::vector features; + + static ExpectedT from_string(const std::string& input); + }; + + bool operator==(const PackageSpec& left, const PackageSpec& right); + bool operator!=(const PackageSpec& left, const PackageSpec& right); +} + +template<> +struct std::hash +{ + size_t operator()(const vcpkg::PackageSpec& value) const + { + size_t hash = 17; + hash = hash * 31 + std::hash()(value.name()); + hash = hash * 31 + std::hash()(value.triplet()); + return hash; + } +}; + +template<> +struct std::equal_to +{ + bool operator()(const vcpkg::PackageSpec& left, const vcpkg::PackageSpec& right) const { return left == right; } +}; diff --git a/toolsrc/include/vcpkg/packagespecparseresult.h b/toolsrc/include/vcpkg/packagespecparseresult.h new file mode 100644 index 000000000..8a56574fd --- /dev/null +++ b/toolsrc/include/vcpkg/packagespecparseresult.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include + +namespace vcpkg +{ + enum class PackageSpecParseResult + { + SUCCESS = 0, + TOO_MANY_COLONS, + INVALID_CHARACTERS + }; + + CStringView to_string(PackageSpecParseResult ev) noexcept; + + template<> + struct ErrorHolder + { + ErrorHolder() : m_err(PackageSpecParseResult::SUCCESS) {} + ErrorHolder(PackageSpecParseResult err) : m_err(err) {} + + constexpr bool has_error() const { return m_err != PackageSpecParseResult::SUCCESS; } + + const PackageSpecParseResult& error() const { return m_err; } + PackageSpecParseResult& error() { return m_err; } + + CStringView to_string() const { return vcpkg::to_string(m_err); } + + private: + PackageSpecParseResult m_err; + }; +} diff --git a/toolsrc/include/vcpkg/paragraphparseresult.h b/toolsrc/include/vcpkg/paragraphparseresult.h new file mode 100644 index 000000000..abdd9eecd --- /dev/null +++ b/toolsrc/include/vcpkg/paragraphparseresult.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +namespace vcpkg +{ + enum class ParagraphParseResult + { + SUCCESS = 0, + EXPECTED_ONE_PARAGRAPH + }; + + struct ParagraphParseResultCategoryImpl final : std::error_category + { + virtual const char* name() const noexcept override; + + virtual std::string message(int ev) const noexcept override; + }; + + const std::error_category& paragraph_parse_result_category(); + + std::error_code make_error_code(ParagraphParseResult e); + + ParagraphParseResult to_paragraph_parse_result(int i); + + ParagraphParseResult to_paragraph_parse_result(std::error_code ec); +} + +// Enable implicit conversion to std::error_code +template<> +struct std::is_error_code_enum : ::std::true_type +{ +}; diff --git a/toolsrc/include/vcpkg/paragraphs.h b/toolsrc/include/vcpkg/paragraphs.h new file mode 100644 index 000000000..c8dbea646 --- /dev/null +++ b/toolsrc/include/vcpkg/paragraphs.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include +#include + +#include + +#include + +namespace vcpkg::Paragraphs +{ + using RawParagraph = Parse::RawParagraph; + + Expected get_single_paragraph(const Files::Filesystem& fs, const fs::path& control_path); + Expected> get_paragraphs(const Files::Filesystem& fs, const fs::path& control_path); + Expected parse_single_paragraph(const std::string& str); + Expected> parse_paragraphs(const std::string& str); + + Parse::ParseExpected try_load_port(const Files::Filesystem& fs, const fs::path& control_path); + + Expected try_load_cached_control_package(const VcpkgPaths& paths, const PackageSpec& spec); + + struct LoadResults + { + std::vector> paragraphs; + std::vector> errors; + }; + + LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir); + + std::vector> load_all_ports(const Files::Filesystem& fs, + const fs::path& ports_dir); + + std::map load_all_port_names_and_versions(const Files::Filesystem& fs, + const fs::path& ports_dir); +} diff --git a/toolsrc/include/vcpkg/parse.h b/toolsrc/include/vcpkg/parse.h new file mode 100644 index 000000000..4b33e302e --- /dev/null +++ b/toolsrc/include/vcpkg/parse.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include + +#include +#include + +namespace vcpkg::Parse +{ + struct ParseControlErrorInfo + { + std::string name; + std::vector missing_fields; + std::vector extra_fields; + std::error_code error; + }; + + template + using ParseExpected = ExpectedT, std::unique_ptr>; + + using RawParagraph = std::unordered_map; + + struct ParagraphParser + { + ParagraphParser(RawParagraph&& fields) : fields(std::move(fields)) {} + + void required_field(const std::string& fieldname, std::string& out); + std::string optional_field(const std::string& fieldname) const; + std::unique_ptr error_info(const std::string& name) const; + + private: + RawParagraph&& fields; + std::vector missing_fields; + }; + + std::vector parse_comma_list(const std::string& str); +} diff --git a/toolsrc/include/vcpkg/postbuildlint.buildtype.h b/toolsrc/include/vcpkg/postbuildlint.buildtype.h new file mode 100644 index 000000000..ff651fd7a --- /dev/null +++ b/toolsrc/include/vcpkg/postbuildlint.buildtype.h @@ -0,0 +1,68 @@ +#pragma once + +#include +#include + +#include +#include + +namespace vcpkg::PostBuildLint +{ + enum class ConfigurationType + { + DEBUG, + RELEASE, + }; + + struct BuildType + { + enum class BackingEnum + { + DEBUG_STATIC = 1, + DEBUG_DYNAMIC, + RELEASE_STATIC, + RELEASE_DYNAMIC + }; + + static BuildType value_of(const ConfigurationType& config, const Build::LinkageType& linkage); + + BuildType() = delete; + + constexpr BuildType(const BackingEnum backing_enum, + const ConfigurationType config, + const Build::LinkageType linkage) + : backing_enum(backing_enum), m_config(config), m_linkage(linkage) + { + } + + constexpr operator BackingEnum() const { return backing_enum; } + + const ConfigurationType& config() const; + const Build::LinkageType& linkage() const; + const std::regex& crt_regex() const; + const std::string& to_string() const; + + private: + BackingEnum backing_enum; + ConfigurationType m_config; + Build::LinkageType m_linkage; + }; + + namespace BuildTypeC + { + using Build::LinkageType; + using BE = BuildType::BackingEnum; + + static constexpr CStringView ENUM_NAME = "vcpkg::PostBuildLint::BuildType"; + + static constexpr BuildType DEBUG_STATIC = {BE::DEBUG_STATIC, ConfigurationType::DEBUG, LinkageType::STATIC}; + static constexpr BuildType DEBUG_DYNAMIC = {BE::DEBUG_DYNAMIC, ConfigurationType::DEBUG, LinkageType::DYNAMIC}; + static constexpr BuildType RELEASE_STATIC = { + BE::RELEASE_STATIC, ConfigurationType::RELEASE, LinkageType::STATIC}; + static constexpr BuildType RELEASE_DYNAMIC = { + BE::RELEASE_DYNAMIC, ConfigurationType::RELEASE, LinkageType::DYNAMIC}; + + static constexpr std::array VALUES = { + DEBUG_STATIC, DEBUG_DYNAMIC, RELEASE_STATIC, RELEASE_DYNAMIC}; + } +} diff --git a/toolsrc/include/vcpkg/postbuildlint.h b/toolsrc/include/vcpkg/postbuildlint.h new file mode 100644 index 000000000..5dcfeb8df --- /dev/null +++ b/toolsrc/include/vcpkg/postbuildlint.h @@ -0,0 +1,13 @@ +#pragma once + +#include +#include +#include + +namespace vcpkg::PostBuildLint +{ + size_t perform_all_checks(const PackageSpec& spec, + const VcpkgPaths& paths, + const Build::PreBuildInfo& pre_build_info, + const Build::BuildInfo& build_info); +} diff --git a/toolsrc/include/vcpkg/remove.h b/toolsrc/include/vcpkg/remove.h new file mode 100644 index 000000000..f4d381ca3 --- /dev/null +++ b/toolsrc/include/vcpkg/remove.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include + +namespace vcpkg::Remove +{ + enum class Purge + { + NO = 0, + YES + }; + + inline Purge to_purge(const bool value) { return value ? Purge::YES : Purge::NO; } + + void perform_remove_plan_action(const VcpkgPaths& paths, + const Dependencies::RemovePlanAction& action, + const Purge purge, + StatusParagraphs& status_db); + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); + void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db); +} diff --git a/toolsrc/include/vcpkg/sourceparagraph.h b/toolsrc/include/vcpkg/sourceparagraph.h new file mode 100644 index 000000000..0a02e4cda --- /dev/null +++ b/toolsrc/include/vcpkg/sourceparagraph.h @@ -0,0 +1,97 @@ +#pragma once + +#include +#include + +#include +#include +#include + +#include +#include + +namespace vcpkg +{ + struct Dependency + { + Features depend; + std::string qualifier; + + std::string name() const; + static Dependency parse_dependency(std::string name, std::string qualifier); + }; + + std::vector filter_dependencies(const std::vector& deps, const Triplet& t); + std::vector filter_dependencies_to_specs(const std::vector& deps, const Triplet& t); + + // zlib[uwp] becomes Dependency{"zlib", "uwp"} + std::vector expand_qualified_dependencies(const std::vector& depends); + + std::string to_string(const Dependency& dep); + + struct FeatureParagraph + { + std::string name; + std::string description; + std::vector depends; + }; + + /// + /// Port metadata (CONTROL file) + /// + struct SourceParagraph + { + std::string name; + std::string version; + std::string description; + std::string maintainer; + std::vector supports; + std::vector depends; + std::vector default_features; + }; + struct SourceControlFile + { + static Parse::ParseExpected parse_control_file( + std::vector&& control_paragraphs); + + std::unique_ptr core_paragraph; + std::vector> feature_paragraphs; + }; + + void print_error_message(Span> error_info_list); + inline void print_error_message(const std::unique_ptr& error_info_list) + { + return print_error_message({&error_info_list, 1}); + } + + struct Supports + { + static ExpectedT> parse(const std::vector& strs); + + using Architecture = System::CPUArchitecture; + + enum class Platform + { + WINDOWS, + UWP, + }; + enum class Linkage + { + DYNAMIC, + STATIC, + }; + enum class ToolsetVersion + { + V140, + V141, + }; + + bool is_supported(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools); + + private: + std::vector architectures; + std::vector platforms; + std::vector crt_linkages; + std::vector toolsets; + }; +} diff --git a/toolsrc/include/vcpkg/statusparagraph.h b/toolsrc/include/vcpkg/statusparagraph.h new file mode 100644 index 000000000..ca84b1bb7 --- /dev/null +++ b/toolsrc/include/vcpkg/statusparagraph.h @@ -0,0 +1,45 @@ +#pragma once + +#include + +#include + +namespace vcpkg +{ + enum class InstallState + { + ERROR_STATE, + NOT_INSTALLED, + HALF_INSTALLED, + INSTALLED, + }; + + enum class Want + { + ERROR_STATE, + UNKNOWN, + INSTALL, + HOLD, + DEINSTALL, + PURGE + }; + + /// + /// Installed package metadata + /// + struct StatusParagraph + { + StatusParagraph(); + explicit StatusParagraph(std::unordered_map&& fields); + + BinaryParagraph package; + Want want; + InstallState state; + }; + + void serialize(const StatusParagraph& pgh, std::string& out_str); + + std::string to_string(InstallState f); + + std::string to_string(Want f); +} diff --git a/toolsrc/include/vcpkg/statusparagraphs.h b/toolsrc/include/vcpkg/statusparagraphs.h new file mode 100644 index 000000000..c2f3b7b8e --- /dev/null +++ b/toolsrc/include/vcpkg/statusparagraphs.h @@ -0,0 +1,47 @@ +#pragma once +#include + +#include +#include + +namespace vcpkg +{ + struct StatusParagraphs + { + StatusParagraphs(); + explicit StatusParagraphs(std::vector>&& ps); + + using container = std::vector>; + using iterator = container::reverse_iterator; + using const_iterator = container::const_reverse_iterator; + + const_iterator find(const PackageSpec& spec) const { return find(spec.name(), spec.triplet()); } + const_iterator find(const std::string& name, const Triplet& triplet) const; + iterator find(const std::string& name, const Triplet& triplet); + std::vector*> find_all(const std::string& name, const Triplet& triplet); + iterator find(const std::string& name, const Triplet& triplet, const std::string& feature); + + const_iterator find_installed(const PackageSpec& spec) const + { + return find_installed(spec.name(), spec.triplet()); + } + const_iterator find_installed(const std::string& name, const Triplet& triplet) const; + + iterator insert(std::unique_ptr); + + friend void serialize(const StatusParagraphs& pgh, std::string& out_str); + + iterator end() { return paragraphs.rend(); } + + const_iterator end() const { return paragraphs.rend(); } + + iterator begin() { return paragraphs.rbegin(); } + + const_iterator begin() const { return paragraphs.rbegin(); } + + private: + std::vector> paragraphs; + }; + + void serialize(const StatusParagraphs& pgh, std::string& out_str); +} diff --git a/toolsrc/include/vcpkg/triplet.h b/toolsrc/include/vcpkg/triplet.h new file mode 100644 index 000000000..46a52f8e6 --- /dev/null +++ b/toolsrc/include/vcpkg/triplet.h @@ -0,0 +1,43 @@ +#pragma once + +#include + +namespace vcpkg +{ + struct TripletInstance; + + struct Triplet + { + public: + constexpr Triplet() : m_instance(&DEFAULT_INSTANCE) {} + + static Triplet from_canonical_name(const std::string& triplet_as_string); + + static const Triplet X86_WINDOWS; + static const Triplet X64_WINDOWS; + static const Triplet X86_UWP; + static const Triplet X64_UWP; + static const Triplet ARM_UWP; + + const std::string& canonical_name() const; + const std::string& to_string() const; + size_t hash_code() const; + + bool operator==(const Triplet& other) const; + + private: + static const TripletInstance DEFAULT_INSTANCE; + + constexpr Triplet(const TripletInstance* ptr) : m_instance(ptr) {} + + const TripletInstance* m_instance; + }; + + bool operator!=(const Triplet& left, const Triplet& right); +} + +template<> +struct std::hash +{ + size_t operator()(const vcpkg::Triplet& t) const { return t.hash_code(); } +}; diff --git a/toolsrc/include/vcpkg/update.h b/toolsrc/include/vcpkg/update.h new file mode 100644 index 000000000..e7303d1b0 --- /dev/null +++ b/toolsrc/include/vcpkg/update.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace vcpkg::Update +{ + struct OutdatedPackage + { + static bool compare_by_name(const OutdatedPackage& left, const OutdatedPackage& right); + + PackageSpec spec; + VersionDiff version_diff; + }; + + std::vector find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db); + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); +} \ No newline at end of file diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h new file mode 100644 index 000000000..6c47b98f6 --- /dev/null +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -0,0 +1,50 @@ +#pragma once + +#include + +#include +#include +#include +#include + +namespace vcpkg +{ + struct ParsedArguments + { + std::unordered_set switches; + std::unordered_map settings; + }; + + struct VcpkgCmdArguments + { + static VcpkgCmdArguments create_from_command_line(const int argc, const wchar_t* const* const argv); + static VcpkgCmdArguments create_from_arg_sequence(const std::string* arg_begin, const std::string* arg_end); + + std::unique_ptr vcpkg_root_dir; + std::unique_ptr triplet; + Optional debug = nullopt; + Optional sendmetrics = nullopt; + Optional printmetrics = nullopt; + + std::string command; + std::vector command_arguments; + std::unordered_set check_and_get_optional_command_arguments( + const std::vector& valid_options) const + { + return std::move(check_and_get_optional_command_arguments(valid_options, {}).switches); + } + + ParsedArguments check_and_get_optional_command_arguments(const std::vector& valid_switches, + const std::vector& valid_settings) const; + + void check_max_arg_count(const size_t expected_arg_count) const; + void check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const; + void check_min_arg_count(const size_t expected_arg_count) const; + void check_min_arg_count(const size_t expected_arg_count, const std::string& example_text) const; + void check_exact_arg_count(const size_t expected_arg_count) const; + void check_exact_arg_count(const size_t expected_arg_count, const std::string& example_text) const; + + private: + std::unordered_map> optional_command_arguments; + }; +} diff --git a/toolsrc/include/vcpkg/vcpkglib.h b/toolsrc/include/vcpkg/vcpkglib.h new file mode 100644 index 000000000..b2aad8d7b --- /dev/null +++ b/toolsrc/include/vcpkg/vcpkglib.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include + +namespace vcpkg +{ + StatusParagraphs database_load_check(const VcpkgPaths& paths); + + void write_update(const VcpkgPaths& paths, const StatusParagraph& p); + + struct StatusParagraphAndAssociatedFiles + { + StatusParagraph pgh; + SortedVector files; + }; + + std::vector get_installed_ports(const StatusParagraphs& status_db); + std::vector get_installed_files(const VcpkgPaths& paths, + const StatusParagraphs& status_db); + + struct CMakeVariable + { + CMakeVariable(const CWStringView varname, const wchar_t* varvalue); + CMakeVariable(const CWStringView varname, const std::string& varvalue); + CMakeVariable(const CWStringView varname, const std::wstring& varvalue); + CMakeVariable(const CWStringView varname, const fs::path& path); + + std::wstring s; + }; + + std::wstring make_cmake_cmd(const fs::path& cmake_exe, + const fs::path& cmake_script, + const std::vector& pass_variables); + + std::string shorten_text(const std::string& desc, size_t length); +} // namespace vcpkg diff --git a/toolsrc/include/vcpkg/vcpkgpaths.h b/toolsrc/include/vcpkg/vcpkgpaths.h new file mode 100644 index 000000000..df4adfd83 --- /dev/null +++ b/toolsrc/include/vcpkg/vcpkgpaths.h @@ -0,0 +1,85 @@ +#pragma once + +#include +#include + +#include +#include +#include + +namespace vcpkg +{ + struct ToolsetArchOption + { + CWStringView name; + System::CPUArchitecture host_arch; + System::CPUArchitecture target_arch; + }; + + struct Toolset + { + fs::path visual_studio_root_path; + fs::path dumpbin; + fs::path vcvarsall; + std::vector vcvarsall_options; + CWStringView version; + std::vector supported_architectures; + }; + + struct VcpkgPaths + { + static Expected create(const fs::path& vcpkg_root_dir); + + fs::path package_dir(const PackageSpec& spec) const; + fs::path port_dir(const PackageSpec& spec) const; + fs::path port_dir(const std::string& name) const; + fs::path build_info_file_path(const PackageSpec& spec) const; + fs::path listfile_path(const BinaryParagraph& pgh) const; + + bool is_valid_triplet(const Triplet& t) const; + + fs::path root; + fs::path packages; + fs::path buildtrees; + fs::path downloads; + fs::path ports; + fs::path installed; + fs::path triplets; + fs::path scripts; + + fs::path buildsystems; + fs::path buildsystems_msbuild_targets; + + fs::path vcpkg_dir; + fs::path vcpkg_dir_status_file; + fs::path vcpkg_dir_info; + fs::path vcpkg_dir_updates; + + fs::path ports_cmake; + + const fs::path& get_cmake_exe() const; + const fs::path& get_git_exe() const; + const fs::path& get_nuget_exe() const; + const fs::path& get_ifw_installerbase_exe() const; + const fs::path& get_ifw_binarycreator_exe() const; + const fs::path& get_ifw_repogen_exe() const; + + /// Retrieve a toolset matching a VS version + /// + /// Valid version strings are "v140", "v141", and "". Empty string gets the latest. + /// + const Toolset& VcpkgPaths::get_toolset(const Optional& toolset_version, + const Optional& visual_studio_path) const; + + Files::Filesystem& get_filesystem() const; + + private: + Lazy cmake_exe; + Lazy git_exe; + Lazy nuget_exe; + Lazy ifw_installerbase_exe; + Lazy ifw_binarycreator_exe; + Lazy ifw_repogen_exe; + Lazy> toolsets; + }; +} diff --git a/toolsrc/include/vcpkg/versiont.h b/toolsrc/include/vcpkg/versiont.h new file mode 100644 index 000000000..67efd8da3 --- /dev/null +++ b/toolsrc/include/vcpkg/versiont.h @@ -0,0 +1,29 @@ +#pragma once +#include + +namespace vcpkg +{ + struct VersionT + { + VersionT(); + VersionT(const std::string& value); + + std::string to_string() const; + + std::string value; + }; + + bool operator==(const VersionT& left, const VersionT& right); + bool operator!=(const VersionT& left, const VersionT& right); + + struct VersionDiff + { + VersionT left; + VersionT right; + + VersionDiff(); + VersionDiff(const VersionT& left, const VersionT& right); + + std::string to_string() const; + }; +} diff --git a/toolsrc/include/vcpkg_Build.h b/toolsrc/include/vcpkg_Build.h deleted file mode 100644 index 5ba675757..000000000 --- a/toolsrc/include/vcpkg_Build.h +++ /dev/null @@ -1,192 +0,0 @@ -#pragma once - -#include "CStringView.h" -#include "PackageSpec.h" -#include "StatusParagraphs.h" -#include "VcpkgPaths.h" -#include "vcpkg_Files.h" -#include "vcpkg_optional.h" - -#include -#include -#include - -namespace vcpkg::Build -{ - enum class UseHeadVersion - { - NO = 0, - YES - }; - - inline UseHeadVersion to_use_head_version(const bool value) - { - return value ? UseHeadVersion::YES : UseHeadVersion::NO; - } - - inline bool to_bool(const UseHeadVersion value) { return value == UseHeadVersion::YES; } - - enum class AllowDownloads - { - NO = 0, - YES - }; - - inline AllowDownloads to_allow_downloads(const bool value) - { - return value ? AllowDownloads::YES : AllowDownloads::NO; - } - - inline bool to_bool(const AllowDownloads value) { return value == AllowDownloads::YES; } - - struct BuildPackageOptions - { - UseHeadVersion use_head_version; - AllowDownloads allow_downloads; - }; - - enum class BuildResult - { - NULLVALUE = 0, - SUCCEEDED, - BUILD_FAILED, - POST_BUILD_CHECKS_FAILED, - FILE_CONFLICTS, - CASCADED_DUE_TO_MISSING_DEPENDENCIES - }; - - static constexpr std::array BUILD_RESULT_VALUES = { - BuildResult::SUCCEEDED, - BuildResult::BUILD_FAILED, - BuildResult::POST_BUILD_CHECKS_FAILED, - BuildResult::FILE_CONFLICTS, - BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES}; - - const std::string& to_string(const BuildResult build_result); - std::string create_error_message(const BuildResult build_result, const PackageSpec& spec); - std::string create_user_troubleshooting_message(const PackageSpec& spec); - - /// - /// Settings from the triplet file which impact the build environment and post-build checks - /// - struct PreBuildInfo - { - /// - /// Runs the triplet file in a "capture" mode to create a PreBuildInfo - /// - static PreBuildInfo from_triplet_file(const VcpkgPaths& paths, const Triplet& triplet); - - std::string target_architecture; - std::string cmake_system_name; - std::string cmake_system_version; - Optional platform_toolset; - Optional visual_studio_path; - }; - - std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset); - - struct ExtendedBuildResult - { - BuildResult code; - std::vector unmet_dependencies; - }; - - struct BuildPackageConfig - { - BuildPackageConfig(const SourceParagraph& src, - const Triplet& triplet, - fs::path&& port_dir, - const BuildPackageOptions& build_package_options) - : src(src) - , scf(nullptr) - , triplet(triplet) - , port_dir(std::move(port_dir)) - , build_package_options(build_package_options) - , feature_list(nullptr) - { - } - - BuildPackageConfig(const SourceControlFile& src, - const Triplet& triplet, - fs::path&& port_dir, - const BuildPackageOptions& build_package_options, - const std::unordered_set& feature_list) - : src(*src.core_paragraph) - , scf(&src) - , triplet(triplet) - , port_dir(std::move(port_dir)) - , build_package_options(build_package_options) - , feature_list(&feature_list) - { - } - - const SourceParagraph& src; - const SourceControlFile* scf; - const Triplet& triplet; - fs::path port_dir; - const BuildPackageOptions& build_package_options; - const std::unordered_set* feature_list; - }; - - ExtendedBuildResult build_package(const VcpkgPaths& paths, - const BuildPackageConfig& config, - const StatusParagraphs& status_db); - - enum class BuildPolicy - { - EMPTY_PACKAGE, - DLLS_WITHOUT_LIBS, - ONLY_RELEASE_CRT, - EMPTY_INCLUDE_FOLDER, - ALLOW_OBSOLETE_MSVCRT, - // Must be last - COUNT, - }; - - constexpr std::array G_ALL_POLICIES = { - BuildPolicy::EMPTY_PACKAGE, - BuildPolicy::DLLS_WITHOUT_LIBS, - BuildPolicy::ONLY_RELEASE_CRT, - BuildPolicy::EMPTY_INCLUDE_FOLDER, - BuildPolicy::ALLOW_OBSOLETE_MSVCRT, - }; - - const std::string& to_string(BuildPolicy policy); - CStringView to_cmake_variable(BuildPolicy policy); - - struct BuildPolicies - { - BuildPolicies() = default; - BuildPolicies(std::map&& map) : m_policies(std::move(map)) {} - - bool is_enabled(BuildPolicy policy) const - { - const auto it = m_policies.find(policy); - if (it != m_policies.cend()) return it->second; - return false; - } - - private: - std::map m_policies; - }; - - enum class LinkageType : char - { - DYNAMIC, - STATIC, - }; - - Optional to_linkage_type(const std::string& str); - - struct BuildInfo - { - LinkageType crt_linkage; - LinkageType library_linkage; - - Optional version; - - BuildPolicies policies; - }; - - BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath); -} diff --git a/toolsrc/include/vcpkg_Checks.h b/toolsrc/include/vcpkg_Checks.h deleted file mode 100644 index ce486ac19..000000000 --- a/toolsrc/include/vcpkg_Checks.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "LineInfo.h" -#include "vcpkg_Strings.h" - -namespace vcpkg::Checks -{ - void register_console_ctrl_handler(); - - // Indicate that an internal error has occurred and exit the tool. This should be used when invariants have been - // broken. - [[noreturn]] void unreachable(const LineInfo& line_info); - - [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code); - - // Exit the tool without an error message. - [[noreturn]] inline void exit_fail(const LineInfo& line_info) { exit_with_code(line_info, EXIT_FAILURE); } - - // Exit the tool successfully. - [[noreturn]] inline void exit_success(const LineInfo& line_info) { exit_with_code(line_info, EXIT_SUCCESS); } - - // Display an error message to the user and exit the tool. - [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message); - - template - // Display an error message to the user and exit the tool. - [[noreturn]] void exit_with_message(const LineInfo& line_info, - const char* error_message_template, - const Arg1 error_message_arg1, - const Args&... error_message_args) - { - exit_with_message(line_info, - Strings::format(error_message_template, error_message_arg1, error_message_args...)); - } - - void check_exit(const LineInfo& line_info, bool expression); - - void check_exit(const LineInfo& line_info, bool expression, const CStringView error_message); - - template - void check_exit(const LineInfo& line_info, - Conditional&& expression, - const char* error_message_template, - const Arg1 error_message_arg1, - const Args&... error_message_args) - { - if (!expression) - { - // Only create the string if the expression is false - exit_with_message(line_info, - Strings::format(error_message_template, error_message_arg1, error_message_args...)); - } - } -} diff --git a/toolsrc/include/vcpkg_Chrono.h b/toolsrc/include/vcpkg_Chrono.h deleted file mode 100644 index c14019ff9..000000000 --- a/toolsrc/include/vcpkg_Chrono.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include - -namespace vcpkg -{ - class ElapsedTime - { - public: - static ElapsedTime create_started(); - - constexpr ElapsedTime() : m_start_tick() {} - - template - TimeUnit elapsed() const - { - return std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - this->m_start_tick); - } - - double microseconds() const { return elapsed>().count(); } - - std::string to_string() const; - - private: - std::chrono::high_resolution_clock::time_point m_start_tick; - }; -} diff --git a/toolsrc/include/vcpkg_Commands.h b/toolsrc/include/vcpkg_Commands.h deleted file mode 100644 index 7cfa2760e..000000000 --- a/toolsrc/include/vcpkg_Commands.h +++ /dev/null @@ -1,258 +0,0 @@ -#pragma once - -#include "StatusParagraphs.h" -#include "VcpkgCmdArguments.h" -#include "VcpkgPaths.h" -#include "VersionT.h" -#include "vcpkg_Build.h" -#include "vcpkg_Dependencies.h" -#include - -namespace vcpkg::Commands -{ - using CommandTypeA = void (*)(const VcpkgCmdArguments& args, - const VcpkgPaths& paths, - const Triplet& default_triplet); - using CommandTypeB = void (*)(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - using CommandTypeC = void (*)(const VcpkgCmdArguments& args); - - namespace BuildCommand - { - void perform_and_exit(const FullPackageSpec& full_spec, - const fs::path& port_dir, - const std::unordered_set& options, - const VcpkgPaths& paths); - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - } - - namespace BuildExternal - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - } - - namespace Install - { - enum class KeepGoing - { - NO = 0, - YES - }; - - inline KeepGoing to_keep_going(const bool value) { return value ? KeepGoing::YES : KeepGoing::NO; } - - enum class PrintSummary - { - NO = 0, - YES - }; - - inline PrintSummary to_print_summary(const bool value) { return value ? PrintSummary::YES : PrintSummary::NO; } - - struct InstallDir - { - static InstallDir from_destination_root(const fs::path& destination_root, - const std::string& destination_subdirectory, - const fs::path& listfile); - - private: - fs::path m_destination; - std::string m_destination_subdirectory; - fs::path m_listfile; - - public: - const fs::path& destination() const; - const std::string& destination_subdirectory() const; - const fs::path& listfile() const; - }; - - Build::BuildResult perform_install_plan_action(const VcpkgPaths& paths, - const Dependencies::InstallPlanAction& action, - const Build::BuildPackageOptions& install_plan_options, - StatusParagraphs& status_db); - - enum class InstallResult - { - FILE_CONFLICTS, - SUCCESS, - }; - - void install_files_and_write_listfile(Files::Filesystem& fs, - const fs::path& source_dir, - const InstallDir& dirs); - InstallResult install_package(const VcpkgPaths& paths, - const BinaryControlFile& binary_paragraph, - StatusParagraphs* status_db); - - void perform_and_exit(const std::vector& action_plan, - const Build::BuildPackageOptions& install_plan_options, - const KeepGoing keep_going, - const PrintSummary print_summary, - const VcpkgPaths& paths, - StatusParagraphs& status_db); - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - } - - namespace Export - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - } - - namespace CI - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - } - - namespace Remove - { - enum class Purge - { - NO = 0, - YES - }; - - inline Purge to_purge(const bool value) { return value ? Purge::YES : Purge::NO; } - - void perform_remove_plan_action(const VcpkgPaths& paths, - const Dependencies::RemovePlanAction& action, - const Purge purge, - StatusParagraphs& status_db); - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db); - } - - namespace Update - { - struct OutdatedPackage - { - static bool compare_by_name(const OutdatedPackage& left, const OutdatedPackage& right); - - PackageSpec spec; - VersionDiff version_diff; - }; - - std::vector find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db); - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Env - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); - } - - namespace Create - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Edit - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace DependInfo - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Search - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace List - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Owns - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Cache - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Import - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Integrate - { - extern const char* const INTEGRATE_COMMAND_HELPSTRING; - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace PortsDiff - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Autocomplete - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - } - - namespace Help - { - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); - - void help_topic_valid_triplet(const VcpkgPaths& paths); - - void print_usage(); - - void print_example(const std::string& command_and_arguments); - - std::string create_example_string(const std::string& command_and_arguments); - } - - namespace Version - { - const std::string& version(); - void warn_if_vcpkg_version_mismatch(const VcpkgPaths& paths); - void perform_and_exit(const VcpkgCmdArguments& args); - } - - namespace Contact - { - const std::string& email(); - void perform_and_exit(const VcpkgCmdArguments& args); - } - - namespace Hash - { - void perform_and_exit(const VcpkgCmdArguments& args); - } - - template - struct PackageNameAndFunction - { - std::string name; - T function; - }; - - const std::vector>& get_available_commands_type_a(); - const std::vector>& get_available_commands_type_b(); - const std::vector>& get_available_commands_type_c(); - - template - T find(const std::string& command_name, const std::vector> available_commands) - { - for (const PackageNameAndFunction& cmd : available_commands) - { - if (cmd.name == command_name) - { - return cmd.function; - } - } - - // not found - return nullptr; - } -} diff --git a/toolsrc/include/vcpkg_Commands_Export.h b/toolsrc/include/vcpkg_Commands_Export.h deleted file mode 100644 index 6e698c1b4..000000000 --- a/toolsrc/include/vcpkg_Commands_Export.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "VcpkgPaths.h" - -namespace vcpkg::Commands::Export -{ - void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths); -} diff --git a/toolsrc/include/vcpkg_Commands_Export_IFW.h b/toolsrc/include/vcpkg_Commands_Export_IFW.h deleted file mode 100644 index 7bee45eaf..000000000 --- a/toolsrc/include/vcpkg_Commands_Export_IFW.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "VcpkgPaths.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Files.h" - -#include -#include - -namespace vcpkg::Commands::Export::IFW -{ - struct Options - { - Optional maybe_repository_url; - Optional maybe_packages_dir_path; - Optional maybe_repository_dir_path; - Optional maybe_config_file_path; - Optional maybe_installer_file_path; - }; - - void do_export(const std::vector& export_plan, - const std::string& export_id, - const Options& ifw_options, - const VcpkgPaths& paths); -} diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h deleted file mode 100644 index d67122e48..000000000 --- a/toolsrc/include/vcpkg_Dependencies.h +++ /dev/null @@ -1,147 +0,0 @@ -#pragma once -#include "PackageSpec.h" -#include "StatusParagraphs.h" -#include "VcpkgPaths.h" -#include "vcpkg_Graphs.h" -#include "vcpkg_Util.h" -#include "vcpkg_optional.h" -#include - -namespace vcpkg::Dependencies -{ - enum class RequestType - { - UNKNOWN, - USER_REQUESTED, - AUTO_SELECTED - }; - - std::string to_output_string(RequestType request_type, const CStringView s); - - struct AnyParagraph - { - std::vector dependencies(const Triplet& triplet) const; - - Optional status_paragraph; - Optional binary_control_file; - Optional source_paragraph; - Optional source_control_file; - }; -} - -namespace vcpkg::Dependencies -{ - enum class InstallPlanType - { - UNKNOWN, - BUILD_AND_INSTALL, - INSTALL, - ALREADY_INSTALLED - }; - - struct InstallPlanAction : Util::MoveOnlyBase - { - static bool compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right); - - InstallPlanAction(); - - InstallPlanAction(const PackageSpec& spec, - const std::unordered_set& features, - const RequestType& request_type); - InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); - InstallPlanAction(const PackageSpec& spec, - const SourceControlFile& any_paragraph, - const std::unordered_set& features, - const RequestType& request_type); - - std::string displayname() const; - - PackageSpec spec; - AnyParagraph any_paragraph; - InstallPlanType plan_type; - RequestType request_type; - std::unordered_set feature_list; - }; - - enum class RemovePlanType - { - UNKNOWN, - NOT_INSTALLED, - REMOVE - }; - - struct RemovePlanAction : Util::MoveOnlyBase - { - static bool compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right); - - RemovePlanAction(); - RemovePlanAction(const PackageSpec& spec, const RemovePlanType& plan_type, const RequestType& request_type); - - PackageSpec spec; - RemovePlanType plan_type; - RequestType request_type; - }; - - struct AnyAction - { - AnyAction(InstallPlanAction&& iplan) : install_plan(std::move(iplan)) {} - AnyAction(RemovePlanAction&& rplan) : remove_plan(std::move(rplan)) {} - - Optional install_plan; - Optional remove_plan; - - const PackageSpec& spec() const; - }; - - enum class ExportPlanType - { - UNKNOWN, - PORT_AVAILABLE_BUT_NOT_BUILT, - ALREADY_BUILT - }; - - struct ExportPlanAction : Util::MoveOnlyBase - { - static bool compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right); - - ExportPlanAction(); - ExportPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); - - PackageSpec spec; - AnyParagraph any_paragraph; - ExportPlanType plan_type; - RequestType request_type; - }; - - __interface PortFileProvider { virtual const SourceControlFile& get_control_file(const std::string& spec) const; }; - - struct MapPortFile : Util::ResourceBase, PortFileProvider - { - const std::unordered_map& ports; - explicit MapPortFile(const std::unordered_map& map); - const SourceControlFile& get_control_file(const std::string& spec) const override; - }; - - struct PathsPortFile : Util::ResourceBase, PortFileProvider - { - const VcpkgPaths& ports; - mutable std::unordered_map cache; - explicit PathsPortFile(const VcpkgPaths& paths); - const SourceControlFile& get_control_file(const std::string& spec) const override; - }; - - std::vector create_install_plan(const PortFileProvider& port_file_provider, - const std::vector& specs, - const StatusParagraphs& status_db); - - std::vector create_remove_plan(const std::vector& specs, - const StatusParagraphs& status_db); - - std::vector create_export_plan(const VcpkgPaths& paths, - const std::vector& specs, - const StatusParagraphs& status_db); - - std::vector create_feature_install_plan(const std::unordered_map& map, - const std::vector& specs, - const StatusParagraphs& status_db); -} diff --git a/toolsrc/include/vcpkg_Enums.h b/toolsrc/include/vcpkg_Enums.h deleted file mode 100644 index c75feaa1f..000000000 --- a/toolsrc/include/vcpkg_Enums.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "LineInfo.h" -#include - -namespace vcpkg::Enums -{ - std::string nullvalue_to_string(const CStringView enum_name); - - [[noreturn]] void nullvalue_used(const LineInfo& line_info, const CStringView enum_name); -} diff --git a/toolsrc/include/vcpkg_Files.h b/toolsrc/include/vcpkg_Files.h deleted file mode 100644 index 855e8ea45..000000000 --- a/toolsrc/include/vcpkg_Files.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include "filesystem_fs.h" -#include "vcpkg_expected.h" - -namespace vcpkg::Files -{ - __interface Filesystem - { - virtual Expected read_contents(const fs::path& file_path) const = 0; - virtual Expected> read_lines(const fs::path& file_path) const = 0; - virtual fs::path find_file_recursively_up(const fs::path& starting_dir, const std::string& filename) const = 0; - virtual std::vector get_files_recursive(const fs::path& dir) const = 0; - virtual std::vector get_files_non_recursive(const fs::path& dir) const = 0; - - virtual void write_lines(const fs::path& file_path, const std::vector& lines) = 0; - virtual void write_contents(const fs::path& file_path, const std::string& data) = 0; - virtual void rename(const fs::path& oldpath, const fs::path& newpath) = 0; - virtual bool remove(const fs::path& path) = 0; - virtual bool remove(const fs::path& path, std::error_code& ec) = 0; - virtual std::uintmax_t remove_all(const fs::path& path, std::error_code& ec) = 0; - virtual bool exists(const fs::path& path) const = 0; - virtual bool is_directory(const fs::path& path) const = 0; - virtual bool is_regular_file(const fs::path& path) const = 0; - virtual bool is_empty(const fs::path& path) const = 0; - virtual bool create_directory(const fs::path& path, std::error_code& ec) = 0; - virtual bool create_directories(const fs::path& path, std::error_code& ec) = 0; - virtual void copy(const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts) = 0; - virtual bool copy_file( - const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts, std::error_code& ec) = 0; - virtual fs::file_status status(const fs::path& path, std::error_code& ec) const = 0; - }; - - Filesystem& get_real_filesystem(); - - static const char* FILESYSTEM_INVALID_CHARACTERS = R"(\/:*?"<>|)"; - - bool has_invalid_chars_for_filesystem(const std::string& s); - - void print_paths(const std::vector& paths); - - std::vector find_from_PATH(const std::wstring& name); -} diff --git a/toolsrc/include/vcpkg_GlobalState.h b/toolsrc/include/vcpkg_GlobalState.h deleted file mode 100644 index 6522a25bf..000000000 --- a/toolsrc/include/vcpkg_GlobalState.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include - -#include "vcpkg_Chrono.h" -#include "vcpkg_Util.h" - -namespace vcpkg -{ - struct GlobalState - { - static Util::LockGuarded timer; - static std::atomic debugging; - static std::atomic feature_packages; - - static std::atomic g_init_console_cp; - static std::atomic g_init_console_output_cp; - }; -} \ No newline at end of file diff --git a/toolsrc/include/vcpkg_Graphs.h b/toolsrc/include/vcpkg_Graphs.h deleted file mode 100644 index 13c0a7136..000000000 --- a/toolsrc/include/vcpkg_Graphs.h +++ /dev/null @@ -1,159 +0,0 @@ -#pragma once - -#include -#include - -namespace vcpkg::Graphs -{ - enum class ExplorationStatus - { - // We have not visited this vertex - NOT_EXPLORED, - - // We have visited this vertex but haven't visited all vertices in its subtree - PARTIALLY_EXPLORED, - - // We have visited this vertex and all vertices in its subtree - FULLY_EXPLORED - }; - - template - __interface AdjacencyProvider - { - std::vector adjacency_list(const U& vertex) const; - - U load_vertex_data(const V& vertex) const; - }; - - template - static void topological_sort_internal(const V& vertex, - const AdjacencyProvider& f, - std::unordered_map& exploration_status, - std::vector& sorted) - { - ExplorationStatus& status = exploration_status[vertex]; - switch (status) - { - case ExplorationStatus::FULLY_EXPLORED: return; - case ExplorationStatus::PARTIALLY_EXPLORED: Checks::exit_with_message(VCPKG_LINE_INFO, "cycle in graph"); - case ExplorationStatus::NOT_EXPLORED: - { - status = ExplorationStatus::PARTIALLY_EXPLORED; - U vertex_data = f.load_vertex_data(vertex); - for (const V& neighbour : f.adjacency_list(vertex_data)) - topological_sort_internal(neighbour, f, exploration_status, sorted); - - sorted.push_back(std::move(vertex_data)); - status = ExplorationStatus::FULLY_EXPLORED; - return; - } - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - template - std::vector topological_sort(const std::vector& starting_vertices, const AdjacencyProvider& f) - { - std::vector sorted; - std::unordered_map exploration_status; - - for (auto& vertex : starting_vertices) - { - topological_sort_internal(vertex, f, exploration_status, sorted); - } - - return sorted; - } - - template - struct GraphAdjacencyProvider final : AdjacencyProvider - { - const std::unordered_map>& vertices; - - GraphAdjacencyProvider(const std::unordered_map>& vertices) : vertices(vertices) {} - - std::vector adjacency_list(const V& vertex) const override - { - const std::unordered_set& as_set = this->vertices.at(vertex); - return std::vector(as_set.cbegin(), as_set.cend()); // TODO: Avoid redundant copy - } - - V load_vertex_data(const V& vertex) const override { return vertex; } - }; - - template - struct Graph - { - public: - void add_vertex(V v) { this->vertices[v]; } - - // TODO: Change with iterators - void add_vertices(const std::vector& vs) - { - for (const V& v : vs) - { - this->vertices[v]; - } - } - - void add_edge(V u, V v) - { - this->vertices[v]; - this->vertices[u].insert(v); - } - - std::vector topological_sort() const - { - GraphAdjacencyProvider adjacency_provider{this->vertices}; - std::unordered_map indegrees = count_indegrees(); - - std::vector sorted; - sorted.reserve(indegrees.size()); - - std::unordered_map exploration_status; - exploration_status.reserve(indegrees.size()); - - for (auto& pair : indegrees) - { - if (pair.second == 0) // Starting from vertices with indegree == 0. Not required. - { - V vertex = pair.first; - topological_sort_internal(vertex, adjacency_provider, exploration_status, sorted); - } - } - - return sorted; - } - - std::unordered_map count_indegrees() const - { - std::unordered_map indegrees; - - for (auto& pair : this->vertices) - { - indegrees[pair.first]; - for (V neighbour : pair.second) - { - ++indegrees[neighbour]; - } - } - - return indegrees; - } - - const std::unordered_map>& adjacency_list() const { return this->vertices; } - std::vector vertex_list() const - { - // why no &? it returns 0 - std::vector vertex_list; - for (const auto& vertex : this->vertices) - { - vertex_list.emplace_back(vertex.first); - } - return vertex_list; - } - - private: - std::unordered_map> vertices; - }; -} diff --git a/toolsrc/include/vcpkg_Input.h b/toolsrc/include/vcpkg_Input.h deleted file mode 100644 index fa568207a..000000000 --- a/toolsrc/include/vcpkg_Input.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include "PackageSpec.h" - -namespace vcpkg::Input -{ - PackageSpec check_and_get_package_spec(const std::string& package_spec_as_string, - const Triplet& default_triplet, - CStringView example_text); - FullPackageSpec check_and_get_full_package_spec(const std::string& full_package_spec_as_string, - const Triplet& default_triplet, - CStringView example_text); - - void check_triplet(const Triplet& t, const VcpkgPaths& paths); -} diff --git a/toolsrc/include/vcpkg_Maps.h b/toolsrc/include/vcpkg_Maps.h deleted file mode 100644 index aadd81c2b..000000000 --- a/toolsrc/include/vcpkg_Maps.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace vcpkg::Maps -{ - template - std::vector extract_keys(const std::unordered_map& input_map) - { - std::vector key_set; - for (auto const& element : input_map) - { - key_set.push_back(element.first); - } - return key_set; - } - - template - std::vector extract_keys(const std::map& input_map) - { - std::vector key_set; - for (auto const& element : input_map) - { - key_set.push_back(element.first); - } - return key_set; - } -} diff --git a/toolsrc/include/vcpkg_Parse.h b/toolsrc/include/vcpkg_Parse.h deleted file mode 100644 index 2dda033b3..000000000 --- a/toolsrc/include/vcpkg_Parse.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include - -#include "vcpkg_expected.h" -#include "vcpkg_optional.h" - -namespace vcpkg::Parse -{ - struct ParseControlErrorInfo - { - std::string name; - std::vector missing_fields; - std::vector extra_fields; - std::error_code error; - }; - - template - using ParseExpected = ExpectedT, std::unique_ptr>; - - using RawParagraph = std::unordered_map; - - struct ParagraphParser - { - ParagraphParser(RawParagraph&& fields) : fields(std::move(fields)) {} - - void required_field(const std::string& fieldname, std::string& out); - std::string optional_field(const std::string& fieldname) const; - std::unique_ptr error_info(const std::string& name) const; - - private: - RawParagraph&& fields; - std::vector missing_fields; - }; - - std::vector parse_comma_list(const std::string& str); -} diff --git a/toolsrc/include/vcpkg_Strings.h b/toolsrc/include/vcpkg_Strings.h deleted file mode 100644 index c44ce2b99..000000000 --- a/toolsrc/include/vcpkg_Strings.h +++ /dev/null @@ -1,113 +0,0 @@ -#pragma once - -#include "CStringView.h" -#include - -namespace vcpkg::Strings::details -{ - template - auto to_printf_arg(const T& t) -> decltype(t.to_string()) - { - return t.to_string(); - } - - inline const char* to_printf_arg(const std::string& s) { return s.c_str(); } - - inline const char* to_printf_arg(const char* s) { return s; } - - inline int to_printf_arg(const int s) { return s; } - - inline long long to_printf_arg(const long long s) { return s; } - - inline unsigned long to_printf_arg(const unsigned long s) { return s; } - - inline size_t to_printf_arg(const size_t s) { return s; } - - inline double to_printf_arg(const double s) { return s; } - - std::string format_internal(const char* fmtstr, ...); - - inline const wchar_t* to_wprintf_arg(const std::wstring& s) { return s.c_str(); } - - inline const wchar_t* to_wprintf_arg(const wchar_t* s) { return s; } - - std::wstring wformat_internal(const wchar_t* fmtstr, ...); -} - -namespace vcpkg::Strings -{ - static constexpr const char* EMPTY = ""; - static constexpr const wchar_t* WEMPTY = L""; - - template - std::string format(const char* fmtstr, const Args&... args) - { - using vcpkg::Strings::details::to_printf_arg; - return details::format_internal(fmtstr, to_printf_arg(to_printf_arg(args))...); - } - - template - std::wstring wformat(const wchar_t* fmtstr, const Args&... args) - { - using vcpkg::Strings::details::to_wprintf_arg; - return details::wformat_internal(fmtstr, to_wprintf_arg(to_wprintf_arg(args))...); - } - - std::wstring to_utf16(const CStringView s); - - std::string to_utf8(const CWStringView w); - - std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern); - - bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern); - - int case_insensitive_ascii_compare(const CStringView left, const CStringView right); - - std::string ascii_to_lowercase(const std::string& input); - - bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern); - - template - std::basic_string join(const CharType* delimiter, const Container& v, Transformer transformer) - { - const auto begin = v.begin(); - const auto end = v.end(); - - if (begin == end) - { - return std::basic_string(); - } - - std::basic_string output; - output.append(transformer(*begin)); - for (auto it = std::next(begin); it != end; ++it) - { - output.append(delimiter); - output.append(transformer(*it)); - } - - return output; - } - template - std::basic_string join(const CharType* delimiter, const Container& v) - { - using Element = decltype(*v.begin()); - return join(delimiter, v, [](const Element& x) -> const Element& { return x; }); - } - - void trim(std::string* s); - - std::string trimmed(const std::string& s); - - void trim_all_and_remove_whitespace_strings(std::vector* strings); - - std::vector split(const std::string& s, const std::string& delimiter); - - template - std::string serialize(const T& t) - { - std::string ret; - serialize(t, ret); - return ret; - } -} diff --git a/toolsrc/include/vcpkg_System.h b/toolsrc/include/vcpkg_System.h deleted file mode 100644 index 65f80ae6d..000000000 --- a/toolsrc/include/vcpkg_System.h +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once - -#include "filesystem_fs.h" -#include "vcpkg_Strings.h" -#include "vcpkg_optional.h" -#include - -namespace vcpkg::System -{ - tm get_current_date_time(); - - fs::path get_exe_path_of_current_process(); - - struct ExitCodeAndOutput - { - int exit_code; - std::string output; - }; - - int cmd_execute_clean(const CWStringView cmd_line); - - int cmd_execute(const CWStringView cmd_line); - - ExitCodeAndOutput cmd_execute_and_capture_output(const CWStringView cmd_line); - - std::wstring create_powershell_script_cmd(const fs::path& script_path, const CWStringView args = Strings::WEMPTY); - - enum class Color - { - success = 10, - error = 12, - warning = 14, - }; - - void println(); - void print(const CStringView message); - void println(const CStringView message); - void print(const Color c, const CStringView message); - void println(const Color c, const CStringView message); - - template - void print(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) - { - return System::print(Strings::format(messageTemplate, messageArg1, messageArgs...)); - } - - template - void print(const Color c, const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) - { - return System::print(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); - } - - template - void println(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) - { - return System::println(Strings::format(messageTemplate, messageArg1, messageArgs...)); - } - - template - void println(const Color c, const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) - { - return System::println(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); - } - - Optional get_environment_variable(const CWStringView varname) noexcept; - - Optional get_registry_string(HKEY base, const CWStringView subkey, const CWStringView valuename); - - enum class CPUArchitecture - { - X86, - X64, - ARM, - ARM64, - }; - - Optional to_cpu_architecture(CStringView arch); - - CPUArchitecture get_host_processor(); - - std::vector get_supported_host_architectures(); - - const fs::path& get_program_files_32_bit(); - - const fs::path& get_program_files_platform_bitness(); -} - -namespace vcpkg::Debug -{ - void println(const CStringView message); - void println(const System::Color c, const CStringView message); - - template - void println(const char* messageTemplate, const Arg1& messageArg1, const Args&... messageArgs) - { - return Debug::println(Strings::format(messageTemplate, messageArg1, messageArgs...)); - } - - template - void println(const System::Color c, - const char* messageTemplate, - const Arg1& messageArg1, - const Args&... messageArgs) - { - return Debug::println(c, Strings::format(messageTemplate, messageArg1, messageArgs...)); - } -} diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h deleted file mode 100644 index facb7dd26..000000000 --- a/toolsrc/include/vcpkg_Util.h +++ /dev/null @@ -1,144 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace vcpkg::Util -{ - template - using FmapOut = decltype(std::declval()(*begin(std::declval()))); - - template> - std::vector fmap(Cont&& xs, Func&& f) - { - std::vector ret; - ret.reserve(xs.size()); - - for (auto&& x : xs) - ret.push_back(f(x)); - - return ret; - } - - template - using FmapFlattenOut = std::decay_t()(*begin(std::declval()))))>; - - template> - std::vector fmap_flatten(Cont&& xs, Func&& f) - { - std::vector ret; - - for (auto&& x : xs) - for (auto&& y : f(x)) - ret.push_back(std::move(y)); - - return ret; - } - - template - void stable_keep_if(Container& cont, Pred pred) - { - cont.erase(std::stable_partition(cont.begin(), cont.end(), pred), cont.end()); - } - - template - void unstable_keep_if(Container& cont, Pred pred) - { - cont.erase(std::partition(cont.begin(), cont.end(), pred), cont.end()); - } - - template - void erase_remove_if(Container& cont, Pred pred) - { - cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); - } - - template - auto find(const Container& cont, V&& v) - { - return std::find(cont.cbegin(), cont.cend(), v); - } - - template - auto find_if(const Container& cont, Pred pred) - { - return std::find_if(cont.cbegin(), cont.cend(), pred); - } - - template - using ElementT = std::remove_reference_t()))>; - - template> - std::vector element_pointers(Container&& cont) - { - return fmap(cont, [](auto&& x) { return &x; }); - } - - template - auto find_if_not(const Container& cont, Pred pred) - { - return std::find_if_not(cont.cbegin(), cont.cend(), pred); - } - - template - void group_by(const Container& cont, std::map>* output, Func f) - { - for (const V& element : cont) - { - K key = f(element); - (*output)[key].push_back(&element); - } - } - - struct MoveOnlyBase - { - MoveOnlyBase() = default; - MoveOnlyBase(const MoveOnlyBase&) = delete; - MoveOnlyBase(MoveOnlyBase&&) = default; - - MoveOnlyBase& operator=(const MoveOnlyBase&) = delete; - MoveOnlyBase& operator=(MoveOnlyBase&&) = default; - }; - - struct ResourceBase - { - ResourceBase() = default; - ResourceBase(const ResourceBase&) = delete; - ResourceBase(ResourceBase&&) = delete; - - ResourceBase& operator=(const ResourceBase&) = delete; - ResourceBase& operator=(ResourceBase&&) = delete; - }; - - template - struct LockGuardPtr; - - template - struct LockGuarded - { - friend struct LockGuardPtr; - - LockGuardPtr lock() { return *this; } - - private: - std::mutex m_mutex; - T m_t; - }; - - template - struct LockGuardPtr - { - T& operator*() { return m_ptr; } - T* operator->() { return &m_ptr; } - - T* get() { return &m_ptr; } - - LockGuardPtr(LockGuarded& sync) : m_lock(sync.m_mutex), m_ptr(sync.m_t) {} - - private: - std::unique_lock m_lock; - T& m_ptr; - }; -} \ No newline at end of file diff --git a/toolsrc/include/vcpkg_expected.h b/toolsrc/include/vcpkg_expected.h deleted file mode 100644 index 9637ec087..000000000 --- a/toolsrc/include/vcpkg_expected.h +++ /dev/null @@ -1,114 +0,0 @@ -#pragma once - -#include "vcpkg_Checks.h" -#include - -namespace vcpkg -{ - template - struct ErrorHolder - { - ErrorHolder() : m_is_error(false) {} - template - ErrorHolder(U&& err) : m_is_error(true), m_err(std::forward(err)) - { - } - - constexpr bool has_error() const { return m_is_error; } - - const Err& error() const { return m_err; } - Err& error() { return m_err; } - - CStringView to_string() const { return "value was error"; } - - private: - bool m_is_error; - Err m_err; - }; - - template<> - struct ErrorHolder - { - ErrorHolder() = default; - ErrorHolder(const std::error_code& err) : m_err(err) {} - - constexpr bool has_error() const { return bool(m_err); } - - const std::error_code& error() const { return m_err; } - std::error_code& error() { return m_err; } - - CStringView to_string() const { return "value was error"; } - - private: - std::error_code m_err; - }; - - template - class ExpectedT - { - public: - constexpr ExpectedT() = default; - - // Constructors are intentionally implicit - - ExpectedT(const S& s) : m_s(s) {} - ExpectedT(S&& s) : m_s(std::move(s)) {} - - ExpectedT(const T& t) : m_t(t) {} - ExpectedT(T&& t) : m_t(std::move(t)) {} - - ExpectedT(const ExpectedT&) = default; - ExpectedT(ExpectedT&&) = default; - ExpectedT& operator=(const ExpectedT&) = default; - ExpectedT& operator=(ExpectedT&&) = default; - - explicit constexpr operator bool() const noexcept { return !m_s.has_error(); } - constexpr bool has_value() const noexcept { return !m_s.has_error(); } - - T&& value_or_exit(const LineInfo& line_info) && - { - exit_if_error(line_info); - return std::move(this->m_t); - } - - const T& value_or_exit(const LineInfo& line_info) const & - { - exit_if_error(line_info); - return this->m_t; - } - - const S& error() const & { return this->m_s.error(); } - - S&& error() && { return std::move(this->m_s.error()); } - - const T* get() const - { - if (!this->has_value()) - { - return nullptr; - } - return &this->m_t; - } - - T* get() - { - if (!this->has_value()) - { - return nullptr; - } - return &this->m_t; - } - - private: - void exit_if_error(const LineInfo& line_info) const - { - Checks::check_exit(line_info, !m_s.has_error(), m_s.to_string()); - } - - ErrorHolder m_s; - T m_t; - }; - - template - using Expected = ExpectedT; -} diff --git a/toolsrc/include/vcpkg_optional.h b/toolsrc/include/vcpkg_optional.h deleted file mode 100644 index 31a2d3e88..000000000 --- a/toolsrc/include/vcpkg_optional.h +++ /dev/null @@ -1,98 +0,0 @@ -#pragma once -#include "vcpkg_Checks.h" - -namespace vcpkg -{ - struct NullOpt - { - explicit constexpr NullOpt(int) {} - }; - - const static constexpr NullOpt nullopt{0}; - - template - class Optional - { - public: - constexpr Optional() : m_is_present(false), m_t() {} - - // Constructors are intentionally implicit - constexpr Optional(NullOpt) : m_is_present(false), m_t() {} - - Optional(const T& t) : m_is_present(true), m_t(t) {} - - Optional(T&& t) : m_is_present(true), m_t(std::move(t)) {} - - T&& value_or_exit(const LineInfo& line_info) && - { - this->exit_if_null(line_info); - return std::move(this->m_t); - } - - const T& value_or_exit(const LineInfo& line_info) const & - { - this->exit_if_null(line_info); - return this->m_t; - } - - constexpr explicit operator bool() const { return this->m_is_present; } - - constexpr bool has_value() const { return m_is_present; } - - template - T value_or(U&& default_value) const & - { - return bool(*this) ? this->m_t : static_cast(std::forward(default_value)); - } - - template - T value_or(U&& default_value) && - { - return bool(*this) ? std::move(this->m_t) : static_cast(std::forward(default_value)); - } - - const T* get() const { return bool(*this) ? &this->m_t : nullptr; } - - T* get() { return bool(*this) ? &this->m_t : nullptr; } - - private: - void exit_if_null(const LineInfo& line_info) const - { - Checks::check_exit(line_info, this->m_is_present, "Value was null"); - } - - bool m_is_present; - T m_t; - }; - - template - Optional> make_optional(U&& u) - { - return Optional>(std::forward(u)); - } - - template - bool operator==(const Optional& o, const T& t) - { - if (auto p = o.get()) return *p == t; - return false; - } - template - bool operator==(const T& t, const Optional& o) - { - if (auto p = o.get()) return t == *p; - return false; - } - template - bool operator!=(const Optional& o, const T& t) - { - if (auto p = o.get()) return *p != t; - return true; - } - template - bool operator!=(const T& t, const Optional& o) - { - if (auto p = o.get()) return t != *p; - return true; - } -} diff --git a/toolsrc/include/vcpkglib.h b/toolsrc/include/vcpkglib.h deleted file mode 100644 index 0bb75f9b5..000000000 --- a/toolsrc/include/vcpkglib.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include "SortedVector.h" -#include "StatusParagraphs.h" -#include "VcpkgPaths.h" - -namespace vcpkg -{ - StatusParagraphs database_load_check(const VcpkgPaths& paths); - - void write_update(const VcpkgPaths& paths, const StatusParagraph& p); - - struct StatusParagraphAndAssociatedFiles - { - StatusParagraph pgh; - SortedVector files; - }; - - std::vector get_installed_ports(const StatusParagraphs& status_db); - std::vector get_installed_files(const VcpkgPaths& paths, - const StatusParagraphs& status_db); - - struct CMakeVariable - { - CMakeVariable(const CWStringView varname, const wchar_t* varvalue); - CMakeVariable(const CWStringView varname, const std::string& varvalue); - CMakeVariable(const CWStringView varname, const std::wstring& varvalue); - CMakeVariable(const CWStringView varname, const fs::path& path); - - std::wstring s; - }; - - std::wstring make_cmake_cmd(const fs::path& cmake_exe, - const fs::path& cmake_script, - const std::vector& pass_variables); - - std::string shorten_text(const std::string& desc, size_t length); -} // namespace vcpkg diff --git a/toolsrc/src/BinaryParagraph.cpp b/toolsrc/src/BinaryParagraph.cpp deleted file mode 100644 index 1504912ab..000000000 --- a/toolsrc/src/BinaryParagraph.cpp +++ /dev/null @@ -1,123 +0,0 @@ -#include "pch.h" - -#include "BinaryParagraph.h" -#include "vcpkg_Checks.h" -#include "vcpkg_Parse.h" - -namespace vcpkg -{ - namespace Fields - { - static const std::string PACKAGE = "Package"; - static const std::string VERSION = "Version"; - static const std::string ARCHITECTURE = "Architecture"; - static const std::string MULTI_ARCH = "Multi-Arch"; - } - - namespace Fields - { - static const std::string FEATURE = "Feature"; - static const std::string DESCRIPTION = "Description"; - static const std::string MAINTAINER = "Maintainer"; - static const std::string DEPENDS = "Depends"; - static const std::string DEFAULTFEATURES = "Default-Features"; - } - - BinaryParagraph::BinaryParagraph() = default; - - BinaryParagraph::BinaryParagraph(std::unordered_map fields) - { - using namespace vcpkg::Parse; - - ParagraphParser parser(std::move(fields)); - - { - std::string name; - parser.required_field(Fields::PACKAGE, name); - std::string architecture; - parser.required_field(Fields::ARCHITECTURE, architecture); - this->spec = PackageSpec::from_name_and_triplet(name, Triplet::from_canonical_name(architecture)) - .value_or_exit(VCPKG_LINE_INFO); - } - - // one or the other - this->version = parser.optional_field(Fields::VERSION); - this->feature = parser.optional_field(Fields::FEATURE); - - this->description = parser.optional_field(Fields::DESCRIPTION); - this->maintainer = parser.optional_field(Fields::MAINTAINER); - - std::string multi_arch; - parser.required_field(Fields::MULTI_ARCH, multi_arch); - - this->depends = parse_comma_list(parser.optional_field(Fields::DEPENDS)); - if (this->feature.empty()) - { - this->default_features = parse_comma_list(parser.optional_field(Fields::DEFAULTFEATURES)); - } - - if (const auto err = parser.error_info(this->spec.to_string())) - { - System::println( - System::Color::error, "Error: while parsing the Binary Paragraph for %s", this->spec.to_string()); - print_error_message(err); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - // prefer failing above when possible because it gives better information - Checks::check_exit(VCPKG_LINE_INFO, multi_arch == "same", "Multi-Arch must be 'same' but was %s", multi_arch); - } - - BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet) - { - this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO); - this->version = spgh.version; - this->description = spgh.description; - this->maintainer = spgh.maintainer; - this->depends = filter_dependencies(spgh.depends, triplet); - } - - BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet) - { - this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO); - this->version = Strings::EMPTY; - this->feature = fpgh.name; - this->description = fpgh.description; - this->maintainer = Strings::EMPTY; - this->depends = filter_dependencies(fpgh.depends, triplet); - } - - std::string BinaryParagraph::displayname() const - { - const auto f = this->feature.empty() ? "core" : this->feature; - return Strings::format("%s[%s]:%s", this->spec.name(), f, this->spec.triplet()); - } - - std::string BinaryParagraph::dir() const { return this->spec.dir(); } - - std::string BinaryParagraph::fullstem() const - { - return Strings::format("%s_%s_%s", this->spec.name(), this->version, this->spec.triplet()); - } - - void serialize(const BinaryParagraph& pgh, std::string& out_str) - { - out_str.append("Package: ").append(pgh.spec.name()).push_back('\n'); - if (!pgh.version.empty()) - out_str.append("Version: ").append(pgh.version).push_back('\n'); - else if (!pgh.feature.empty()) - out_str.append("Feature: ").append(pgh.feature).push_back('\n'); - if (!pgh.depends.empty()) - { - out_str.append("Depends: "); - out_str.append(Strings::join(", ", pgh.depends)); - out_str.push_back('\n'); - } - - out_str.append("Architecture: ").append(pgh.spec.triplet().to_string()).push_back('\n'); - out_str.append("Multi-Arch: same\n"); - - if (!pgh.maintainer.empty()) out_str.append("Maintainer: ").append(pgh.maintainer).push_back('\n'); - if (!pgh.description.empty()) out_str.append("Description: ").append(pgh.description).push_back('\n'); - } -} diff --git a/toolsrc/src/LineInfo.cpp b/toolsrc/src/LineInfo.cpp deleted file mode 100644 index d1bf9a4b1..000000000 --- a/toolsrc/src/LineInfo.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "pch.h" - -#include "LineInfo.h" -#include "vcpkg_Strings.h" - -namespace vcpkg -{ - std::string LineInfo::to_string() const { return Strings::format("%s(%d)", this->file_name, this->line_number); } -} diff --git a/toolsrc/src/MachineType.cpp b/toolsrc/src/MachineType.cpp deleted file mode 100644 index af6378c88..000000000 --- a/toolsrc/src/MachineType.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "pch.h" - -#include "MachineType.h" -#include "vcpkg_Checks.h" - -namespace vcpkg -{ - MachineType to_machine_type(const uint16_t value) - { - const MachineType t = static_cast(value); - switch (t) - { - case MachineType::UNKNOWN: - case MachineType::AM33: - case MachineType::AMD64: - case MachineType::ARM: - case MachineType::ARM64: - case MachineType::ARMNT: - case MachineType::EBC: - case MachineType::I386: - case MachineType::IA64: - case MachineType::M32R: - case MachineType::MIPS16: - case MachineType::MIPSFPU: - case MachineType::MIPSFPU16: - case MachineType::POWERPC: - case MachineType::POWERPCFP: - case MachineType::R4000: - case MachineType::RISCV32: - case MachineType::RISCV64: - case MachineType::RISCV128: - case MachineType::SH3: - case MachineType::SH3DSP: - case MachineType::SH4: - case MachineType::SH5: - case MachineType::THUMB: - case MachineType::WCEMIPSV2: return t; - default: Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown machine type code 0x%x", value); - } - } -} diff --git a/toolsrc/src/PackageSpec.cpp b/toolsrc/src/PackageSpec.cpp deleted file mode 100644 index 890de8899..000000000 --- a/toolsrc/src/PackageSpec.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include "pch.h" - -#include "PackageSpec.h" -#include "vcpkg_Parse.h" -#include "vcpkg_Util.h" - -using vcpkg::Parse::parse_comma_list; - -namespace vcpkg -{ - static bool is_valid_package_spec_char(char c) - { - return (c == '-') || isdigit(c) || (isalpha(c) && islower(c)) || (c == '[') || (c == ']'); - } - - std::string FeatureSpec::to_string() const - { - if (feature().empty()) return spec().to_string(); - return Strings::format("%s[%s]:%s", name(), feature(), triplet()); - } - - std::vector FeatureSpec::from_strings_and_triplet(const std::vector& depends, - const Triplet& triplet) - { - std::vector f_specs; - for (auto&& depend : depends) - { - auto maybe_spec = ParsedSpecifier::from_string(depend); - if (auto spec = maybe_spec.get()) - { - Checks::check_exit(VCPKG_LINE_INFO, - spec->triplet.empty(), - "error: triplets cannot currently be specified in this context: %s", - depend); - PackageSpec pspec = - PackageSpec::from_name_and_triplet(spec->name, triplet).value_or_exit(VCPKG_LINE_INFO); - - for (auto&& feature : spec->features) - f_specs.push_back(FeatureSpec{pspec, feature}); - - if (spec->features.empty()) f_specs.push_back(FeatureSpec{pspec, Strings::EMPTY}); - } - else - { - Checks::exit_with_message(VCPKG_LINE_INFO, - "error while parsing feature list: %s: %s", - vcpkg::to_string(maybe_spec.error()), - depend); - } - } - return f_specs; - } - - std::vector FullPackageSpec::to_feature_specs(const std::vector& specs) - { - std::vector ret; - for (auto&& spec : specs) - { - ret.emplace_back(spec.package_spec, Strings::EMPTY); - for (auto&& feature : spec.features) - ret.emplace_back(spec.package_spec, feature); - } - return ret; - } - - ExpectedT FullPackageSpec::from_string(const std::string& spec_as_string, - const Triplet& default_triplet) - { - auto res = ParsedSpecifier::from_string(spec_as_string); - if (auto p = res.get()) - { - FullPackageSpec fspec; - Triplet t = p->triplet.empty() ? default_triplet : Triplet::from_canonical_name(p->triplet); - fspec.package_spec = PackageSpec::from_name_and_triplet(p->name, t).value_or_exit(VCPKG_LINE_INFO); - fspec.features = std::move(p->features); - return fspec; - } - return res.error(); - } - - ExpectedT PackageSpec::from_name_and_triplet(const std::string& name, - const Triplet& triplet) - { - if (Util::find_if_not(name, is_valid_package_spec_char) != name.end()) - { - return PackageSpecParseResult::INVALID_CHARACTERS; - } - - PackageSpec p; - p.m_name = name; - p.m_triplet = triplet; - return p; - } - - const std::string& PackageSpec::name() const { return this->m_name; } - - const Triplet& PackageSpec::triplet() const { return this->m_triplet; } - - std::string PackageSpec::dir() const { return Strings::format("%s_%s", this->m_name, this->m_triplet); } - - std::string PackageSpec::to_string() const { return Strings::format("%s:%s", this->name(), this->triplet()); } - - bool operator==(const PackageSpec& left, const PackageSpec& right) - { - return left.name() == right.name() && left.triplet() == right.triplet(); - } - - bool operator!=(const PackageSpec& left, const PackageSpec& right) { return !(left == right); } - - ExpectedT ParsedSpecifier::from_string(const std::string& input) - { - auto pos = input.find(':'); - auto pos_l_bracket = input.find('['); - auto pos_r_bracket = input.find(']'); - - ParsedSpecifier f; - if (pos == std::string::npos && pos_l_bracket == std::string::npos) - { - f.name = input; - return f; - } - else if (pos == std::string::npos) - { - if (pos_r_bracket == std::string::npos || pos_l_bracket >= pos_r_bracket) - { - return PackageSpecParseResult::INVALID_CHARACTERS; - } - const std::string name = input.substr(0, pos_l_bracket); - f.name = name; - f.features = parse_comma_list(input.substr(pos_l_bracket + 1, pos_r_bracket - pos_l_bracket - 1)); - return f; - } - else if (pos_l_bracket == std::string::npos && pos_r_bracket == std::string::npos) - { - const std::string name = input.substr(0, pos); - f.triplet = input.substr(pos + 1); - f.name = name; - } - else - { - if (pos_r_bracket == std::string::npos || pos_l_bracket >= pos_r_bracket) - { - return PackageSpecParseResult::INVALID_CHARACTERS; - } - const std::string name = input.substr(0, pos_l_bracket); - f.features = parse_comma_list(input.substr(pos_l_bracket + 1, pos_r_bracket - pos_l_bracket - 1)); - f.triplet = input.substr(pos + 1); - f.name = name; - } - - auto pos2 = input.find(':', pos + 1); - if (pos2 != std::string::npos) - { - return PackageSpecParseResult::TOO_MANY_COLONS; - } - return f; - } - - ExpectedT Features::from_string(const std::string& name) - { - auto maybe_spec = ParsedSpecifier::from_string(name); - if (auto spec = maybe_spec.get()) - { - Checks::check_exit( - VCPKG_LINE_INFO, spec->triplet.empty(), "error: triplet not allowed in specifier: %s", name); - - Features f; - f.name = spec->name; - f.features = spec->features; - return f; - } - - return maybe_spec.error(); - } -} diff --git a/toolsrc/src/PackageSpecParseResult.cpp b/toolsrc/src/PackageSpecParseResult.cpp deleted file mode 100644 index 838c788ba..000000000 --- a/toolsrc/src/PackageSpecParseResult.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "pch.h" - -#include "PackageSpecParseResult.h" -#include "vcpkg_Checks.h" - -namespace vcpkg -{ - CStringView to_string(PackageSpecParseResult ev) noexcept - { - switch (ev) - { - case PackageSpecParseResult::SUCCESS: return "OK"; - case PackageSpecParseResult::TOO_MANY_COLONS: return "Too many colons"; - case PackageSpecParseResult::INVALID_CHARACTERS: - return "Contains invalid characters. Only alphanumeric lowercase ASCII characters and dashes are " - "allowed"; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } -} diff --git a/toolsrc/src/ParagraphParseResult.cpp b/toolsrc/src/ParagraphParseResult.cpp deleted file mode 100644 index 5c8c1d59d..000000000 --- a/toolsrc/src/ParagraphParseResult.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "pch.h" - -#include "ParagraphParseResult.h" -#include "vcpkg_Checks.h" - -namespace vcpkg -{ - const char* ParagraphParseResultCategoryImpl::name() const noexcept { return "ParagraphParseResult"; } - - std::string ParagraphParseResultCategoryImpl::message(int ev) const noexcept - { - switch (static_cast(ev)) - { - case ParagraphParseResult::SUCCESS: return "OK"; - case ParagraphParseResult::EXPECTED_ONE_PARAGRAPH: return "There should be exactly one paragraph"; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - const std::error_category& paragraph_parse_result_category() - { - static ParagraphParseResultCategoryImpl instance; - return instance; - } - - std::error_code make_error_code(ParagraphParseResult e) - { - return std::error_code(static_cast(e), paragraph_parse_result_category()); - } - - ParagraphParseResult to_paragraph_parse_result(int i) { return static_cast(i); } - - ParagraphParseResult to_paragraph_parse_result(std::error_code ec) { return to_paragraph_parse_result(ec.value()); } -} diff --git a/toolsrc/src/Paragraphs.cpp b/toolsrc/src/Paragraphs.cpp deleted file mode 100644 index 6a6f191df..000000000 --- a/toolsrc/src/Paragraphs.cpp +++ /dev/null @@ -1,304 +0,0 @@ -#include "pch.h" - -#include "ParagraphParseResult.h" -#include "Paragraphs.h" -#include "vcpkg_Files.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_Util.h" - -using namespace vcpkg::Parse; - -namespace vcpkg::Paragraphs -{ - struct Parser - { - Parser(const char* c, const char* e) : cur(c), end(e) {} - - private: - const char* cur; - const char* const end; - - void peek(char& ch) const - { - if (cur == end) - ch = 0; - else - ch = *cur; - } - - void next(char& ch) - { - if (cur == end) - ch = 0; - else - { - ++cur; - peek(ch); - } - } - - void skip_comment(char& ch) - { - while (ch != '\r' && ch != '\n' && ch != '\0') - next(ch); - if (ch == '\r') next(ch); - if (ch == '\n') next(ch); - } - - void skip_spaces(char& ch) - { - while (ch == ' ' || ch == '\t') - next(ch); - } - - static bool is_alphanum(char ch) - { - return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'); - } - - static bool is_comment(char ch) { return (ch == '#'); } - - static bool is_lineend(char ch) { return ch == '\r' || ch == '\n' || ch == 0; } - - void get_fieldvalue(char& ch, std::string& fieldvalue) - { - fieldvalue.clear(); - - auto beginning_of_line = cur; - do - { - // scan to end of current line (it is part of the field value) - while (!is_lineend(ch)) - next(ch); - - fieldvalue.append(beginning_of_line, cur); - - if (ch == '\r') next(ch); - if (ch == '\n') next(ch); - - if (is_alphanum(ch) || is_comment(ch)) - { - // Line begins a new field. - return; - } - - beginning_of_line = cur; - - // Line may continue the current field with data or terminate the paragraph, - // depending on first nonspace character. - skip_spaces(ch); - - if (is_lineend(ch)) - { - // Line was whitespace or empty. - // This terminates the field and the paragraph. - // We leave the blank line's whitespace consumed, because it doesn't matter. - return; - } - - // First nonspace is not a newline. This continues the current field value. - // We forcibly convert all newlines into single '\n' for ease of text handling later on. - fieldvalue.push_back('\n'); - } while (true); - } - - void get_fieldname(char& ch, std::string& fieldname) - { - auto begin_fieldname = cur; - while (is_alphanum(ch) || ch == '-') - next(ch); - Checks::check_exit(VCPKG_LINE_INFO, ch == ':', "Expected ':'"); - fieldname = std::string(begin_fieldname, cur); - - // skip ': ' - next(ch); - skip_spaces(ch); - } - - void get_paragraph(char& ch, std::unordered_map& fields) - { - fields.clear(); - std::string fieldname; - std::string fieldvalue; - do - { - if (is_comment(ch)) - { - skip_comment(ch); - continue; - } - - get_fieldname(ch, fieldname); - - auto it = fields.find(fieldname); - Checks::check_exit(VCPKG_LINE_INFO, it == fields.end(), "Duplicate field"); - - get_fieldvalue(ch, fieldvalue); - - fields.emplace(fieldname, fieldvalue); - } while (!is_lineend(ch)); - } - - public: - std::vector> get_paragraphs() - { - std::vector> paragraphs; - - char ch; - peek(ch); - - while (ch != 0) - { - if (ch == '\n' || ch == '\r' || ch == ' ' || ch == '\t') - { - next(ch); - continue; - } - - paragraphs.emplace_back(); - get_paragraph(ch, paragraphs.back()); - } - - return paragraphs; - } - }; - - Expected> get_single_paragraph(const Files::Filesystem& fs, - const fs::path& control_path) - { - const Expected contents = fs.read_contents(control_path); - if (auto spgh = contents.get()) - { - return parse_single_paragraph(*spgh); - } - - return contents.error(); - } - - Expected>> get_paragraphs(const Files::Filesystem& fs, - const fs::path& control_path) - { - const Expected contents = fs.read_contents(control_path); - if (auto spgh = contents.get()) - { - return parse_paragraphs(*spgh); - } - - return contents.error(); - } - - Expected> parse_single_paragraph(const std::string& str) - { - const std::vector> p = - Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs(); - - if (p.size() == 1) - { - return p.at(0); - } - - return std::error_code(ParagraphParseResult::EXPECTED_ONE_PARAGRAPH); - } - - Expected>> parse_paragraphs(const std::string& str) - { - return Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs(); - } - - ParseExpected try_load_port(const Files::Filesystem& fs, const fs::path& path) - { - Expected>> pghs = get_paragraphs(fs, path / "CONTROL"); - if (auto vector_pghs = pghs.get()) - { - auto csf = SourceControlFile::parse_control_file(std::move(*vector_pghs)); - if (!GlobalState::feature_packages) - { - if (auto ptr = csf.get()) - { - Checks::check_exit(VCPKG_LINE_INFO, ptr->get() != nullptr); - ptr->get()->core_paragraph->default_features.clear(); - ptr->get()->feature_paragraphs.clear(); - } - } - return csf; - } - auto error_info = std::make_unique(); - error_info->name = path.filename().generic_u8string(); - error_info->error = pghs.error(); - return error_info; - } - - Expected try_load_cached_control_package(const VcpkgPaths& paths, const PackageSpec& spec) - { - Expected>> pghs = - get_paragraphs(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL"); - - if (auto p = pghs.get()) - { - BinaryControlFile bcf; - bcf.core_paragraph = BinaryParagraph(p->front()); - p->erase(p->begin()); - - bcf.features = - Util::fmap(*p, [&](auto&& raw_feature) -> BinaryParagraph { return BinaryParagraph(raw_feature); }); - - return bcf; - } - - return pghs.error(); - } - - LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir) - { - LoadResults ret; - for (auto&& path : fs.get_files_non_recursive(ports_dir)) - { - auto maybe_spgh = try_load_port(fs, path); - if (const auto spgh = maybe_spgh.get()) - { - ret.paragraphs.emplace_back(std::move(*spgh)); - } - else - { - ret.errors.emplace_back(std::move(maybe_spgh).error()); - } - } - return ret; - } - - std::vector> load_all_ports(const Files::Filesystem& fs, - const fs::path& ports_dir) - { - auto results = try_load_all_ports(fs, ports_dir); - if (!results.errors.empty()) - { - if (GlobalState::debugging) - { - print_error_message(results.errors); - } - else - { - for (auto&& error : results.errors) - { - System::println( - System::Color::warning, "Warning: an error occurred while parsing '%s'", error->name); - } - System::println(System::Color::warning, - "Use '--debug' to get more information about the parse failures.\n"); - } - } - return std::move(results.paragraphs); - } - - std::map load_all_port_names_and_versions(const Files::Filesystem& fs, - const fs::path& ports_dir) - { - auto all_ports = load_all_ports(fs, ports_dir); - - std::map names_and_versions; - for (auto&& port : all_ports) - names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version); - - return names_and_versions; - } -} diff --git a/toolsrc/src/PostBuildLint.cpp b/toolsrc/src/PostBuildLint.cpp deleted file mode 100644 index a0699e15c..000000000 --- a/toolsrc/src/PostBuildLint.cpp +++ /dev/null @@ -1,846 +0,0 @@ -#include "pch.h" - -#include "PackageSpec.h" -#include "PostBuildLint.h" -#include "PostBuildLint_BuildType.h" -#include "VcpkgPaths.h" -#include "coff_file_reader.h" -#include "vcpkg_Build.h" -#include "vcpkg_Files.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" - -using vcpkg::Build::BuildInfo; -using vcpkg::Build::BuildPolicy; -using vcpkg::Build::PreBuildInfo; - -namespace vcpkg::PostBuildLint -{ - static auto has_extension_pred(const Files::Filesystem& fs, const std::string& ext) - { - return [&fs, ext](const fs::path& path) { return !fs.is_directory(path) && path.extension() == ext; }; - } - - enum class LintStatus - { - SUCCESS = 0, - ERROR_DETECTED = 1 - }; - - struct OutdatedDynamicCrt - { - std::string name; - std::regex regex; - - OutdatedDynamicCrt(const std::string& name, const std::string& regex_as_string) - : name(name), regex(std::regex(regex_as_string, std::regex_constants::icase)) - { - } - }; - - Span get_outdated_dynamic_crts(CStringView toolset) - { - static const std::vector V_NO_MSVCRT = { - {"msvcp100.dll", R"(msvcp100\.dll)"}, - {"msvcp100d.dll", R"(msvcp100d\.dll)"}, - {"msvcp110.dll", R"(msvcp110\.dll)"}, - {"msvcp110_win.dll", R"(msvcp110_win\.dll)"}, - {"msvcp120.dll", R"(msvcp120\.dll)"}, - {"msvcp120_clr0400.dll", R"(msvcp120_clr0400\.dll)"}, - {"msvcp60.dll", R"(msvcp60\.dll)"}, - {"msvcp60.dll", R"(msvcp60\.dll)"}, - - {"msvcr100.dll", R"(msvcr100\.dll)"}, - {"msvcr100d.dll", R"(msvcr100d\.dll)"}, - {"msvcr100_clr0400.dll", R"(msvcr100_clr0400\.dll)"}, - {"msvcr110.dll", R"(msvcr110\.dll)"}, - {"msvcr120.dll", R"(msvcr120\.dll)"}, - {"msvcr120_clr0400.dll", R"(msvcr120_clr0400\.dll)"}, - {"msvcrt20.dll", R"(msvcrt20\.dll)"}, - {"msvcrt40.dll", R"(msvcrt40\.dll)"}}; - - return V_NO_MSVCRT; - } - - static LintStatus check_for_files_in_include_directory(const Files::Filesystem& fs, - const Build::BuildPolicies& policies, - const fs::path& package_dir) - { - if (policies.is_enabled(BuildPolicy::EMPTY_INCLUDE_FOLDER)) - { - return LintStatus::SUCCESS; - } - - const fs::path include_dir = package_dir / "include"; - if (!fs.exists(include_dir) || fs.is_empty(include_dir)) - { - System::println(System::Color::warning, - "The folder /include is empty. This indicates the library was not correctly installed."); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_for_files_in_debug_include_directory(const Files::Filesystem& fs, - const fs::path& package_dir) - { - const fs::path debug_include_dir = package_dir / "debug" / "include"; - - std::vector files_found = fs.get_files_recursive(debug_include_dir); - - Util::unstable_keep_if( - files_found, [&fs](const fs::path& path) { return !fs.is_directory(path) && path.extension() != ".ifc"; }); - - if (!files_found.empty()) - { - System::println(System::Color::warning, - "Include files should not be duplicated into the /debug/include directory. If this cannot " - "be disabled in the project cmake, use\n" - " file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include)"); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_for_files_in_debug_share_directory(const Files::Filesystem& fs, const fs::path& package_dir) - { - const fs::path debug_share = package_dir / "debug" / "share"; - - if (fs.exists(debug_share)) - { - System::println(System::Color::warning, - "/debug/share should not exist. Please reorganize any important files, then use\n" - " file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/share)"); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_folder_lib_cmake(const Files::Filesystem& fs, - const fs::path& package_dir, - const PackageSpec& spec) - { - const fs::path lib_cmake = package_dir / "lib" / "cmake"; - if (fs.exists(lib_cmake)) - { - System::println( - System::Color::warning, - "The /lib/cmake folder should be merged with /debug/lib/cmake and moved to /share/%s/cmake.", - spec.name()); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_for_misplaced_cmake_files(const Files::Filesystem& fs, - const fs::path& package_dir, - const PackageSpec& spec) - { - std::vector dirs = { - package_dir / "cmake", - package_dir / "debug" / "cmake", - package_dir / "lib" / "cmake", - package_dir / "debug" / "lib" / "cmake", - }; - - std::vector misplaced_cmake_files; - for (auto&& dir : dirs) - { - auto files = fs.get_files_recursive(dir); - for (auto&& file : files) - { - if (!fs.is_directory(file) && file.extension() == ".cmake") - misplaced_cmake_files.push_back(std::move(file)); - } - } - - if (!misplaced_cmake_files.empty()) - { - System::println( - System::Color::warning, - "The following cmake files were found outside /share/%s. Please place cmake files in /share/%s.", - spec.name(), - spec.name()); - Files::print_paths(misplaced_cmake_files); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_folder_debug_lib_cmake(const Files::Filesystem& fs, - const fs::path& package_dir, - const PackageSpec& spec) - { - const fs::path lib_cmake_debug = package_dir / "debug" / "lib" / "cmake"; - if (fs.exists(lib_cmake_debug)) - { - System::println(System::Color::warning, - "The /debug/lib/cmake folder should be merged with /lib/cmake into /share/%s", - spec.name()); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_for_dlls_in_lib_dir(const Files::Filesystem& fs, const fs::path& package_dir) - { - std::vector dlls = fs.get_files_recursive(package_dir / "lib"); - Util::unstable_keep_if(dlls, has_extension_pred(fs, ".dll")); - - if (!dlls.empty()) - { - System::println(System::Color::warning, - "\nThe following dlls were found in /lib or /debug/lib. Please move them to /bin or " - "/debug/bin, respectively."); - Files::print_paths(dlls); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_for_copyright_file(const Files::Filesystem& fs, - const PackageSpec& spec, - const VcpkgPaths& paths) - { - const fs::path packages_dir = paths.packages / spec.dir(); - const fs::path copyright_file = packages_dir / "share" / spec.name() / "copyright"; - if (fs.exists(copyright_file)) - { - return LintStatus::SUCCESS; - } - const fs::path current_buildtrees_dir = paths.buildtrees / spec.name(); - const fs::path current_buildtrees_dir_src = current_buildtrees_dir / "src"; - - std::vector potential_copyright_files; - // We only search in the root of each unpacked source archive to reduce false positives - auto src_dirs = fs.get_files_non_recursive(current_buildtrees_dir_src); - for (auto&& src_dir : src_dirs) - { - if (!fs.is_directory(src_dir)) continue; - - for (auto&& src_file : fs.get_files_non_recursive(src_dir)) - { - const std::string filename = src_file.filename().string(); - - if (filename == "LICENSE" || filename == "LICENSE.txt" || filename == "COPYING") - { - potential_copyright_files.push_back(src_file); - } - } - } - - System::println(System::Color::warning, - "The software license must be available at ${CURRENT_PACKAGES_DIR}/share/%s/copyright", - spec.name()); - if (potential_copyright_files.size() == - 1) // if there is only one candidate, provide the cmake lines needed to place it in the proper location - { - const fs::path found_file = potential_copyright_files[0]; - const fs::path relative_path = found_file.string().erase( - 0, current_buildtrees_dir.string().size() + 1); // The +1 is needed to remove the "/" - System::println( - "\n file(COPY ${CURRENT_BUILDTREES_DIR}/%s DESTINATION ${CURRENT_PACKAGES_DIR}/share/%s)\n" - " file(RENAME ${CURRENT_PACKAGES_DIR}/share/%s/%s ${CURRENT_PACKAGES_DIR}/share/%s/copyright)", - relative_path.generic_string(), - spec.name(), - spec.name(), - found_file.filename().generic_string(), - spec.name()); - } - else if (potential_copyright_files.size() > 1) - { - System::println(System::Color::warning, "The following files are potential copyright files:"); - Files::print_paths(potential_copyright_files); - } - return LintStatus::ERROR_DETECTED; - } - - static LintStatus check_for_exes(const Files::Filesystem& fs, const fs::path& package_dir) - { - std::vector exes = fs.get_files_recursive(package_dir / "bin"); - Util::unstable_keep_if(exes, has_extension_pred(fs, ".exe")); - - if (!exes.empty()) - { - System::println( - System::Color::warning, - "The following EXEs were found in /bin or /debug/bin. EXEs are not valid distribution targets."); - Files::print_paths(exes); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_exports_of_dlls(const std::vector& dlls, const fs::path& dumpbin_exe) - { - std::vector dlls_with_no_exports; - for (const fs::path& dll : dlls) - { - const std::wstring cmd_line = - Strings::wformat(LR"("%s" /exports "%s")", dumpbin_exe.native(), dll.native()); - System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, - ec_data.exit_code == 0, - "Running command:\n %s\n failed", - Strings::to_utf8(cmd_line)); - - if (ec_data.output.find("ordinal hint RVA name") == std::string::npos) - { - dlls_with_no_exports.push_back(dll); - } - } - - if (!dlls_with_no_exports.empty()) - { - System::println(System::Color::warning, "The following DLLs have no exports:"); - Files::print_paths(dlls_with_no_exports); - System::println(System::Color::warning, "DLLs without any exports are likely a bug in the build script."); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_uwp_bit_of_dlls(const std::string& expected_system_name, - const std::vector& dlls, - const fs::path dumpbin_exe) - { - if (expected_system_name != "WindowsStore") - { - return LintStatus::SUCCESS; - } - - std::vector dlls_with_improper_uwp_bit; - for (const fs::path& dll : dlls) - { - const std::wstring cmd_line = - Strings::wformat(LR"("%s" /headers "%s")", dumpbin_exe.native(), dll.native()); - System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, - ec_data.exit_code == 0, - "Running command:\n %s\n failed", - Strings::to_utf8(cmd_line)); - - if (ec_data.output.find("App Container") == std::string::npos) - { - dlls_with_improper_uwp_bit.push_back(dll); - } - } - - if (!dlls_with_improper_uwp_bit.empty()) - { - System::println(System::Color::warning, "The following DLLs do not have the App Container bit set:"); - Files::print_paths(dlls_with_improper_uwp_bit); - System::println(System::Color::warning, "This bit is required for Windows Store apps."); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - struct FileAndArch - { - fs::path file; - std::string actual_arch; - }; - - static std::string get_actual_architecture(const MachineType& machine_type) - { - switch (machine_type) - { - case MachineType::AMD64: - case MachineType::IA64: return "x64"; - case MachineType::I386: return "x86"; - case MachineType::ARM: - case MachineType::ARMNT: return "arm"; - default: return "Machine Type Code = " + std::to_string(static_cast(machine_type)); - } - } - - static void print_invalid_architecture_files(const std::string& expected_architecture, - std::vector binaries_with_invalid_architecture) - { - System::println(System::Color::warning, "The following files were built for an incorrect architecture:"); - System::println(); - for (const FileAndArch& b : binaries_with_invalid_architecture) - { - System::println(" %s", b.file.generic_string()); - System::println("Expected %s, but was: %s", expected_architecture, b.actual_arch); - System::println(); - } - } - - static LintStatus check_dll_architecture(const std::string& expected_architecture, - const std::vector& files) - { - std::vector binaries_with_invalid_architecture; - - for (const fs::path& file : files) - { - Checks::check_exit(VCPKG_LINE_INFO, - file.extension() == ".dll", - "The file extension was not .dll: %s", - file.generic_string()); - const CoffFileReader::DllInfo info = CoffFileReader::read_dll(file); - const std::string actual_architecture = get_actual_architecture(info.machine_type); - - if (expected_architecture != actual_architecture) - { - binaries_with_invalid_architecture.push_back({file, actual_architecture}); - } - } - - if (!binaries_with_invalid_architecture.empty()) - { - print_invalid_architecture_files(expected_architecture, binaries_with_invalid_architecture); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_lib_architecture(const std::string& expected_architecture, - const std::vector& files) - { - std::vector binaries_with_invalid_architecture; - - for (const fs::path& file : files) - { - Checks::check_exit(VCPKG_LINE_INFO, - file.extension() == ".lib", - "The file extension was not .lib: %s", - file.generic_string()); - CoffFileReader::LibInfo info = CoffFileReader::read_lib(file); - - // This is zero for folly's debug library - // TODO: Why? - if (info.machine_types.size() == 0) return LintStatus::SUCCESS; - - Checks::check_exit(VCPKG_LINE_INFO, - info.machine_types.size() == 1, - "Found more than 1 architecture in file %s", - file.generic_string()); - - const std::string actual_architecture = get_actual_architecture(info.machine_types.at(0)); - if (expected_architecture != actual_architecture) - { - binaries_with_invalid_architecture.push_back({file, actual_architecture}); - } - } - - if (!binaries_with_invalid_architecture.empty()) - { - print_invalid_architecture_files(expected_architecture, binaries_with_invalid_architecture); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_no_dlls_present(const std::vector& dlls) - { - if (dlls.empty()) - { - return LintStatus::SUCCESS; - } - - System::println(System::Color::warning, - "DLLs should not be present in a static build, but the following DLLs were found:"); - Files::print_paths(dlls); - return LintStatus::ERROR_DETECTED; - } - - static LintStatus check_matching_debug_and_release_binaries(const std::vector& debug_binaries, - const std::vector& release_binaries) - { - const size_t debug_count = debug_binaries.size(); - const size_t release_count = release_binaries.size(); - if (debug_count == release_count) - { - return LintStatus::SUCCESS; - } - - System::println(System::Color::warning, - "Mismatching number of debug and release binaries. Found %d for debug but %d for release.", - debug_count, - release_count); - System::println("Debug binaries"); - Files::print_paths(debug_binaries); - - System::println("Release binaries"); - Files::print_paths(release_binaries); - - if (debug_count == 0) - { - System::println(System::Color::warning, "Debug binaries were not found"); - } - if (release_count == 0) - { - System::println(System::Color::warning, "Release binaries were not found"); - } - - System::println(); - - return LintStatus::ERROR_DETECTED; - } - - static LintStatus check_lib_files_are_available_if_dlls_are_available(const Build::BuildPolicies& policies, - const size_t lib_count, - const size_t dll_count, - const fs::path& lib_dir) - { - if (policies.is_enabled(BuildPolicy::DLLS_WITHOUT_LIBS)) return LintStatus::SUCCESS; - - if (lib_count == 0 && dll_count != 0) - { - System::println(System::Color::warning, "Import libs were not present in %s", lib_dir.u8string()); - System::println(System::Color::warning, - "If this is intended, add the following line in the portfile:\n" - " SET(%s enabled)", - to_cmake_variable(BuildPolicy::DLLS_WITHOUT_LIBS)); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_bin_folders_are_not_present_in_static_build(const Files::Filesystem& fs, - const fs::path& package_dir) - { - const fs::path bin = package_dir / "bin"; - const fs::path debug_bin = package_dir / "debug" / "bin"; - - if (!fs.exists(bin) && !fs.exists(debug_bin)) - { - return LintStatus::SUCCESS; - } - - if (fs.exists(bin)) - { - System::println(System::Color::warning, - R"(There should be no bin\ directory in a static build, but %s is present.)", - bin.u8string()); - } - - if (fs.exists(debug_bin)) - { - System::println(System::Color::warning, - R"(There should be no debug\bin\ directory in a static build, but %s is present.)", - debug_bin.u8string()); - } - - System::println( - System::Color::warning, - R"(If the creation of bin\ and/or debug\bin\ cannot be disabled, use this in the portfile to remove them)" - "\n" - "\n" - R"###( if(VCPKG_LIBRARY_LINKAGE STREQUAL static))###" - "\n" - R"###( file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/bin ${CURRENT_PACKAGES_DIR}/debug/bin))###" - "\n" - R"###( endif())###" - "\n"); - - return LintStatus::ERROR_DETECTED; - } - - static LintStatus check_no_empty_folders(const Files::Filesystem& fs, const fs::path& dir) - { - std::vector empty_directories = fs.get_files_recursive(dir); - - Util::unstable_keep_if(empty_directories, [&fs](const fs::path& current) { - return fs.is_directory(current) && fs.is_empty(current); - }); - - if (!empty_directories.empty()) - { - System::println(System::Color::warning, "There should be no empty directories in %s", dir.generic_string()); - System::println("The following empty directories were found: "); - Files::print_paths(empty_directories); - System::println( - System::Color::warning, - "If a directory should be populated but is not, this might indicate an error in the portfile.\n" - "If the directories are not needed and their creation cannot be disabled, use something like this in " - "the portfile to remove them:\n" - "\n" - R"###( file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/a/dir ${CURRENT_PACKAGES_DIR}/some/other/dir))###" - "\n" - "\n"); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - struct BuildTypeAndFile - { - fs::path file; - BuildType build_type; - }; - - static LintStatus check_crt_linkage_of_libs(const BuildType& expected_build_type, - const std::vector& libs, - const fs::path dumpbin_exe) - { - std::vector bad_build_types(BuildTypeC::VALUES.cbegin(), BuildTypeC::VALUES.cend()); - bad_build_types.erase(std::remove(bad_build_types.begin(), bad_build_types.end(), expected_build_type), - bad_build_types.end()); - - std::vector libs_with_invalid_crt; - - for (const fs::path& lib : libs) - { - const std::wstring cmd_line = - Strings::wformat(LR"("%s" /directives "%s")", dumpbin_exe.native(), lib.native()); - System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, - ec_data.exit_code == 0, - "Running command:\n %s\n failed", - Strings::to_utf8(cmd_line)); - - for (const BuildType& bad_build_type : bad_build_types) - { - if (std::regex_search(ec_data.output.cbegin(), ec_data.output.cend(), bad_build_type.crt_regex())) - { - libs_with_invalid_crt.push_back({lib, bad_build_type}); - break; - } - } - } - - if (!libs_with_invalid_crt.empty()) - { - System::println(System::Color::warning, - "Expected %s crt linkage, but the following libs had invalid crt linkage:", - expected_build_type.to_string()); - System::println(); - for (const BuildTypeAndFile btf : libs_with_invalid_crt) - { - System::println(" %s: %s", btf.file.generic_string(), btf.build_type.to_string()); - } - System::println(); - - System::println(System::Color::warning, - "To inspect the lib files, use:\n dumpbin.exe /directives mylibfile.lib"); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - struct OutdatedDynamicCrtAndFile - { - fs::path file; - OutdatedDynamicCrt outdated_crt; - - OutdatedDynamicCrtAndFile() = delete; - }; - - static LintStatus check_outdated_crt_linkage_of_dlls(const std::vector& dlls, - const fs::path dumpbin_exe, - const BuildInfo& build_info) - { - if (build_info.policies.is_enabled(BuildPolicy::ALLOW_OBSOLETE_MSVCRT)) return LintStatus::SUCCESS; - - std::vector dlls_with_outdated_crt; - - for (const fs::path& dll : dlls) - { - const std::wstring cmd_line = - Strings::wformat(LR"("%s" /dependents "%s")", dumpbin_exe.native(), dll.native()); - System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, - ec_data.exit_code == 0, - "Running command:\n %s\n failed", - Strings::to_utf8(cmd_line)); - - for (const OutdatedDynamicCrt& outdated_crt : get_outdated_dynamic_crts("v141")) - { - if (std::regex_search(ec_data.output.cbegin(), ec_data.output.cend(), outdated_crt.regex)) - { - dlls_with_outdated_crt.push_back({dll, outdated_crt}); - break; - } - } - } - - if (!dlls_with_outdated_crt.empty()) - { - System::println(System::Color::warning, "Detected outdated dynamic CRT in the following files:"); - System::println(); - for (const OutdatedDynamicCrtAndFile btf : dlls_with_outdated_crt) - { - System::println(" %s: %s", btf.file.generic_string(), btf.outdated_crt.name); - } - System::println(); - - System::println(System::Color::warning, - "To inspect the dll files, use:\n dumpbin.exe /dependents mydllfile.dll"); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static LintStatus check_no_files_in_dir(const Files::Filesystem& fs, const fs::path& dir) - { - std::vector misplaced_files = fs.get_files_non_recursive(dir); - Util::unstable_keep_if(misplaced_files, [&fs](const fs::path& path) { - const std::string filename = path.filename().generic_string(); - if (Strings::case_insensitive_ascii_compare(filename.c_str(), "CONTROL") == 0 || - Strings::case_insensitive_ascii_compare(filename.c_str(), "BUILD_INFO") == 0) - return false; - return !fs.is_directory(path); - }); - - if (!misplaced_files.empty()) - { - System::println(System::Color::warning, "The following files are placed in\n%s: ", dir.u8string()); - Files::print_paths(misplaced_files); - System::println(System::Color::warning, "Files cannot be present in those directories.\n"); - return LintStatus::ERROR_DETECTED; - } - - return LintStatus::SUCCESS; - } - - static void operator+=(size_t& left, const LintStatus& right) { left += static_cast(right); } - - static size_t perform_all_checks_and_return_error_count(const PackageSpec& spec, - const VcpkgPaths& paths, - const PreBuildInfo& pre_build_info, - const BuildInfo& build_info) - { - const auto& fs = paths.get_filesystem(); - - // for dumpbin - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); - const fs::path package_dir = paths.package_dir(spec); - - size_t error_count = 0; - - if (build_info.policies.is_enabled(BuildPolicy::EMPTY_PACKAGE)) - { - return error_count; - } - - error_count += check_for_files_in_include_directory(fs, build_info.policies, package_dir); - error_count += check_for_files_in_debug_include_directory(fs, package_dir); - error_count += check_for_files_in_debug_share_directory(fs, package_dir); - error_count += check_folder_lib_cmake(fs, package_dir, spec); - error_count += check_for_misplaced_cmake_files(fs, package_dir, spec); - error_count += check_folder_debug_lib_cmake(fs, package_dir, spec); - error_count += check_for_dlls_in_lib_dir(fs, package_dir); - error_count += check_for_dlls_in_lib_dir(fs, package_dir / "debug"); - error_count += check_for_copyright_file(fs, spec, paths); - error_count += check_for_exes(fs, package_dir); - error_count += check_for_exes(fs, package_dir / "debug"); - - const fs::path debug_lib_dir = package_dir / "debug" / "lib"; - const fs::path release_lib_dir = package_dir / "lib"; - const fs::path debug_bin_dir = package_dir / "debug" / "bin"; - const fs::path release_bin_dir = package_dir / "bin"; - - std::vector debug_libs = fs.get_files_recursive(debug_lib_dir); - Util::unstable_keep_if(debug_libs, has_extension_pred(fs, ".lib")); - std::vector release_libs = fs.get_files_recursive(release_lib_dir); - Util::unstable_keep_if(release_libs, has_extension_pred(fs, ".lib")); - - error_count += check_matching_debug_and_release_binaries(debug_libs, release_libs); - - { - std::vector libs; - libs.insert(libs.cend(), debug_libs.cbegin(), debug_libs.cend()); - libs.insert(libs.cend(), release_libs.cbegin(), release_libs.cend()); - - error_count += check_lib_architecture(pre_build_info.target_architecture, libs); - } - - std::vector debug_dlls = fs.get_files_recursive(debug_bin_dir); - Util::unstable_keep_if(debug_dlls, has_extension_pred(fs, ".dll")); - std::vector release_dlls = fs.get_files_recursive(release_bin_dir); - Util::unstable_keep_if(release_dlls, has_extension_pred(fs, ".dll")); - - switch (build_info.library_linkage) - { - case Build::LinkageType::DYNAMIC: - { - error_count += check_matching_debug_and_release_binaries(debug_dlls, release_dlls); - - error_count += check_lib_files_are_available_if_dlls_are_available( - build_info.policies, debug_libs.size(), debug_dlls.size(), debug_lib_dir); - error_count += check_lib_files_are_available_if_dlls_are_available( - build_info.policies, release_libs.size(), release_dlls.size(), release_lib_dir); - - std::vector dlls; - dlls.insert(dlls.cend(), debug_dlls.cbegin(), debug_dlls.cend()); - dlls.insert(dlls.cend(), release_dlls.cbegin(), release_dlls.cend()); - - error_count += check_exports_of_dlls(dlls, toolset.dumpbin); - error_count += check_uwp_bit_of_dlls(pre_build_info.cmake_system_name, dlls, toolset.dumpbin); - error_count += check_dll_architecture(pre_build_info.target_architecture, dlls); - - error_count += check_outdated_crt_linkage_of_dlls(dlls, toolset.dumpbin, build_info); - break; - } - case Build::LinkageType::STATIC: - { - auto dlls = release_dlls; - dlls.insert(dlls.end(), debug_dlls.begin(), debug_dlls.end()); - error_count += check_no_dlls_present(dlls); - - error_count += check_bin_folders_are_not_present_in_static_build(fs, package_dir); - - if (!build_info.policies.is_enabled(BuildPolicy::ONLY_RELEASE_CRT)) - { - error_count += - check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::DEBUG, build_info.crt_linkage), - debug_libs, - toolset.dumpbin); - } - error_count += - check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::RELEASE, build_info.crt_linkage), - release_libs, - toolset.dumpbin); - break; - } - default: Checks::unreachable(VCPKG_LINE_INFO); - } - - error_count += check_no_empty_folders(fs, package_dir); - error_count += check_no_files_in_dir(fs, package_dir); - error_count += check_no_files_in_dir(fs, package_dir / "debug"); - - return error_count; - } - - size_t perform_all_checks(const PackageSpec& spec, - const VcpkgPaths& paths, - const PreBuildInfo& pre_build_info, - const BuildInfo& build_info) - { - System::println("-- Performing post-build validation"); - const size_t error_count = perform_all_checks_and_return_error_count(spec, paths, pre_build_info, build_info); - - if (error_count != 0) - { - const fs::path portfile = paths.ports / spec.name() / "portfile.cmake"; - System::println(System::Color::error, - "Found %u error(s). Please correct the portfile:\n %s", - error_count, - portfile.string()); - } - - System::println("-- Performing post-build validation done"); - - return error_count; - } -} diff --git a/toolsrc/src/PostBuildLint_BuildType.cpp b/toolsrc/src/PostBuildLint_BuildType.cpp deleted file mode 100644 index 649f0ccca..000000000 --- a/toolsrc/src/PostBuildLint_BuildType.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "pch.h" - -#include "PostBuildLint_BuildType.h" -#include "vcpkg_Checks.h" - -namespace vcpkg::PostBuildLint -{ - BuildType BuildType::value_of(const ConfigurationType& config, const Build::LinkageType& linkage) - { - if (config == ConfigurationType::DEBUG && linkage == Build::LinkageType::STATIC) - { - return BuildTypeC::DEBUG_STATIC; - } - - if (config == ConfigurationType::DEBUG && linkage == Build::LinkageType::DYNAMIC) - { - return BuildTypeC::DEBUG_DYNAMIC; - } - - if (config == ConfigurationType::RELEASE && linkage == Build::LinkageType::STATIC) - { - return BuildTypeC::RELEASE_STATIC; - } - - if (config == ConfigurationType::RELEASE && linkage == Build::LinkageType::DYNAMIC) - { - return BuildTypeC::RELEASE_DYNAMIC; - } - - Checks::unreachable(VCPKG_LINE_INFO); - } - - const ConfigurationType& BuildType::config() const { return this->m_config; } - - const Build::LinkageType& BuildType::linkage() const { return this->m_linkage; } - - const std::regex& BuildType::crt_regex() const - { - static const std::regex REGEX_DEBUG_STATIC(R"(/DEFAULTLIB:LIBCMTD)", std::regex_constants::icase); - static const std::regex REGEX_DEBUG_DYNAMIC(R"(/DEFAULTLIB:MSVCRTD)", std::regex_constants::icase); - static const std::regex REGEX_RELEASE_STATIC(R"(/DEFAULTLIB:LIBCMT[^D])", std::regex_constants::icase); - static const std::regex REGEX_RELEASE_DYNAMIC(R"(/DEFAULTLIB:MSVCRT[^D])", std::regex_constants::icase); - - switch (backing_enum) - { - case BuildTypeC::DEBUG_STATIC: return REGEX_DEBUG_STATIC; - case BuildTypeC::DEBUG_DYNAMIC: return REGEX_DEBUG_DYNAMIC; - case BuildTypeC::RELEASE_STATIC: return REGEX_RELEASE_STATIC; - case BuildTypeC::RELEASE_DYNAMIC: return REGEX_RELEASE_DYNAMIC; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - const std::string& BuildType::to_string() const - { - static const std::string NAME_DEBUG_STATIC("Debug,Static"); - static const std::string NAME_DEBUG_DYNAMIC("Debug,Dynamic"); - static const std::string NAME_RELEASE_STATIC("Release,Static"); - static const std::string NAME_RELEASE_DYNAMIC("Release,Dynamic"); - - switch (backing_enum) - { - case BuildTypeC::DEBUG_STATIC: return NAME_DEBUG_STATIC; - case BuildTypeC::DEBUG_DYNAMIC: return NAME_DEBUG_DYNAMIC; - case BuildTypeC::RELEASE_STATIC: return NAME_RELEASE_STATIC; - case BuildTypeC::RELEASE_DYNAMIC: return NAME_RELEASE_DYNAMIC; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } -} diff --git a/toolsrc/src/SourceParagraph.cpp b/toolsrc/src/SourceParagraph.cpp deleted file mode 100644 index 0f1a38d19..000000000 --- a/toolsrc/src/SourceParagraph.cpp +++ /dev/null @@ -1,262 +0,0 @@ -#include "pch.h" - -#include "PackageSpec.h" -#include "SourceParagraph.h" -#include "Triplet.h" -#include "vcpkg_Checks.h" -#include "vcpkg_Maps.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" -#include "vcpkg_expected.h" - -namespace vcpkg -{ - using namespace vcpkg::Parse; - - namespace Fields - { - static const std::string BUILD_DEPENDS = "Build-Depends"; - static const std::string DEFAULTFEATURES = "Default-Features"; - static const std::string DESCRIPTION = "Description"; - static const std::string FEATURE = "Feature"; - static const std::string MAINTAINER = "Maintainer"; - static const std::string SOURCE = "Source"; - static const std::string SUPPORTS = "Supports"; - static const std::string VERSION = "Version"; - } - - static Span get_list_of_valid_fields() - { - static const std::string valid_fields[] = { - Fields::SOURCE, - Fields::VERSION, - Fields::DESCRIPTION, - Fields::MAINTAINER, - Fields::BUILD_DEPENDS, - }; - - return valid_fields; - } - - void print_error_message(Span> error_info_list) - { - Checks::check_exit(VCPKG_LINE_INFO, error_info_list.size() > 0); - - for (auto&& error_info : error_info_list) - { - Checks::check_exit(VCPKG_LINE_INFO, error_info != nullptr); - if (error_info->error) - { - System::println( - System::Color::error, "Error: while loading %s: %s", error_info->name, error_info->error.message()); - } - } - - bool have_remaining_fields = false; - for (auto&& error_info : error_info_list) - { - if (!error_info->extra_fields.empty()) - { - System::println(System::Color::error, - "Error: There are invalid fields in the control file of %s", - error_info->name); - System::println("The following fields were not expected:\n\n %s\n", - Strings::join("\n ", error_info->extra_fields)); - have_remaining_fields = true; - } - } - - if (have_remaining_fields) - { - System::println("This is the list of valid fields (case-sensitive): \n\n %s\n", - Strings::join("\n ", get_list_of_valid_fields())); - System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n"); - } - - for (auto&& error_info : error_info_list) - { - if (!error_info->missing_fields.empty()) - { - System::println(System::Color::error, - "Error: There are missing fields in the control file of %s", - error_info->name); - System::println("The following fields were missing:\n\n %s\n", - Strings::join("\n ", error_info->missing_fields)); - } - } - } - - static ParseExpected parse_source_paragraph(RawParagraph&& fields) - { - ParagraphParser parser(std::move(fields)); - - auto spgh = std::make_unique(); - - parser.required_field(Fields::SOURCE, spgh->name); - parser.required_field(Fields::VERSION, spgh->version); - - spgh->description = parser.optional_field(Fields::DESCRIPTION); - spgh->maintainer = parser.optional_field(Fields::MAINTAINER); - spgh->depends = expand_qualified_dependencies(parse_comma_list(parser.optional_field(Fields::BUILD_DEPENDS))); - spgh->supports = parse_comma_list(parser.optional_field(Fields::SUPPORTS)); - spgh->default_features = parse_comma_list(parser.optional_field(Fields::DEFAULTFEATURES)); - - auto err = parser.error_info(spgh->name); - if (err) - return std::move(err); - else - return std::move(spgh); - } - - static ParseExpected parse_feature_paragraph(RawParagraph&& fields) - { - ParagraphParser parser(std::move(fields)); - - auto fpgh = std::make_unique(); - - parser.required_field(Fields::FEATURE, fpgh->name); - parser.required_field(Fields::DESCRIPTION, fpgh->description); - - fpgh->depends = expand_qualified_dependencies(parse_comma_list(parser.optional_field(Fields::BUILD_DEPENDS))); - - auto err = parser.error_info(fpgh->name); - if (err) - return std::move(err); - else - return std::move(fpgh); - } - - ParseExpected SourceControlFile::parse_control_file( - std::vector>&& control_paragraphs) - { - if (control_paragraphs.size() == 0) - { - return std::make_unique(); - } - - auto control_file = std::make_unique(); - - auto maybe_source = parse_source_paragraph(std::move(control_paragraphs.front())); - if (const auto source = maybe_source.get()) - control_file->core_paragraph = std::move(*source); - else - return std::move(maybe_source).error(); - - control_paragraphs.erase(control_paragraphs.begin()); - - for (auto&& feature_pgh : control_paragraphs) - { - auto maybe_feature = parse_feature_paragraph(std::move(feature_pgh)); - if (const auto feature = maybe_feature.get()) - control_file->feature_paragraphs.emplace_back(std::move(*feature)); - else - return std::move(maybe_feature).error(); - } - - return std::move(control_file); - } - - Dependency Dependency::parse_dependency(std::string name, std::string qualifier) - { - Dependency dep; - dep.qualifier = qualifier; - if (auto maybe_features = Features::from_string(name)) - dep.depend = *maybe_features.get(); - else - Checks::exit_with_message( - VCPKG_LINE_INFO, "error while parsing dependency: %s: %s", to_string(maybe_features.error()), name); - return dep; - } - - std::string Dependency::name() const - { - if (this->depend.features.empty()) return this->depend.name; - - const std::string features = Strings::join(",", this->depend.features); - return Strings::format("%s[%s]", this->depend.name, features); - } - - std::vector vcpkg::expand_qualified_dependencies(const std::vector& depends) - { - return Util::fmap(depends, [&](const std::string& depend_string) -> Dependency { - auto pos = depend_string.find(' '); - if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, Strings::EMPTY); - // expect of the form "\w+ \[\w+\]" - Dependency dep; - - dep.depend.name = depend_string.substr(0, pos); - if (depend_string.c_str()[pos + 1] != '(' || depend_string[depend_string.size() - 1] != ')') - { - // Error, but for now just slurp the entire string. - return Dependency::parse_dependency(depend_string, Strings::EMPTY); - } - dep.qualifier = depend_string.substr(pos + 2, depend_string.size() - pos - 3); - return dep; - }); - } - - std::vector filter_dependencies(const std::vector& deps, const Triplet& t) - { - std::vector ret; - for (auto&& dep : deps) - { - if (dep.qualifier.empty() || t.canonical_name().find(dep.qualifier) != std::string::npos) - { - ret.emplace_back(dep.name()); - } - } - return ret; - } - - std::vector filter_dependencies_to_specs(const std::vector& deps, const Triplet& t) - { - return FeatureSpec::from_strings_and_triplet(filter_dependencies(deps, t), t); - } - - std::string to_string(const Dependency& dep) { return dep.name(); } - - ExpectedT> Supports::parse(const std::vector& strs) - { - Supports ret; - std::vector unrecognized; - - for (auto&& str : strs) - { - if (str == "x64") - ret.architectures.push_back(Architecture::X64); - else if (str == "x86") - ret.architectures.push_back(Architecture::X86); - else if (str == "arm") - ret.architectures.push_back(Architecture::ARM); - else if (str == "windows") - ret.platforms.push_back(Platform::WINDOWS); - else if (str == "uwp") - ret.platforms.push_back(Platform::UWP); - else if (str == "v140") - ret.toolsets.push_back(ToolsetVersion::V140); - else if (str == "v141") - ret.toolsets.push_back(ToolsetVersion::V141); - else if (str == "crt-static") - ret.crt_linkages.push_back(Linkage::STATIC); - else if (str == "crt-dynamic") - ret.crt_linkages.push_back(Linkage::DYNAMIC); - else - unrecognized.push_back(str); - } - - if (unrecognized.empty()) - return std::move(ret); - else - return std::move(unrecognized); - } - - bool Supports::is_supported(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools) - { - const auto is_in_or_empty = [](auto v, auto&& c) -> bool { return c.empty() || c.end() != Util::find(c, v); }; - if (!is_in_or_empty(arch, architectures)) return false; - if (!is_in_or_empty(plat, platforms)) return false; - if (!is_in_or_empty(crt, crt_linkages)) return false; - if (!is_in_or_empty(tools, toolsets)) return false; - return true; - } -} diff --git a/toolsrc/src/StatusParagraph.cpp b/toolsrc/src/StatusParagraph.cpp deleted file mode 100644 index f8ae293c2..000000000 --- a/toolsrc/src/StatusParagraph.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "pch.h" - -#include "StatusParagraph.h" - -using namespace vcpkg::Parse; - -namespace vcpkg -{ - namespace BinaryParagraphRequiredField - { - static const std::string STATUS = "Status"; - } - - StatusParagraph::StatusParagraph() : want(Want::ERROR_STATE), state(InstallState::ERROR_STATE) {} - - void serialize(const StatusParagraph& pgh, std::string& out_str) - { - serialize(pgh.package, out_str); - out_str.append("Status: ") - .append(to_string(pgh.want)) - .append(" ok ") - .append(to_string(pgh.state)) - .push_back('\n'); - } - - StatusParagraph::StatusParagraph(std::unordered_map&& fields) - { - auto status_it = fields.find(BinaryParagraphRequiredField::STATUS); - Checks::check_exit(VCPKG_LINE_INFO, status_it != fields.end(), "Expected 'Status' field in status paragraph"); - std::string status_field = std::move(status_it->second); - fields.erase(status_it); - - this->package = BinaryParagraph(std::move(fields)); - - auto b = status_field.begin(); - const auto mark = b; - const auto e = status_field.end(); - - // Todo: improve error handling - while (b != e && *b != ' ') - ++b; - - want = [](const std::string& text) { - if (text == "unknown") return Want::UNKNOWN; - if (text == "install") return Want::INSTALL; - if (text == "hold") return Want::HOLD; - if (text == "deinstall") return Want::DEINSTALL; - if (text == "purge") return Want::PURGE; - return Want::ERROR_STATE; - }(std::string(mark, b)); - - if (std::distance(b, e) < 4) return; - b += 4; - - state = [](const std::string& text) { - if (text == "not-installed") return InstallState::NOT_INSTALLED; - if (text == "installed") return InstallState::INSTALLED; - if (text == "half-installed") return InstallState::HALF_INSTALLED; - return InstallState::ERROR_STATE; - }(std::string(b, e)); - } - - std::string to_string(InstallState f) - { - switch (f) - { - case InstallState::HALF_INSTALLED: return "half-installed"; - case InstallState::INSTALLED: return "installed"; - case InstallState::NOT_INSTALLED: return "not-installed"; - default: return "error"; - } - } - - std::string to_string(Want f) - { - switch (f) - { - case Want::DEINSTALL: return "deinstall"; - case Want::HOLD: return "hold"; - case Want::INSTALL: return "install"; - case Want::PURGE: return "purge"; - case Want::UNKNOWN: return "unknown"; - default: return "error"; - } - } -} diff --git a/toolsrc/src/StatusParagraphs.cpp b/toolsrc/src/StatusParagraphs.cpp deleted file mode 100644 index aaba95eb9..000000000 --- a/toolsrc/src/StatusParagraphs.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "pch.h" - -#include "StatusParagraphs.h" -#include "vcpkg_Checks.h" -#include - -namespace vcpkg -{ - StatusParagraphs::StatusParagraphs() = default; - - StatusParagraphs::StatusParagraphs(std::vector>&& ps) - : paragraphs(std::move(ps)){}; - - StatusParagraphs::const_iterator StatusParagraphs::find(const std::string& name, const Triplet& triplet) const - { - return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { - const PackageSpec& spec = pgh->package.spec; - return spec.name() == name && spec.triplet() == triplet; - }); - } - - StatusParagraphs::iterator StatusParagraphs::find(const std::string& name, const Triplet& triplet) - { - return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { - const PackageSpec& spec = pgh->package.spec; - return spec.name() == name && spec.triplet() == triplet; - }); - } - - std::vector*> StatusParagraphs::find_all(const std::string& name, - const Triplet& triplet) - { - std::vector*> spghs; - for (auto&& p : *this) - { - if (p->package.spec.name() == name && p->package.spec.triplet() == triplet) - { - spghs.emplace_back(&p); - } - } - return spghs; - } - - StatusParagraphs::iterator StatusParagraphs::find(const std::string& name, - const Triplet& triplet, - const std::string& feature) - { - return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { - const PackageSpec& spec = pgh->package.spec; - return spec.name() == name && spec.triplet() == triplet && pgh->package.feature == feature; - }); - } - - StatusParagraphs::const_iterator StatusParagraphs::find_installed(const std::string& name, - const Triplet& triplet) const - { - const const_iterator it = find(name, triplet); - if (it != end() && (*it)->want == Want::INSTALL && (*it)->state == InstallState::INSTALLED) - { - return it; - } - - return end(); - } - - StatusParagraphs::iterator StatusParagraphs::insert(std::unique_ptr pgh) - { - Checks::check_exit(VCPKG_LINE_INFO, pgh != nullptr, "Inserted null paragraph"); - const PackageSpec& spec = pgh->package.spec; - const auto ptr = find(spec.name(), spec.triplet(), pgh->package.feature); - if (ptr == end()) - { - paragraphs.push_back(std::move(pgh)); - return paragraphs.rbegin(); - } - - // consume data from provided pgh. - **ptr = std::move(*pgh); - return ptr; - } - - void serialize(const StatusParagraphs& pghs, std::string& out_str) - { - for (auto& pgh : pghs.paragraphs) - { - serialize(*pgh, out_str); - out_str.push_back('\n'); - } - } -} diff --git a/toolsrc/src/VcpkgCmdArguments.cpp b/toolsrc/src/VcpkgCmdArguments.cpp deleted file mode 100644 index cb261930e..000000000 --- a/toolsrc/src/VcpkgCmdArguments.cpp +++ /dev/null @@ -1,283 +0,0 @@ -#include "pch.h" - -#include "VcpkgCmdArguments.h" -#include "metrics.h" -#include "vcpkg_Commands.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_System.h" - -namespace vcpkg -{ - static void parse_value(const std::string* arg_begin, - const std::string* arg_end, - const std::string& option_name, - std::unique_ptr& option_field) - { - if (arg_begin == arg_end) - { - System::println(System::Color::error, "Error: expected value after %s", option_name); - Metrics::g_metrics.lock()->track_property("error", "error option name"); - Commands::Help::print_usage(); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - if (option_field != nullptr) - { - System::println(System::Color::error, "Error: %s specified multiple times", option_name); - Metrics::g_metrics.lock()->track_property("error", "error option specified multiple times"); - Commands::Help::print_usage(); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - option_field = std::make_unique(*arg_begin); - } - - static void parse_switch(bool new_setting, const std::string& option_name, Optional& option_field) - { - if (option_field && option_field != new_setting) - { - System::println(System::Color::error, "Error: conflicting values specified for --%s", option_name); - Metrics::g_metrics.lock()->track_property("error", "error conflicting switches"); - Commands::Help::print_usage(); - Checks::exit_fail(VCPKG_LINE_INFO); - } - option_field = new_setting; - } - - VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc, const wchar_t* const* const argv) - { - std::vector v; - for (int i = 1; i < argc; ++i) - { - v.push_back(Strings::to_utf8(argv[i])); - } - - return VcpkgCmdArguments::create_from_arg_sequence(v.data(), v.data() + v.size()); - } - - VcpkgCmdArguments VcpkgCmdArguments::create_from_arg_sequence(const std::string* arg_begin, - const std::string* arg_end) - { - VcpkgCmdArguments args; - - for (; arg_begin != arg_end; ++arg_begin) - { - std::string arg = *arg_begin; - - if (arg.empty()) - { - continue; - } - - if (arg[0] == '-' && arg[1] != '-') - { - Metrics::g_metrics.lock()->track_property("error", "error short options are not supported"); - Checks::exit_with_message(VCPKG_LINE_INFO, "Error: short options are not supported: %s", arg); - } - - if (arg[0] == '-' && arg[1] == '-') - { - // make argument case insensitive - auto& f = std::use_facet>(std::locale()); - f.tolower(&arg[0], &arg[0] + arg.size()); - // command switch - if (arg == "--vcpkg-root") - { - ++arg_begin; - parse_value(arg_begin, arg_end, "--vcpkg-root", args.vcpkg_root_dir); - continue; - } - if (arg == "--triplet") - { - ++arg_begin; - parse_value(arg_begin, arg_end, "--triplet", args.triplet); - continue; - } - if (arg == "--debug") - { - parse_switch(true, "debug", args.debug); - continue; - } - if (arg == "--sendmetrics") - { - parse_switch(true, "sendmetrics", args.sendmetrics); - continue; - } - if (arg == "--printmetrics") - { - parse_switch(true, "printmetrics", args.printmetrics); - continue; - } - if (arg == "--no-sendmetrics") - { - parse_switch(false, "sendmetrics", args.sendmetrics); - continue; - } - if (arg == "--no-printmetrics") - { - parse_switch(false, "printmetrics", args.printmetrics); - continue; - } - if (arg == "--featurepackages") - { - GlobalState::feature_packages = true; - continue; - } - - const auto eq_pos = arg.find('='); - if (eq_pos != std::string::npos) - { - args.optional_command_arguments.emplace(arg.substr(0, eq_pos), arg.substr(eq_pos + 1)); - } - else - { - args.optional_command_arguments.emplace(arg, nullopt); - } - continue; - } - - if (args.command.empty()) - { - args.command = arg; - } - else - { - args.command_arguments.push_back(arg); - } - } - - return args; - } - - ParsedArguments VcpkgCmdArguments::check_and_get_optional_command_arguments( - const std::vector& valid_switches, const std::vector& valid_settings) const - { - bool failed = false; - ParsedArguments output; - - auto options_copy = this->optional_command_arguments; - for (const std::string& option : valid_switches) - { - const auto it = options_copy.find(option); - if (it != options_copy.end()) - { - if (it->second.has_value()) - { - // Having a string value indicates it was passed like '--a=xyz' - System::println(System::Color::error, "The option '%s' does not accept an argument.", option); - failed = true; - } - else - { - output.switches.insert(option); - options_copy.erase(it); - } - } - } - - for (const std::string& option : valid_settings) - { - const auto it = options_copy.find(option); - if (it != options_copy.end()) - { - if (!it->second.has_value()) - { - // Not having a string value indicates it was passed like '--a' - System::println(System::Color::error, "The option '%s' must be passed an argument.", option); - failed = true; - } - else - { - output.settings.emplace(option, it->second.value_or_exit(VCPKG_LINE_INFO)); - options_copy.erase(it); - } - } - } - - if (!options_copy.empty()) - { - System::println(System::Color::error, "Unknown option(s) for command '%s':", this->command); - for (auto&& option : options_copy) - { - System::println(" %s", option.first); - } - System::println("\nValid options are:", this->command); - for (auto&& option : valid_switches) - { - System::println(" %s", option); - } - for (auto&& option : valid_settings) - { - System::println(" %s=...", option); - } - System::println(" --triplet "); - System::println(" --vcpkg-root "); - - Checks::exit_fail(VCPKG_LINE_INFO); - } - if (failed) Checks::exit_fail(VCPKG_LINE_INFO); - - return output; - } - - void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count) const - { - return check_max_arg_count(expected_arg_count, Strings::EMPTY); - } - - void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count) const - { - return check_min_arg_count(expected_arg_count, Strings::EMPTY); - } - - void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count) const - { - return check_exact_arg_count(expected_arg_count, Strings::EMPTY); - } - - void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const - { - const size_t actual_arg_count = command_arguments.size(); - if (actual_arg_count > expected_arg_count) - { - System::println(System::Color::error, - "Error: `%s` requires at most %u arguments, but %u were provided", - this->command, - expected_arg_count, - actual_arg_count); - System::print(example_text); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - - void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count, const std::string& example_text) const - { - const size_t actual_arg_count = command_arguments.size(); - if (actual_arg_count < expected_arg_count) - { - System::println(System::Color::error, - "Error: `%s` requires at least %u arguments, but %u were provided", - this->command, - expected_arg_count, - actual_arg_count); - System::print(example_text); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - - void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count, - const std::string& example_text) const - { - const size_t actual_arg_count = command_arguments.size(); - if (actual_arg_count != expected_arg_count) - { - System::println(System::Color::error, - "Error: `%s` requires %u arguments, but %u were provided", - this->command, - expected_arg_count, - actual_arg_count); - System::print(example_text); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } -} diff --git a/toolsrc/src/VcpkgPaths.cpp b/toolsrc/src/VcpkgPaths.cpp deleted file mode 100644 index d14002e47..000000000 --- a/toolsrc/src/VcpkgPaths.cpp +++ /dev/null @@ -1,519 +0,0 @@ -#include "pch.h" - -#include "PackageSpec.h" -#include "VcpkgPaths.h" -#include "metrics.h" -#include "vcpkg_Files.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" -#include "vcpkg_expected.h" - -namespace vcpkg -{ - static constexpr CWStringView V_120 = L"v120"; - static constexpr CWStringView V_140 = L"v140"; - static constexpr CWStringView V_141 = L"v141"; - - static bool exists_and_has_equal_or_greater_version(const std::wstring& version_cmd, - const std::array& expected_version) - { - static const std::regex RE(R"###((\d+)\.(\d+)\.(\d+))###"); - - const auto rc = System::cmd_execute_and_capture_output(Strings::wformat(LR"(%s)", version_cmd)); - if (rc.exit_code != 0) - { - return false; - } - - std::match_results match; - const auto found = std::regex_search(rc.output, match, RE); - if (!found) - { - return false; - } - - const int d1 = atoi(match[1].str().c_str()); - const int d2 = atoi(match[2].str().c_str()); - const int d3 = atoi(match[3].str().c_str()); - if (d1 > expected_version[0] || (d1 == expected_version[0] && d2 > expected_version[1]) || - (d1 == expected_version[0] && d2 == expected_version[1] && d3 >= expected_version[2])) - { - // satisfactory version found - return true; - } - - return false; - } - - static Optional find_if_has_equal_or_greater_version(const std::vector& candidate_paths, - const std::wstring& version_check_arguments, - const std::array& expected_version) - { - auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { - const std::wstring cmd = Strings::wformat(LR"("%s" %s)", p.native(), version_check_arguments); - return exists_and_has_equal_or_greater_version(cmd, expected_version); - }); - - if (it != candidate_paths.cend()) - { - return std::move(*it); - } - - return nullopt; - } - - static fs::path fetch_dependency(const fs::path& scripts_folder, - const std::wstring& tool_name, - const fs::path& expected_downloaded_path, - const std::array& version) - { - const std::string tool_name_utf8 = Strings::to_utf8(tool_name); - const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); - System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...", - tool_name_utf8, - version_as_string, - tool_name_utf8, - version_as_string); - const fs::path script = scripts_folder / "fetchDependency.ps1"; - const auto install_cmd = - System::create_powershell_script_cmd(script, Strings::wformat(L"-Dependency %s", tool_name)); - const System::ExitCodeAndOutput rc = System::cmd_execute_and_capture_output(install_cmd); - if (rc.exit_code) - { - System::println(System::Color::error, - "Launching powershell failed or was denied when trying to fetch %s version %s.\n" - "(No sufficient installed version was found)", - tool_name_utf8, - version_as_string); - { - auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->track_property("error", "powershell install failed"); - locked_metrics->track_property("dependency", tool_name); - } - Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code); - } - - const fs::path actual_downloaded_path = Strings::trimmed(rc.output); - std::error_code ec; - const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - eq && !ec, - "Expected dependency downloaded path to be %s, but was %s", - expected_downloaded_path.u8string(), - actual_downloaded_path.u8string()); - return actual_downloaded_path; - } - - static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) - { - static constexpr std::array EXPECTED_VERSION = {3, 9, 3}; - static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version"; - - const fs::path downloaded_copy = downloads_folder / "cmake-3.9.3-win32-x86" / "bin" / "cmake.exe"; - const std::vector from_path = Files::find_from_PATH(L"cmake"); - - std::vector candidate_paths; - candidate_paths.push_back(downloaded_copy); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - candidate_paths.push_back(System::get_program_files_platform_bitness() / "CMake" / "bin" / "cmake.exe"); - candidate_paths.push_back(System::get_program_files_32_bit() / "CMake" / "bin"); - - const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); - if (const auto p = path.get()) - { - return *p; - } - - return fetch_dependency(scripts_folder, L"cmake", downloaded_copy, EXPECTED_VERSION); - } - - fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder) - { - static constexpr std::array EXPECTED_VERSION = {4, 3, 0}; - static const std::wstring VERSION_CHECK_ARGUMENTS = Strings::WEMPTY; - - const fs::path downloaded_copy = downloads_folder / "nuget-4.3.0" / "nuget.exe"; - const std::vector from_path = Files::find_from_PATH(L"nuget"); - - std::vector candidate_paths; - candidate_paths.push_back(downloaded_copy); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - - auto path = find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); - if (const auto p = path.get()) - { - return *p; - } - - return fetch_dependency(scripts_folder, L"nuget", downloaded_copy, EXPECTED_VERSION); - } - - fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder) - { - static constexpr std::array EXPECTED_VERSION = {2, 14, 1}; - static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version"; - - const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.1-32-bit" / "cmd" / "git.exe"; - const std::vector from_path = Files::find_from_PATH(L"git"); - - std::vector candidate_paths; - candidate_paths.push_back(downloaded_copy); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - candidate_paths.push_back(System::get_program_files_platform_bitness() / "git" / "cmd" / "git.exe"); - candidate_paths.push_back(System::get_program_files_32_bit() / "git" / "cmd" / "git.exe"); - - const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); - if (const auto p = path.get()) - { - return *p; - } - - return fetch_dependency(scripts_folder, L"git", downloaded_copy, EXPECTED_VERSION); - } - - static fs::path get_ifw_installerbase_path(const fs::path& downloads_folder, const fs::path& scripts_folder) - { - static constexpr std::array EXPECTED_VERSION = {3, 1, 81}; - static const std::wstring VERSION_CHECK_ARGUMENTS = L"--framework-version"; - - const fs::path downloaded_copy = - downloads_folder / "QtInstallerFramework-win-x86" / "bin" / "installerbase.exe"; - - std::vector candidate_paths; - candidate_paths.push_back(downloaded_copy); - // TODO: Uncomment later - // const std::vector from_path = Files::find_from_PATH(L"installerbase"); - // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / - // "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe"); - // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / - // "QtIFW-3.1.0" / "bin" / "installerbase.exe"); - - const Optional path = - find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); - if (const auto p = path.get()) - { - return *p; - } - - return fetch_dependency(scripts_folder, L"installerbase", downloaded_copy, EXPECTED_VERSION); - } - - Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir) - { - std::error_code ec; - const fs::path canonical_vcpkg_root_dir = fs::stdfs::canonical(vcpkg_root_dir, ec); - if (ec) - { - return ec; - } - - VcpkgPaths paths; - paths.root = canonical_vcpkg_root_dir; - - if (paths.root.empty()) - { - Metrics::g_metrics.lock()->track_property("error", "Invalid vcpkg root directory"); - Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid vcpkg root directory: %s", paths.root.string()); - } - - paths.packages = paths.root / "packages"; - paths.buildtrees = paths.root / "buildtrees"; - paths.downloads = paths.root / "downloads"; - paths.ports = paths.root / "ports"; - paths.installed = paths.root / "installed"; - paths.triplets = paths.root / "triplets"; - paths.scripts = paths.root / "scripts"; - - paths.buildsystems = paths.scripts / "buildsystems"; - paths.buildsystems_msbuild_targets = paths.buildsystems / "msbuild" / "vcpkg.targets"; - - paths.vcpkg_dir = paths.installed / "vcpkg"; - paths.vcpkg_dir_status_file = paths.vcpkg_dir / "status"; - paths.vcpkg_dir_info = paths.vcpkg_dir / "info"; - paths.vcpkg_dir_updates = paths.vcpkg_dir / "updates"; - - paths.ports_cmake = paths.scripts / "ports.cmake"; - - return paths; - } - - fs::path VcpkgPaths::package_dir(const PackageSpec& spec) const { return this->packages / spec.dir(); } - - fs::path VcpkgPaths::port_dir(const PackageSpec& spec) const { return this->ports / spec.name(); } - fs::path VcpkgPaths::port_dir(const std::string& name) const { return this->ports / name; } - - fs::path VcpkgPaths::build_info_file_path(const PackageSpec& spec) const - { - return this->package_dir(spec) / "BUILD_INFO"; - } - - fs::path VcpkgPaths::listfile_path(const BinaryParagraph& pgh) const - { - return this->vcpkg_dir_info / (pgh.fullstem() + ".list"); - } - - bool VcpkgPaths::is_valid_triplet(const Triplet& t) const - { - for (auto&& path : get_filesystem().get_files_non_recursive(this->triplets)) - { - const std::string triplet_file_name = path.stem().generic_u8string(); - if (t.canonical_name() == triplet_file_name) // TODO: fuzzy compare - { - // t.value = triplet_file_name; // NOTE: uncomment when implementing fuzzy compare - return true; - } - } - return false; - } - - const fs::path& VcpkgPaths::get_cmake_exe() const - { - return this->cmake_exe.get_lazy([this]() { return get_cmake_path(this->downloads, this->scripts); }); - } - - const fs::path& VcpkgPaths::get_git_exe() const - { - return this->git_exe.get_lazy([this]() { return get_git_path(this->downloads, this->scripts); }); - } - - const fs::path& VcpkgPaths::get_nuget_exe() const - { - return this->nuget_exe.get_lazy([this]() { return get_nuget_path(this->downloads, this->scripts); }); - } - - const fs::path& VcpkgPaths::get_ifw_installerbase_exe() const - { - return this->ifw_installerbase_exe.get_lazy( - [this]() { return get_ifw_installerbase_path(this->downloads, this->scripts); }); - } - - const fs::path& VcpkgPaths::get_ifw_binarycreator_exe() const - { - return this->ifw_binarycreator_exe.get_lazy( - [this]() { return get_ifw_installerbase_exe().parent_path() / "binarycreator.exe"; }); - } - - const fs::path& VcpkgPaths::get_ifw_repogen_exe() const - { - return this->ifw_repogen_exe.get_lazy( - [this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; }); - } - - struct VisualStudioInstance - { - fs::path root_path; - std::string version; - std::string release_type; - std::string preference_weight; // Mostly unused, just for verification that order is as intended - - std::string major_version() const { return version.substr(0, 2); } - }; - - static std::vector get_visual_studio_instances(const VcpkgPaths& paths) - { - const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; - const std::wstring cmd = System::create_powershell_script_cmd(script); - const System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd); - Checks::check_exit( - VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect Visual Studio instances"); - - const std::vector instances_as_strings = Strings::split(ec_data.output, "\n"); - std::vector output; - for (const std::string& instance_as_string : instances_as_strings) - { - const std::vector split = Strings::split(instance_as_string, "::"); - output.push_back({split.at(3), split.at(2), split.at(1), split.at(0)}); - } - - return output; - } - - static std::vector find_toolset_instances(const VcpkgPaths& paths) - { - using CPU = System::CPUArchitecture; - - const auto& fs = paths.get_filesystem(); - - // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations. - std::vector paths_examined; - - std::vector found_toolsets; - - const std::vector vs_instances = get_visual_studio_instances(paths); - const bool v140_is_available = Util::find_if(vs_instances, [&](const VisualStudioInstance& vs_instance) { - return vs_instance.major_version() == "14"; - }) != vs_instances.cend(); - - for (const VisualStudioInstance& vs_instance : vs_instances) - { - const std::string major_version = vs_instance.major_version(); - if (major_version == "15") - { - const fs::path vc_dir = vs_instance.root_path / "VC"; - - // Skip any instances that do not have vcvarsall. - const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build"; - const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat"; - paths_examined.push_back(vcvarsall_bat); - if (!fs.exists(vcvarsall_bat)) continue; - - // Get all supported architectures - std::vector supported_architectures; - if (fs.exists(vcvarsall_dir / "vcvars32.bat")) - supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); - if (fs.exists(vcvarsall_dir / "vcvars64.bat")) - supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64}); - if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) - supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); - if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) - supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); - if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) - supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); - if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) - supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); - - // Locate the "best" MSVC toolchain version - const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; - std::vector msvc_subdirectories = fs.get_files_non_recursive(msvc_path); - Util::unstable_keep_if(msvc_subdirectories, - [&fs](const fs::path& path) { return fs.is_directory(path); }); - - // Sort them so that latest comes first - std::sort( - msvc_subdirectories.begin(), - msvc_subdirectories.end(), - [](const fs::path& left, const fs::path& right) { return left.filename() > right.filename(); }); - - for (const fs::path& subdir : msvc_subdirectories) - { - const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe"; - paths_examined.push_back(dumpbin_path); - if (fs.exists(dumpbin_path)) - { - found_toolsets.push_back(Toolset{ - vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}); - - if (v140_is_available) - { - found_toolsets.push_back(Toolset{vs_instance.root_path, - dumpbin_path, - vcvarsall_bat, - {L"-vcvars_ver=14.0"}, - V_140, - supported_architectures}); - } - - break; - } - } - - continue; - } - - if (major_version == "14") - { - const fs::path vcvarsall_bat = vs_instance.root_path / "VC" / "vcvarsall.bat"; - - paths_examined.push_back(vcvarsall_bat); - if (fs.exists(vcvarsall_bat)) - { - const fs::path vs2015_dumpbin_exe = vs_instance.root_path / "VC" / "bin" / "dumpbin.exe"; - paths_examined.push_back(vs2015_dumpbin_exe); - - const fs::path vs2015_bin_dir = vcvarsall_bat.parent_path() / "bin"; - std::vector supported_architectures; - if (fs.exists(vs2015_bin_dir / "vcvars32.bat")) - supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); - if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat")) - supported_architectures.push_back({L"x64", CPU::X64, CPU::X64}); - if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) - supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); - if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) - supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); - if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) - supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); - if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) - supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); - - if (fs.exists(vs2015_dumpbin_exe)) - { - found_toolsets.push_back({vs_instance.root_path, - vs2015_dumpbin_exe, - vcvarsall_bat, - {}, - V_140, - supported_architectures}); - } - } - } - } - - if (found_toolsets.empty()) - { - System::println(System::Color::error, "Could not locate a complete toolset."); - System::println("The following paths were examined:"); - for (const fs::path& path : paths_examined) - { - System::println(" %s", path.u8string()); - } - Checks::exit_fail(VCPKG_LINE_INFO); - } - - return found_toolsets; - } - - const Toolset& VcpkgPaths::get_toolset(const Optional& toolset_version, - const Optional& visual_studio_path) const - { - // Invariant: toolsets are non-empty and sorted with newest at back() - const std::vector& vs_toolsets = - this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); - - std::vector candidates = Util::element_pointers(vs_toolsets); - const auto tsv = toolset_version.get(); - const auto vsp = visual_studio_path.get(); - - if (tsv && vsp) - { - const std::wstring w_toolset_version = Strings::to_utf16(*tsv); - const fs::path vs_root_path = *vsp; - Util::stable_keep_if(candidates, [&](const Toolset* t) { - return w_toolset_version == t->version && vs_root_path == t->visual_studio_root_path; - }); - Checks::check_exit(VCPKG_LINE_INFO, - !candidates.empty(), - "Could not find Visual Studio instace at %s with %s toolset.", - vs_root_path.generic_string(), - *tsv); - - Checks::check_exit(VCPKG_LINE_INFO, candidates.size() == 1); - return *candidates.back(); - } - - if (tsv) - { - const std::wstring w_toolset_version = Strings::to_utf16(*tsv); - Util::stable_keep_if(candidates, [&](const Toolset* t) { return w_toolset_version == t->version; }); - Checks::check_exit( - VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instace with %s toolset.", *tsv); - } - - if (vsp) - { - const fs::path vs_root_path = *vsp; - Util::stable_keep_if(candidates, - [&](const Toolset* t) { return vs_root_path == t->visual_studio_root_path; }); - Checks::check_exit(VCPKG_LINE_INFO, - !candidates.empty(), - "Could not find Visual Studio instace at %s.", - vs_root_path.generic_string()); - } - - return *candidates.front(); - } - - Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); } -} diff --git a/toolsrc/src/VersionT.cpp b/toolsrc/src/VersionT.cpp deleted file mode 100644 index 738d2ce88..000000000 --- a/toolsrc/src/VersionT.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "pch.h" - -#include "VersionT.h" -#include "vcpkg_Strings.h" - -namespace vcpkg -{ - VersionT::VersionT() : value("0.0.0") {} - VersionT::VersionT(const std::string& value) : value(value) {} - std::string VersionT::to_string() const { return value; } - bool operator==(const VersionT& left, const VersionT& right) { return left.value == right.value; } - bool operator!=(const VersionT& left, const VersionT& right) { return left.value != right.value; } - std::string to_printf_arg(const VersionT& version) { return version.value; } - - VersionDiff::VersionDiff() : left(), right() {} - VersionDiff::VersionDiff(const VersionT& left, const VersionT& right) : left(left), right(right) {} - - std::string VersionDiff::to_string() const { return Strings::format("%s -> %s", left.value, right.value); } -} diff --git a/toolsrc/src/coff_file_reader.cpp b/toolsrc/src/coff_file_reader.cpp deleted file mode 100644 index bb3a6cefd..000000000 --- a/toolsrc/src/coff_file_reader.cpp +++ /dev/null @@ -1,308 +0,0 @@ -#include "pch.h" - -#include "coff_file_reader.h" -#include "vcpkg_Checks.h" - -using namespace std; - -namespace vcpkg::CoffFileReader -{ - template - static T reinterpret_bytes(const char* data) - { - return (*reinterpret_cast(&data[0])); - } - - template - static T read_value_from_stream(fstream& fs) - { - T data; - fs.read(reinterpret_cast(&data), sizeof data); - return data; - } - - template - static T peek_value_from_stream(fstream& fs) - { - const fpos_t original_pos = fs.tellg().seekpos(); - T data; - fs.read(reinterpret_cast(&data), sizeof data); - fs.seekg(original_pos); - return data; - } - - static void verify_equal_strings( - const LineInfo& line_info, const char* expected, const char* actual, int size, const char* label) - { - Checks::check_exit(line_info, - memcmp(expected, actual, size) == 0, - "Incorrect string (%s) found. Expected: (%s) but found (%s)", - label, - expected, - actual); - } - - static void read_and_verify_PE_signature(fstream& fs) - { - static const size_t OFFSET_TO_PE_SIGNATURE_OFFSET = 0x3c; - - static const char* PE_SIGNATURE = "PE\0\0"; - static const size_t PE_SIGNATURE_SIZE = 4; - - fs.seekg(OFFSET_TO_PE_SIGNATURE_OFFSET, ios_base::beg); - const int32_t offset_to_PE_signature = read_value_from_stream(fs); - - fs.seekg(offset_to_PE_signature); - char signature[PE_SIGNATURE_SIZE]; - fs.read(signature, PE_SIGNATURE_SIZE); - verify_equal_strings(VCPKG_LINE_INFO, PE_SIGNATURE, signature, PE_SIGNATURE_SIZE, "PE_SIGNATURE"); - fs.seekg(offset_to_PE_signature + PE_SIGNATURE_SIZE, ios_base::beg); - } - - static fpos_t align_to_size(const uint64_t unaligned, const uint64_t alignment_size) - { - fpos_t aligned = unaligned - 1; - aligned /= alignment_size; - aligned += 1; - aligned *= alignment_size; - return aligned; - } - - struct CoffFileHeader - { - static const size_t HEADER_SIZE = 20; - - static CoffFileHeader read(fstream& fs) - { - CoffFileHeader ret; - ret.data.resize(HEADER_SIZE); - fs.read(&ret.data[0], HEADER_SIZE); - return ret; - } - - MachineType machine_type() const - { - static const size_t MACHINE_TYPE_OFFSET = 0; - static const size_t MACHINE_TYPE_SIZE = 2; - - std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE); - const uint16_t machine = reinterpret_bytes(machine_field_as_string.c_str()); - return to_machine_type(machine); - } - - private: - std::string data; - }; - - struct ArchiveMemberHeader - { - static const size_t HEADER_SIZE = 60; - - static ArchiveMemberHeader read(fstream& fs) - { - static const size_t HEADER_END_OFFSET = 58; - static const char* HEADER_END = "`\n"; - static const size_t HEADER_END_SIZE = 2; - - ArchiveMemberHeader ret; - ret.data.resize(HEADER_SIZE); - fs.read(&ret.data[0], HEADER_SIZE); - - if (ret.data[0] != '\0') // Due to freeglut. github issue #223 - { - const std::string header_end = ret.data.substr(HEADER_END_OFFSET, HEADER_END_SIZE); - verify_equal_strings( - VCPKG_LINE_INFO, HEADER_END, header_end.c_str(), HEADER_END_SIZE, "LIB HEADER_END"); - } - - return ret; - } - - std::string name() const - { - static const size_t HEADER_NAME_OFFSET = 0; - static const size_t HEADER_NAME_SIZE = 16; - return data.substr(HEADER_NAME_OFFSET, HEADER_NAME_SIZE); - } - - uint64_t member_size() const - { - static const size_t ALIGNMENT_SIZE = 2; - - static const size_t HEADER_SIZE_OFFSET = 48; - static const size_t HEADER_SIZE_FIELD_SIZE = 10; - const std::string as_string = data.substr(HEADER_SIZE_OFFSET, HEADER_SIZE_FIELD_SIZE); - // This is in ASCII decimal representation - const uint64_t value = std::strtoull(as_string.c_str(), nullptr, 10); - - const uint64_t aligned = align_to_size(value, ALIGNMENT_SIZE); - return aligned; - } - - std::string data; - }; - - struct OffsetsArray - { - static OffsetsArray read(fstream& fs, const uint32_t offset_count) - { - static const size_t OFFSET_WIDTH = 4; - - std::string raw_offsets; - const size_t raw_offset_size = offset_count * OFFSET_WIDTH; - raw_offsets.resize(raw_offset_size); - fs.read(&raw_offsets[0], raw_offset_size); - - OffsetsArray ret; - for (uint32_t i = 0; i < offset_count; ++i) - { - const std::string value_as_string = raw_offsets.substr(OFFSET_WIDTH * i, OFFSET_WIDTH * (i + 1)); - const uint32_t value = reinterpret_bytes(value_as_string.c_str()); - - // Ignore offsets that point to offset 0. See vcpkg github #223 #288 #292 - if (value != 0) - { - ret.data.push_back(value); - } - } - - // Sort the offsets, because it is possible for them to be unsorted. See vcpkg github #292 - std::sort(ret.data.begin(), ret.data.end()); - return ret; - } - - std::vector data; - }; - - struct ImportHeader - { - static const size_t HEADER_SIZE = 20; - - static ImportHeader read(fstream& fs) - { - static const size_t SIG1_OFFSET = 0; - static const uint16_t SIG1 = static_cast(MachineType::UNKNOWN); - static const size_t SIG1_SIZE = 2; - - static const size_t SIG2_OFFSET = 2; - static const uint16_t SIG2 = 0xFFFF; - static const size_t SIG2_SIZE = 2; - - ImportHeader ret; - ret.data.resize(HEADER_SIZE); - fs.read(&ret.data[0], HEADER_SIZE); - - const std::string sig1_as_string = ret.data.substr(SIG1_OFFSET, SIG1_SIZE); - const uint16_t sig1 = reinterpret_bytes(sig1_as_string.c_str()); - Checks::check_exit(VCPKG_LINE_INFO, sig1 == SIG1, "Sig1 was incorrect. Expected %s but got %s", SIG1, sig1); - - const std::string sig2_as_string = ret.data.substr(SIG2_OFFSET, SIG2_SIZE); - const uint16_t sig2 = reinterpret_bytes(sig2_as_string.c_str()); - Checks::check_exit(VCPKG_LINE_INFO, sig2 == SIG2, "Sig2 was incorrect. Expected %s but got %s", SIG2, sig2); - - return ret; - } - - MachineType machine_type() const - { - static const size_t MACHINE_TYPE_OFFSET = 6; - static const size_t MACHINE_TYPE_SIZE = 2; - - std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE); - const uint16_t machine = reinterpret_bytes(machine_field_as_string.c_str()); - return to_machine_type(machine); - } - - private: - std::string data; - }; - - static void read_and_verify_archive_file_signature(fstream& fs) - { - static const char* FILE_START = "!\n"; - static const size_t FILE_START_SIZE = 8; - - fs.seekg(fs.beg); - - char file_start[FILE_START_SIZE]; - fs.read(file_start, FILE_START_SIZE); - verify_equal_strings(VCPKG_LINE_INFO, FILE_START, file_start, FILE_START_SIZE, "LIB FILE_START"); - } - - DllInfo read_dll(const fs::path& path) - { - std::fstream fs(path, std::ios::in | std::ios::binary | std::ios::ate); - Checks::check_exit(VCPKG_LINE_INFO, fs.is_open(), "Could not open file %s for reading", path.generic_string()); - - read_and_verify_PE_signature(fs); - CoffFileHeader header = CoffFileHeader::read(fs); - const MachineType machine = header.machine_type(); - return {machine}; - } - - struct Marker - { - void set_to_offset(const fpos_t position) { this->m_absolute_position = position; } - - void set_to_current_pos(fstream& fs) { this->m_absolute_position = fs.tellg().seekpos(); } - - void seek_to_marker(fstream& fs) const { fs.seekg(this->m_absolute_position, ios_base::beg); } - - void advance_by(const uint64_t offset) { this->m_absolute_position += offset; } - - private: - fpos_t m_absolute_position = 0; - }; - - LibInfo read_lib(const fs::path& path) - { - std::fstream fs(path, std::ios::in | std::ios::binary | std::ios::ate); - Checks::check_exit(VCPKG_LINE_INFO, fs.is_open(), "Could not open file %s for reading", path.generic_string()); - - read_and_verify_archive_file_signature(fs); - - Marker marker; - marker.set_to_current_pos(fs); - - // First Linker Member - const ArchiveMemberHeader first_linker_member_header = ArchiveMemberHeader::read(fs); - Checks::check_exit(VCPKG_LINE_INFO, - first_linker_member_header.name().substr(0, 2) == "/ ", - "Could not find proper first linker member"); - marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + first_linker_member_header.member_size()); - marker.seek_to_marker(fs); - - const ArchiveMemberHeader second_linker_member_header = ArchiveMemberHeader::read(fs); - Checks::check_exit(VCPKG_LINE_INFO, - second_linker_member_header.name().substr(0, 2) == "/ ", - "Could not find proper second linker member"); - // The first 4 bytes contains the number of archive members - const uint32_t archive_member_count = read_value_from_stream(fs); - const OffsetsArray offsets = OffsetsArray::read(fs, archive_member_count); - marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + second_linker_member_header.member_size()); - marker.seek_to_marker(fs); - - const bool hasLongnameMemberHeader = peek_value_from_stream(fs) == 0x2F2F; - if (hasLongnameMemberHeader) - { - const ArchiveMemberHeader longnames_member_header = ArchiveMemberHeader::read(fs); - marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + longnames_member_header.member_size()); - marker.seek_to_marker(fs); - } - - std::set machine_types; - // Next we have the obj and pseudo-object files - for (const uint32_t offset : offsets.data) - { - marker.set_to_offset(offset + ArchiveMemberHeader::HEADER_SIZE); // Skip the header, no need to read it. - marker.seek_to_marker(fs); - const uint16_t first_two_bytes = peek_value_from_stream(fs); - const bool isImportHeader = to_machine_type(first_two_bytes) == MachineType::UNKNOWN; - const MachineType machine = - isImportHeader ? ImportHeader::read(fs).machine_type() : CoffFileHeader::read(fs).machine_type(); - machine_types.insert(machine); - } - - return {std::vector(machine_types.cbegin(), machine_types.cend())}; - } -} diff --git a/toolsrc/src/commands_autocomplete.cpp b/toolsrc/src/commands_autocomplete.cpp deleted file mode 100644 index 3963f904b..000000000 --- a/toolsrc/src/commands_autocomplete.cpp +++ /dev/null @@ -1,79 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "SortedVector.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Maps.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::Autocomplete -{ - std::vector autocomplete_install( - const std::vector>& source_paragraphs, const std::string& start_with) - { - std::vector results; - const auto& istartswith = Strings::case_insensitive_ascii_starts_with; - - for (const auto& source_control_file : source_paragraphs) - { - auto&& sp = *source_control_file->core_paragraph; - - if (istartswith(sp.name, start_with)) - { - results.push_back(sp.name); - } - } - return results; - } - - std::vector autocomplete_remove(std::vector installed_packages, - const std::string& start_with) - { - std::vector results; - const auto& istartswith = Strings::case_insensitive_ascii_starts_with; - - for (const auto& installed_package : installed_packages) - { - auto sp = installed_package->package.displayname(); - - if (istartswith(sp, start_with)) - { - results.push_back(sp); - } - } - return results; - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = - Strings::format("The argument should be a command line to autocomplete.\n%s", - Commands::Help::create_example_string("autocomplete install z")); - - args.check_min_arg_count(1, EXAMPLE); - args.check_max_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - const std::string requested_command = args.command_arguments.at(0); - const std::string start_with = - args.command_arguments.size() > 1 ? args.command_arguments.at(1) : Strings::EMPTY; - std::vector results; - if (requested_command == "install") - { - auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); - auto& source_paragraphs = sources_and_errors.paragraphs; - - results = autocomplete_install(source_paragraphs, start_with); - } - else if (requested_command == "remove") - { - const StatusParagraphs status_db = database_load_check(paths); - std::vector installed_packages = get_installed_ports(status_db); - results = autocomplete_remove(installed_packages, start_with); - } - - System::println(Strings::join(" ", results)); - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_available_commands.cpp b/toolsrc/src/commands_available_commands.cpp deleted file mode 100644 index d3280e6d7..000000000 --- a/toolsrc/src/commands_available_commands.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" - -namespace vcpkg::Commands -{ - const std::vector>& get_available_commands_type_a() - { - static std::vector> t = { - {"install", &Install::perform_and_exit}, - {"ci", &CI::perform_and_exit}, - {"remove", &Remove::perform_and_exit}, - {"build", &BuildCommand::perform_and_exit}, - {"env", &Env::perform_and_exit}, - {"build-external", &BuildExternal::perform_and_exit}, - {"export", &Export::perform_and_exit}, - }; - return t; - } - - const std::vector>& get_available_commands_type_b() - { - static std::vector> t = { - {"/?", &Help::perform_and_exit}, - {"help", &Help::perform_and_exit}, - {"search", &Search::perform_and_exit}, - {"list", &List::perform_and_exit}, - {"integrate", &Integrate::perform_and_exit}, - {"owns", &Owns::perform_and_exit}, - {"update", &Update::perform_and_exit}, - {"depend-info", &DependInfo::perform_and_exit}, - {"edit", &Edit::perform_and_exit}, - {"create", &Create::perform_and_exit}, - {"import", &Import::perform_and_exit}, - {"cache", &Cache::perform_and_exit}, - {"portsdiff", &PortsDiff::perform_and_exit}, - {"autocomplete", &Autocomplete::perform_and_exit}}; - return t; - } - - const std::vector>& get_available_commands_type_c() - { - static std::vector> t = { - {"version", &Version::perform_and_exit}, - {"contact", &Contact::perform_and_exit}, - {"hash", &Hash::perform_and_exit}, - }; - return t; - } -} diff --git a/toolsrc/src/commands_build.cpp b/toolsrc/src/commands_build.cpp deleted file mode 100644 index a69958058..000000000 --- a/toolsrc/src/commands_build.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "PostBuildLint.h" -#include "StatusParagraphs.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Enums.h" -#include "vcpkg_Input.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -using vcpkg::Build::BuildResult; -using vcpkg::Parse::ParseControlErrorInfo; -using vcpkg::Parse::ParseExpected; - -namespace vcpkg::Commands::BuildCommand -{ - using Dependencies::InstallPlanAction; - using Dependencies::InstallPlanType; - - static const std::string OPTION_CHECKS_ONLY = "--checks-only"; - - void perform_and_exit(const FullPackageSpec& full_spec, - const fs::path& port_dir, - const std::unordered_set& options, - const VcpkgPaths& paths) - { - const PackageSpec& spec = full_spec.package_spec; - if (options.find(OPTION_CHECKS_ONLY) != options.end()) - { - const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, spec.triplet()); - const auto build_info = Build::read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); - const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); - Checks::check_exit(VCPKG_LINE_INFO, error_count == 0); - Checks::exit_success(VCPKG_LINE_INFO); - } - - const ParseExpected source_control_file = - Paragraphs::try_load_port(paths.get_filesystem(), port_dir); - - if (!source_control_file.has_value()) - { - print_error_message(source_control_file.error()); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - for (const std::string& str : full_spec.features) - { - System::println("%s \n", str); - } - const auto& scf = source_control_file.value_or_exit(VCPKG_LINE_INFO); - Checks::check_exit(VCPKG_LINE_INFO, - spec.name() == scf->core_paragraph->name, - "The Name: field inside the CONTROL does not match the port directory: '%s' != '%s'", - scf->core_paragraph->name, - spec.name()); - - const StatusParagraphs status_db = database_load_check(paths); - const Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; - - const Build::BuildPackageConfig build_config{ - *scf->core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options}; - - const auto result = Build::build_package(paths, build_config, status_db); - if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES) - { - System::println(System::Color::error, - "The build command requires all dependencies to be already installed."); - System::println("The following dependencies are missing:"); - System::println(); - for (const auto& p : result.unmet_dependencies) - { - System::println(" %s", p); - } - System::println(); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - if (result.code != BuildResult::SUCCEEDED) - { - System::println(System::Color::error, Build::create_error_message(result.code, spec)); - System::println(Build::create_user_troubleshooting_message(spec)); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - static const std::string EXAMPLE = Commands::Help::create_example_string("build zlib:x64-windows"); - // Build only takes a single package and all dependencies must already be installed - args.check_exact_arg_count(1, EXAMPLE); - const std::string command_argument = args.command_arguments.at(0); - const FullPackageSpec spec = Input::check_and_get_full_package_spec(command_argument, default_triplet, EXAMPLE); - Input::check_triplet(spec.package_spec.triplet(), paths); - const std::unordered_set options = - args.check_and_get_optional_command_arguments({OPTION_CHECKS_ONLY}); - perform_and_exit(spec, paths.port_dir(spec.package_spec), options, paths); - } -} diff --git a/toolsrc/src/commands_build_external.cpp b/toolsrc/src/commands_build_external.cpp deleted file mode 100644 index 7e85f2250..000000000 --- a/toolsrc/src/commands_build_external.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_Input.h" - -namespace vcpkg::Commands::BuildExternal -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - static const std::string EXAMPLE = - Commands::Help::create_example_string(R"(build_external zlib2 C:\path\to\dir\with\controlfile\)"); - args.check_exact_arg_count(2, EXAMPLE); - const FullPackageSpec spec = - Input::check_and_get_full_package_spec(args.command_arguments.at(0), default_triplet, EXAMPLE); - Input::check_triplet(spec.package_spec.triplet(), paths); - const std::unordered_set options = args.check_and_get_optional_command_arguments({}); - - const fs::path port_dir = args.command_arguments.at(1); - BuildCommand::perform_and_exit(spec, port_dir, options, paths); - } -} diff --git a/toolsrc/src/commands_cache.cpp b/toolsrc/src/commands_cache.cpp deleted file mode 100644 index 5b65b197f..000000000 --- a/toolsrc/src/commands_cache.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "pch.h" - -#include "BinaryParagraph.h" -#include "Paragraphs.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Files.h" -#include "vcpkg_System.h" - -namespace vcpkg::Commands::Cache -{ - static std::vector read_all_binary_paragraphs(const VcpkgPaths& paths) - { - std::vector output; - for (auto&& path : paths.get_filesystem().get_files_non_recursive(paths.packages)) - { - const Expected> pghs = - Paragraphs::get_single_paragraph(paths.get_filesystem(), path / "CONTROL"); - if (const auto p = pghs.get()) - { - const BinaryParagraph binary_paragraph = BinaryParagraph(*p); - output.push_back(binary_paragraph); - } - } - - return output; - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Strings::format( - "The argument should be a substring to search for, or no argument to display all cached libraries.\n%s", - Commands::Help::create_example_string("cache png")); - args.check_max_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - const std::vector binary_paragraphs = read_all_binary_paragraphs(paths); - if (binary_paragraphs.empty()) - { - System::println("No packages are cached."); - Checks::exit_success(VCPKG_LINE_INFO); - } - - if (args.command_arguments.size() == 0) - { - for (const BinaryParagraph& binary_paragraph : binary_paragraphs) - { - const std::string displayname = binary_paragraph.displayname(); - System::println(displayname); - } - } - else - { - // At this point there is 1 argument - for (const BinaryParagraph& binary_paragraph : binary_paragraphs) - { - const std::string displayname = binary_paragraph.displayname(); - if (Strings::case_insensitive_ascii_find(displayname, args.command_arguments[0]) == displayname.end()) - { - continue; - } - - System::println(displayname); - } - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_ci.cpp b/toolsrc/src/commands_ci.cpp deleted file mode 100644 index 75ff65556..000000000 --- a/toolsrc/src/commands_ci.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "vcpkg_Build.h" -#include "vcpkg_Chrono.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Files.h" -#include "vcpkg_Input.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::CI -{ - using Build::BuildResult; - using Dependencies::InstallPlanAction; - using Dependencies::InstallPlanType; - - static std::vector load_all_package_specs(Files::Filesystem& fs, - const fs::path& ports_directory, - const Triplet& triplet) - { - auto ports = Paragraphs::load_all_ports(fs, ports_directory); - return Util::fmap(ports, [&](auto&& control_file) -> PackageSpec { - return PackageSpec::from_name_and_triplet(control_file->core_paragraph->name, triplet) - .value_or_exit(VCPKG_LINE_INFO); - }); - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - static const std::string EXAMPLE = Commands::Help::create_example_string("ci x64-windows"); - args.check_max_arg_count(1, EXAMPLE); - const Triplet triplet = args.command_arguments.size() == 1 - ? Triplet::from_canonical_name(args.command_arguments.at(0)) - : default_triplet; - Input::check_triplet(triplet, paths); - args.check_and_get_optional_command_arguments({}); - const std::vector specs = load_all_package_specs(paths.get_filesystem(), paths.ports, triplet); - - StatusParagraphs status_db = database_load_check(paths); - const auto& paths_port_file = Dependencies::PathsPortFile(paths); - std::vector install_plan = - Dependencies::create_install_plan(paths_port_file, specs, status_db); - Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); - - const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; - - const std::vector action_plan = - Util::fmap(install_plan, [](InstallPlanAction& install_action) { - return Dependencies::AnyAction(std::move(install_action)); - }); - - Install::perform_and_exit( - action_plan, install_plan_options, Install::KeepGoing::YES, Install::PrintSummary::YES, paths, status_db); - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_contact.cpp b/toolsrc/src/commands_contact.cpp deleted file mode 100644 index 8374350ee..000000000 --- a/toolsrc/src/commands_contact.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" - -namespace vcpkg::Commands::Contact -{ - const std::string& email() - { - static const std::string S_EMAIL = R"(vcpkg@microsoft.com)"; - return S_EMAIL; - } - - void perform_and_exit(const VcpkgCmdArguments& args) - { - args.check_exact_arg_count(0); - args.check_and_get_optional_command_arguments({}); - - System::println("Send an email to %s with any feedback.", email()); - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_create.cpp b/toolsrc/src/commands_create.cpp deleted file mode 100644 index 6898f7399..000000000 --- a/toolsrc/src/commands_create.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_Files.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::Create -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Commands::Help::create_example_string( - R"###(create zlib2 http://zlib.net/zlib1211.zip "zlib1211-2.zip")###"); - args.check_max_arg_count(3, EXAMPLE); - args.check_min_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - const std::string port_name = args.command_arguments.at(0); - const std::string url = args.command_arguments.at(1); - - const fs::path& cmake_exe = paths.get_cmake_exe(); - - std::vector cmake_args{{L"CMD", L"CREATE"}, {L"PORT", port_name}, {L"URL", url}}; - - if (args.command_arguments.size() >= 3) - { - const std::string& zip_file_name = args.command_arguments.at(2); - Checks::check_exit(VCPKG_LINE_INFO, - !Files::has_invalid_chars_for_filesystem(zip_file_name), - R"(Filename cannot contain invalid chars %s, but was %s)", - Files::FILESYSTEM_INVALID_CHARACTERS, - zip_file_name); - cmake_args.push_back({L"FILENAME", zip_file_name}); - } - - const std::wstring cmd_launch_cmake = make_cmake_cmd(cmake_exe, paths.ports_cmake, cmake_args); - Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute_clean(cmd_launch_cmake)); - } -} diff --git a/toolsrc/src/commands_depends.cpp b/toolsrc/src/commands_depends.cpp deleted file mode 100644 index 17cd9c881..000000000 --- a/toolsrc/src/commands_depends.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Strings.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" - -namespace vcpkg::Commands::DependInfo -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Commands::Help::create_example_string(R"###(depend-info [pat])###"); - args.check_max_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - std::vector> source_control_files = - Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - - if (args.command_arguments.size() == 1) - { - const std::string filter = args.command_arguments.at(0); - - Util::erase_remove_if(source_control_files, - [&](const std::unique_ptr& source_control_file) { - - const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; - - if (Strings::case_insensitive_ascii_contains(source_paragraph.name, filter)) - { - return false; - } - - for (const Dependency& dependency : source_paragraph.depends) - { - if (Strings::case_insensitive_ascii_contains(dependency.name(), filter)) - { - return false; - } - } - - return true; - }); - } - - for (auto&& source_control_file : source_control_files) - { - const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; - const auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name(); }); - System::println("%s: %s", source_paragraph.name, s); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_edit.cpp b/toolsrc/src/commands_edit.cpp deleted file mode 100644 index 823c87534..000000000 --- a/toolsrc/src/commands_edit.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_Input.h" -#include "vcpkg_System.h" - -namespace vcpkg::Commands::Edit -{ - static std::vector find_from_registry() - { - static const std::array REGKEYS = { - LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)", - LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1287CAD5-7C8D-410D-88B9-0D1EE4A83FF2}_is1)", - LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)", - }; - - std::vector output; - for (auto&& keypath : REGKEYS) - { - const Optional code_installpath = - System::get_registry_string(HKEY_LOCAL_MACHINE, keypath, L"InstallLocation"); - if (const auto c = code_installpath.get()) - { - const fs::path install_path = fs::path(*c); - output.push_back(install_path / "Code - Insiders.exe"); - output.push_back(install_path / "Code.exe"); - } - } - return output; - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string OPTION_BUILDTREES = "--buildtrees"; - - static const fs::path VS_CODE_INSIDERS = fs::path{"Microsoft VS Code Insiders"} / "Code - Insiders.exe"; - static const fs::path VS_CODE = fs::path{"Microsoft VS Code"} / "Code.exe"; - - auto& fs = paths.get_filesystem(); - - static const std::string EXAMPLE = Commands::Help::create_example_string("edit zlib"); - args.check_exact_arg_count(1, EXAMPLE); - const std::unordered_set options = - args.check_and_get_optional_command_arguments({OPTION_BUILDTREES}); - const std::string port_name = args.command_arguments.at(0); - - const fs::path portpath = paths.ports / port_name; - Checks::check_exit(VCPKG_LINE_INFO, fs.is_directory(portpath), R"(Could not find port named "%s")", port_name); - - std::vector candidate_paths; - const std::vector from_path = Files::find_from_PATH(L"EDITOR"); - candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); - candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE_INSIDERS); - candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE_INSIDERS); - candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE); - candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE); - - const std::vector from_registry = find_from_registry(); - candidate_paths.insert(candidate_paths.end(), from_registry.cbegin(), from_registry.cend()); - - auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { return fs.exists(p); }); - if (it == candidate_paths.cend()) - { - System::println(System::Color::error, - "Error: Visual Studio Code was not found and the environment variable EDITOR is not set."); - System::println("The following paths were examined:"); - Files::print_paths(candidate_paths); - System::println("You can also set the environmental variable EDITOR to your editor of choice."); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - const fs::path env_editor = *it; - if (options.find(OPTION_BUILDTREES) != options.cend()) - { - const auto buildtrees_current_dir = paths.buildtrees / port_name; - - const std::wstring cmd_line = - Strings::wformat(LR"("%s" "%s" -n)", env_editor, buildtrees_current_dir.native()); - Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); - } - - const std::wstring cmd_line = Strings::wformat( - LR"("%s" "%s" "%s" -n)", env_editor, portpath.native(), (portpath / "portfile.cmake").native()); - Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); - } -} diff --git a/toolsrc/src/commands_env.cpp b/toolsrc/src/commands_env.cpp deleted file mode 100644 index 6dad3e882..000000000 --- a/toolsrc/src/commands_env.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Build.h" -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" - -namespace vcpkg::Commands::Env -{ - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - static const std::string EXAMPLE = Commands::Help::create_example_string(R"(env --Triplet x64-windows)"); - args.check_exact_arg_count(0, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); - System::cmd_execute_clean(Build::make_build_env_cmd(pre_build_info, toolset) + L" && cmd"); - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_export.cpp b/toolsrc/src/commands_export.cpp deleted file mode 100644 index 20838f5a5..000000000 --- a/toolsrc/src/commands_export.cpp +++ /dev/null @@ -1,526 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Commands_Export_IFW.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Input.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" -#include "vcpkglib.h" -#include - -namespace vcpkg::Commands::Export -{ - using Dependencies::ExportPlanAction; - using Dependencies::ExportPlanType; - using Dependencies::RequestType; - using Install::InstallDir; - - static std::string create_nuspec_file_contents(const std::string& raw_exported_dir, - const std::string& targets_redirect_path, - const std::string& nuget_id, - const std::string& nupkg_version) - { - static constexpr auto CONTENT_TEMPLATE = R"( - - - @NUGET_ID@ - @VERSION@ - vcpkg - - Vcpkg NuGet export - - - - - - - - - -)"; - - std::string nuspec_file_content = std::regex_replace(CONTENT_TEMPLATE, std::regex("@NUGET_ID@"), nuget_id); - nuspec_file_content = std::regex_replace(nuspec_file_content, std::regex("@VERSION@"), nupkg_version); - nuspec_file_content = - std::regex_replace(nuspec_file_content, std::regex("@RAW_EXPORTED_DIR@"), raw_exported_dir); - nuspec_file_content = - std::regex_replace(nuspec_file_content, std::regex("@TARGETS_REDIRECT_PATH@"), targets_redirect_path); - return nuspec_file_content; - } - - static std::string create_targets_redirect(const std::string& target_path) noexcept - { - return Strings::format(R"###( - - - -)###", - target_path, - target_path); - } - - static void print_plan(const std::map>& group_by_plan_type) - { - static constexpr std::array ORDER = {ExportPlanType::ALREADY_BUILT, - ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT}; - - for (const ExportPlanType plan_type : ORDER) - { - const auto it = group_by_plan_type.find(plan_type); - if (it == group_by_plan_type.cend()) - { - continue; - } - - std::vector cont = it->second; - std::sort(cont.begin(), cont.end(), &ExportPlanAction::compare_by_name); - const std::string as_string = Strings::join("\n", cont, [](const ExportPlanAction* p) { - return Dependencies::to_output_string(p->request_type, p->spec.to_string()); - }); - - switch (plan_type) - { - case ExportPlanType::ALREADY_BUILT: - System::println("The following packages are already built and will be exported:\n%s", as_string); - continue; - case ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT: - System::println("The following packages need to be built:\n%s", as_string); - continue; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - } - - static std::string create_export_id() - { - const tm date_time = System::get_current_date_time(); - - // Format is: YYYYmmdd-HHMMSS - // 15 characters + 1 null terminating character will be written for a total of 16 chars - char mbstr[16]; - const size_t bytes_written = std::strftime(mbstr, sizeof(mbstr), "%Y%m%d-%H%M%S", &date_time); - Checks::check_exit(VCPKG_LINE_INFO, - bytes_written == 15, - "Expected 15 bytes to be written, but %u were written", - bytes_written); - const std::string date_time_as_string(mbstr); - return ("vcpkg-export-" + date_time_as_string); - } - - static fs::path do_nuget_export(const VcpkgPaths& paths, - const std::string& nuget_id, - const std::string& nuget_version, - const fs::path& raw_exported_dir, - const fs::path& output_dir) - { - Files::Filesystem& fs = paths.get_filesystem(); - const fs::path& nuget_exe = paths.get_nuget_exe(); - - // This file will be placed in "build\native" in the nuget package. Therefore, go up two dirs. - const std::string targets_redirect_content = - create_targets_redirect("../../scripts/buildsystems/msbuild/vcpkg.targets"); - const fs::path targets_redirect = paths.buildsystems / "tmp" / "vcpkg.export.nuget.targets"; - - std::error_code ec; - fs.create_directories(paths.buildsystems / "tmp", ec); - - fs.write_contents(targets_redirect, targets_redirect_content); - - const std::string nuspec_file_content = - create_nuspec_file_contents(raw_exported_dir.string(), targets_redirect.string(), nuget_id, nuget_version); - const fs::path nuspec_file_path = paths.buildsystems / "tmp" / "vcpkg.export.nuspec"; - fs.write_contents(nuspec_file_path, nuspec_file_content); - - // -NoDefaultExcludes is needed for ".vcpkg-root" - const std::wstring cmd_line = - Strings::wformat(LR"("%s" pack -OutputDirectory "%s" "%s" -NoDefaultExcludes > nul)", - nuget_exe.native(), - output_dir.native(), - nuspec_file_path.native()); - - const int exit_code = System::cmd_execute_clean(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: NuGet package creation failed"); - - const fs::path output_path = output_dir / (nuget_id + ".nupkg"); - return output_path; - } - - struct ArchiveFormat final - { - enum class BackingEnum - { - ZIP = 1, - SEVEN_ZIP, - }; - - constexpr ArchiveFormat() = delete; - - constexpr ArchiveFormat(BackingEnum backing_enum, const wchar_t* extension, const wchar_t* cmake_option) - : backing_enum(backing_enum), m_extension(extension), m_cmake_option(cmake_option) - { - } - - constexpr operator BackingEnum() const { return backing_enum; } - constexpr CWStringView extension() const { return this->m_extension; } - constexpr CWStringView cmake_option() const { return this->m_cmake_option; } - - private: - BackingEnum backing_enum; - const wchar_t* m_extension; - const wchar_t* m_cmake_option; - }; - - namespace ArchiveFormatC - { - constexpr const ArchiveFormat ZIP(ArchiveFormat::BackingEnum::ZIP, L"zip", L"zip"); - constexpr const ArchiveFormat SEVEN_ZIP(ArchiveFormat::BackingEnum::SEVEN_ZIP, L"7z", L"7zip"); - } - - static fs::path do_archive_export(const VcpkgPaths& paths, - const fs::path& raw_exported_dir, - const fs::path& output_dir, - const ArchiveFormat& format) - { - const fs::path& cmake_exe = paths.get_cmake_exe(); - - const std::wstring exported_dir_filename = raw_exported_dir.filename().native(); - const std::wstring exported_archive_filename = - Strings::wformat(L"%s.%s", exported_dir_filename, format.extension()); - const fs::path exported_archive_path = (output_dir / exported_archive_filename); - - // -NoDefaultExcludes is needed for ".vcpkg-root" - const std::wstring cmd_line = Strings::wformat(LR"("%s" -E tar "cf" "%s" --format=%s -- "%s")", - cmake_exe.native(), - exported_archive_path.native(), - format.cmake_option(), - raw_exported_dir.native()); - - const int exit_code = System::cmd_execute_clean(cmd_line); - Checks::check_exit( - VCPKG_LINE_INFO, exit_code == 0, "Error: %s creation failed", exported_archive_path.generic_string()); - return exported_archive_path; - } - - static Optional maybe_lookup(std::unordered_map const& m, - std::string const& key) - { - const auto it = m.find(key); - if (it != m.end()) return it->second; - return nullopt; - } - - void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths) - { - const std::vector integration_files_relative_to_root = { - {".vcpkg-root"}, - {fs::path{"scripts"} / "buildsystems" / "msbuild" / "applocal.ps1"}, - {fs::path{"scripts"} / "buildsystems" / "msbuild" / "vcpkg.targets"}, - {fs::path{"scripts"} / "buildsystems" / "vcpkg.cmake"}, - {fs::path{"scripts"} / "cmake" / "vcpkg_get_windows_sdk.cmake"}, - {fs::path{"scripts"} / "getWindowsSDK.ps1"}, - {fs::path{"scripts"} / "getProgramFilesPlatformBitness.ps1"}, - {fs::path{"scripts"} / "getProgramFiles32bit.ps1"}, - }; - - for (const fs::path& file : integration_files_relative_to_root) - { - const fs::path source = paths.root / file; - fs::path destination = raw_exported_dir_path / file; - Files::Filesystem& fs = paths.get_filesystem(); - std::error_code ec; - fs.create_directories(destination.parent_path(), ec); - Checks::check_exit(VCPKG_LINE_INFO, !ec); - fs.copy_file(source, destination, fs::copy_options::overwrite_existing, ec); - Checks::check_exit(VCPKG_LINE_INFO, !ec); - } - } - - struct ExportArguments - { - bool dry_run; - bool raw; - bool nuget; - bool ifw; - bool zip; - bool seven_zip; - - Optional maybe_nuget_id; - Optional maybe_nuget_version; - - IFW::Options ifw_options; - std::vector specs; - }; - - static ExportArguments handle_export_command_arguments(const VcpkgCmdArguments& args, - const Triplet& default_triplet) - { - ExportArguments ret; - - static const std::string OPTION_DRY_RUN = "--dry-run"; - static const std::string OPTION_RAW = "--raw"; - static const std::string OPTION_NUGET = "--nuget"; - static const std::string OPTION_IFW = "--ifw"; - static const std::string OPTION_ZIP = "--zip"; - static const std::string OPTION_SEVEN_ZIP = "--7zip"; - static const std::string OPTION_NUGET_ID = "--nuget-id"; - static const std::string OPTION_NUGET_VERSION = "--nuget-version"; - static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url"; - static const std::string OPTION_IFW_PACKAGES_DIR_PATH = "--ifw-packages-directory-path"; - static const std::string OPTION_IFW_REPOSITORY_DIR_PATH = "--ifw-repository-directory-path"; - static const std::string OPTION_IFW_CONFIG_FILE_PATH = "--ifw-configuration-file-path"; - static const std::string OPTION_IFW_INSTALLER_FILE_PATH = "--ifw-installer-file-path"; - - // input sanitization - static const std::string EXAMPLE = - Commands::Help::create_example_string("export zlib zlib:x64-windows boost --nuget"); - args.check_min_arg_count(1, EXAMPLE); - - ret.specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE); - }); - - const auto options = args.check_and_get_optional_command_arguments( - { - OPTION_DRY_RUN, - OPTION_RAW, - OPTION_NUGET, - OPTION_IFW, - OPTION_ZIP, - OPTION_SEVEN_ZIP, - }, - { - OPTION_NUGET_ID, - OPTION_NUGET_VERSION, - OPTION_IFW_REPOSITORY_URL, - OPTION_IFW_PACKAGES_DIR_PATH, - OPTION_IFW_REPOSITORY_DIR_PATH, - OPTION_IFW_CONFIG_FILE_PATH, - OPTION_IFW_INSTALLER_FILE_PATH, - }); - ret.dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); - ret.raw = options.switches.find(OPTION_RAW) != options.switches.cend(); - ret.nuget = options.switches.find(OPTION_NUGET) != options.switches.cend(); - ret.ifw = options.switches.find(OPTION_IFW) != options.switches.cend(); - ret.zip = options.switches.find(OPTION_ZIP) != options.switches.cend(); - ret.seven_zip = options.switches.find(OPTION_SEVEN_ZIP) != options.switches.cend(); - - if (!ret.raw && !ret.nuget && !ret.ifw && !ret.zip && !ret.seven_zip && !ret.dry_run) - { - System::println(System::Color::error, - "Must provide at least one export type: --raw --nuget --ifw --zip --7zip"); - System::print(EXAMPLE); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - struct OptionPair - { - const std::string& name; - Optional& out_opt; - }; - const auto options_implies = - [&](const std::string& main_opt_name, bool main_opt, Span implying_opts) { - if (main_opt) - { - for (auto&& opt : implying_opts) - opt.out_opt = maybe_lookup(options.settings, opt.name); - } - else - { - for (auto&& opt : implying_opts) - Checks::check_exit(VCPKG_LINE_INFO, - !maybe_lookup(options.settings, opt.name), - "%s is only valid with %s", - opt.name, - main_opt_name); - } - }; - - options_implies(OPTION_NUGET, - ret.nuget, - { - {OPTION_NUGET_ID, ret.maybe_nuget_id}, - {OPTION_NUGET_VERSION, ret.maybe_nuget_version}, - }); - - options_implies(OPTION_IFW, - ret.ifw, - { - {OPTION_IFW_REPOSITORY_URL, ret.ifw_options.maybe_repository_url}, - {OPTION_IFW_PACKAGES_DIR_PATH, ret.ifw_options.maybe_packages_dir_path}, - {OPTION_IFW_REPOSITORY_DIR_PATH, ret.ifw_options.maybe_repository_dir_path}, - {OPTION_IFW_CONFIG_FILE_PATH, ret.ifw_options.maybe_config_file_path}, - {OPTION_IFW_INSTALLER_FILE_PATH, ret.ifw_options.maybe_installer_file_path}, - }); - return ret; - } - - static void print_next_step_info(const fs::path& prefix) - { - const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; - const CMakeVariable cmake_variable = CMakeVariable(L"CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); - System::println("\n" - "To use the exported libraries in CMake projects use:" - "\n" - " %s" - "\n", - Strings::to_utf8(cmake_variable.s)); - }; - - static void handle_raw_based_export(Span export_plan, - const ExportArguments& opts, - const std::string& export_id, - const VcpkgPaths& paths) - { - Files::Filesystem& fs = paths.get_filesystem(); - const fs::path export_to_path = paths.root; - const fs::path raw_exported_dir_path = export_to_path / export_id; - std::error_code ec; - fs.remove_all(raw_exported_dir_path, ec); - fs.create_directory(raw_exported_dir_path, ec); - - // execute the plan - for (const ExportPlanAction& action : export_plan) - { - if (action.plan_type != ExportPlanType::ALREADY_BUILT) - { - Checks::unreachable(VCPKG_LINE_INFO); - } - - const std::string display_name = action.spec.to_string(); - System::println("Exporting package %s... ", display_name); - - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; - - const InstallDir dirs = InstallDir::from_destination_root( - raw_exported_dir_path / "installed", - action.spec.triplet().to_string(), - raw_exported_dir_path / "installed" / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); - - Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); - System::println(System::Color::success, "Exporting package %s... done", display_name); - } - - // Copy files needed for integration - export_integration_files(raw_exported_dir_path, paths); - - if (opts.raw) - { - System::println( - System::Color::success, R"(Files exported at: "%s")", raw_exported_dir_path.generic_string()); - print_next_step_info(export_to_path); - } - - if (opts.nuget) - { - System::println("Creating nuget package... "); - - const std::string nuget_id = opts.maybe_nuget_id.value_or(raw_exported_dir_path.filename().string()); - const std::string nuget_version = opts.maybe_nuget_version.value_or("1.0.0"); - const fs::path output_path = - do_nuget_export(paths, nuget_id, nuget_version, raw_exported_dir_path, export_to_path); - System::println(System::Color::success, "Creating nuget package... done"); - System::println(System::Color::success, "NuGet package exported at: %s", output_path.generic_string()); - - System::println(R"( -With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: - Install-Package %s -Source "%s" -)" - "\n", - nuget_id, - output_path.parent_path().u8string()); - } - - if (opts.zip) - { - System::println("Creating zip archive... "); - const fs::path output_path = - do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::ZIP); - System::println(System::Color::success, "Creating zip archive... done"); - System::println(System::Color::success, "Zip archive exported at: %s", output_path.generic_string()); - print_next_step_info("[...]"); - } - - if (opts.seven_zip) - { - System::println("Creating 7zip archive... "); - const fs::path output_path = - do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::SEVEN_ZIP); - System::println(System::Color::success, "Creating 7zip archive... done"); - System::println(System::Color::success, "7zip archive exported at: %s", output_path.generic_string()); - print_next_step_info("[...]"); - } - - if (!opts.raw) - { - fs.remove_all(raw_exported_dir_path, ec); - } - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - const auto opts = handle_export_command_arguments(args, default_triplet); - for (auto&& spec : opts.specs) - Input::check_triplet(spec.triplet(), paths); - - // create the plan - const StatusParagraphs status_db = database_load_check(paths); - std::vector export_plan = Dependencies::create_export_plan(paths, opts.specs, status_db); - Checks::check_exit(VCPKG_LINE_INFO, !export_plan.empty(), "Export plan cannot be empty"); - - std::map> group_by_plan_type; - Util::group_by(export_plan, &group_by_plan_type, [](const ExportPlanAction& p) { return p.plan_type; }); - print_plan(group_by_plan_type); - - const bool has_non_user_requested_packages = - Util::find_if(export_plan, [](const ExportPlanAction& package) -> bool { - return package.request_type != RequestType::USER_REQUESTED; - }) != export_plan.cend(); - - if (has_non_user_requested_packages) - { - System::println(System::Color::warning, - "Additional packages (*) need to be exported to complete this operation."); - } - - const auto it = group_by_plan_type.find(ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT); - if (it != group_by_plan_type.cend() && !it->second.empty()) - { - System::println(System::Color::error, "There are packages that have not been built."); - - // No need to show all of them, just the user-requested ones. Dependency resolution will handle the rest. - std::vector unbuilt = it->second; - Util::erase_remove_if( - unbuilt, [](const ExportPlanAction* a) { return a->request_type != RequestType::USER_REQUESTED; }); - - const auto s = Strings::join(" ", unbuilt, [](const ExportPlanAction* a) { return a->spec.to_string(); }); - System::println("To build them, run:\n" - " vcpkg install %s", - s); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - if (opts.dry_run) - { - Checks::exit_success(VCPKG_LINE_INFO); - } - - std::string export_id = create_export_id(); - - if (opts.raw || opts.nuget || opts.zip || opts.seven_zip) - { - handle_raw_based_export(export_plan, opts, export_id, paths); - } - - if (opts.ifw) - { - IFW::do_export(export_plan, export_id, opts.ifw_options, paths); - - print_next_step_info("@RootDir@/src/vcpkg"); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_export_ifw.cpp b/toolsrc/src/commands_export_ifw.cpp deleted file mode 100644 index 191dbb763..000000000 --- a/toolsrc/src/commands_export_ifw.cpp +++ /dev/null @@ -1,481 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_Commands_Export.h" -#include "vcpkg_Commands_Export_IFW.h" - -namespace vcpkg::Commands::Export::IFW -{ - using Dependencies::ExportPlanAction; - using Dependencies::ExportPlanType; - using Install::InstallDir; - - static std::string create_release_date() - { - const tm date_time = System::get_current_date_time(); - - // Format is: YYYY-mm-dd - // 10 characters + 1 null terminating character will be written for a total of 11 chars - char mbstr[11]; - const size_t bytes_written = std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d", &date_time); - Checks::check_exit(VCPKG_LINE_INFO, - bytes_written == 10, - "Expected 10 bytes to be written, but %u were written", - bytes_written); - const std::string date_time_as_string(mbstr); - return date_time_as_string; - } - - fs::path get_packages_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) - { - return ifw_options.maybe_packages_dir_path.has_value() - ? fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-packages"); - } - - fs::path get_repository_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) - { - return ifw_options.maybe_repository_dir_path.has_value() - ? fs::path(ifw_options.maybe_repository_dir_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-repository"); - } - - fs::path get_config_file_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) - { - return ifw_options.maybe_config_file_path.has_value() - ? fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-configuration.xml"); - } - - fs::path get_installer_file_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) - { - return ifw_options.maybe_installer_file_path.has_value() - ? fs::path(ifw_options.maybe_installer_file_path.value_or_exit(VCPKG_LINE_INFO)) - : paths.root / (export_id + "-ifw-installer.exe"); - } - - fs::path export_real_package(const fs::path& ifw_packages_dir_path, - const ExportPlanAction& action, - Files::Filesystem& fs) - { - std::error_code ec; - - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; - - // Prepare meta dir - const fs::path package_xml_file_path = - ifw_packages_dir_path / - Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "meta" / - "package.xml"; - const fs::path package_xml_dir_path = package_xml_file_path.parent_path(); - fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); - - auto deps = Strings::join( - ",", binary_paragraph.depends, [](const std::string& dep) { return "packages." + dep + ":"; }); - - if (!deps.empty()) deps = "\n " + deps + ""; - - fs.write_contents(package_xml_file_path, - Strings::format( - R"###( - - %s - %s - %s - packages.%s:,triplets.%s:%s - true - -)###", - action.spec.to_string(), - binary_paragraph.version, - create_release_date(), - action.spec.name(), - action.spec.triplet().canonical_name(), - deps)); - - // Return dir path for export package data - return ifw_packages_dir_path / - Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "data" / - "installed"; - } - - void export_unique_packages(const fs::path& raw_exported_dir_path, - std::map unique_packages, - Files::Filesystem& fs) - { - std::error_code ec; - - // packages - - fs::path package_xml_file_path = raw_exported_dir_path / "packages" / "meta" / "package.xml"; - fs::path package_xml_dir_path = package_xml_file_path.parent_path(); - fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, - Strings::format( - R"###( - - Packages - 1.0.0 - %s - -)###", - create_release_date())); - - for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) - { - const ExportPlanAction& action = *(package->second); - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; - - package_xml_file_path = - raw_exported_dir_path / Strings::format("packages.%s", package->first) / "meta" / "package.xml"; - package_xml_dir_path = package_xml_file_path.parent_path(); - fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); - - fs.write_contents(package_xml_file_path, - Strings::format( - R"###( - - %s - %s - %s - %s - -)###", - action.spec.name(), - binary_paragraph.description, - binary_paragraph.version, - create_release_date())); - } - } - - void export_unique_triplets(const fs::path& raw_exported_dir_path, - std::set unique_triplets, - Files::Filesystem& fs) - { - std::error_code ec; - - // triplets - - fs::path package_xml_file_path = raw_exported_dir_path / "triplets" / "meta" / "package.xml"; - fs::path package_xml_dir_path = package_xml_file_path.parent_path(); - fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, - Strings::format( - R"###( - - Triplets - 1.0.0 - %s - -)###", - create_release_date())); - - for (const std::string& triplet : unique_triplets) - { - package_xml_file_path = - raw_exported_dir_path / Strings::format("triplets.%s", triplet) / "meta" / "package.xml"; - package_xml_dir_path = package_xml_file_path.parent_path(); - fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, - Strings::format( - R"###( - - %s - 1.0.0 - %s - -)###", - triplet, - create_release_date())); - } - } - - void export_integration(const fs::path& raw_exported_dir_path, Files::Filesystem& fs) - { - std::error_code ec; - - // integration - fs::path package_xml_file_path = raw_exported_dir_path / "integration" / "meta" / "package.xml"; - fs::path package_xml_dir_path = package_xml_file_path.parent_path(); - fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); - - fs.write_contents(package_xml_file_path, - Strings::format( - R"###( - - Integration - 1.0.0 - %s - -)###", - create_release_date())); - } - - void export_config(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) - { - std::error_code ec; - Files::Filesystem& fs = paths.get_filesystem(); - - const fs::path config_xml_file_path = get_config_file_path(export_id, ifw_options, paths); - - fs::path config_xml_dir_path = config_xml_file_path.parent_path(); - fs.create_directories(config_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for configuration file %s", - config_xml_file_path.generic_string()); - - std::string formatted_repo_url; - std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); - if (!ifw_repo_url.empty()) - { - formatted_repo_url = Strings::format(R"###( - - - %s - - )###", - ifw_repo_url); - } - - fs.write_contents(config_xml_file_path, - Strings::format( - R"###( - - vcpkg - 1.0.0 - vcpkg - @RootDir@/src/vcpkg%s - -)###", - formatted_repo_url)); - } - - void export_maintenance_tool(const fs::path& ifw_packages_dir_path, const VcpkgPaths& paths) - { - System::println("Exporting maintenance tool... "); - - std::error_code ec; - Files::Filesystem& fs = paths.get_filesystem(); - - const fs::path& installerbase_exe = paths.get_ifw_installerbase_exe(); - fs::path tempmaintenancetool = ifw_packages_dir_path / "maintenance" / "data" / "tempmaintenancetool.exe"; - fs.create_directories(tempmaintenancetool.parent_path(), ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - tempmaintenancetool.generic_string()); - fs.copy_file(installerbase_exe, tempmaintenancetool, fs::copy_options::overwrite_existing, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not write package file %s", tempmaintenancetool.generic_string()); - - fs::path package_xml_file_path = ifw_packages_dir_path / "maintenance" / "meta" / "package.xml"; - fs::path package_xml_dir_path = package_xml_file_path.parent_path(); - fs.create_directories(package_xml_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not create directory for package file %s", - package_xml_file_path.generic_string()); - fs.write_contents(package_xml_file_path, - Strings::format( - R"###( - - Maintenance Tool - Maintenance Tool - 1.0.0 - %s - - true - true - true - -)###", - create_release_date())); - const fs::path script_source = paths.root / "scripts" / "ifw" / "maintenance.qs"; - const fs::path script_destination = ifw_packages_dir_path / "maintenance" / "meta" / "maintenance.qs"; - fs.copy_file(script_source, script_destination, fs::copy_options::overwrite_existing, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not write package file %s", script_destination.generic_string()); - - System::println("Exporting maintenance tool... done"); - } - - void do_repository(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) - { - const fs::path& repogen_exe = paths.get_ifw_repogen_exe(); - const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); - const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); - - System::println("Generating repository %s...", repository_dir.generic_string()); - - std::error_code ec; - Files::Filesystem& fs = paths.get_filesystem(); - - fs.remove_all(repository_dir, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not remove outdated repository directory %s", repository_dir.generic_string()); - - const std::wstring cmd_line = Strings::wformat(LR"("%s" --packages "%s" "%s" > nul)", - repogen_exe.native(), - packages_dir.native(), - repository_dir.native()); - - const int exit_code = System::cmd_execute_clean(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW repository generating failed"); - - System::println(System::Color::success, "Generating repository %s... done.", repository_dir.generic_string()); - } - - void do_installer(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) - { - const fs::path& binarycreator_exe = paths.get_ifw_binarycreator_exe(); - const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); - const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); - const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); - const fs::path installer_file = get_installer_file_path(export_id, ifw_options, paths); - - System::println("Generating installer %s...", installer_file.generic_string()); - - std::wstring cmd_line; - - std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); - if (!ifw_repo_url.empty()) - { - cmd_line = Strings::wformat(LR"("%s" --online-only --config "%s" --repository "%s" "%s" > nul)", - binarycreator_exe.native(), - config_file.native(), - repository_dir.native(), - installer_file.native()); - } - else - { - cmd_line = Strings::wformat(LR"("%s" --config "%s" --packages "%s" "%s" > nul)", - binarycreator_exe.native(), - config_file.native(), - packages_dir.native(), - installer_file.native()); - } - - const int exit_code = System::cmd_execute_clean(cmd_line); - Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW installer generating failed"); - - System::println(System::Color::success, "Generating installer %s... done.", installer_file.generic_string()); - } - - void do_export(const std::vector& export_plan, - const std::string& export_id, - const Options& ifw_options, - const VcpkgPaths& paths) - { - std::error_code ec; - Files::Filesystem& fs = paths.get_filesystem(); - - // Prepare packages directory - const fs::path ifw_packages_dir_path = get_packages_dir_path(export_id, ifw_options, paths); - - fs.remove_all(ifw_packages_dir_path, ec); - Checks::check_exit(VCPKG_LINE_INFO, - !ec, - "Could not remove outdated packages directory %s", - ifw_packages_dir_path.generic_string()); - - fs.create_directory(ifw_packages_dir_path, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create packages directory %s", ifw_packages_dir_path.generic_string()); - - // Export maintenance tool - export_maintenance_tool(ifw_packages_dir_path, paths); - - System::println("Exporting packages %s... ", ifw_packages_dir_path.generic_string()); - - // execute the plan - std::map unique_packages; - std::set unique_triplets; - for (const ExportPlanAction& action : export_plan) - { - if (action.plan_type != ExportPlanType::ALREADY_BUILT) - { - Checks::unreachable(VCPKG_LINE_INFO); - } - - const std::string display_name = action.spec.to_string(); - System::println("Exporting package %s... ", display_name); - - const BinaryParagraph& binary_paragraph = - action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; - - unique_packages[action.spec.name()] = &action; - unique_triplets.insert(action.spec.triplet().canonical_name()); - - // Export real package and return data dir for installation - fs::path ifw_package_dir_path = export_real_package(ifw_packages_dir_path, action, fs); - - // Copy package data - const InstallDir dirs = InstallDir::from_destination_root(ifw_package_dir_path, - action.spec.triplet().to_string(), - ifw_package_dir_path / "vcpkg" / "info" / - (binary_paragraph.fullstem() + ".list")); - - Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); - System::println("Exporting package %s... done", display_name); - } - - System::println("Exporting packages %s... done", ifw_packages_dir_path.generic_string()); - - const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); - - System::println("Generating configuration %s...", config_file.generic_string()); - - // Unique packages - export_unique_packages(ifw_packages_dir_path, unique_packages, fs); - - // Unique triplets - export_unique_triplets(ifw_packages_dir_path, unique_triplets, fs); - - // Copy files needed for integration - export_integration_files(ifw_packages_dir_path / "integration" / "data", paths); - // Integration - export_integration(ifw_packages_dir_path, fs); - - // Configuration - export_config(export_id, ifw_options, paths); - - System::println("Generating configuration %s... done.", config_file.generic_string()); - - // Do repository (optional) - std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); - if (!ifw_repo_url.empty()) - { - do_repository(export_id, ifw_options, paths); - } - - // Do installer - do_installer(export_id, ifw_options, paths); - } -} diff --git a/toolsrc/src/commands_hash.cpp b/toolsrc/src/commands_hash.cpp deleted file mode 100644 index b3211b9f8..000000000 --- a/toolsrc/src/commands_hash.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" - -namespace vcpkg::Commands::Hash -{ - static void do_file_hash(fs::path const& path, std::wstring const& hash_type) - { - const auto cmd_line = Strings::wformat(LR"(CertUtil.exe -hashfile "%s" %s)", path.c_str(), hash_type); - const auto ec_data = System::cmd_execute_and_capture_output(cmd_line); - Checks::check_exit( - VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", Strings::to_utf8(cmd_line)); - - std::string const& output = ec_data.output; - - const auto start = output.find_first_of("\r\n"); - Checks::check_exit(VCPKG_LINE_INFO, - start != std::string::npos, - "Unexpected output format from command: %s", - Strings::to_utf8(cmd_line)); - - const auto end = output.find_first_of("\r\n", start + 1); - Checks::check_exit(VCPKG_LINE_INFO, - end != std::string::npos, - "Unexpected output format from command: %s", - Strings::to_utf8(cmd_line)); - - auto hash = output.substr(start, end - start); - Util::erase_remove_if(hash, isspace); - System::println(hash); - } - - void perform_and_exit(const VcpkgCmdArguments& args) - { - static const std::string EXAMPLE = - Strings::format("The argument should be a file path\n%s", - Commands::Help::create_example_string("hash boost_1_62_0.tar.bz2")); - args.check_min_arg_count(1, EXAMPLE); - args.check_max_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - if (args.command_arguments.size() == 1) - { - do_file_hash(args.command_arguments[0], L"SHA512"); - } - if (args.command_arguments.size() == 2) - { - do_file_hash(args.command_arguments[0], Strings::to_utf16(args.command_arguments[1])); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_help.cpp b/toolsrc/src/commands_help.cpp deleted file mode 100644 index a12f9003d..000000000 --- a/toolsrc/src/commands_help.cpp +++ /dev/null @@ -1,131 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" - -namespace vcpkg::Commands::Help -{ - void help_topics() - { - System::println("Available help topics:\n" - " triplet\n" - " integrate\n" - " export"); - } - - void help_topic_valid_triplet(const VcpkgPaths& paths) - { - System::println("Available architecture triplets:"); - for (auto&& path : paths.get_filesystem().get_files_non_recursive(paths.triplets)) - { - System::println(" %s", path.stem().filename().string()); - } - } - - void help_topic_export() - { - System::println("Summary:\n" - " vcpkg export [options] ...\n" - "\n" - "Options:\n" - " --7zip Export to a 7zip (.7z) file\n" - " --dry-run Do not actually export\n" - " --nuget Export a NuGet package\n" - " --nuget-id= Specify the id for the exported NuGet package\n" - " --nuget-version= Specify the version for the exported NuGet package\n" - " --raw Export to an uncompressed directory\n" - " --zip Export to a zip file"); - } - - void print_usage() - { - System::println( - "Commands:\n" - " vcpkg search [pat] Search for packages available to be built\n" - " vcpkg install ... Install a package\n" - " vcpkg remove ... Uninstall a package\n" - " vcpkg remove --outdated Uninstall all out-of-date packages\n" - " vcpkg list List installed packages\n" - " vcpkg update Display list of packages for updating\n" - " vcpkg hash [alg] Hash a file by specific algorithm, default SHA512\n" - " vcpkg help topics Display the list of help topics\n" - " vcpkg help Display help for a specific topic\n" - "\n" - "%s" // Integration help - "\n" - " vcpkg export ... [opt]... Exports a package\n" - " vcpkg edit Open up a port for editing (uses %%EDITOR%%, default 'code')\n" - " vcpkg import Import a pre-built library\n" - " vcpkg create \n" - " [archivename] Create a new package\n" - " vcpkg owns Search for files in installed packages\n" - " vcpkg cache List cached compiled packages\n" - " vcpkg version Display version information\n" - " vcpkg contact Display contact information to send feedback\n" - "\n" - //"internal commands:\n" - //" --check-build-deps \n" - //" --create-binary-control \n" - //"\n" - "Options:\n" - " --triplet Specify the target architecture triplet.\n" - " (default: %%VCPKG_DEFAULT_TRIPLET%%, see 'vcpkg help triplet')\n" - "\n" - " --vcpkg-root Specify the vcpkg root directory\n" - " (default: %%VCPKG_ROOT%%)\n" - "\n" - "For more help (including examples) see the accompanying README.md.", - Integrate::INTEGRATE_COMMAND_HELPSTRING); - } - - std::string create_example_string(const std::string& command_and_arguments) - { - std::string cs = Strings::format("Example:\n" - " vcpkg %s\n", - command_and_arguments); - return cs; - } - - void print_example(const std::string& command_and_arguments) - { - System::println(create_example_string(command_and_arguments)); - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - args.check_max_arg_count(1); - args.check_and_get_optional_command_arguments({}); - - if (args.command_arguments.empty()) - { - print_usage(); - Checks::exit_success(VCPKG_LINE_INFO); - } - const auto& topic = args.command_arguments[0]; - if (topic == "triplet" || topic == "triplets" || topic == "triple") - { - help_topic_valid_triplet(paths); - } - else if (topic == "export") - { - help_topic_export(); - } - else if (topic == "integrate") - { - System::print("Commands:\n" - "%s", - Integrate::INTEGRATE_COMMAND_HELPSTRING); - } - else if (topic == "topics") - { - help_topics(); - } - else - { - System::println(System::Color::error, "Error: unknown topic %s", topic); - help_topics(); - Checks::exit_fail(VCPKG_LINE_INFO); - } - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_import.cpp b/toolsrc/src/commands_import.cpp deleted file mode 100644 index 412a03d7f..000000000 --- a/toolsrc/src/commands_import.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "StatusParagraph.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Files.h" - -namespace vcpkg::Commands::Import -{ - struct Binaries - { - std::vector dlls; - std::vector libs; - }; - - static void check_is_directory(const LineInfo& line_info, const Files::Filesystem& fs, const fs::path& dirpath) - { - Checks::check_exit(line_info, fs.is_directory(dirpath), "The path %s is not a directory", dirpath.string()); - } - - static Binaries find_binaries_in_dir(const Files::Filesystem& fs, const fs::path& path) - { - auto files = fs.get_files_recursive(path); - - check_is_directory(VCPKG_LINE_INFO, fs, path); - - Binaries binaries; - for (auto&& file : files) - { - if (fs.is_directory(file)) continue; - const auto ext = file.extension(); - if (ext == ".dll") - binaries.dlls.push_back(std::move(file)); - else if (ext == ".lib") - binaries.libs.push_back(std::move(file)); - } - return binaries; - } - - static void copy_files_into_directory(Files::Filesystem& fs, - const std::vector& files, - const fs::path& destination_folder) - { - std::error_code ec; - fs.create_directory(destination_folder, ec); - - for (auto const& src_path : files) - { - const fs::path dest_path = destination_folder / src_path.filename(); - fs.copy(src_path, dest_path, fs::copy_options::overwrite_existing); - } - } - - static void place_library_files_in(Files::Filesystem& fs, - const fs::path& include_directory, - const fs::path& project_directory, - const fs::path& destination_path) - { - check_is_directory(VCPKG_LINE_INFO, fs, include_directory); - check_is_directory(VCPKG_LINE_INFO, fs, project_directory); - check_is_directory(VCPKG_LINE_INFO, fs, destination_path); - const Binaries debug_binaries = find_binaries_in_dir(fs, project_directory / "Debug"); - const Binaries release_binaries = find_binaries_in_dir(fs, project_directory / "Release"); - - const fs::path destination_include_directory = destination_path / "include"; - fs.copy(include_directory, - destination_include_directory, - fs::copy_options::recursive | fs::copy_options::overwrite_existing); - - copy_files_into_directory(fs, release_binaries.dlls, destination_path / "bin"); - copy_files_into_directory(fs, release_binaries.libs, destination_path / "lib"); - - std::error_code ec; - fs.create_directory(destination_path / "debug", ec); - copy_files_into_directory(fs, debug_binaries.dlls, destination_path / "debug" / "bin"); - copy_files_into_directory(fs, debug_binaries.libs, destination_path / "debug" / "lib"); - } - - static void do_import(const VcpkgPaths& paths, - const fs::path& include_directory, - const fs::path& project_directory, - const BinaryParagraph& control_file_data) - { - auto& fs = paths.get_filesystem(); - const fs::path library_destination_path = paths.package_dir(control_file_data.spec); - std::error_code ec; - fs.create_directory(library_destination_path, ec); - place_library_files_in(paths.get_filesystem(), include_directory, project_directory, library_destination_path); - - const fs::path control_file_path = library_destination_path / "CONTROL"; - fs.write_contents(control_file_path, Strings::serialize(control_file_data)); - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Commands::Help::create_example_string( - R"(import C:\path\to\CONTROLfile C:\path\to\includedir C:\path\to\projectdir)"); - args.check_exact_arg_count(3, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - const fs::path control_file_path(args.command_arguments[0]); - const fs::path include_directory(args.command_arguments[1]); - const fs::path project_directory(args.command_arguments[2]); - - const Expected> pghs = - Paragraphs::get_single_paragraph(paths.get_filesystem(), control_file_path); - Checks::check_exit(VCPKG_LINE_INFO, - pghs.get() != nullptr, - "Invalid control file %s for package", - control_file_path.generic_string()); - - StatusParagraph spgh; - spgh.package = BinaryParagraph(*pghs.get()); - auto& control_file_data = spgh.package; - - do_import(paths, include_directory, project_directory, control_file_data); - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_install.cpp b/toolsrc/src/commands_install.cpp deleted file mode 100644 index d815332fe..000000000 --- a/toolsrc/src/commands_install.cpp +++ /dev/null @@ -1,613 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "metrics.h" -#include "vcpkg_Build.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Files.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_Input.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::Install -{ - using namespace Dependencies; - - InstallDir InstallDir::from_destination_root(const fs::path& destination_root, - const std::string& destination_subdirectory, - const fs::path& listfile) - { - InstallDir dirs; - dirs.m_destination = destination_root / destination_subdirectory; - dirs.m_destination_subdirectory = destination_subdirectory; - dirs.m_listfile = listfile; - return dirs; - } - - const fs::path& InstallDir::destination() const { return this->m_destination; } - - const std::string& InstallDir::destination_subdirectory() const { return this->m_destination_subdirectory; } - - const fs::path& InstallDir::listfile() const { return this->m_listfile; } - - void install_files_and_write_listfile(Files::Filesystem& fs, - const fs::path& source_dir, - const InstallDir& destination_dir) - { - std::vector output; - std::error_code ec; - - const size_t prefix_length = source_dir.native().size(); - const fs::path& destination = destination_dir.destination(); - const std::string& destination_subdirectory = destination_dir.destination_subdirectory(); - const fs::path& listfile = destination_dir.listfile(); - - Checks::check_exit( - VCPKG_LINE_INFO, fs.exists(source_dir), "Source directory %s does not exist", source_dir.generic_string()); - fs.create_directories(destination, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create destination directory %s", destination.generic_string()); - const fs::path listfile_parent = listfile.parent_path(); - fs.create_directories(listfile_parent, ec); - Checks::check_exit( - VCPKG_LINE_INFO, !ec, "Could not create directory for listfile %s", listfile.generic_string()); - - output.push_back(Strings::format(R"(%s/)", destination_subdirectory)); - auto files = fs.get_files_recursive(source_dir); - for (auto&& file : files) - { - const auto status = fs.status(file, ec); - if (ec) - { - System::println(System::Color::error, "failed: %s: %s", file.u8string(), ec.message()); - continue; - } - - const std::string filename = file.filename().generic_string(); - if (fs::is_regular_file(status) && - (Strings::case_insensitive_ascii_compare(filename.c_str(), "CONTROL") == 0 || - Strings::case_insensitive_ascii_compare(filename.c_str(), "BUILD_INFO") == 0)) - { - // Do not copy the control file - continue; - } - - const std::string suffix = file.generic_u8string().substr(prefix_length + 1); - const fs::path target = destination / suffix; - - if (fs::is_directory(status)) - { - fs.create_directory(target, ec); - if (ec) - { - System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); - } - - // Trailing backslash for directories - output.push_back(Strings::format(R"(%s/%s/)", destination_subdirectory, suffix)); - continue; - } - - if (fs::is_regular_file(status)) - { - if (fs.exists(target)) - { - System::println(System::Color::warning, - "File %s was already present and will be overwritten", - target.u8string(), - ec.message()); - } - fs.copy_file(file, target, fs::copy_options::overwrite_existing, ec); - if (ec) - { - System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); - } - output.push_back(Strings::format(R"(%s/%s)", destination_subdirectory, suffix)); - continue; - } - - if (!fs::status_known(status)) - { - System::println(System::Color::error, "failed: %s: unknown status", file.u8string()); - continue; - } - - System::println(System::Color::error, "failed: %s: cannot handle file type", file.u8string()); - } - - std::sort(output.begin(), output.end()); - - fs.write_lines(listfile, output); - } - - static void remove_first_n_chars(std::vector* strings, const size_t n) - { - for (std::string& s : *strings) - { - s.erase(0, n); - } - }; - - static std::vector extract_files_in_triplet( - const std::vector& pgh_and_files, const Triplet& triplet) - { - std::vector output; - for (const StatusParagraphAndAssociatedFiles& t : pgh_and_files) - { - if (t.pgh.package.spec.triplet() != triplet) - { - continue; - } - - output.insert(output.end(), t.files.begin(), t.files.end()); - } - - std::sort(output.begin(), output.end()); - return output; - } - - static SortedVector build_list_of_package_files(const Files::Filesystem& fs, - const fs::path& package_dir) - { - const std::vector package_file_paths = fs.get_files_recursive(package_dir); - const size_t package_remove_char_count = package_dir.generic_string().size() + 1; // +1 for the slash - auto package_files = Util::fmap(package_file_paths, [package_remove_char_count](const fs::path& path) { - std::string as_string = path.generic_string(); - as_string.erase(0, package_remove_char_count); - return std::move(as_string); - }); - - return SortedVector(std::move(package_files)); - } - - static SortedVector build_list_of_installed_files( - const std::vector& pgh_and_files, const Triplet& triplet) - { - std::vector installed_files = extract_files_in_triplet(pgh_and_files, triplet); - const size_t installed_remove_char_count = triplet.canonical_name().size() + 1; // +1 for the slash - remove_first_n_chars(&installed_files, installed_remove_char_count); - - return SortedVector(std::move(installed_files)); - } - - InstallResult install_package(const VcpkgPaths& paths, const BinaryControlFile& bcf, StatusParagraphs* status_db) - { - const fs::path package_dir = paths.package_dir(bcf.core_paragraph.spec); - const Triplet& triplet = bcf.core_paragraph.spec.triplet(); - const std::vector pgh_and_files = get_installed_files(paths, *status_db); - - const SortedVector package_files = - build_list_of_package_files(paths.get_filesystem(), package_dir); - const SortedVector installed_files = build_list_of_installed_files(pgh_and_files, triplet); - - std::vector intersection; - std::set_intersection(package_files.begin(), - package_files.end(), - installed_files.begin(), - installed_files.end(), - std::back_inserter(intersection)); - - if (!intersection.empty()) - { - const fs::path triplet_install_path = paths.installed / triplet.canonical_name(); - System::println(System::Color::error, - "The following files are already installed in %s and are in conflict with %s", - triplet_install_path.generic_string(), - bcf.core_paragraph.spec); - System::print("\n "); - System::println(Strings::join("\n ", intersection)); - System::println(); - return InstallResult::FILE_CONFLICTS; - } - - StatusParagraph source_paragraph; - source_paragraph.package = bcf.core_paragraph; - source_paragraph.want = Want::INSTALL; - source_paragraph.state = InstallState::HALF_INSTALLED; - - write_update(paths, source_paragraph); - status_db->insert(std::make_unique(source_paragraph)); - - std::vector features_spghs; - for (auto&& feature : bcf.features) - { - features_spghs.emplace_back(); - - StatusParagraph& feature_paragraph = features_spghs.back(); - feature_paragraph.package = feature; - feature_paragraph.want = Want::INSTALL; - feature_paragraph.state = InstallState::HALF_INSTALLED; - - write_update(paths, feature_paragraph); - status_db->insert(std::make_unique(feature_paragraph)); - } - - const InstallDir install_dir = InstallDir::from_destination_root( - paths.installed, triplet.to_string(), paths.listfile_path(bcf.core_paragraph)); - - install_files_and_write_listfile(paths.get_filesystem(), package_dir, install_dir); - - source_paragraph.state = InstallState::INSTALLED; - write_update(paths, source_paragraph); - status_db->insert(std::make_unique(source_paragraph)); - - for (auto&& feature_paragraph : features_spghs) - { - feature_paragraph.state = InstallState::INSTALLED; - write_update(paths, feature_paragraph); - status_db->insert(std::make_unique(feature_paragraph)); - } - - return InstallResult::SUCCESS; - } - - using Build::BuildResult; - - BuildResult perform_install_plan_action(const VcpkgPaths& paths, - const InstallPlanAction& action, - const Build::BuildPackageOptions& build_package_options, - StatusParagraphs& status_db) - { - const InstallPlanType& plan_type = action.plan_type; - const std::string display_name = action.spec.to_string(); - const std::string display_name_with_features = - GlobalState::feature_packages ? action.displayname() : display_name; - - const bool is_user_requested = action.request_type == RequestType::USER_REQUESTED; - const bool use_head_version = to_bool(build_package_options.use_head_version); - - if (plan_type == InstallPlanType::ALREADY_INSTALLED) - { - if (use_head_version && is_user_requested) - System::println( - System::Color::warning, "Package %s is already installed -- not building from HEAD", display_name); - else - System::println(System::Color::success, "Package %s is already installed", display_name); - return BuildResult::SUCCEEDED; - } - - if (plan_type == InstallPlanType::BUILD_AND_INSTALL) - { - if (use_head_version) - System::println("Building package %s from HEAD... ", display_name_with_features); - else - System::println("Building package %s... ", display_name_with_features); - - const auto result = [&]() -> Build::ExtendedBuildResult { - if (GlobalState::feature_packages) - { - const Build::BuildPackageConfig build_config{ - *action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO), - action.spec.triplet(), - paths.port_dir(action.spec), - build_package_options, - action.feature_list}; - return Build::build_package(paths, build_config, status_db); - } - else - { - const Build::BuildPackageConfig build_config{ - action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO), - action.spec.triplet(), - paths.port_dir(action.spec), - build_package_options}; - return Build::build_package(paths, build_config, status_db); - } - }(); - - if (result.code != Build::BuildResult::SUCCEEDED) - { - System::println(System::Color::error, Build::create_error_message(result.code, action.spec)); - return result.code; - } - - System::println("Building package %s... done", display_name_with_features); - - const BinaryControlFile bcf = - Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); - System::println("Installing package %s... ", display_name_with_features); - const auto install_result = install_package(paths, bcf, &status_db); - switch (install_result) - { - case InstallResult::SUCCESS: - System::println(System::Color::success, "Installing package %s... done", display_name); - return BuildResult::SUCCEEDED; - case InstallResult::FILE_CONFLICTS: return BuildResult::FILE_CONFLICTS; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - if (plan_type == InstallPlanType::INSTALL) - { - if (use_head_version && is_user_requested) - { - System::println( - System::Color::warning, "Package %s is already built -- not building from HEAD", display_name); - } - System::println("Installing package %s... ", display_name); - const auto install_result = install_package( - paths, action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO), &status_db); - switch (install_result) - { - case InstallResult::SUCCESS: - System::println(System::Color::success, "Installing package %s... done", display_name); - return BuildResult::SUCCEEDED; - case InstallResult::FILE_CONFLICTS: return BuildResult::FILE_CONFLICTS; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - Checks::unreachable(VCPKG_LINE_INFO); - } - - static void print_plan(const std::vector& action_plan, bool is_recursive) - { - std::vector remove_plans; - std::vector rebuilt_plans; - std::vector only_install_plans; - std::vector new_plans; - std::vector already_installed_plans; - - const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { - if (auto iplan = package.install_plan.get()) - return iplan->request_type != RequestType::USER_REQUESTED; - else - return false; - }) != action_plan.cend(); - - for (auto&& action : action_plan) - { - if (auto install_action = action.install_plan.get()) - { - // remove plans are guaranteed to come before install plans, so we know the plan will be contained if at - // all. - auto it = Util::find_if( - remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); - if (it != remove_plans.end()) - { - rebuilt_plans.emplace_back(install_action); - } - else - { - switch (install_action->plan_type) - { - case InstallPlanType::INSTALL: only_install_plans.emplace_back(install_action); break; - case InstallPlanType::ALREADY_INSTALLED: - if (install_action->request_type == RequestType::USER_REQUESTED) - already_installed_plans.emplace_back(install_action); - break; - case InstallPlanType::BUILD_AND_INSTALL: new_plans.emplace_back(install_action); break; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - } - else if (auto remove_action = action.remove_plan.get()) - { - remove_plans.emplace_back(remove_action); - } - } - - std::sort(remove_plans.begin(), remove_plans.end(), &RemovePlanAction::compare_by_name); - std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); - std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); - - if (already_installed_plans.size() > 0) - { - const std::string already_string = - Strings::join("\n", already_installed_plans, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); - System::println("The following packages are already installed:\n%s", already_string); - } - - if (rebuilt_plans.size() > 0) - { - const std::string rebuilt_string = Strings::join("\n", rebuilt_plans, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); - System::println("The following packages will be rebuilt:\n%s", rebuilt_string); - } - - if (new_plans.size() > 0) - { - const std::string new_string = Strings::join("\n", new_plans, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); - System::println("The following packages will be built and installed:\n%s", new_string); - } - - if (only_install_plans.size() > 0) - { - const std::string only_install_string = - Strings::join("\n", only_install_plans, [](const InstallPlanAction* p) { - return to_output_string(p->request_type, p->displayname()); - }); - System::println("The following packages will be directly installed:\n%s", only_install_string); - } - - if (has_non_user_requested_packages) - System::println("Additional packages (*) will be installed to complete this operation."); - - if (remove_plans.size() > 0 && !is_recursive) - { - System::println(System::Color::warning, - "If you are sure you want to rebuild the above packages, run the command with the " - "--recurse option"); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - - void perform_and_exit(const std::vector& action_plan, - const Build::BuildPackageOptions& install_plan_options, - const KeepGoing keep_going, - const PrintSummary print_summary, - const VcpkgPaths& paths, - StatusParagraphs& status_db) - { - std::vector results; - std::vector timing; - const ElapsedTime timer = ElapsedTime::create_started(); - size_t counter = 0; - const size_t package_count = action_plan.size(); - - for (const auto& action : action_plan) - { - const ElapsedTime build_timer = ElapsedTime::create_started(); - counter++; - - const std::string display_name = action.spec().to_string(); - System::println("Starting package %d/%d: %s", counter, package_count, display_name); - - timing.push_back("0"); - results.push_back(BuildResult::NULLVALUE); - - if (const auto install_action = action.install_plan.get()) - { - const BuildResult result = - perform_install_plan_action(paths, *install_action, install_plan_options, status_db); - if (result != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO) - { - System::println(Build::create_user_troubleshooting_message(install_action->spec)); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - results.back() = result; - } - else if (const auto remove_action = action.remove_plan.get()) - { - Checks::check_exit(VCPKG_LINE_INFO, GlobalState::feature_packages); - Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, status_db); - } - else - { - Checks::unreachable(VCPKG_LINE_INFO); - } - - timing.back() = build_timer.to_string(); - System::println("Elapsed time for package %s: %s", display_name, build_timer.to_string()); - } - - System::println("Total time taken: %s", timer.to_string()); - - if (print_summary == PrintSummary::YES) - { - for (size_t i = 0; i < results.size(); i++) - { - System::println("%s: %s: %s", action_plan[i].spec(), Build::to_string(results[i]), timing[i]); - } - - std::map summary; - for (const BuildResult& v : Build::BUILD_RESULT_VALUES) - { - summary[v] = 0; - } - - for (const BuildResult& r : results) - { - summary[r]++; - } - - System::println("\n\nSUMMARY"); - for (const std::pair& entry : summary) - { - System::println(" %s: %d", Build::to_string(entry.first), entry.second); - } - } - - Checks::exit_success(VCPKG_LINE_INFO); - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - static const std::string OPTION_DRY_RUN = "--dry-run"; - static const std::string OPTION_USE_HEAD_VERSION = "--head"; - static const std::string OPTION_NO_DOWNLOADS = "--no-downloads"; - static const std::string OPTION_RECURSE = "--recurse"; - static const std::string OPTION_KEEP_GOING = "--keep-going"; - - // input sanitization - static const std::string EXAMPLE = - Commands::Help::create_example_string("install zlib zlib:x64-windows curl boost"); - args.check_min_arg_count(1, EXAMPLE); - - const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_full_package_spec(arg, default_triplet, EXAMPLE); - }); - - for (auto&& spec : specs) - { - Input::check_triplet(spec.package_spec.triplet(), paths); - if (!spec.features.empty() && !GlobalState::feature_packages) - { - Checks::exit_with_message( - VCPKG_LINE_INFO, "Feature packages are experimentally available under the --featurepackages flag."); - } - } - - const std::unordered_set options = args.check_and_get_optional_command_arguments( - {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE, OPTION_KEEP_GOING}); - const bool dry_run = options.find(OPTION_DRY_RUN) != options.cend(); - const bool use_head_version = options.find(OPTION_USE_HEAD_VERSION) != options.cend(); - const bool no_downloads = options.find(OPTION_NO_DOWNLOADS) != options.cend(); - const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); - const KeepGoing keep_going = to_keep_going(options.find(OPTION_KEEP_GOING) != options.cend()); - - // create the plan - StatusParagraphs status_db = database_load_check(paths); - - const Build::BuildPackageOptions install_plan_options = {Build::to_use_head_version(use_head_version), - Build::to_allow_downloads(!no_downloads)}; - - std::vector action_plan; - - if (GlobalState::feature_packages) - { - std::unordered_map scf_map; - auto all_ports = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - for (auto&& port : all_ports) - { - scf_map[port->core_paragraph->name] = std::move(*port); - } - action_plan = create_feature_install_plan(scf_map, FullPackageSpec::to_feature_specs(specs), status_db); - } - else - { - Dependencies::PathsPortFile paths_port_file(paths); - auto install_plan = Dependencies::create_install_plan( - paths_port_file, Util::fmap(specs, [](auto&& spec) { return spec.package_spec; }), status_db); - - action_plan = Util::fmap( - install_plan, [](InstallPlanAction& install_action) { return AnyAction(std::move(install_action)); }); - } - - // install plan will be empty if it is already installed - need to change this at status paragraph part - Checks::check_exit(VCPKG_LINE_INFO, !action_plan.empty(), "Install plan cannot be empty"); - - // log the plan - const std::string specs_string = Strings::join(",", action_plan, [](const AnyAction& action) { - if (auto iaction = action.install_plan.get()) - return iaction->spec.to_string(); - else if (auto raction = action.remove_plan.get()) - return "R$" + raction->spec.to_string(); - Checks::unreachable(VCPKG_LINE_INFO); - }); - - Metrics::g_metrics.lock()->track_property("installplan", specs_string); - - print_plan(action_plan, is_recursive); - - if (dry_run) - { - Checks::exit_success(VCPKG_LINE_INFO); - } - - perform_and_exit(action_plan, install_plan_options, keep_going, PrintSummary::NO, paths, status_db); - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_integrate.cpp b/toolsrc/src/commands_integrate.cpp deleted file mode 100644 index fd2f11294..000000000 --- a/toolsrc/src/commands_integrate.cpp +++ /dev/null @@ -1,342 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Checks.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Files.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" - -namespace vcpkg::Commands::Integrate -{ - static const std::array OLD_SYSTEM_TARGET_FILES = { - System::get_program_files_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets", - System::get_program_files_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"}; - static const fs::path SYSTEM_WIDE_TARGETS_FILE = - System::get_program_files_32_bit() / "MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props"; - - static std::string create_appdata_targets_shortcut(const std::string& target_path) noexcept - { - return Strings::format(R"###( - - - -)###", - target_path, - target_path); - } - - static std::string create_system_targets_shortcut() noexcept - { - return R"###( - - - - $(LOCALAPPDATA)\vcpkg\vcpkg.user - - - -)###"; - } - - static std::string create_nuget_targets_file_contents(const fs::path& msbuild_vcpkg_targets_file) noexcept - { - const std::string as_string = msbuild_vcpkg_targets_file.string(); - - return Strings::format(R"###( - - - - - - -)###", - as_string, - as_string); - } - - static std::string create_nuget_props_file_contents() noexcept - { - return R"###( - - - true - - -)###"; - } - - static std::string get_nuget_id(const fs::path& vcpkg_root_dir) - { - std::string dir_id = vcpkg_root_dir.generic_string(); - std::replace(dir_id.begin(), dir_id.end(), '/', '.'); - dir_id.erase(1, 1); // Erasing the ":" - - // NuGet id cannot have invalid characters. We will only use alphanumeric and dot. - Util::erase_remove_if(dir_id, [](char c) { return !isalnum(c) && (c != '.'); }); - - const std::string nuget_id = "vcpkg." + dir_id; - return nuget_id; - } - - static std::string create_nuspec_file_contents(const fs::path& vcpkg_root_dir, - const std::string& nuget_id, - const std::string& nupkg_version) - { - static constexpr auto CONTENT_TEMPLATE = R"( - - - @NUGET_ID@ - @VERSION@ - vcpkg - - This package imports all libraries currently installed in @VCPKG_DIR@. This package does not contain any libraries and instead refers to the folder directly (like a symlink). - - - - - - - -)"; - - std::string content = std::regex_replace(CONTENT_TEMPLATE, std::regex("@NUGET_ID@"), nuget_id); - content = std::regex_replace(content, std::regex("@VCPKG_DIR@"), vcpkg_root_dir.string()); - content = std::regex_replace(content, std::regex("@VERSION@"), nupkg_version); - return content; - } - - enum class ElevationPromptChoice - { - YES, - NO - }; - - static ElevationPromptChoice elevated_cmd_execute(const std::string& param) - { - SHELLEXECUTEINFOW sh_ex_info = {0}; - sh_ex_info.cbSize = sizeof(sh_ex_info); - sh_ex_info.fMask = SEE_MASK_NOCLOSEPROCESS; - sh_ex_info.hwnd = nullptr; - sh_ex_info.lpVerb = L"runas"; - sh_ex_info.lpFile = L"cmd"; // Application to start - - auto wparam = Strings::to_utf16(param); - sh_ex_info.lpParameters = wparam.c_str(); // Additional parameters - sh_ex_info.lpDirectory = nullptr; - sh_ex_info.nShow = SW_HIDE; - sh_ex_info.hInstApp = nullptr; - - if (!ShellExecuteExW(&sh_ex_info)) - { - return ElevationPromptChoice::NO; - } - if (sh_ex_info.hProcess == nullptr) - { - return ElevationPromptChoice::NO; - } - WaitForSingleObject(sh_ex_info.hProcess, INFINITE); - CloseHandle(sh_ex_info.hProcess); - return ElevationPromptChoice::YES; - } - - static fs::path get_appdata_targets_path() - { - static const fs::path LOCAL_APP_DATA = - fs::path(System::get_environment_variable(L"LOCALAPPDATA").value_or_exit(VCPKG_LINE_INFO)); - return LOCAL_APP_DATA / "vcpkg" / "vcpkg.user.targets"; - } - - static void integrate_install(const VcpkgPaths& paths) - { - auto& fs = paths.get_filesystem(); - - // TODO: This block of code should eventually be removed - for (auto&& old_system_wide_targets_file : OLD_SYSTEM_TARGET_FILES) - { - if (fs.exists(old_system_wide_targets_file)) - { - const std::string param = - Strings::format(R"(/c DEL "%s" /Q > nul)", old_system_wide_targets_file.string()); - const ElevationPromptChoice user_choice = elevated_cmd_execute(param); - switch (user_choice) - { - case ElevationPromptChoice::YES: break; - case ElevationPromptChoice::NO: - System::println(System::Color::warning, "Warning: Previous integration file was not removed"); - Checks::exit_fail(VCPKG_LINE_INFO); - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - } - - std::error_code ec; - const fs::path tmp_dir = paths.buildsystems / "tmp"; - fs.create_directory(paths.buildsystems, ec); - fs.create_directory(tmp_dir, ec); - - bool should_install_system = true; - const Expected system_wide_file_contents = fs.read_contents(SYSTEM_WIDE_TARGETS_FILE); - static const std::regex RE(R"###()###"); - if (const auto contents_data = system_wide_file_contents.get()) - { - std::match_results match; - const auto found = std::regex_search(*contents_data, match, RE); - if (found) - { - const int ver = atoi(match[1].str().c_str()); - if (ver >= 1) should_install_system = false; - } - } - - if (should_install_system) - { - const fs::path sys_src_path = tmp_dir / "vcpkg.system.targets"; - fs.write_contents(sys_src_path, create_system_targets_shortcut()); - - const std::string param = Strings::format(R"(/c mkdir "%s" & copy "%s" "%s" /Y > nul)", - SYSTEM_WIDE_TARGETS_FILE.parent_path().string(), - sys_src_path.string(), - SYSTEM_WIDE_TARGETS_FILE.string()); - const ElevationPromptChoice user_choice = elevated_cmd_execute(param); - switch (user_choice) - { - case ElevationPromptChoice::YES: break; - case ElevationPromptChoice::NO: - System::println(System::Color::warning, "Warning: integration was not applied"); - Checks::exit_fail(VCPKG_LINE_INFO); - default: Checks::unreachable(VCPKG_LINE_INFO); - } - - Checks::check_exit(VCPKG_LINE_INFO, - fs.exists(SYSTEM_WIDE_TARGETS_FILE), - "Error: failed to copy targets file to %s", - SYSTEM_WIDE_TARGETS_FILE.string()); - } - - const fs::path appdata_src_path = tmp_dir / "vcpkg.user.targets"; - fs.write_contents(appdata_src_path, - create_appdata_targets_shortcut(paths.buildsystems_msbuild_targets.string())); - auto appdata_dst_path = get_appdata_targets_path(); - - const auto rc = fs.copy_file(appdata_src_path, appdata_dst_path, fs::copy_options::overwrite_existing, ec); - - if (!rc || ec) - { - System::println(System::Color::error, - "Error: Failed to copy file: %s -> %s", - appdata_src_path.string(), - appdata_dst_path.string()); - Checks::exit_fail(VCPKG_LINE_INFO); - } - System::println(System::Color::success, "Applied user-wide integration for this vcpkg root."); - const fs::path cmake_toolchain = paths.buildsystems / "vcpkg.cmake"; - System::println("\n" - "All MSBuild C++ projects can now #include any installed libraries.\n" - "Linking will be handled automatically.\n" - "Installing new libraries will make them instantly available.\n" - "\n" - "CMake projects should use -DCMAKE_TOOLCHAIN_FILE=%s", - cmake_toolchain.generic_string()); - - Checks::exit_success(VCPKG_LINE_INFO); - } - - static void integrate_remove(Files::Filesystem& fs) - { - const fs::path path = get_appdata_targets_path(); - - std::error_code ec; - const bool was_deleted = fs.remove(path, ec); - - Checks::check_exit(VCPKG_LINE_INFO, !ec, "Error: Unable to remove user-wide integration: %d", ec.message()); - - if (was_deleted) - { - System::println(System::Color::success, "User-wide integration was removed"); - } - else - { - System::println(System::Color::success, "User-wide integration is not installed"); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } - - static void integrate_project(const VcpkgPaths& paths) - { - auto& fs = paths.get_filesystem(); - - const fs::path& nuget_exe = paths.get_nuget_exe(); - - const fs::path& buildsystems_dir = paths.buildsystems; - const fs::path tmp_dir = buildsystems_dir / "tmp"; - std::error_code ec; - fs.create_directory(buildsystems_dir, ec); - fs.create_directory(tmp_dir, ec); - - const fs::path targets_file_path = tmp_dir / "vcpkg.nuget.targets"; - const fs::path props_file_path = tmp_dir / "vcpkg.nuget.props"; - const fs::path nuspec_file_path = tmp_dir / "vcpkg.nuget.nuspec"; - const std::string nuget_id = get_nuget_id(paths.root); - const std::string nupkg_version = "1.0.0"; - - fs.write_contents(targets_file_path, create_nuget_targets_file_contents(paths.buildsystems_msbuild_targets)); - fs.write_contents(props_file_path, create_nuget_props_file_contents()); - fs.write_contents(nuspec_file_path, create_nuspec_file_contents(paths.root, nuget_id, nupkg_version)); - - // Using all forward slashes for the command line - const std::wstring cmd_line = Strings::wformat(LR"("%s" pack -OutputDirectory "%s" "%s" > nul)", - nuget_exe.native(), - buildsystems_dir.native(), - nuspec_file_path.native()); - - const int exit_code = System::cmd_execute_clean(cmd_line); - - const fs::path nuget_package = buildsystems_dir / Strings::format("%s.%s.nupkg", nuget_id, nupkg_version); - Checks::check_exit( - VCPKG_LINE_INFO, exit_code == 0 && fs.exists(nuget_package), "Error: NuGet package creation failed"); - System::println(System::Color::success, "Created nupkg: %s", nuget_package.string()); - - auto source_path = buildsystems_dir.u8string(); - source_path = std::regex_replace(source_path, std::regex("`"), "``"); - - System::println(R"( -With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: - Install-Package %s -Source "%s" -)", - nuget_id, - source_path); - - Checks::exit_success(VCPKG_LINE_INFO); - } - - const char* const INTEGRATE_COMMAND_HELPSTRING = - " vcpkg integrate install Make installed packages available user-wide. Requires admin privileges on " - "first use\n" - " vcpkg integrate remove Remove user-wide integration\n" - " vcpkg integrate project Generate a referencing nuget package for individual VS project use\n"; - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Strings::format("Commands:\n" - "%s", - INTEGRATE_COMMAND_HELPSTRING); - args.check_exact_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - if (args.command_arguments[0] == "install") - { - return integrate_install(paths); - } - if (args.command_arguments[0] == "remove") - { - return integrate_remove(paths.get_filesystem()); - } - if (args.command_arguments[0] == "project") - { - return integrate_project(paths); - } - - Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown parameter %s for integrate", args.command_arguments[0]); - } -} diff --git a/toolsrc/src/commands_list.cpp b/toolsrc/src/commands_list.cpp deleted file mode 100644 index 640885860..000000000 --- a/toolsrc/src/commands_list.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::List -{ - static const std::string OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually - - static void do_print(const StatusParagraph& pgh, bool full_desc) - { - if (full_desc) - { - System::println("%-30s %-16s %s", pgh.package.displayname(), pgh.package.version, pgh.package.description); - } - else - { - System::println("%-30s %-16s %s", - vcpkg::shorten_text(pgh.package.displayname(), 30), - vcpkg::shorten_text(pgh.package.version, 16), - vcpkg::shorten_text(pgh.package.description, 71)); - } - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Strings::format( - "The argument should be a substring to search for, or no argument to display all installed libraries.\n%s", - Commands::Help::create_example_string("list png")); - args.check_max_arg_count(1, EXAMPLE); - const std::unordered_set options = - args.check_and_get_optional_command_arguments({OPTION_FULLDESC}); - - const StatusParagraphs status_paragraphs = database_load_check(paths); - std::vector installed_packages = get_installed_ports(status_paragraphs); - - if (installed_packages.empty()) - { - System::println("No packages are installed. Did you mean `search`?"); - Checks::exit_success(VCPKG_LINE_INFO); - } - - std::sort(installed_packages.begin(), - installed_packages.end(), - [](const StatusParagraph* lhs, const StatusParagraph* rhs) -> bool { - return lhs->package.displayname() < rhs->package.displayname(); - }); - - if (args.command_arguments.size() == 0) - { - for (const StatusParagraph* status_paragraph : installed_packages) - { - do_print(*status_paragraph, options.find(OPTION_FULLDESC) != options.cend()); - } - } - else - { - // At this point there is 1 argument - for (const StatusParagraph* status_paragraph : installed_packages) - { - const std::string displayname = status_paragraph->package.displayname(); - if (Strings::case_insensitive_ascii_find(displayname, args.command_arguments[0]) == displayname.end()) - { - continue; - } - - do_print(*status_paragraph, options.find(OPTION_FULLDESC) != options.cend()); - } - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_owns.cpp b/toolsrc/src/commands_owns.cpp deleted file mode 100644 index 718a0277f..000000000 --- a/toolsrc/src/commands_owns.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::Owns -{ - static void search_file(const VcpkgPaths& paths, const std::string& file_substr, const StatusParagraphs& status_db) - { - const std::vector installed_files = get_installed_files(paths, status_db); - for (const StatusParagraphAndAssociatedFiles& pgh_and_file : installed_files) - { - const StatusParagraph& pgh = pgh_and_file.pgh; - - for (const std::string& file : pgh_and_file.files) - { - if (file.find(file_substr) != std::string::npos) - { - System::println("%s: %s", pgh.package.displayname(), file); - } - } - } - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Strings::format("The argument should be a pattern to search for. %s", - Commands::Help::create_example_string("owns zlib.dll")); - args.check_exact_arg_count(1, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - StatusParagraphs status_db = database_load_check(paths); - search_file(paths, args.command_arguments[0], status_db); - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_portsdiff.cpp b/toolsrc/src/commands_portsdiff.cpp deleted file mode 100644 index 2334b2270..000000000 --- a/toolsrc/src/commands_portsdiff.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "SortedVector.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Maps.h" -#include "vcpkg_System.h" - -namespace vcpkg::Commands::PortsDiff -{ - struct UpdatedPort - { - static bool compare_by_name(const UpdatedPort& left, const UpdatedPort& right) - { - return left.port < right.port; - } - - std::string port; - VersionDiff version_diff; - }; - - template - struct SetElementPresence - { - static SetElementPresence create(std::vector left, std::vector right) - { - // TODO: This can be done with one pass instead of three passes - SetElementPresence output; - std::set_difference( - left.cbegin(), left.cend(), right.cbegin(), right.cend(), std::back_inserter(output.only_left)); - std::set_intersection( - left.cbegin(), left.cend(), right.cbegin(), right.cend(), std::back_inserter(output.both)); - std::set_difference( - right.cbegin(), right.cend(), left.cbegin(), left.cend(), std::back_inserter(output.only_right)); - - return output; - } - - std::vector only_left; - std::vector both; - std::vector only_right; - }; - - static std::vector find_updated_ports( - const std::vector& ports, - const std::map& previous_names_and_versions, - const std::map& current_names_and_versions) - { - std::vector output; - for (const std::string& name : ports) - { - const VersionT& previous_version = previous_names_and_versions.at(name); - const VersionT& current_version = current_names_and_versions.at(name); - if (previous_version == current_version) - { - continue; - } - - output.push_back({name, VersionDiff(previous_version, current_version)}); - } - - return output; - } - - static void do_print_name_and_version(const std::vector& ports_to_print, - const std::map& names_and_versions) - { - for (const std::string& name : ports_to_print) - { - const VersionT& version = names_and_versions.at(name); - System::println(" - %-14s %-16s", name, version); - } - } - - static std::map read_ports_from_commit(const VcpkgPaths& paths, - const std::wstring& git_commit_id) - { - std::error_code ec; - auto& fs = paths.get_filesystem(); - const fs::path& git_exe = paths.get_git_exe(); - const fs::path dot_git_dir = paths.root / ".git"; - const std::wstring ports_dir_name_as_string = paths.ports.filename().native(); - const fs::path temp_checkout_path = - paths.root / Strings::wformat(L"%s-%s", ports_dir_name_as_string, git_commit_id); - fs.create_directory(temp_checkout_path, ec); - const std::wstring checkout_this_dir = - Strings::wformat(LR"(.\%s)", ports_dir_name_as_string); // Must be relative to the root of the repository - - const std::wstring cmd = - Strings::wformat(LR"("%s" --git-dir="%s" --work-tree="%s" checkout %s -f -q -- %s %s & "%s" reset >NUL)", - git_exe.native(), - dot_git_dir.native(), - temp_checkout_path.native(), - git_commit_id, - checkout_this_dir, - L".vcpkg-root", - git_exe.native()); - System::cmd_execute_clean(cmd); - const std::map names_and_versions = Paragraphs::load_all_port_names_and_versions( - paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); - fs.remove_all(temp_checkout_path, ec); - return names_and_versions; - } - - static void check_commit_exists(const fs::path& git_exe, const std::wstring& git_commit_id) - { - static const std::string VALID_COMMIT_OUTPUT = "commit\n"; - - const std::wstring cmd = Strings::wformat(LR"("%s" cat-file -t %s)", git_exe.native(), git_commit_id); - const System::ExitCodeAndOutput output = System::cmd_execute_and_capture_output(cmd); - Checks::check_exit(VCPKG_LINE_INFO, - output.output == VALID_COMMIT_OUTPUT, - "Invalid commit id %s", - Strings::to_utf8(git_commit_id)); - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = - Strings::format("The argument should be a branch/tag/hash to checkout.\n%s", - Commands::Help::create_example_string("portsdiff mybranchname")); - args.check_min_arg_count(1, EXAMPLE); - args.check_max_arg_count(2, EXAMPLE); - args.check_and_get_optional_command_arguments({}); - - const fs::path& git_exe = paths.get_git_exe(); - - const std::wstring git_commit_id_for_previous_snapshot = Strings::to_utf16(args.command_arguments.at(0)); - const std::wstring git_commit_id_for_current_snapshot = - args.command_arguments.size() < 2 ? L"HEAD" : Strings::to_utf16(args.command_arguments.at(1)); - - check_commit_exists(git_exe, git_commit_id_for_current_snapshot); - check_commit_exists(git_exe, git_commit_id_for_previous_snapshot); - - const std::map current_names_and_versions = - read_ports_from_commit(paths, git_commit_id_for_current_snapshot); - const std::map previous_names_and_versions = - read_ports_from_commit(paths, git_commit_id_for_previous_snapshot); - - // Already sorted, so set_difference can work on std::vector too - const std::vector current_ports = Maps::extract_keys(current_names_and_versions); - const std::vector previous_ports = Maps::extract_keys(previous_names_and_versions); - - const SetElementPresence setp = - SetElementPresence::create(current_ports, previous_ports); - - const std::vector& added_ports = setp.only_left; - if (!added_ports.empty()) - { - System::println("\nThe following %d ports were added:", added_ports.size()); - do_print_name_and_version(added_ports, current_names_and_versions); - } - - const std::vector& removed_ports = setp.only_right; - if (!removed_ports.empty()) - { - System::println("\nThe following %d ports were removed:", removed_ports.size()); - do_print_name_and_version(removed_ports, previous_names_and_versions); - } - - const std::vector& common_ports = setp.both; - const std::vector updated_ports = - find_updated_ports(common_ports, previous_names_and_versions, current_names_and_versions); - - if (!updated_ports.empty()) - { - System::println("\nThe following %d ports were updated:", updated_ports.size()); - for (const UpdatedPort& p : updated_ports) - { - System::println(" - %-14s %-16s", p.port, p.version_diff.to_string()); - } - } - - if (added_ports.empty() && removed_ports.empty() && updated_ports.empty()) - { - System::println("There were no changes in the ports between the two commits."); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_remove.cpp b/toolsrc/src/commands_remove.cpp deleted file mode 100644 index a9f1b2564..000000000 --- a/toolsrc/src/commands_remove.cpp +++ /dev/null @@ -1,249 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Commands.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Input.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::Remove -{ - using Dependencies::RemovePlanAction; - using Dependencies::RemovePlanType; - using Dependencies::RequestType; - using Update::OutdatedPackage; - - void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db) - { - auto& fs = paths.get_filesystem(); - auto spghs = status_db->find_all(spec.name(), spec.triplet()); - const auto core_pkg = **status_db->find(spec.name(), spec.triplet(), Strings::EMPTY); - - for (auto&& spgh : spghs) - { - StatusParagraph& pkg = **spgh; - if (pkg.state != InstallState::INSTALLED) continue; - pkg.want = Want::PURGE; - pkg.state = InstallState::HALF_INSTALLED; - write_update(paths, pkg); - } - - auto maybe_lines = fs.read_lines(paths.listfile_path(core_pkg.package)); - - if (const auto lines = maybe_lines.get()) - { - std::vector dirs_touched; - for (auto&& suffix : *lines) - { - if (!suffix.empty() && suffix.back() == '\r') suffix.pop_back(); - - std::error_code ec; - - auto target = paths.installed / suffix; - - const auto status = fs.status(target, ec); - if (ec) - { - System::println(System::Color::error, "failed: %s", ec.message()); - continue; - } - - if (fs::is_directory(status)) - { - dirs_touched.push_back(target); - } - else if (fs::is_regular_file(status)) - { - fs.remove(target, ec); - if (ec) - { - System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); - } - } - else if (!fs::status_known(status)) - { - System::println(System::Color::warning, "Warning: unknown status: %s", target.u8string()); - } - else - { - System::println(System::Color::warning, "Warning: %s: cannot handle file type", target.u8string()); - } - } - - auto b = dirs_touched.rbegin(); - const auto e = dirs_touched.rend(); - for (; b != e; ++b) - { - if (fs.is_empty(*b)) - { - std::error_code ec; - fs.remove(*b, ec); - if (ec) - { - System::println(System::Color::error, "failed: %s", ec.message()); - } - } - } - - fs.remove(paths.listfile_path(core_pkg.package)); - } - - for (auto&& spgh : spghs) - { - StatusParagraph& pkg = **spgh; - if (pkg.state != InstallState::HALF_INSTALLED) continue; - pkg.state = InstallState::NOT_INSTALLED; - write_update(paths, pkg); - } - } - - static void print_plan(const std::map>& group_by_plan_type) - { - static constexpr std::array ORDER = {RemovePlanType::NOT_INSTALLED, RemovePlanType::REMOVE}; - - for (const RemovePlanType plan_type : ORDER) - { - const auto it = group_by_plan_type.find(plan_type); - if (it == group_by_plan_type.cend()) - { - continue; - } - - std::vector cont = it->second; - std::sort(cont.begin(), cont.end(), &RemovePlanAction::compare_by_name); - const std::string as_string = Strings::join("\n", cont, [](const RemovePlanAction* p) { - return Dependencies::to_output_string(p->request_type, p->spec.to_string()); - }); - - switch (plan_type) - { - case RemovePlanType::NOT_INSTALLED: - System::println("The following packages are not installed, so not removed:\n%s", as_string); - continue; - case RemovePlanType::REMOVE: - System::println("The following packages will be removed:\n%s", as_string); - continue; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - } - - void perform_remove_plan_action(const VcpkgPaths& paths, - const RemovePlanAction& action, - const Purge purge, - StatusParagraphs& status_db) - { - const std::string display_name = action.spec.to_string(); - - switch (action.plan_type) - { - case RemovePlanType::NOT_INSTALLED: - System::println(System::Color::success, "Package %s is not installed", display_name); - break; - case RemovePlanType::REMOVE: - System::println("Removing package %s... ", display_name); - remove_package(paths, action.spec, &status_db); - System::println(System::Color::success, "Removing package %s... done", display_name); - break; - case RemovePlanType::UNKNOWN: - default: Checks::unreachable(VCPKG_LINE_INFO); - } - - if (purge == Purge::YES) - { - System::println("Purging package %s... ", display_name); - Files::Filesystem& fs = paths.get_filesystem(); - std::error_code ec; - fs.remove_all(paths.packages / action.spec.dir(), ec); - System::println(System::Color::success, "Purging package %s... done", display_name); - } - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) - { - static const std::string OPTION_PURGE = "--purge"; - static const std::string OPTION_NO_PURGE = "--no-purge"; - static const std::string OPTION_RECURSE = "--recurse"; - static const std::string OPTION_DRY_RUN = "--dry-run"; - static const std::string OPTION_OUTDATED = "--outdated"; - static const std::string EXAMPLE = - Commands::Help::create_example_string("remove zlib zlib:x64-windows curl boost"); - const std::unordered_set options = args.check_and_get_optional_command_arguments( - {OPTION_PURGE, OPTION_NO_PURGE, OPTION_RECURSE, OPTION_DRY_RUN, OPTION_OUTDATED}); - - StatusParagraphs status_db = database_load_check(paths); - std::vector specs; - if (options.find(OPTION_OUTDATED) != options.cend()) - { - args.check_exact_arg_count(0, EXAMPLE); - specs = Util::fmap(Update::find_outdated_packages(paths, status_db), - [](auto&& outdated) { return outdated.spec; }); - - if (specs.empty()) - { - System::println(System::Color::success, "There are no outdated packages."); - Checks::exit_success(VCPKG_LINE_INFO); - } - } - else - { - args.check_min_arg_count(1, EXAMPLE); - specs = Util::fmap(args.command_arguments, [&](auto&& arg) { - return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE); - }); - - for (auto&& spec : specs) - Input::check_triplet(spec.triplet(), paths); - } - - const bool no_purge_was_passed = options.find(OPTION_NO_PURGE) != options.end(); - const bool purge_was_passed = options.find(OPTION_PURGE) != options.end(); - if (purge_was_passed && no_purge_was_passed) - { - System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge."); - System::print(EXAMPLE); - Checks::exit_fail(VCPKG_LINE_INFO); - } - const Purge purge = to_purge(purge_was_passed || !no_purge_was_passed); - const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); - const bool dry_run = options.find(OPTION_DRY_RUN) != options.cend(); - - const std::vector remove_plan = Dependencies::create_remove_plan(specs, status_db); - Checks::check_exit(VCPKG_LINE_INFO, !remove_plan.empty(), "Remove plan cannot be empty"); - - std::map> group_by_plan_type; - Util::group_by(remove_plan, &group_by_plan_type, [](const RemovePlanAction& p) { return p.plan_type; }); - print_plan(group_by_plan_type); - - const bool has_non_user_requested_packages = - Util::find_if(remove_plan, [](const RemovePlanAction& package) -> bool { - return package.request_type != RequestType::USER_REQUESTED; - }) != remove_plan.cend(); - - if (has_non_user_requested_packages) - { - System::println(System::Color::warning, - "Additional packages (*) need to be removed to complete this operation."); - - if (!is_recursive) - { - System::println(System::Color::warning, - "If you are sure you want to remove them, run the command with the --recurse option"); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - - if (dry_run) - { - Checks::exit_success(VCPKG_LINE_INFO); - } - - for (const RemovePlanAction& action : remove_plan) - { - perform_remove_plan_action(paths, action, purge, status_db); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_search.cpp b/toolsrc/src/commands_search.cpp deleted file mode 100644 index d35a546c4..000000000 --- a/toolsrc/src/commands_search.cpp +++ /dev/null @@ -1,145 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "SourceParagraph.h" -#include "vcpkg_Commands.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::Search -{ - static const std::string OPTION_GRAPH = "--graph"; // TODO: This should find a better home, eventually - static const std::string OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually - - static std::string replace_dashes_with_underscore(const std::string& input) - { - std::string output = input; - std::replace(output.begin(), output.end(), '-', '_'); - return output; - } - - static std::string create_graph_as_string( - const std::vector>& source_control_files) - { - int empty_node_count = 0; - - std::string s; - s.append("digraph G{ rankdir=LR; edge [minlen=3]; overlap=false;"); - - for (const auto& source_control_file : source_control_files) - { - const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; - if (source_paragraph.depends.empty()) - { - empty_node_count++; - continue; - } - - const std::string name = replace_dashes_with_underscore(source_paragraph.name); - s.append(Strings::format("%s;", name)); - for (const Dependency& d : source_paragraph.depends) - { - const std::string dependency_name = replace_dashes_with_underscore(d.name()); - s.append(Strings::format("%s -> %s;", name, dependency_name)); - } - } - - s.append(Strings::format("empty [label=\"%d singletons...\"]; }", empty_node_count)); - return s; - } - static void do_print(const SourceParagraph& source_paragraph, bool full_desc) - { - if (full_desc) - { - System::println( - "%-20s %-16s %s", source_paragraph.name, source_paragraph.version, source_paragraph.description); - } - else - { - System::println("%-20s %-16s %s", - vcpkg::shorten_text(source_paragraph.name, 20), - vcpkg::shorten_text(source_paragraph.version, 16), - vcpkg::shorten_text(source_paragraph.description, 81)); - } - } - - static void do_print(const std::string& name, const FeatureParagraph& feature_paragraph, bool full_desc) - { - if (full_desc) - { - System::println("%-37s %s", name + "[" + feature_paragraph.name + "]", feature_paragraph.description); - } - else - { - System::println("%-37s %s", - vcpkg::shorten_text(name + "[" + feature_paragraph.name + "]", 37), - vcpkg::shorten_text(feature_paragraph.description, 81)); - } - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - static const std::string EXAMPLE = Strings::format( - "The argument should be a substring to search for, or no argument to display all libraries.\n%s", - Commands::Help::create_example_string("search png")); - args.check_max_arg_count(1, EXAMPLE); - const std::unordered_set options = - args.check_and_get_optional_command_arguments({OPTION_GRAPH, OPTION_FULLDESC}); - - auto source_paragraphs = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); - - if (options.find(OPTION_GRAPH) != options.cend()) - { - const std::string graph_as_string = create_graph_as_string(source_paragraphs); - System::println(graph_as_string); - Checks::exit_success(VCPKG_LINE_INFO); - } - - if (args.command_arguments.empty()) - { - for (const auto& source_control_file : source_paragraphs) - { - do_print(*source_control_file->core_paragraph, options.find(OPTION_FULLDESC) != options.cend()); - for (auto&& feature_paragraph : source_control_file->feature_paragraphs) - { - do_print(source_control_file->core_paragraph->name, - *feature_paragraph, - options.find(OPTION_FULLDESC) != options.cend()); - } - } - } - else - { - const auto& icontains = Strings::case_insensitive_ascii_contains; - - // At this point there is 1 argument - auto&& args_zero = args.command_arguments[0]; - for (const auto& source_control_file : source_paragraphs) - { - auto&& sp = *source_control_file->core_paragraph; - - bool contains_name = icontains(sp.name, args_zero); - if (contains_name || icontains(sp.description, args_zero)) - { - do_print(sp, options.find(OPTION_FULLDESC) != options.cend()); - } - - for (auto&& feature_paragraph : source_control_file->feature_paragraphs) - { - if (contains_name || icontains(feature_paragraph->name, args_zero) || - icontains(feature_paragraph->description, args_zero)) - { - do_print(sp.name, *feature_paragraph, options.find(OPTION_FULLDESC) != options.cend()); - } - } - } - } - - System::println( - "\nIf your library is not listed, please open an issue at and/or consider making a pull request:\n" - " https://github.com/Microsoft/vcpkg/issues"); - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_update.cpp b/toolsrc/src/commands_update.cpp deleted file mode 100644 index 71ea4b063..000000000 --- a/toolsrc/src/commands_update.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::Commands::Update -{ - bool OutdatedPackage::compare_by_name(const OutdatedPackage& left, const OutdatedPackage& right) - { - return left.spec.name() < right.spec.name(); - } - - std::vector find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db) - { - const std::map src_names_to_versions = - Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports); - const std::vector installed_packages = get_installed_ports(status_db); - - std::vector output; - for (const StatusParagraph* pgh : installed_packages) - { - const auto it = src_names_to_versions.find(pgh->package.spec.name()); - if (it == src_names_to_versions.end()) - { - // Package was not installed from portfile - continue; - } - if (it->second != pgh->package.version) - { - output.push_back({pgh->package.spec, VersionDiff(pgh->package.version, it->second)}); - } - } - - return output; - } - - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) - { - args.check_exact_arg_count(0); - args.check_and_get_optional_command_arguments({}); - System::println("Using local portfile versions. To update the local portfiles, use `git pull`."); - - const StatusParagraphs status_db = database_load_check(paths); - - const auto outdated_packages = - SortedVector(find_outdated_packages(paths, status_db), &OutdatedPackage::compare_by_name); - - if (outdated_packages.empty()) - { - System::println("No packages need updating."); - } - else - { - std::string install_line; - System::println("The following packages differ from their port versions:"); - for (auto&& package : outdated_packages) - { - install_line += package.spec.to_string(); - install_line += " "; - System::println(" %-32s %s", package.spec, package.version_diff.to_string()); - } - System::println("\n" - "To update these packages, run\n" - " .\\vcpkg remove --outdated\n" - " .\\vcpkg install " + - install_line); - } - - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/commands_version.cpp b/toolsrc/src/commands_version.cpp deleted file mode 100644 index 5744ea9ef..000000000 --- a/toolsrc/src/commands_version.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "pch.h" - -#include "metrics.h" -#include "vcpkg_Commands.h" -#include "vcpkg_System.h" - -#define STRINGIFY(...) #__VA_ARGS__ -#define MACRO_TO_STRING(X) STRINGIFY(X) - -#define VCPKG_VERSION_AS_STRING MACRO_TO_STRING(VCPKG_VERSION) - -namespace vcpkg::Commands::Version -{ - const std::string& version() - { - static const std::string S_VERSION = -#include "../VERSION.txt" - - +std::string(VCPKG_VERSION_AS_STRING) -#ifndef NDEBUG - + std::string("-debug") -#endif - + std::string(Metrics::get_compiled_metrics_enabled() ? Strings::EMPTY : "-external"); - return S_VERSION; - } - - void warn_if_vcpkg_version_mismatch(const VcpkgPaths& paths) - { - auto version_file = paths.get_filesystem().read_contents(paths.root / "toolsrc" / "VERSION.txt"); - if (const auto version_contents = version_file.get()) - { - int maj1, min1, rev1; - const auto num1 = sscanf_s(version_contents->c_str(), "\"%d.%d.%d\"", &maj1, &min1, &rev1); - - int maj2, min2, rev2; - const auto num2 = sscanf_s(Version::version().c_str(), "%d.%d.%d-", &maj2, &min2, &rev2); - - if (num1 == 3 && num2 == 3) - { - if (maj1 != maj2 || min1 != min2 || rev1 != rev2) - { - System::println(System::Color::warning, - "Warning: Different source is available for vcpkg (%d.%d.%d -> %d.%d.%d). Use " - ".\\bootstrap-vcpkg.bat to update.", - maj2, - min2, - rev2, - maj1, - min1, - rev1); - } - } - } - } - - void perform_and_exit(const VcpkgCmdArguments& args) - { - args.check_exact_arg_count(0); - args.check_and_get_optional_command_arguments({}); - - System::println("Vcpkg package management program version %s\n" - "\n" - "See LICENSE.txt for license information.", - version()); - Checks::exit_success(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/metrics.cpp b/toolsrc/src/metrics.cpp deleted file mode 100644 index 8a0050bfc..000000000 --- a/toolsrc/src/metrics.cpp +++ /dev/null @@ -1,395 +0,0 @@ -#include "pch.h" - -#include "filesystem_fs.h" -#include "metrics.h" -#include "vcpkg_Files.h" -#include "vcpkg_Strings.h" -#include "vcpkg_System.h" - -namespace vcpkg::Metrics -{ - Util::LockGuarded g_metrics; - - static std::string get_current_date_time() - { - struct tm newtime; - std::array date; - date.fill(0); - - struct _timeb timebuffer; - - _ftime_s(&timebuffer); - time_t now = timebuffer.time; - const int milli = timebuffer.millitm; - - const errno_t err = gmtime_s(&newtime, &now); - if (err) - { - return Strings::EMPTY; - } - - strftime(&date[0], date.size(), "%Y-%m-%dT%H:%M:%S", &newtime); - return std::string(&date[0]) + "." + std::to_string(milli) + "Z"; - } - - static std::string generate_random_UUID() - { - int part_sizes[] = {8, 4, 4, 4, 12}; - char uuid[37]; - memset(uuid, 0, sizeof(uuid)); - int num; - srand(static_cast(time(nullptr))); - int index = 0; - for (int part = 0; part < 5; part++) - { - if (part > 0) - { - uuid[index] = '-'; - index++; - } - - // Generating UUID format version 4 - // http://en.wikipedia.org/wiki/Universally_unique_identifier - for (int i = 0; i < part_sizes[part]; i++, index++) - { - if (part == 2 && i == 0) - { - num = 4; - } - else if (part == 4 && i == 0) - { - num = (rand() % 4) + 8; - } - else - { - num = rand() % 16; - } - - if (num < 10) - { - uuid[index] = static_cast('0' + num); - } - else - { - uuid[index] = static_cast('a' + (num - 10)); - } - } - } - - return uuid; - } - - static const std::string& get_session_id() - { - static const std::string ID = generate_random_UUID(); - return ID; - } - - static std::string to_json_string(const std::string& str) - { - std::string encoded = "\""; - for (auto&& ch : str) - { - if (ch == '\\') - { - encoded.append("\\\\"); - } - else if (ch == '"') - { - encoded.append("\\\""); - } - else if (ch < 0x20 || ch >= 0x80) - { - // Note: this treats incoming Strings as Latin-1 - static constexpr const char HEX[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; - encoded.append("\\u00"); - encoded.push_back(HEX[ch / 16]); - encoded.push_back(HEX[ch % 16]); - } - else - { - encoded.push_back(ch); - } - } - encoded.push_back('"'); - return encoded; - } - - static std::string get_os_version_string() - { - std::wstring path; - path.resize(MAX_PATH); - const auto n = GetSystemDirectoryW(&path[0], static_cast(path.size())); - path.resize(n); - path += L"\\kernel32.dll"; - - const auto versz = GetFileVersionInfoSizeW(path.c_str(), nullptr); - if (versz == 0) return Strings::EMPTY; - - std::vector verbuf; - verbuf.resize(versz); - - if (!GetFileVersionInfoW(path.c_str(), 0, static_cast(verbuf.size()), &verbuf[0])) return Strings::EMPTY; - - void* rootblock; - UINT rootblocksize; - if (!VerQueryValueW(&verbuf[0], L"\\", &rootblock, &rootblocksize)) return Strings::EMPTY; - - auto rootblock_ffi = static_cast(rootblock); - - return Strings::format("%d.%d.%d", - static_cast(HIWORD(rootblock_ffi->dwProductVersionMS)), - static_cast(LOWORD(rootblock_ffi->dwProductVersionMS)), - static_cast(HIWORD(rootblock_ffi->dwProductVersionLS))); - } - - struct MetricMessage - { - std::string user_id = generate_random_UUID(); - std::string user_timestamp; - std::string timestamp = get_current_date_time(); - std::string properties; - std::string measurements; - - void track_property(const std::string& name, const std::string& value) - { - if (properties.size() != 0) properties.push_back(','); - properties.append(to_json_string(name)); - properties.push_back(':'); - properties.append(to_json_string(value)); - } - - void track_metric(const std::string& name, double value) - { - if (measurements.size() != 0) measurements.push_back(','); - measurements.append(to_json_string(name)); - measurements.push_back(':'); - measurements.append(std::to_string(value)); - } - - std::string format_event_data_template() const - { - const std::string& session_id = get_session_id(); - return Strings::format(R"([{ - "ver": 1, - "name": "Microsoft.ApplicationInsights.Event", - "time": "%s", - "sampleRate": 100.000000, - "seq": "0:0", - "iKey": "b4e88960-4393-4dd9-ab8e-97e8fe6d7603", - "flags": 0.000000, - "tags": { - "ai.device.os": "Windows", - "ai.device.osVersion": "%s", - "ai.session.id": "%s", - "ai.user.id": "%s", - "ai.user.accountAcquisitionDate": "%s" - }, - "data": { - "baseType": "EventData", - "baseData": { - "ver": 2, - "name": "commandline_test7", - "properties": { %s }, - "measurements": { %s } - } - } -}])", - timestamp, - get_os_version_string(), - session_id, - user_id, - user_timestamp, - properties, - measurements); - } - }; - - static MetricMessage g_metricmessage; - static bool g_should_send_metrics = -#if defined(NDEBUG) && (DISABLE_METRICS == 0) - true -#else - false -#endif - ; - static bool g_should_print_metrics = false; - - bool get_compiled_metrics_enabled() { return DISABLE_METRICS == 0; } - - std::wstring get_SQM_user() - { - auto hkcu_sqmclient = - System::get_registry_string(HKEY_CURRENT_USER, LR"(Software\Microsoft\SQMClient)", L"UserId"); - return hkcu_sqmclient.value_or(L"{}"); - } - - void Metrics::set_user_information(const std::string& user_id, const std::string& first_use_time) - { - g_metricmessage.user_id = user_id; - g_metricmessage.user_timestamp = first_use_time; - } - - void Metrics::init_user_information(std::string& user_id, std::string& first_use_time) - { - user_id = generate_random_UUID(); - first_use_time = get_current_date_time(); - } - - void Metrics::set_send_metrics(bool should_send_metrics) { g_should_send_metrics = should_send_metrics; } - - void Metrics::set_print_metrics(bool should_print_metrics) { g_should_print_metrics = should_print_metrics; } - - void Metrics::track_metric(const std::string& name, double value) { g_metricmessage.track_metric(name, value); } - - void Metrics::track_property(const std::string& name, const std::wstring& value) - { - // Note: this is not valid UTF-16 -> UTF-8, it just yields a close enough approximation for our purposes. - std::string converted_value; - converted_value.resize(value.size()); - std::transform( - value.begin(), value.end(), converted_value.begin(), [](wchar_t ch) { return static_cast(ch); }); - - g_metricmessage.track_property(name, converted_value); - } - - void Metrics::track_property(const std::string& name, const std::string& value) - { - g_metricmessage.track_property(name, value); - } - - void Metrics::upload(const std::string& payload) - { - HINTERNET connect = nullptr, request = nullptr; - BOOL results = FALSE; - - const HINTERNET session = WinHttpOpen( - L"vcpkg/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); - if (session) connect = WinHttpConnect(session, L"dc.services.visualstudio.com", INTERNET_DEFAULT_HTTPS_PORT, 0); - - if (connect) - request = WinHttpOpenRequest(connect, - L"POST", - L"/v2/track", - nullptr, - WINHTTP_NO_REFERER, - WINHTTP_DEFAULT_ACCEPT_TYPES, - WINHTTP_FLAG_SECURE); - - if (request) - { - if (MAXDWORD <= payload.size()) abort(); - std::wstring hdrs = L"Content-Type: application/json\r\n"; - std::string& p = const_cast(payload); - results = WinHttpSendRequest(request, - hdrs.c_str(), - static_cast(hdrs.size()), - static_cast(&p[0]), - static_cast(payload.size()), - static_cast(payload.size()), - 0); - } - - if (results) - { - results = WinHttpReceiveResponse(request, nullptr); - } - - DWORD http_code = 0, junk = sizeof(DWORD); - - if (results) - { - results = WinHttpQueryHeaders(request, - WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, - nullptr, - &http_code, - &junk, - WINHTTP_NO_HEADER_INDEX); - } - - std::vector response_buffer; - if (results) - { - DWORD available_data = 0, read_data = 0, total_data = 0; - while ((results = WinHttpQueryDataAvailable(request, &available_data)) == TRUE && available_data > 0) - { - response_buffer.resize(response_buffer.size() + available_data); - - results = WinHttpReadData(request, &response_buffer.data()[total_data], available_data, &read_data); - - if (!results) - { - break; - } - - total_data += read_data; - - response_buffer.resize(total_data); - } - } - - if (!results) - { -#ifndef NDEBUG - __debugbreak(); - auto err = GetLastError(); - std::cerr << "[DEBUG] failed to connect to server: " << err << "\n"; -#endif - } - - if (request) WinHttpCloseHandle(request); - if (connect) WinHttpCloseHandle(connect); - if (session) WinHttpCloseHandle(session); - } - - static fs::path get_bindir() - { - wchar_t buf[_MAX_PATH]; - const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); - if (bytes == 0) std::abort(); - return fs::path(buf, buf + bytes); - } - - void Metrics::flush() - { - const std::string payload = g_metricmessage.format_event_data_template(); - if (g_should_print_metrics) std::cerr << payload << "\n"; - if (!g_should_send_metrics) return; - - // upload(payload); - - wchar_t temp_folder[MAX_PATH]; - GetTempPathW(MAX_PATH, temp_folder); - - const fs::path temp_folder_path = temp_folder; - const fs::path temp_folder_path_exe = temp_folder_path / "vcpkgmetricsuploader.exe"; - - auto& fs = Files::get_real_filesystem(); - - if (true) - { - const fs::path exe_path = [&fs]() -> fs::path { - auto vcpkgdir = get_bindir().parent_path(); - auto path = vcpkgdir / "vcpkgmetricsuploader.exe"; - if (fs.exists(path)) return path; - - path = vcpkgdir / "scripts" / "vcpkgmetricsuploader.exe"; - if (fs.exists(path)) return path; - - return Strings::WEMPTY; - }(); - - std::error_code ec; - fs.copy_file(exe_path, temp_folder_path_exe, fs::copy_options::skip_existing, ec); - if (ec) return; - } - - const fs::path vcpkg_metrics_txt_path = temp_folder_path / ("vcpkg" + generate_random_UUID() + ".txt"); - fs.write_contents(vcpkg_metrics_txt_path, payload); - - const std::wstring cmd_line = - Strings::wformat(L"start %s %s", temp_folder_path_exe.native(), vcpkg_metrics_txt_path.native()); - System::cmd_execute_clean(cmd_line); - } -} diff --git a/toolsrc/src/test_install_plan.cpp b/toolsrc/src/test_install_plan.cpp deleted file mode 100644 index 6c9311264..000000000 --- a/toolsrc/src/test_install_plan.cpp +++ /dev/null @@ -1,486 +0,0 @@ -#include "CppUnitTest.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Util.h" - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -using namespace vcpkg; - -namespace Microsoft::VisualStudio::CppUnitTestFramework -{ - template<> - inline std::wstring ToString(const vcpkg::Dependencies::InstallPlanType& t) - { - switch (t) - { - case Dependencies::InstallPlanType::ALREADY_INSTALLED: return L"ALREADY_INSTALLED"; - case Dependencies::InstallPlanType::BUILD_AND_INSTALL: return L"BUILD_AND_INSTALL"; - case Dependencies::InstallPlanType::INSTALL: return L"INSTALL"; - case Dependencies::InstallPlanType::UNKNOWN: return L"UNKNOWN"; - default: return ToString((int)t); - } - } - - template<> - inline std::wstring ToString(const vcpkg::Dependencies::RequestType& t) - { - switch (t) - { - case Dependencies::RequestType::AUTO_SELECTED: return L"AUTO_SELECTED"; - case Dependencies::RequestType::USER_REQUESTED: return L"USER_REQUESTED"; - case Dependencies::RequestType::UNKNOWN: return L"UNKNOWN"; - default: return ToString((int)t); - } - } -} - -namespace UnitTest1 -{ - class InstallPlanTests : public TestClass - { - static std::unique_ptr make_control_file( - const char* name, - const char* depends, - const std::vector>& features = {}) - { - using Pgh = std::unordered_map; - std::vector scf_pghs; - scf_pghs.push_back(Pgh{ - {"Source", name}, - {"Version", "0"}, - {"Build-Depends", depends}, - }); - for (auto&& feature : features) - { - scf_pghs.push_back(Pgh{ - {"Feature", feature.first}, - {"Description", "feature"}, - {"Build-Depends", feature.second}, - }); - } - auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(scf_pghs)); - Assert::IsTrue(m_pgh.has_value()); - return std::move(*m_pgh.get()); - } - - static void features_check(Dependencies::AnyAction* install_action, - std::string pkg_name, - std::vector vec, - const Triplet& triplet = Triplet::X86_WINDOWS) - { - const auto& plan = install_action->install_plan.value_or_exit(VCPKG_LINE_INFO); - const auto& feature_list = plan.feature_list; - - Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); - - Assert::AreEqual(pkg_name.c_str(), - (*plan.any_paragraph.source_control_file.get())->core_paragraph->name.c_str()); - Assert::AreEqual(size_t(vec.size()), feature_list.size()); - - for (auto&& feature_name : vec) - { - if (feature_name == "core" || feature_name == "") - { - Assert::IsTrue(Util::find(feature_list, "core") != feature_list.end() || - Util::find(feature_list, "") != feature_list.end()); - continue; - } - Assert::IsTrue(Util::find(feature_list, feature_name) != feature_list.end()); - } - } - - static void remove_plan_check(Dependencies::AnyAction* remove_action, - std::string pkg_name, - const Triplet& triplet = Triplet::X86_WINDOWS) - { - const auto& plan = remove_action->remove_plan.value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); - Assert::AreEqual(pkg_name.c_str(), plan.spec.name().c_str()); - } - - static std::unique_ptr make_status_pgh(const char* name, const char* depends = "") - { - using Pgh = std::unordered_map; - return std::make_unique(Pgh{{"Package", name}, - {"Version", "1"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", depends}, - {"Status", "install ok installed"}}); - } - static std::unique_ptr make_status_feature_pgh(const char* name, - const char* feature, - const char* depends = "") - { - using Pgh = std::unordered_map; - return std::make_unique(Pgh{{"Package", name}, - {"Version", "1"}, - {"Feature", feature}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", depends}, - {"Status", "install ok installed"}}); - } - struct PackageSpecMap - { - std::unordered_map map; - Triplet triplet; - PackageSpecMap(const Triplet& t) { triplet = t; } - - PackageSpec emplace(const char* name, - const char* depends = "", - const std::vector>& features = {}) - { - return emplace(std::move(*make_control_file(name, depends, features))); - } - PackageSpec emplace(vcpkg::SourceControlFile&& scf) - { - auto spec = PackageSpec::from_name_and_triplet(scf.core_paragraph->name, triplet); - Assert::IsTrue(spec.has_value()); - map.emplace(scf.core_paragraph->name, std::move(scf)); - return PackageSpec{*spec.get()}; - } - }; - - TEST_METHOD(basic_install_scheme) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a", "b"); - auto spec_b = spec_map.emplace("b", "c"); - auto spec_c = spec_map.emplace("c"); - - Dependencies::MapPortFile map_port(spec_map.map); - auto install_plan = - Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(3), install_plan.size()); - Assert::AreEqual("c", install_plan[0].spec.name().c_str()); - Assert::AreEqual("b", install_plan[1].spec.name().c_str()); - Assert::AreEqual("a", install_plan[2].spec.name().c_str()); - } - - TEST_METHOD(multiple_install_scheme) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = spec_map.emplace("a", "d"); - auto spec_b = spec_map.emplace("b", "d, e"); - auto spec_c = spec_map.emplace("c", "e, h"); - auto spec_d = spec_map.emplace("d", "f, g, h"); - auto spec_e = spec_map.emplace("e", "g"); - auto spec_f = spec_map.emplace("f"); - auto spec_g = spec_map.emplace("g"); - auto spec_h = spec_map.emplace("h"); - - Dependencies::MapPortFile map_port(spec_map.map); - auto install_plan = Dependencies::create_install_plan( - map_port, {spec_a, spec_b, spec_c}, StatusParagraphs(std::move(status_paragraphs))); - - auto iterator_pos = [&](const PackageSpec& spec) -> int { - auto it = std::find_if( - install_plan.begin(), install_plan.end(), [&](auto& action) { return action.spec == spec; }); - Assert::IsTrue(it != install_plan.end()); - return (int)(it - install_plan.begin()); - }; - - int a_pos = iterator_pos(spec_a), b_pos = iterator_pos(spec_b), c_pos = iterator_pos(spec_c), - d_pos = iterator_pos(spec_d), e_pos = iterator_pos(spec_e), f_pos = iterator_pos(spec_f), - g_pos = iterator_pos(spec_g), h_pos = iterator_pos(spec_h); - - Assert::IsTrue(a_pos > d_pos); - Assert::IsTrue(b_pos > e_pos); - Assert::IsTrue(b_pos > d_pos); - Assert::IsTrue(c_pos > e_pos); - Assert::IsTrue(c_pos > h_pos); - Assert::IsTrue(d_pos > f_pos); - Assert::IsTrue(d_pos > g_pos); - Assert::IsTrue(d_pos > h_pos); - Assert::IsTrue(e_pos > g_pos); - } - - TEST_METHOD(existing_package_scheme) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("a")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{spec_map.emplace("a")}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(1), install_plan.size()); - auto p = install_plan[0].install_plan.get(); - Assert::IsNotNull(p); - Assert::AreEqual("a", p->spec.name().c_str()); - Assert::AreEqual(Dependencies::InstallPlanType::ALREADY_INSTALLED, p->plan_type); - Assert::AreEqual(Dependencies::RequestType::USER_REQUESTED, p->request_type); - } - - TEST_METHOD(user_requested_package_scheme) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b")}; - auto spec_b = FullPackageSpec{spec_map.emplace("b")}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(2), install_plan.size()); - auto p = install_plan[0].install_plan.get(); - Assert::IsNotNull(p); - Assert::AreEqual("b", p->spec.name().c_str()); - Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p->plan_type); - Assert::AreEqual(Dependencies::RequestType::AUTO_SELECTED, p->request_type); - - auto p2 = install_plan[1].install_plan.get(); - Assert::IsNotNull(p2); - Assert::AreEqual("a", p2->spec.name().c_str()); - Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p2->plan_type); - Assert::AreEqual(Dependencies::RequestType::USER_REQUESTED, p2->request_type); - } - - TEST_METHOD(long_install_scheme) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("j", "k")); - status_paragraphs.push_back(make_status_pgh("k")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = spec_map.emplace("a", "b, c, d, e, f, g, h, j, k"); - auto spec_b = spec_map.emplace("b", "c, d, e, f, g, h, j, k"); - auto spec_c = spec_map.emplace("c", "d, e, f, g, h, j, k"); - auto spec_d = spec_map.emplace("d", "e, f, g, h, j, k"); - auto spec_e = spec_map.emplace("e", "f, g, h, j, k"); - auto spec_f = spec_map.emplace("f", "g, h, j, k"); - auto spec_g = spec_map.emplace("g", "h, j, k"); - auto spec_h = spec_map.emplace("h", "j, k"); - auto spec_j = spec_map.emplace("j", "k"); - auto spec_k = spec_map.emplace("k"); - - Dependencies::MapPortFile map_port(spec_map.map); - auto install_plan = - Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(8), install_plan.size()); - Assert::AreEqual("h", install_plan[0].spec.name().c_str()); - Assert::AreEqual("g", install_plan[1].spec.name().c_str()); - Assert::AreEqual("f", install_plan[2].spec.name().c_str()); - Assert::AreEqual("e", install_plan[3].spec.name().c_str()); - Assert::AreEqual("d", install_plan[4].spec.name().c_str()); - Assert::AreEqual("c", install_plan[5].spec.name().c_str()); - Assert::AreEqual("b", install_plan[6].spec.name().c_str()); - Assert::AreEqual("a", install_plan[7].spec.name().c_str()); - } - - TEST_METHOD(basic_feature_test_1) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("a", "b, b[b1]")); - status_paragraphs.push_back(make_status_pgh("b")); - status_paragraphs.push_back(make_status_feature_pgh("b", "b1")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b, b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(4), install_plan.size()); - remove_plan_check(&install_plan[0], "a"); - remove_plan_check(&install_plan[1], "b"); - features_check(&install_plan[2], "b", {"b1", "core", "b1"}); - features_check(&install_plan[3], "a", {"a1", "core"}); - } - - TEST_METHOD(basic_feature_test_2) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(2), install_plan.size()); - features_check(&install_plan[0], "b", {"b1", "b2", "core"}); - features_check(&install_plan[1], "a", {"a1", "core"}); - } - - TEST_METHOD(basic_feature_test_3) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("a")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b")}; - auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_c, spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(4), install_plan.size()); - remove_plan_check(&install_plan[0], "a"); - features_check(&install_plan[1], "b", {"core"}); - features_check(&install_plan[2], "a", {"a1", "core"}); - features_check(&install_plan[3], "c", {"core"}); - } - - TEST_METHOD(basic_feature_test_4) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("a")); - status_paragraphs.push_back(make_status_feature_pgh("a", "a1", "")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}})}; - auto spec_b = FullPackageSpec{spec_map.emplace("b")}; - auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_c}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(1), install_plan.size()); - features_check(&install_plan[0], "c", {"core"}); - } - - TEST_METHOD(basic_feature_test_5) - { - std::vector> status_paragraphs; - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = - FullPackageSpec{spec_map.emplace("a", "", {{"a1", "b[b1]"}, {"a2", "b[b2]"}, {"a3", "a[a2]"}}), {"a3"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}})}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(2), install_plan.size()); - features_check(&install_plan[0], "b", {"core", "b2"}); - features_check(&install_plan[1], "a", {"core", "a3", "a2"}); - } - - TEST_METHOD(basic_feature_test_6) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("b")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[core]"), {"core"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_a, spec_b}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(3), install_plan.size()); - remove_plan_check(&install_plan[0], "b"); - features_check(&install_plan[1], "b", {"core", "b1"}); - features_check(&install_plan[2], "a", {"core"}); - } - - TEST_METHOD(basic_feature_test_7) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("x", "b")); - status_paragraphs.push_back(make_status_pgh("b")); - - PackageSpecMap spec_map(Triplet::X86_WINDOWS); - - auto spec_a = FullPackageSpec{spec_map.emplace("a")}; - auto spec_x = FullPackageSpec{spec_map.emplace("x", "a"), {"core"}}; - auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}}; - - auto install_plan = - Dependencies::create_feature_install_plan(spec_map.map, - FullPackageSpec::to_feature_specs({spec_b}), - StatusParagraphs(std::move(status_paragraphs))); - - Assert::AreEqual(size_t(5), install_plan.size()); - remove_plan_check(&install_plan[0], "x"); - remove_plan_check(&install_plan[1], "b"); - - // TODO: order here may change but A < X, and B anywhere - features_check(&install_plan[2], "b", {"core", "b1"}); - features_check(&install_plan[3], "a", {"core"}); - features_check(&install_plan[4], "x", {"core"}); - } - - TEST_METHOD(basic_feature_test_8) - { - std::vector> status_paragraphs; - status_paragraphs.push_back(make_status_pgh("a")); - status_paragraphs.push_back(make_status_pgh("a")); - status_paragraphs.back()->package.spec = - PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); - - PackageSpecMap spec_map(Triplet::X64_WINDOWS); - auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; - auto spec_b_64 = FullPackageSpec{spec_map.emplace("b")}; - auto spec_c_64 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; - - spec_map.triplet = Triplet::X86_WINDOWS; - auto spec_a_86 = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; - auto spec_b_86 = FullPackageSpec{spec_map.emplace("b")}; - auto spec_c_86 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; - - auto install_plan = Dependencies::create_feature_install_plan( - spec_map.map, - FullPackageSpec::to_feature_specs({spec_c_64, spec_a_86, spec_a_64, spec_c_86}), - StatusParagraphs(std::move(status_paragraphs))); - - /*Assert::AreEqual(size_t(8), install_plan.size()); - auto iterator_pos = [&](const PackageSpec& spec, size_t start) -> int { - auto it = std::find_if(install_plan.begin() + start, install_plan.end(), [&](auto& action) { - return action.spec == spec; - }); - Assert::IsTrue(it != install_plan.end()); - return (int)(it - install_plan.begin()); - }; - int a_64_1 = iterator_pos(spec_a_64.package_spec, 0), a_86_1 = iterator_pos(spec_a_86.package_spec, 0), - b_64 = iterator_pos(spec_b_64.package_spec, 0), b_86 = iterator_pos(spec_b_86.package_spec, 0), - c_64 = iterator_pos(spec_c_64.package_spec, 0), c_86 = iterator_pos(spec_c_86.package_spec, 0), - a_64_2 = iterator_pos(spec_a_64.package_spec, a_64_1 + 1), - a_86_2 = iterator_pos(spec_a_86.package_spec, a_86_1 + 1);*/ - - remove_plan_check(&install_plan[0], "a", Triplet::X64_WINDOWS); - remove_plan_check(&install_plan[1], "a"); - features_check(&install_plan[2], "b", {"core"}, Triplet::X64_WINDOWS); - features_check(&install_plan[3], "a", {"a1", "core"}, Triplet::X64_WINDOWS); - features_check(&install_plan[4], "c", {"core"}, Triplet::X64_WINDOWS); - features_check(&install_plan[5], "b", {"core"}); - features_check(&install_plan[6], "a", {"a1", "core"}); - features_check(&install_plan[7], "c", {"core"}); - } - }; -} \ No newline at end of file diff --git a/toolsrc/src/tests.arguments.cpp b/toolsrc/src/tests.arguments.cpp new file mode 100644 index 000000000..25bf0f085 --- /dev/null +++ b/toolsrc/src/tests.arguments.cpp @@ -0,0 +1,58 @@ +#include +#include + +#pragma comment(lib, "version") +#pragma comment(lib, "winhttp") + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +using namespace vcpkg; + +namespace UnitTest1 +{ + class ArgumentTests : public TestClass + { + TEST_METHOD(create_from_arg_sequence_options_lower) + { + std::vector t = {"--vcpkg-root", "C:\\vcpkg", "--debug", "--sendmetrics", "--printmetrics"}; + auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); + Assert::AreEqual("C:\\vcpkg", v.vcpkg_root_dir.get()->c_str()); + Assert::IsTrue(v.debug && *v.debug.get()); + Assert::IsTrue(v.sendmetrics && v.sendmetrics.get()); + Assert::IsTrue(v.printmetrics && *v.printmetrics.get()); + } + + TEST_METHOD(create_from_arg_sequence_options_upper) + { + std::vector t = {"--VCPKG-ROOT", "C:\\vcpkg", "--DEBUG", "--SENDMETRICS", "--PRINTMETRICS"}; + auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); + Assert::AreEqual("C:\\vcpkg", v.vcpkg_root_dir.get()->c_str()); + Assert::IsTrue(v.debug && *v.debug.get()); + Assert::IsTrue(v.sendmetrics && v.sendmetrics.get()); + Assert::IsTrue(v.printmetrics && *v.printmetrics.get()); + } + + TEST_METHOD(create_from_arg_sequence_valued_options) + { + std::vector t = {"--a=b", "command", "argument"}; + auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); + auto opts = v.check_and_get_optional_command_arguments({}, {"--a"}); + Assert::AreEqual("b", opts.settings["--a"].c_str()); + Assert::AreEqual(size_t{1}, v.command_arguments.size()); + Assert::AreEqual("argument", v.command_arguments[0].c_str()); + Assert::AreEqual("command", v.command.c_str()); + } + + TEST_METHOD(create_from_arg_sequence_valued_options2) + { + std::vector t = {"--a", "--b=c"}; + auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); + auto opts = v.check_and_get_optional_command_arguments({"--a", "--c"}, {"--b", "--d"}); + Assert::AreEqual("c", opts.settings["--b"].c_str()); + Assert::IsTrue(opts.settings.find("--d") == opts.settings.end()); + Assert::IsTrue(opts.switches.find("--a") != opts.switches.end()); + Assert::IsTrue(opts.settings.find("--c") == opts.settings.end()); + Assert::AreEqual(size_t{0}, v.command_arguments.size()); + } + }; +} \ No newline at end of file diff --git a/toolsrc/src/tests.dependencies.cpp b/toolsrc/src/tests.dependencies.cpp new file mode 100644 index 000000000..3f6e0dd10 --- /dev/null +++ b/toolsrc/src/tests.dependencies.cpp @@ -0,0 +1,110 @@ +#include +#include +#include + +#pragma comment(lib, "version") +#pragma comment(lib, "winhttp") + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +using namespace vcpkg; +using Parse::parse_comma_list; + +namespace UnitTest1 +{ + class DependencyTests : public TestClass + { + TEST_METHOD(parse_depends_one) + { + auto v = expand_qualified_dependencies(parse_comma_list("libA (windows)")); + Assert::AreEqual(size_t(1), v.size()); + Assert::AreEqual("libA", v[0].depend.name.c_str()); + Assert::AreEqual("windows", v[0].qualifier.c_str()); + } + + TEST_METHOD(filter_depends) + { + auto deps = expand_qualified_dependencies(parse_comma_list("libA (windows), libB, libC (uwp)")); + auto v = filter_dependencies(deps, Triplet::X64_WINDOWS); + Assert::AreEqual(size_t(2), v.size()); + Assert::AreEqual("libA", v[0].c_str()); + Assert::AreEqual("libB", v[1].c_str()); + + auto v2 = filter_dependencies(deps, Triplet::ARM_UWP); + Assert::AreEqual(size_t(2), v.size()); + Assert::AreEqual("libB", v2[0].c_str()); + Assert::AreEqual("libC", v2[1].c_str()); + } + }; + + class SupportsTests : public TestClass + { + TEST_METHOD(parse_supports_all) + { + auto v = Supports::parse({ + "x64", + "x86", + "arm", + "windows", + "uwp", + "v140", + "v141", + "crt-static", + "crt-dynamic", + }); + Assert::AreNotEqual(uintptr_t(0), uintptr_t(v.get())); + + Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::X64, + Supports::Platform::UWP, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::ARM, + Supports::Platform::WINDOWS, + Supports::Linkage::STATIC, + Supports::ToolsetVersion::V141)); + } + + TEST_METHOD(parse_supports_invalid) + { + auto v = Supports::parse({"arm64"}); + Assert::AreEqual(uintptr_t(0), uintptr_t(v.get())); + Assert::AreEqual(size_t(1), v.error().size()); + Assert::AreEqual("arm64", v.error()[0].c_str()); + } + + TEST_METHOD(parse_supports_case_sensitive) + { + auto v = Supports::parse({"Windows"}); + Assert::AreEqual(uintptr_t(0), uintptr_t(v.get())); + Assert::AreEqual(size_t(1), v.error().size()); + Assert::AreEqual("Windows", v.error()[0].c_str()); + } + + TEST_METHOD(parse_supports_some) + { + auto v = Supports::parse({ + "x64", + "x86", + "windows", + }); + Assert::AreNotEqual(uintptr_t(0), uintptr_t(v.get())); + + Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::X64, + Supports::Platform::WINDOWS, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsFalse(v.get()->is_supported(System::CPUArchitecture::ARM, + Supports::Platform::WINDOWS, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsFalse(v.get()->is_supported(System::CPUArchitecture::X64, + Supports::Platform::UWP, + Supports::Linkage::DYNAMIC, + Supports::ToolsetVersion::V140)); + Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::X64, + Supports::Platform::WINDOWS, + Supports::Linkage::STATIC, + Supports::ToolsetVersion::V141)); + } + }; +} diff --git a/toolsrc/src/tests.installplan.cpp b/toolsrc/src/tests.installplan.cpp new file mode 100644 index 000000000..120009db5 --- /dev/null +++ b/toolsrc/src/tests.installplan.cpp @@ -0,0 +1,487 @@ +#include +#include + +#include + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +using namespace vcpkg; + +namespace Microsoft::VisualStudio::CppUnitTestFramework +{ + template<> + inline std::wstring ToString(const vcpkg::Dependencies::InstallPlanType& t) + { + switch (t) + { + case Dependencies::InstallPlanType::ALREADY_INSTALLED: return L"ALREADY_INSTALLED"; + case Dependencies::InstallPlanType::BUILD_AND_INSTALL: return L"BUILD_AND_INSTALL"; + case Dependencies::InstallPlanType::INSTALL: return L"INSTALL"; + case Dependencies::InstallPlanType::UNKNOWN: return L"UNKNOWN"; + default: return ToString((int)t); + } + } + + template<> + inline std::wstring ToString(const vcpkg::Dependencies::RequestType& t) + { + switch (t) + { + case Dependencies::RequestType::AUTO_SELECTED: return L"AUTO_SELECTED"; + case Dependencies::RequestType::USER_REQUESTED: return L"USER_REQUESTED"; + case Dependencies::RequestType::UNKNOWN: return L"UNKNOWN"; + default: return ToString((int)t); + } + } +} + +namespace UnitTest1 +{ + class InstallPlanTests : public TestClass + { + static std::unique_ptr make_control_file( + const char* name, + const char* depends, + const std::vector>& features = {}) + { + using Pgh = std::unordered_map; + std::vector scf_pghs; + scf_pghs.push_back(Pgh{ + {"Source", name}, + {"Version", "0"}, + {"Build-Depends", depends}, + }); + for (auto&& feature : features) + { + scf_pghs.push_back(Pgh{ + {"Feature", feature.first}, + {"Description", "feature"}, + {"Build-Depends", feature.second}, + }); + } + auto m_pgh = vcpkg::SourceControlFile::parse_control_file(std::move(scf_pghs)); + Assert::IsTrue(m_pgh.has_value()); + return std::move(*m_pgh.get()); + } + + static void features_check(Dependencies::AnyAction* install_action, + std::string pkg_name, + std::vector vec, + const Triplet& triplet = Triplet::X86_WINDOWS) + { + const auto& plan = install_action->install_plan.value_or_exit(VCPKG_LINE_INFO); + const auto& feature_list = plan.feature_list; + + Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); + + Assert::AreEqual(pkg_name.c_str(), + (*plan.any_paragraph.source_control_file.get())->core_paragraph->name.c_str()); + Assert::AreEqual(size_t(vec.size()), feature_list.size()); + + for (auto&& feature_name : vec) + { + if (feature_name == "core" || feature_name == "") + { + Assert::IsTrue(Util::find(feature_list, "core") != feature_list.end() || + Util::find(feature_list, "") != feature_list.end()); + continue; + } + Assert::IsTrue(Util::find(feature_list, feature_name) != feature_list.end()); + } + } + + static void remove_plan_check(Dependencies::AnyAction* remove_action, + std::string pkg_name, + const Triplet& triplet = Triplet::X86_WINDOWS) + { + const auto& plan = remove_action->remove_plan.value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(plan.spec.triplet().to_string().c_str(), triplet.to_string().c_str()); + Assert::AreEqual(pkg_name.c_str(), plan.spec.name().c_str()); + } + + static std::unique_ptr make_status_pgh(const char* name, const char* depends = "") + { + using Pgh = std::unordered_map; + return std::make_unique(Pgh{{"Package", name}, + {"Version", "1"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", depends}, + {"Status", "install ok installed"}}); + } + static std::unique_ptr make_status_feature_pgh(const char* name, + const char* feature, + const char* depends = "") + { + using Pgh = std::unordered_map; + return std::make_unique(Pgh{{"Package", name}, + {"Version", "1"}, + {"Feature", feature}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", depends}, + {"Status", "install ok installed"}}); + } + struct PackageSpecMap + { + std::unordered_map map; + Triplet triplet; + PackageSpecMap(const Triplet& t) { triplet = t; } + + PackageSpec emplace(const char* name, + const char* depends = "", + const std::vector>& features = {}) + { + return emplace(std::move(*make_control_file(name, depends, features))); + } + PackageSpec emplace(vcpkg::SourceControlFile&& scf) + { + auto spec = PackageSpec::from_name_and_triplet(scf.core_paragraph->name, triplet); + Assert::IsTrue(spec.has_value()); + map.emplace(scf.core_paragraph->name, std::move(scf)); + return PackageSpec{*spec.get()}; + } + }; + + TEST_METHOD(basic_install_scheme) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a", "b"); + auto spec_b = spec_map.emplace("b", "c"); + auto spec_c = spec_map.emplace("c"); + + Dependencies::MapPortFile map_port(spec_map.map); + auto install_plan = + Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(3), install_plan.size()); + Assert::AreEqual("c", install_plan[0].spec.name().c_str()); + Assert::AreEqual("b", install_plan[1].spec.name().c_str()); + Assert::AreEqual("a", install_plan[2].spec.name().c_str()); + } + + TEST_METHOD(multiple_install_scheme) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = spec_map.emplace("a", "d"); + auto spec_b = spec_map.emplace("b", "d, e"); + auto spec_c = spec_map.emplace("c", "e, h"); + auto spec_d = spec_map.emplace("d", "f, g, h"); + auto spec_e = spec_map.emplace("e", "g"); + auto spec_f = spec_map.emplace("f"); + auto spec_g = spec_map.emplace("g"); + auto spec_h = spec_map.emplace("h"); + + Dependencies::MapPortFile map_port(spec_map.map); + auto install_plan = Dependencies::create_install_plan( + map_port, {spec_a, spec_b, spec_c}, StatusParagraphs(std::move(status_paragraphs))); + + auto iterator_pos = [&](const PackageSpec& spec) -> int { + auto it = std::find_if( + install_plan.begin(), install_plan.end(), [&](auto& action) { return action.spec == spec; }); + Assert::IsTrue(it != install_plan.end()); + return (int)(it - install_plan.begin()); + }; + + int a_pos = iterator_pos(spec_a), b_pos = iterator_pos(spec_b), c_pos = iterator_pos(spec_c), + d_pos = iterator_pos(spec_d), e_pos = iterator_pos(spec_e), f_pos = iterator_pos(spec_f), + g_pos = iterator_pos(spec_g), h_pos = iterator_pos(spec_h); + + Assert::IsTrue(a_pos > d_pos); + Assert::IsTrue(b_pos > e_pos); + Assert::IsTrue(b_pos > d_pos); + Assert::IsTrue(c_pos > e_pos); + Assert::IsTrue(c_pos > h_pos); + Assert::IsTrue(d_pos > f_pos); + Assert::IsTrue(d_pos > g_pos); + Assert::IsTrue(d_pos > h_pos); + Assert::IsTrue(e_pos > g_pos); + } + + TEST_METHOD(existing_package_scheme) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = FullPackageSpec{spec_map.emplace("a")}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(1), install_plan.size()); + auto p = install_plan[0].install_plan.get(); + Assert::IsNotNull(p); + Assert::AreEqual("a", p->spec.name().c_str()); + Assert::AreEqual(Dependencies::InstallPlanType::ALREADY_INSTALLED, p->plan_type); + Assert::AreEqual(Dependencies::RequestType::USER_REQUESTED, p->request_type); + } + + TEST_METHOD(user_requested_package_scheme) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b")}; + auto spec_b = FullPackageSpec{spec_map.emplace("b")}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(2), install_plan.size()); + auto p = install_plan[0].install_plan.get(); + Assert::IsNotNull(p); + Assert::AreEqual("b", p->spec.name().c_str()); + Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p->plan_type); + Assert::AreEqual(Dependencies::RequestType::AUTO_SELECTED, p->request_type); + + auto p2 = install_plan[1].install_plan.get(); + Assert::IsNotNull(p2); + Assert::AreEqual("a", p2->spec.name().c_str()); + Assert::AreEqual(Dependencies::InstallPlanType::BUILD_AND_INSTALL, p2->plan_type); + Assert::AreEqual(Dependencies::RequestType::USER_REQUESTED, p2->request_type); + } + + TEST_METHOD(long_install_scheme) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("j", "k")); + status_paragraphs.push_back(make_status_pgh("k")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = spec_map.emplace("a", "b, c, d, e, f, g, h, j, k"); + auto spec_b = spec_map.emplace("b", "c, d, e, f, g, h, j, k"); + auto spec_c = spec_map.emplace("c", "d, e, f, g, h, j, k"); + auto spec_d = spec_map.emplace("d", "e, f, g, h, j, k"); + auto spec_e = spec_map.emplace("e", "f, g, h, j, k"); + auto spec_f = spec_map.emplace("f", "g, h, j, k"); + auto spec_g = spec_map.emplace("g", "h, j, k"); + auto spec_h = spec_map.emplace("h", "j, k"); + auto spec_j = spec_map.emplace("j", "k"); + auto spec_k = spec_map.emplace("k"); + + Dependencies::MapPortFile map_port(spec_map.map); + auto install_plan = + Dependencies::create_install_plan(map_port, {spec_a}, StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(8), install_plan.size()); + Assert::AreEqual("h", install_plan[0].spec.name().c_str()); + Assert::AreEqual("g", install_plan[1].spec.name().c_str()); + Assert::AreEqual("f", install_plan[2].spec.name().c_str()); + Assert::AreEqual("e", install_plan[3].spec.name().c_str()); + Assert::AreEqual("d", install_plan[4].spec.name().c_str()); + Assert::AreEqual("c", install_plan[5].spec.name().c_str()); + Assert::AreEqual("b", install_plan[6].spec.name().c_str()); + Assert::AreEqual("a", install_plan[7].spec.name().c_str()); + } + + TEST_METHOD(basic_feature_test_1) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a", "b, b[b1]")); + status_paragraphs.push_back(make_status_pgh("b")); + status_paragraphs.push_back(make_status_feature_pgh("b", "b1")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b, b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(4), install_plan.size()); + remove_plan_check(&install_plan[0], "a"); + remove_plan_check(&install_plan[1], "b"); + features_check(&install_plan[2], "b", {"b1", "core", "b1"}); + features_check(&install_plan[3], "a", {"a1", "core"}); + } + + TEST_METHOD(basic_feature_test_2) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[b1]", {{"a1", "b[b2]"}}), {"a1"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}, {"b3", ""}})}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(2), install_plan.size()); + features_check(&install_plan[0], "b", {"b1", "b2", "core"}); + features_check(&install_plan[1], "a", {"a1", "core"}); + } + + TEST_METHOD(basic_feature_test_3) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_c, spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(4), install_plan.size()); + remove_plan_check(&install_plan[0], "a"); + features_check(&install_plan[1], "b", {"core"}); + features_check(&install_plan[2], "a", {"a1", "core"}); + features_check(&install_plan[3], "c", {"core"}); + } + + TEST_METHOD(basic_feature_test_4) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.push_back(make_status_feature_pgh("a", "a1", "")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}})}; + auto spec_b = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_c}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(1), install_plan.size()); + features_check(&install_plan[0], "c", {"core"}); + } + + TEST_METHOD(basic_feature_test_5) + { + std::vector> status_paragraphs; + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = + FullPackageSpec{spec_map.emplace("a", "", {{"a1", "b[b1]"}, {"a2", "b[b2]"}, {"a3", "a[a2]"}}), {"a3"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}, {"b2", ""}})}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(2), install_plan.size()); + features_check(&install_plan[0], "b", {"core", "b2"}); + features_check(&install_plan[1], "a", {"core", "a3", "a2"}); + } + + TEST_METHOD(basic_feature_test_6) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("b")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + auto spec_a = FullPackageSpec{spec_map.emplace("a", "b[core]"), {"core"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_a, spec_b}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(3), install_plan.size()); + remove_plan_check(&install_plan[0], "b"); + features_check(&install_plan[1], "b", {"core", "b1"}); + features_check(&install_plan[2], "a", {"core"}); + } + + TEST_METHOD(basic_feature_test_7) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("x", "b")); + status_paragraphs.push_back(make_status_pgh("b")); + + PackageSpecMap spec_map(Triplet::X86_WINDOWS); + + auto spec_a = FullPackageSpec{spec_map.emplace("a")}; + auto spec_x = FullPackageSpec{spec_map.emplace("x", "a"), {"core"}}; + auto spec_b = FullPackageSpec{spec_map.emplace("b", "", {{"b1", ""}}), {"b1"}}; + + auto install_plan = + Dependencies::create_feature_install_plan(spec_map.map, + FullPackageSpec::to_feature_specs({spec_b}), + StatusParagraphs(std::move(status_paragraphs))); + + Assert::AreEqual(size_t(5), install_plan.size()); + remove_plan_check(&install_plan[0], "x"); + remove_plan_check(&install_plan[1], "b"); + + // TODO: order here may change but A < X, and B anywhere + features_check(&install_plan[2], "b", {"core", "b1"}); + features_check(&install_plan[3], "a", {"core"}); + features_check(&install_plan[4], "x", {"core"}); + } + + TEST_METHOD(basic_feature_test_8) + { + std::vector> status_paragraphs; + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.push_back(make_status_pgh("a")); + status_paragraphs.back()->package.spec = + PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); + + PackageSpecMap spec_map(Triplet::X64_WINDOWS); + auto spec_a_64 = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; + auto spec_b_64 = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c_64 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; + + spec_map.triplet = Triplet::X86_WINDOWS; + auto spec_a_86 = FullPackageSpec{spec_map.emplace("a", "b", {{"a1", ""}}), {"core"}}; + auto spec_b_86 = FullPackageSpec{spec_map.emplace("b")}; + auto spec_c_86 = FullPackageSpec{spec_map.emplace("c", "a[a1]"), {"core"}}; + + auto install_plan = Dependencies::create_feature_install_plan( + spec_map.map, + FullPackageSpec::to_feature_specs({spec_c_64, spec_a_86, spec_a_64, spec_c_86}), + StatusParagraphs(std::move(status_paragraphs))); + + /*Assert::AreEqual(size_t(8), install_plan.size()); + auto iterator_pos = [&](const PackageSpec& spec, size_t start) -> int { + auto it = std::find_if(install_plan.begin() + start, install_plan.end(), [&](auto& action) { + return action.spec == spec; + }); + Assert::IsTrue(it != install_plan.end()); + return (int)(it - install_plan.begin()); + }; + int a_64_1 = iterator_pos(spec_a_64.package_spec, 0), a_86_1 = iterator_pos(spec_a_86.package_spec, 0), + b_64 = iterator_pos(spec_b_64.package_spec, 0), b_86 = iterator_pos(spec_b_86.package_spec, 0), + c_64 = iterator_pos(spec_c_64.package_spec, 0), c_86 = iterator_pos(spec_c_86.package_spec, 0), + a_64_2 = iterator_pos(spec_a_64.package_spec, a_64_1 + 1), + a_86_2 = iterator_pos(spec_a_86.package_spec, a_86_1 + 1);*/ + + remove_plan_check(&install_plan[0], "a", Triplet::X64_WINDOWS); + remove_plan_check(&install_plan[1], "a"); + features_check(&install_plan[2], "b", {"core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[3], "a", {"a1", "core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[4], "c", {"core"}, Triplet::X64_WINDOWS); + features_check(&install_plan[5], "b", {"core"}); + features_check(&install_plan[6], "a", {"a1", "core"}); + features_check(&install_plan[7], "c", {"core"}); + } + }; +} \ No newline at end of file diff --git a/toolsrc/src/tests.packagespec.cpp b/toolsrc/src/tests.packagespec.cpp new file mode 100644 index 000000000..cb5c41af0 --- /dev/null +++ b/toolsrc/src/tests.packagespec.cpp @@ -0,0 +1,120 @@ +#include +#include +#include + +#include + +#pragma comment(lib, "version") +#pragma comment(lib, "winhttp") + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +namespace Microsoft::VisualStudio::CppUnitTestFramework +{ + template<> + inline std::wstring ToString(const vcpkg::PackageSpecParseResult& t) + { + return ToString(static_cast(t)); + } + + template<> + inline std::wstring ToString(const vcpkg::PackageSpec& t) + { + return ToString(t.to_string()); + } +} + +namespace Strings = vcpkg::Strings; + +namespace UnitTest1 +{ + using namespace vcpkg; + + class SpecifierConversion : public TestClass + { + TEST_METHOD(full_package_spec_to_feature_specs) + { + auto a_spec = PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); + auto b_spec = PackageSpec::from_name_and_triplet("b", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); + + auto fspecs = FullPackageSpec::to_feature_specs({{a_spec, {"0", "1"}}, {b_spec, {"2", "3"}}}); + + Assert::AreEqual(size_t(6), fspecs.size()); + + std::array features = {"", "0", "1", "", "2", "3"}; + std::array specs = {&a_spec, &a_spec, &a_spec, &b_spec, &b_spec, &b_spec}; + + for (size_t i = 0; i < features.size(); ++i) + { + Assert::AreEqual(features[i], fspecs[i].feature().c_str()); + Assert::AreEqual(*specs[i], fspecs[i].spec()); + } + } + }; + + class SpecifierParsing : public TestClass + { + TEST_METHOD(parsed_specifier_from_string) + { + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::AreEqual(size_t(0), spec->features.size()); + Assert::AreEqual("", spec->triplet.c_str()); + } + + TEST_METHOD(parsed_specifier_from_string_with_triplet) + { + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib:x64-uwp"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::AreEqual("x64-uwp", spec->triplet.c_str()); + } + + TEST_METHOD(parsed_specifier_from_string_with_colons) + { + auto ec = vcpkg::ParsedSpecifier::from_string("zlib:x86-uwp:").error(); + Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, ec); + } + + TEST_METHOD(parsed_specifier_from_string_with_feature) + { + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib[feature]:x64-uwp"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::IsTrue(spec->features.size() == 1); + Assert::AreEqual("feature", spec->features.front().c_str()); + Assert::AreEqual("x64-uwp", spec->triplet.c_str()); + } + + TEST_METHOD(parsed_specifier_from_string_with_many_features) + { + auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib[0, 1,2]"); + Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); + auto spec = maybe_spec.get(); + Assert::AreEqual("zlib", spec->name.c_str()); + Assert::IsTrue(spec->features.size() == 3); + Assert::AreEqual("0", spec->features[0].c_str()); + Assert::AreEqual("1", spec->features[1].c_str()); + Assert::AreEqual("2", spec->features[2].c_str()); + Assert::AreEqual("", spec->triplet.c_str()); + } + + TEST_METHOD(utf8_to_utf16) + { + auto str = vcpkg::Strings::to_utf16("abc"); + Assert::AreEqual(L"abc", str.c_str()); + } + + TEST_METHOD(utf8_to_utf16_with_whitespace) + { + auto str = vcpkg::Strings::to_utf16("abc -x86-windows"); + Assert::AreEqual(L"abc -x86-windows", str.c_str()); + } + }; + + TEST_CLASS(Metrics){}; +} diff --git a/toolsrc/src/tests.paragraph.cpp b/toolsrc/src/tests.paragraph.cpp new file mode 100644 index 000000000..d9301abd0 --- /dev/null +++ b/toolsrc/src/tests.paragraph.cpp @@ -0,0 +1,389 @@ +#include +#include +#include + +#include + +#pragma comment(lib, "version") +#pragma comment(lib, "winhttp") + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +namespace Microsoft::VisualStudio::CppUnitTestFramework +{ + template<> + inline std::wstring ToString(const vcpkg::PackageSpecParseResult& t) + { + return ToString(static_cast(t)); + } +} + +namespace Strings = vcpkg::Strings; + +namespace UnitTest1 +{ + class ControlParsing : public TestClass + { + TEST_METHOD(SourceParagraph_Construct_Minimum) + { + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "zlib"}, + {"Version", "1.2.8"}, + }}); + + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); + + Assert::AreEqual("zlib", pgh->core_paragraph->name.c_str()); + Assert::AreEqual("1.2.8", pgh->core_paragraph->version.c_str()); + Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str()); + Assert::AreEqual("", pgh->core_paragraph->description.c_str()); + Assert::AreEqual(size_t(0), pgh->core_paragraph->depends.size()); + } + + TEST_METHOD(SourceParagraph_Construct_Maximum) + { + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "s"}, + {"Version", "v"}, + {"Maintainer", "m"}, + {"Description", "d"}, + {"Build-Depends", "bd"}, + {"Supports", "x64"}, + }}); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); + + Assert::AreEqual("s", pgh->core_paragraph->name.c_str()); + Assert::AreEqual("v", pgh->core_paragraph->version.c_str()); + Assert::AreEqual("m", pgh->core_paragraph->maintainer.c_str()); + Assert::AreEqual("d", pgh->core_paragraph->description.c_str()); + Assert::AreEqual(size_t(1), pgh->core_paragraph->depends.size()); + Assert::AreEqual("bd", pgh->core_paragraph->depends[0].name().c_str()); + Assert::AreEqual(size_t(1), pgh->core_paragraph->supports.size()); + Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str()); + } + + TEST_METHOD(SourceParagraph_Two_Depends) + { + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "zlib"}, + {"Version", "1.2.8"}, + {"Build-Depends", "z, openssl"}, + }}); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); + + Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size()); + Assert::AreEqual("z", pgh->core_paragraph->depends[0].name().c_str()); + Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name().c_str()); + } + + TEST_METHOD(SourceParagraph_Three_Depends) + { + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "zlib"}, + {"Version", "1.2.8"}, + {"Build-Depends", "z, openssl, xyz"}, + }}); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); + + Assert::AreEqual(size_t(3), pgh->core_paragraph->depends.size()); + Assert::AreEqual("z", pgh->core_paragraph->depends[0].name().c_str()); + Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name().c_str()); + Assert::AreEqual("xyz", pgh->core_paragraph->depends[2].name().c_str()); + } + + TEST_METHOD(SourceParagraph_Three_Supports) + { + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "zlib"}, + {"Version", "1.2.8"}, + {"Supports", "x64, windows, uwp"}, + }}); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); + + Assert::AreEqual(size_t(3), pgh->core_paragraph->supports.size()); + Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str()); + Assert::AreEqual("windows", pgh->core_paragraph->supports[1].c_str()); + Assert::AreEqual("uwp", pgh->core_paragraph->supports[2].c_str()); + } + + TEST_METHOD(SourceParagraph_Construct_Qualified_Depends) + { + auto m_pgh = + vcpkg::SourceControlFile::parse_control_file(std::vector>{{ + {"Source", "zlib"}, + {"Version", "1.2.8"}, + {"Build-Depends", "libA (windows), libB (uwp)"}, + }}); + Assert::IsTrue(m_pgh.has_value()); + auto& pgh = *m_pgh.get(); + + Assert::AreEqual("zlib", pgh->core_paragraph->name.c_str()); + Assert::AreEqual("1.2.8", pgh->core_paragraph->version.c_str()); + Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str()); + Assert::AreEqual("", pgh->core_paragraph->description.c_str()); + Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size()); + Assert::AreEqual("libA", pgh->core_paragraph->depends[0].name().c_str()); + Assert::AreEqual("windows", pgh->core_paragraph->depends[0].qualifier.c_str()); + Assert::AreEqual("libB", pgh->core_paragraph->depends[1].name().c_str()); + Assert::AreEqual("uwp", pgh->core_paragraph->depends[1].qualifier.c_str()); + } + + TEST_METHOD(BinaryParagraph_Construct_Minimum) + { + vcpkg::BinaryParagraph pgh({ + {"Package", "zlib"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + }); + + Assert::AreEqual("zlib", pgh.spec.name().c_str()); + Assert::AreEqual("1.2.8", pgh.version.c_str()); + Assert::AreEqual("", pgh.maintainer.c_str()); + Assert::AreEqual("", pgh.description.c_str()); + Assert::AreEqual("x86-windows", pgh.spec.triplet().canonical_name().c_str()); + Assert::AreEqual(size_t(0), pgh.depends.size()); + } + + TEST_METHOD(BinaryParagraph_Construct_Maximum) + { + vcpkg::BinaryParagraph pgh({ + {"Package", "s"}, + {"Version", "v"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Maintainer", "m"}, + {"Description", "d"}, + {"Depends", "bd"}, + }); + Assert::AreEqual("s", pgh.spec.name().c_str()); + Assert::AreEqual("v", pgh.version.c_str()); + Assert::AreEqual("m", pgh.maintainer.c_str()); + Assert::AreEqual("d", pgh.description.c_str()); + Assert::AreEqual(size_t(1), pgh.depends.size()); + Assert::AreEqual("bd", pgh.depends[0].c_str()); + } + + TEST_METHOD(BinaryParagraph_Three_Depends) + { + vcpkg::BinaryParagraph pgh({ + {"Package", "zlib"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", "a, b, c"}, + }); + + Assert::AreEqual(size_t(3), pgh.depends.size()); + Assert::AreEqual("a", pgh.depends[0].c_str()); + Assert::AreEqual("b", pgh.depends[1].c_str()); + Assert::AreEqual("c", pgh.depends[2].c_str()); + } + + TEST_METHOD(parse_paragraphs_empty) + { + const char* str = ""; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::IsTrue(pghs.empty()); + } + + TEST_METHOD(parse_paragraphs_one_field) + { + const char* str = "f1: v1"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(1), pghs.size()); + Assert::AreEqual(size_t(1), pghs[0].size()); + Assert::AreEqual("v1", pghs[0]["f1"].c_str()); + } + + TEST_METHOD(parse_paragraphs_one_pgh) + { + const char* str = "f1: v1\n" + "f2: v2"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(1), pghs.size()); + Assert::AreEqual(size_t(2), pghs[0].size()); + Assert::AreEqual("v1", pghs[0]["f1"].c_str()); + Assert::AreEqual("v2", pghs[0]["f2"].c_str()); + } + + TEST_METHOD(parse_paragraphs_two_pgh) + { + const char* str = "f1: v1\n" + "f2: v2\n" + "\n" + "f3: v3\n" + "f4: v4"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(2), pghs.size()); + Assert::AreEqual(size_t(2), pghs[0].size()); + Assert::AreEqual("v1", pghs[0]["f1"].c_str()); + Assert::AreEqual("v2", pghs[0]["f2"].c_str()); + Assert::AreEqual(size_t(2), pghs[1].size()); + Assert::AreEqual("v3", pghs[1]["f3"].c_str()); + Assert::AreEqual("v4", pghs[1]["f4"].c_str()); + } + + TEST_METHOD(parse_paragraphs_field_names) + { + const char* str = "1:\n" + "f:\n" + "F:\n" + "0:\n" + "F-2:\n"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(1), pghs.size()); + Assert::AreEqual(size_t(5), pghs[0].size()); + } + + TEST_METHOD(parse_paragraphs_multiple_blank_lines) + { + const char* str = "f1: v1\n" + "f2: v2\n" + "\n" + "\n" + "f3: v3\n" + "f4: v4"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(2), pghs.size()); + } + + TEST_METHOD(parse_paragraphs_empty_fields) + { + const char* str = "f1:\n" + "f2: "; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(1), pghs.size()); + Assert::AreEqual(size_t(2), pghs[0].size()); + Assert::AreEqual("", pghs[0]["f1"].c_str()); + Assert::AreEqual("", pghs[0]["f2"].c_str()); + Assert::AreEqual(size_t(2), pghs[0].size()); + } + + TEST_METHOD(parse_paragraphs_multiline_fields) + { + const char* str = "f1: simple\n" + " f1\r\n" + "f2:\r\n" + " f2\r\n" + " continue\r\n"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(1), pghs.size()); + Assert::AreEqual("simple\n f1", pghs[0]["f1"].c_str()); + Assert::AreEqual("\n f2\n continue", pghs[0]["f2"].c_str()); + } + + TEST_METHOD(parse_paragraphs_crlfs) + { + const char* str = "f1: v1\r\n" + "f2: v2\r\n" + "\r\n" + "f3: v3\r\n" + "f4: v4"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(2), pghs.size()); + Assert::AreEqual(size_t(2), pghs[0].size()); + Assert::AreEqual("v1", pghs[0]["f1"].c_str()); + Assert::AreEqual("v2", pghs[0]["f2"].c_str()); + Assert::AreEqual(size_t(2), pghs[1].size()); + Assert::AreEqual("v3", pghs[1]["f3"].c_str()); + Assert::AreEqual("v4", pghs[1]["f4"].c_str()); + } + + TEST_METHOD(parse_paragraphs_comment) + { + const char* str = "f1: v1\r\n" + "#comment\r\n" + "f2: v2\r\n" + "#comment\r\n" + "\r\n" + "#comment\r\n" + "f3: v3\r\n" + "#comment\r\n" + "f4: v4"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(2), pghs.size()); + Assert::AreEqual(size_t(2), pghs[0].size()); + Assert::AreEqual("v1", pghs[0]["f1"].c_str()); + Assert::AreEqual("v2", pghs[0]["f2"].c_str()); + Assert::AreEqual(size_t(2), pghs[1].size()); + Assert::AreEqual("v3", pghs[1]["f3"].c_str()); + Assert::AreEqual("v4", pghs[1]["f4"].c_str()); + } + + TEST_METHOD(parse_comment_before_single_slashN) + { + const char* str = "f1: v1\r\n" + "#comment\n"; + auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(1), pghs[0].size()); + Assert::AreEqual("v1", pghs[0]["f1"].c_str()); + } + + TEST_METHOD(BinaryParagraph_serialize_min) + { + vcpkg::BinaryParagraph pgh({ + {"Package", "zlib"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + }); + std::string ss = Strings::serialize(pgh); + auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(1), pghs.size()); + Assert::AreEqual(size_t(4), pghs[0].size()); + Assert::AreEqual("zlib", pghs[0]["Package"].c_str()); + Assert::AreEqual("1.2.8", pghs[0]["Version"].c_str()); + Assert::AreEqual("x86-windows", pghs[0]["Architecture"].c_str()); + Assert::AreEqual("same", pghs[0]["Multi-Arch"].c_str()); + } + + TEST_METHOD(BinaryParagraph_serialize_max) + { + vcpkg::BinaryParagraph pgh({ + {"Package", "zlib"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Description", "first line\n second line"}, + {"Maintainer", "abc "}, + {"Depends", "dep"}, + {"Multi-Arch", "same"}, + }); + std::string ss = Strings::serialize(pgh); + auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(1), pghs.size()); + Assert::AreEqual(size_t(7), pghs[0].size()); + Assert::AreEqual("zlib", pghs[0]["Package"].c_str()); + Assert::AreEqual("1.2.8", pghs[0]["Version"].c_str()); + Assert::AreEqual("x86-windows", pghs[0]["Architecture"].c_str()); + Assert::AreEqual("same", pghs[0]["Multi-Arch"].c_str()); + Assert::AreEqual("first line\n second line", pghs[0]["Description"].c_str()); + Assert::AreEqual("dep", pghs[0]["Depends"].c_str()); + } + + TEST_METHOD(BinaryParagraph_serialize_multiple_deps) + { + vcpkg::BinaryParagraph pgh({ + {"Package", "zlib"}, + {"Version", "1.2.8"}, + {"Architecture", "x86-windows"}, + {"Multi-Arch", "same"}, + {"Depends", "a, b, c"}, + }); + std::string ss = Strings::serialize(pgh); + auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss).value_or_exit(VCPKG_LINE_INFO); + Assert::AreEqual(size_t(1), pghs.size()); + Assert::AreEqual("a, b, c", pghs[0]["Depends"].c_str()); + } + }; +} diff --git a/toolsrc/src/tests_arguments.cpp b/toolsrc/src/tests_arguments.cpp deleted file mode 100644 index 14b3c3d4f..000000000 --- a/toolsrc/src/tests_arguments.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "CppUnitTest.h" -#include "VcpkgCmdArguments.h" - -#pragma comment(lib, "version") -#pragma comment(lib, "winhttp") - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -using namespace vcpkg; - -namespace UnitTest1 -{ - class ArgumentTests : public TestClass - { - TEST_METHOD(create_from_arg_sequence_options_lower) - { - std::vector t = {"--vcpkg-root", "C:\\vcpkg", "--debug", "--sendmetrics", "--printmetrics"}; - auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); - Assert::AreEqual("C:\\vcpkg", v.vcpkg_root_dir.get()->c_str()); - Assert::IsTrue(v.debug && *v.debug.get()); - Assert::IsTrue(v.sendmetrics && v.sendmetrics.get()); - Assert::IsTrue(v.printmetrics && *v.printmetrics.get()); - } - - TEST_METHOD(create_from_arg_sequence_options_upper) - { - std::vector t = {"--VCPKG-ROOT", "C:\\vcpkg", "--DEBUG", "--SENDMETRICS", "--PRINTMETRICS"}; - auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); - Assert::AreEqual("C:\\vcpkg", v.vcpkg_root_dir.get()->c_str()); - Assert::IsTrue(v.debug && *v.debug.get()); - Assert::IsTrue(v.sendmetrics && v.sendmetrics.get()); - Assert::IsTrue(v.printmetrics && *v.printmetrics.get()); - } - - TEST_METHOD(create_from_arg_sequence_valued_options) - { - std::vector t = {"--a=b", "command", "argument"}; - auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); - auto opts = v.check_and_get_optional_command_arguments({}, {"--a"}); - Assert::AreEqual("b", opts.settings["--a"].c_str()); - Assert::AreEqual(size_t{1}, v.command_arguments.size()); - Assert::AreEqual("argument", v.command_arguments[0].c_str()); - Assert::AreEqual("command", v.command.c_str()); - } - - TEST_METHOD(create_from_arg_sequence_valued_options2) - { - std::vector t = {"--a", "--b=c"}; - auto v = VcpkgCmdArguments::create_from_arg_sequence(t.data(), t.data() + t.size()); - auto opts = v.check_and_get_optional_command_arguments({"--a", "--c"}, {"--b", "--d"}); - Assert::AreEqual("c", opts.settings["--b"].c_str()); - Assert::IsTrue(opts.settings.find("--d") == opts.settings.end()); - Assert::IsTrue(opts.switches.find("--a") != opts.switches.end()); - Assert::IsTrue(opts.settings.find("--c") == opts.settings.end()); - Assert::AreEqual(size_t{0}, v.command_arguments.size()); - } - }; -} \ No newline at end of file diff --git a/toolsrc/src/tests_dependencies.cpp b/toolsrc/src/tests_dependencies.cpp deleted file mode 100644 index 6a6981d73..000000000 --- a/toolsrc/src/tests_dependencies.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include "CppUnitTest.h" -#include "SourceParagraph.h" -#include "Triplet.h" - -#pragma comment(lib, "version") -#pragma comment(lib, "winhttp") - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -using namespace vcpkg; -using Parse::parse_comma_list; - -namespace UnitTest1 -{ - class DependencyTests : public TestClass - { - TEST_METHOD(parse_depends_one) - { - auto v = expand_qualified_dependencies(parse_comma_list("libA (windows)")); - Assert::AreEqual(size_t(1), v.size()); - Assert::AreEqual("libA", v[0].depend.name.c_str()); - Assert::AreEqual("windows", v[0].qualifier.c_str()); - } - - TEST_METHOD(filter_depends) - { - auto deps = expand_qualified_dependencies(parse_comma_list("libA (windows), libB, libC (uwp)")); - auto v = filter_dependencies(deps, Triplet::X64_WINDOWS); - Assert::AreEqual(size_t(2), v.size()); - Assert::AreEqual("libA", v[0].c_str()); - Assert::AreEqual("libB", v[1].c_str()); - - auto v2 = filter_dependencies(deps, Triplet::ARM_UWP); - Assert::AreEqual(size_t(2), v.size()); - Assert::AreEqual("libB", v2[0].c_str()); - Assert::AreEqual("libC", v2[1].c_str()); - } - }; - - class SupportsTests : public TestClass - { - TEST_METHOD(parse_supports_all) - { - auto v = Supports::parse({ - "x64", - "x86", - "arm", - "windows", - "uwp", - "v140", - "v141", - "crt-static", - "crt-dynamic", - }); - Assert::AreNotEqual(uintptr_t(0), uintptr_t(v.get())); - - Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::X64, - Supports::Platform::UWP, - Supports::Linkage::DYNAMIC, - Supports::ToolsetVersion::V140)); - Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::ARM, - Supports::Platform::WINDOWS, - Supports::Linkage::STATIC, - Supports::ToolsetVersion::V141)); - } - - TEST_METHOD(parse_supports_invalid) - { - auto v = Supports::parse({"arm64"}); - Assert::AreEqual(uintptr_t(0), uintptr_t(v.get())); - Assert::AreEqual(size_t(1), v.error().size()); - Assert::AreEqual("arm64", v.error()[0].c_str()); - } - - TEST_METHOD(parse_supports_case_sensitive) - { - auto v = Supports::parse({"Windows"}); - Assert::AreEqual(uintptr_t(0), uintptr_t(v.get())); - Assert::AreEqual(size_t(1), v.error().size()); - Assert::AreEqual("Windows", v.error()[0].c_str()); - } - - TEST_METHOD(parse_supports_some) - { - auto v = Supports::parse({ - "x64", - "x86", - "windows", - }); - Assert::AreNotEqual(uintptr_t(0), uintptr_t(v.get())); - - Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::X64, - Supports::Platform::WINDOWS, - Supports::Linkage::DYNAMIC, - Supports::ToolsetVersion::V140)); - Assert::IsFalse(v.get()->is_supported(System::CPUArchitecture::ARM, - Supports::Platform::WINDOWS, - Supports::Linkage::DYNAMIC, - Supports::ToolsetVersion::V140)); - Assert::IsFalse(v.get()->is_supported(System::CPUArchitecture::X64, - Supports::Platform::UWP, - Supports::Linkage::DYNAMIC, - Supports::ToolsetVersion::V140)); - Assert::IsTrue(v.get()->is_supported(System::CPUArchitecture::X64, - Supports::Platform::WINDOWS, - Supports::Linkage::STATIC, - Supports::ToolsetVersion::V141)); - } - }; -} diff --git a/toolsrc/src/tests_package_spec.cpp b/toolsrc/src/tests_package_spec.cpp deleted file mode 100644 index a6b9d5b13..000000000 --- a/toolsrc/src/tests_package_spec.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "BinaryParagraph.h" -#include "CppUnitTest.h" -#include "Paragraphs.h" -#include "vcpkg_Strings.h" - -#pragma comment(lib, "version") -#pragma comment(lib, "winhttp") - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -namespace Microsoft::VisualStudio::CppUnitTestFramework -{ - template<> - inline std::wstring ToString(const vcpkg::PackageSpecParseResult& t) - { - return ToString(static_cast(t)); - } - - template<> - inline std::wstring ToString(const vcpkg::PackageSpec& t) - { - return ToString(t.to_string()); - } -} - -namespace Strings = vcpkg::Strings; - -namespace UnitTest1 -{ - using namespace vcpkg; - - class SpecifierConversion : public TestClass - { - TEST_METHOD(full_package_spec_to_feature_specs) - { - auto a_spec = PackageSpec::from_name_and_triplet("a", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); - auto b_spec = PackageSpec::from_name_and_triplet("b", Triplet::X64_WINDOWS).value_or_exit(VCPKG_LINE_INFO); - - auto fspecs = FullPackageSpec::to_feature_specs({{a_spec, {"0", "1"}}, {b_spec, {"2", "3"}}}); - - Assert::AreEqual(size_t(6), fspecs.size()); - - std::array features = {"", "0", "1", "", "2", "3"}; - std::array specs = {&a_spec, &a_spec, &a_spec, &b_spec, &b_spec, &b_spec}; - - for (size_t i = 0; i < features.size(); ++i) - { - Assert::AreEqual(features[i], fspecs[i].feature().c_str()); - Assert::AreEqual(*specs[i], fspecs[i].spec()); - } - } - }; - - class SpecifierParsing : public TestClass - { - TEST_METHOD(parsed_specifier_from_string) - { - auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib"); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); - auto spec = maybe_spec.get(); - Assert::AreEqual("zlib", spec->name.c_str()); - Assert::AreEqual(size_t(0), spec->features.size()); - Assert::AreEqual("", spec->triplet.c_str()); - } - - TEST_METHOD(parsed_specifier_from_string_with_triplet) - { - auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib:x64-uwp"); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); - auto spec = maybe_spec.get(); - Assert::AreEqual("zlib", spec->name.c_str()); - Assert::AreEqual("x64-uwp", spec->triplet.c_str()); - } - - TEST_METHOD(parsed_specifier_from_string_with_colons) - { - auto ec = vcpkg::ParsedSpecifier::from_string("zlib:x86-uwp:").error(); - Assert::AreEqual(vcpkg::PackageSpecParseResult::TOO_MANY_COLONS, ec); - } - - TEST_METHOD(parsed_specifier_from_string_with_feature) - { - auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib[feature]:x64-uwp"); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); - auto spec = maybe_spec.get(); - Assert::AreEqual("zlib", spec->name.c_str()); - Assert::IsTrue(spec->features.size() == 1); - Assert::AreEqual("feature", spec->features.front().c_str()); - Assert::AreEqual("x64-uwp", spec->triplet.c_str()); - } - - TEST_METHOD(parsed_specifier_from_string_with_many_features) - { - auto maybe_spec = vcpkg::ParsedSpecifier::from_string("zlib[0, 1,2]"); - Assert::AreEqual(vcpkg::PackageSpecParseResult::SUCCESS, maybe_spec.error()); - auto spec = maybe_spec.get(); - Assert::AreEqual("zlib", spec->name.c_str()); - Assert::IsTrue(spec->features.size() == 3); - Assert::AreEqual("0", spec->features[0].c_str()); - Assert::AreEqual("1", spec->features[1].c_str()); - Assert::AreEqual("2", spec->features[2].c_str()); - Assert::AreEqual("", spec->triplet.c_str()); - } - - TEST_METHOD(utf8_to_utf16) - { - auto str = vcpkg::Strings::to_utf16("abc"); - Assert::AreEqual(L"abc", str.c_str()); - } - - TEST_METHOD(utf8_to_utf16_with_whitespace) - { - auto str = vcpkg::Strings::to_utf16("abc -x86-windows"); - Assert::AreEqual(L"abc -x86-windows", str.c_str()); - } - }; - - TEST_CLASS(Metrics){}; -} diff --git a/toolsrc/src/tests_paragraph.cpp b/toolsrc/src/tests_paragraph.cpp deleted file mode 100644 index 47a07e12d..000000000 --- a/toolsrc/src/tests_paragraph.cpp +++ /dev/null @@ -1,388 +0,0 @@ -#include "BinaryParagraph.h" -#include "CppUnitTest.h" -#include "Paragraphs.h" -#include "vcpkg_Strings.h" - -#pragma comment(lib, "version") -#pragma comment(lib, "winhttp") - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -namespace Microsoft::VisualStudio::CppUnitTestFramework -{ - template<> - inline std::wstring ToString(const vcpkg::PackageSpecParseResult& t) - { - return ToString(static_cast(t)); - } -} - -namespace Strings = vcpkg::Strings; - -namespace UnitTest1 -{ - class ControlParsing : public TestClass - { - TEST_METHOD(SourceParagraph_Construct_Minimum) - { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, - {"Version", "1.2.8"}, - }}); - - Assert::IsTrue(m_pgh.has_value()); - auto& pgh = *m_pgh.get(); - - Assert::AreEqual("zlib", pgh->core_paragraph->name.c_str()); - Assert::AreEqual("1.2.8", pgh->core_paragraph->version.c_str()); - Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str()); - Assert::AreEqual("", pgh->core_paragraph->description.c_str()); - Assert::AreEqual(size_t(0), pgh->core_paragraph->depends.size()); - } - - TEST_METHOD(SourceParagraph_Construct_Maximum) - { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "s"}, - {"Version", "v"}, - {"Maintainer", "m"}, - {"Description", "d"}, - {"Build-Depends", "bd"}, - {"Supports", "x64"}, - }}); - Assert::IsTrue(m_pgh.has_value()); - auto& pgh = *m_pgh.get(); - - Assert::AreEqual("s", pgh->core_paragraph->name.c_str()); - Assert::AreEqual("v", pgh->core_paragraph->version.c_str()); - Assert::AreEqual("m", pgh->core_paragraph->maintainer.c_str()); - Assert::AreEqual("d", pgh->core_paragraph->description.c_str()); - Assert::AreEqual(size_t(1), pgh->core_paragraph->depends.size()); - Assert::AreEqual("bd", pgh->core_paragraph->depends[0].name().c_str()); - Assert::AreEqual(size_t(1), pgh->core_paragraph->supports.size()); - Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str()); - } - - TEST_METHOD(SourceParagraph_Two_Depends) - { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, - {"Version", "1.2.8"}, - {"Build-Depends", "z, openssl"}, - }}); - Assert::IsTrue(m_pgh.has_value()); - auto& pgh = *m_pgh.get(); - - Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size()); - Assert::AreEqual("z", pgh->core_paragraph->depends[0].name().c_str()); - Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name().c_str()); - } - - TEST_METHOD(SourceParagraph_Three_Depends) - { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, - {"Version", "1.2.8"}, - {"Build-Depends", "z, openssl, xyz"}, - }}); - Assert::IsTrue(m_pgh.has_value()); - auto& pgh = *m_pgh.get(); - - Assert::AreEqual(size_t(3), pgh->core_paragraph->depends.size()); - Assert::AreEqual("z", pgh->core_paragraph->depends[0].name().c_str()); - Assert::AreEqual("openssl", pgh->core_paragraph->depends[1].name().c_str()); - Assert::AreEqual("xyz", pgh->core_paragraph->depends[2].name().c_str()); - } - - TEST_METHOD(SourceParagraph_Three_Supports) - { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, - {"Version", "1.2.8"}, - {"Supports", "x64, windows, uwp"}, - }}); - Assert::IsTrue(m_pgh.has_value()); - auto& pgh = *m_pgh.get(); - - Assert::AreEqual(size_t(3), pgh->core_paragraph->supports.size()); - Assert::AreEqual("x64", pgh->core_paragraph->supports[0].c_str()); - Assert::AreEqual("windows", pgh->core_paragraph->supports[1].c_str()); - Assert::AreEqual("uwp", pgh->core_paragraph->supports[2].c_str()); - } - - TEST_METHOD(SourceParagraph_Construct_Qualified_Depends) - { - auto m_pgh = - vcpkg::SourceControlFile::parse_control_file(std::vector>{{ - {"Source", "zlib"}, - {"Version", "1.2.8"}, - {"Build-Depends", "libA (windows), libB (uwp)"}, - }}); - Assert::IsTrue(m_pgh.has_value()); - auto& pgh = *m_pgh.get(); - - Assert::AreEqual("zlib", pgh->core_paragraph->name.c_str()); - Assert::AreEqual("1.2.8", pgh->core_paragraph->version.c_str()); - Assert::AreEqual("", pgh->core_paragraph->maintainer.c_str()); - Assert::AreEqual("", pgh->core_paragraph->description.c_str()); - Assert::AreEqual(size_t(2), pgh->core_paragraph->depends.size()); - Assert::AreEqual("libA", pgh->core_paragraph->depends[0].name().c_str()); - Assert::AreEqual("windows", pgh->core_paragraph->depends[0].qualifier.c_str()); - Assert::AreEqual("libB", pgh->core_paragraph->depends[1].name().c_str()); - Assert::AreEqual("uwp", pgh->core_paragraph->depends[1].qualifier.c_str()); - } - - TEST_METHOD(BinaryParagraph_Construct_Minimum) - { - vcpkg::BinaryParagraph pgh({ - {"Package", "zlib"}, - {"Version", "1.2.8"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - }); - - Assert::AreEqual("zlib", pgh.spec.name().c_str()); - Assert::AreEqual("1.2.8", pgh.version.c_str()); - Assert::AreEqual("", pgh.maintainer.c_str()); - Assert::AreEqual("", pgh.description.c_str()); - Assert::AreEqual("x86-windows", pgh.spec.triplet().canonical_name().c_str()); - Assert::AreEqual(size_t(0), pgh.depends.size()); - } - - TEST_METHOD(BinaryParagraph_Construct_Maximum) - { - vcpkg::BinaryParagraph pgh({ - {"Package", "s"}, - {"Version", "v"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Maintainer", "m"}, - {"Description", "d"}, - {"Depends", "bd"}, - }); - Assert::AreEqual("s", pgh.spec.name().c_str()); - Assert::AreEqual("v", pgh.version.c_str()); - Assert::AreEqual("m", pgh.maintainer.c_str()); - Assert::AreEqual("d", pgh.description.c_str()); - Assert::AreEqual(size_t(1), pgh.depends.size()); - Assert::AreEqual("bd", pgh.depends[0].c_str()); - } - - TEST_METHOD(BinaryParagraph_Three_Depends) - { - vcpkg::BinaryParagraph pgh({ - {"Package", "zlib"}, - {"Version", "1.2.8"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", "a, b, c"}, - }); - - Assert::AreEqual(size_t(3), pgh.depends.size()); - Assert::AreEqual("a", pgh.depends[0].c_str()); - Assert::AreEqual("b", pgh.depends[1].c_str()); - Assert::AreEqual("c", pgh.depends[2].c_str()); - } - - TEST_METHOD(parse_paragraphs_empty) - { - const char* str = ""; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::IsTrue(pghs.empty()); - } - - TEST_METHOD(parse_paragraphs_one_field) - { - const char* str = "f1: v1"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(1), pghs.size()); - Assert::AreEqual(size_t(1), pghs[0].size()); - Assert::AreEqual("v1", pghs[0]["f1"].c_str()); - } - - TEST_METHOD(parse_paragraphs_one_pgh) - { - const char* str = "f1: v1\n" - "f2: v2"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(1), pghs.size()); - Assert::AreEqual(size_t(2), pghs[0].size()); - Assert::AreEqual("v1", pghs[0]["f1"].c_str()); - Assert::AreEqual("v2", pghs[0]["f2"].c_str()); - } - - TEST_METHOD(parse_paragraphs_two_pgh) - { - const char* str = "f1: v1\n" - "f2: v2\n" - "\n" - "f3: v3\n" - "f4: v4"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(2), pghs.size()); - Assert::AreEqual(size_t(2), pghs[0].size()); - Assert::AreEqual("v1", pghs[0]["f1"].c_str()); - Assert::AreEqual("v2", pghs[0]["f2"].c_str()); - Assert::AreEqual(size_t(2), pghs[1].size()); - Assert::AreEqual("v3", pghs[1]["f3"].c_str()); - Assert::AreEqual("v4", pghs[1]["f4"].c_str()); - } - - TEST_METHOD(parse_paragraphs_field_names) - { - const char* str = "1:\n" - "f:\n" - "F:\n" - "0:\n" - "F-2:\n"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(1), pghs.size()); - Assert::AreEqual(size_t(5), pghs[0].size()); - } - - TEST_METHOD(parse_paragraphs_multiple_blank_lines) - { - const char* str = "f1: v1\n" - "f2: v2\n" - "\n" - "\n" - "f3: v3\n" - "f4: v4"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(2), pghs.size()); - } - - TEST_METHOD(parse_paragraphs_empty_fields) - { - const char* str = "f1:\n" - "f2: "; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(1), pghs.size()); - Assert::AreEqual(size_t(2), pghs[0].size()); - Assert::AreEqual("", pghs[0]["f1"].c_str()); - Assert::AreEqual("", pghs[0]["f2"].c_str()); - Assert::AreEqual(size_t(2), pghs[0].size()); - } - - TEST_METHOD(parse_paragraphs_multiline_fields) - { - const char* str = "f1: simple\n" - " f1\r\n" - "f2:\r\n" - " f2\r\n" - " continue\r\n"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(1), pghs.size()); - Assert::AreEqual("simple\n f1", pghs[0]["f1"].c_str()); - Assert::AreEqual("\n f2\n continue", pghs[0]["f2"].c_str()); - } - - TEST_METHOD(parse_paragraphs_crlfs) - { - const char* str = "f1: v1\r\n" - "f2: v2\r\n" - "\r\n" - "f3: v3\r\n" - "f4: v4"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(2), pghs.size()); - Assert::AreEqual(size_t(2), pghs[0].size()); - Assert::AreEqual("v1", pghs[0]["f1"].c_str()); - Assert::AreEqual("v2", pghs[0]["f2"].c_str()); - Assert::AreEqual(size_t(2), pghs[1].size()); - Assert::AreEqual("v3", pghs[1]["f3"].c_str()); - Assert::AreEqual("v4", pghs[1]["f4"].c_str()); - } - - TEST_METHOD(parse_paragraphs_comment) - { - const char* str = "f1: v1\r\n" - "#comment\r\n" - "f2: v2\r\n" - "#comment\r\n" - "\r\n" - "#comment\r\n" - "f3: v3\r\n" - "#comment\r\n" - "f4: v4"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(2), pghs.size()); - Assert::AreEqual(size_t(2), pghs[0].size()); - Assert::AreEqual("v1", pghs[0]["f1"].c_str()); - Assert::AreEqual("v2", pghs[0]["f2"].c_str()); - Assert::AreEqual(size_t(2), pghs[1].size()); - Assert::AreEqual("v3", pghs[1]["f3"].c_str()); - Assert::AreEqual("v4", pghs[1]["f4"].c_str()); - } - - TEST_METHOD(parse_comment_before_single_slashN) - { - const char* str = "f1: v1\r\n" - "#comment\n"; - auto pghs = vcpkg::Paragraphs::parse_paragraphs(str).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(1), pghs[0].size()); - Assert::AreEqual("v1", pghs[0]["f1"].c_str()); - } - - TEST_METHOD(BinaryParagraph_serialize_min) - { - vcpkg::BinaryParagraph pgh({ - {"Package", "zlib"}, - {"Version", "1.2.8"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - }); - std::string ss = Strings::serialize(pgh); - auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(1), pghs.size()); - Assert::AreEqual(size_t(4), pghs[0].size()); - Assert::AreEqual("zlib", pghs[0]["Package"].c_str()); - Assert::AreEqual("1.2.8", pghs[0]["Version"].c_str()); - Assert::AreEqual("x86-windows", pghs[0]["Architecture"].c_str()); - Assert::AreEqual("same", pghs[0]["Multi-Arch"].c_str()); - } - - TEST_METHOD(BinaryParagraph_serialize_max) - { - vcpkg::BinaryParagraph pgh({ - {"Package", "zlib"}, - {"Version", "1.2.8"}, - {"Architecture", "x86-windows"}, - {"Description", "first line\n second line"}, - {"Maintainer", "abc "}, - {"Depends", "dep"}, - {"Multi-Arch", "same"}, - }); - std::string ss = Strings::serialize(pgh); - auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(1), pghs.size()); - Assert::AreEqual(size_t(7), pghs[0].size()); - Assert::AreEqual("zlib", pghs[0]["Package"].c_str()); - Assert::AreEqual("1.2.8", pghs[0]["Version"].c_str()); - Assert::AreEqual("x86-windows", pghs[0]["Architecture"].c_str()); - Assert::AreEqual("same", pghs[0]["Multi-Arch"].c_str()); - Assert::AreEqual("first line\n second line", pghs[0]["Description"].c_str()); - Assert::AreEqual("dep", pghs[0]["Depends"].c_str()); - } - - TEST_METHOD(BinaryParagraph_serialize_multiple_deps) - { - vcpkg::BinaryParagraph pgh({ - {"Package", "zlib"}, - {"Version", "1.2.8"}, - {"Architecture", "x86-windows"}, - {"Multi-Arch", "same"}, - {"Depends", "a, b, c"}, - }); - std::string ss = Strings::serialize(pgh); - auto pghs = vcpkg::Paragraphs::parse_paragraphs(ss).value_or_exit(VCPKG_LINE_INFO); - Assert::AreEqual(size_t(1), pghs.size()); - Assert::AreEqual("a, b, c", pghs[0]["Depends"].c_str()); - } - }; -} diff --git a/toolsrc/src/triplet.cpp b/toolsrc/src/triplet.cpp deleted file mode 100644 index 3b56da02a..000000000 --- a/toolsrc/src/triplet.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include "pch.h" - -#include "Triplet.h" -#include "vcpkg_Checks.h" -#include "vcpkg_Strings.h" - -namespace vcpkg -{ - struct TripletInstance - { - TripletInstance(std::string&& s) : value(std::move(s)), hash(std::hash()(value)) {} - - const std::string value; - const size_t hash = 0; - - bool operator==(const TripletInstance& o) const { return o.value == value; } - }; - const TripletInstance Triplet::DEFAULT_INSTANCE({}); -} - -template<> -struct std::hash -{ - size_t operator()(const vcpkg::TripletInstance& t) const { return t.hash; } -}; - -namespace vcpkg -{ - static std::unordered_set g_triplet_instances; - - const Triplet Triplet::X86_WINDOWS = from_canonical_name("x86-windows"); - const Triplet Triplet::X64_WINDOWS = from_canonical_name("x64-windows"); - const Triplet Triplet::X86_UWP = from_canonical_name("x86-uwp"); - const Triplet Triplet::X64_UWP = from_canonical_name("x64-uwp"); - const Triplet Triplet::ARM_UWP = from_canonical_name("arm-uwp"); - - bool Triplet::operator==(const Triplet& other) const { return this->m_instance == other.m_instance; } - - bool operator!=(const Triplet& left, const Triplet& right) { return !(left == right); } - - Triplet Triplet::from_canonical_name(const std::string& triplet_as_string) - { - std::string s(Strings::ascii_to_lowercase(triplet_as_string)); - const auto it = std::find(s.cbegin(), s.cend(), '-'); - Checks::check_exit(VCPKG_LINE_INFO, it != s.cend(), "Invalid triplet: %s", triplet_as_string); - - const auto p = g_triplet_instances.emplace(std::move(s)); - return &*p.first; - } - - const std::string& Triplet::canonical_name() const { return this->m_instance->value; } - - const std::string& Triplet::to_string() const { return this->canonical_name(); } - size_t Triplet::hash_code() const { return m_instance->hash; } -} diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 706c641fb..748b4f0ee 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -1,16 +1,18 @@ #define WIN32_LEAN_AND_MEAN #include -#include "Paragraphs.h" -#include "metrics.h" -#include "vcpkg_Chrono.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Files.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_Input.h" -#include "vcpkg_Strings.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #pragma warning(push) #pragma warning(disable : 4768) #include @@ -19,12 +21,15 @@ #include #include +#pragma comment(lib, "ole32") +#pragma comment(lib, "shell32") + using namespace vcpkg; void invalid_command(const std::string& cmd) { System::println(System::Color::error, "invalid command: %s", cmd); - Commands::Help::print_usage(); + Help::print_usage(); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -33,13 +38,26 @@ static void inner(const VcpkgCmdArguments& args) Metrics::g_metrics.lock()->track_property("command", args.command); if (args.command.empty()) { - Commands::Help::print_usage(); + Help::print_usage(); Checks::exit_fail(VCPKG_LINE_INFO); } - if (const auto command_function = Commands::find(args.command, Commands::get_available_commands_type_c())) + static const auto find_command = [&](auto&& commands) { + auto it = Util::find_if(commands, [&](auto&& commandc) { + return Strings::case_insensitive_ascii_compare(commandc.name, args.command); + }); + using std::end; + if (it != end(commands)) + { + return &*it; + } + else + return static_cast(nullptr); + }; + + if (const auto command_function = find_command(Commands::get_available_commands_type_c())) { - return command_function(args); + return command_function->function(args); } fs::path vcpkg_root_dir; @@ -74,9 +92,9 @@ static void inner(const VcpkgCmdArguments& args) Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Changing the working dir failed"); Commands::Version::warn_if_vcpkg_version_mismatch(paths); - if (const auto command_function = Commands::find(args.command, Commands::get_available_commands_type_b())) + if (const auto command_function = find_command(Commands::get_available_commands_type_b())) { - return command_function(args, paths); + return command_function->function(args, paths); } Triplet default_triplet; @@ -100,9 +118,9 @@ static void inner(const VcpkgCmdArguments& args) Input::check_triplet(default_triplet, paths); - if (const auto command_function = Commands::find(args.command, Commands::get_available_commands_type_a())) + if (const auto command_function = find_command(Commands::get_available_commands_type_a())) { - return command_function(args, paths, default_triplet); + return command_function->function(args, paths, default_triplet); } return invalid_command(args.command); @@ -202,7 +220,7 @@ int wmain(const int argc, const wchar_t* const* const argv) SetConsoleCP(65001); SetConsoleOutputCP(65001); - *GlobalState::timer.lock() = ElapsedTime::create_started(); + *GlobalState::timer.lock() = Chrono::ElapsedTime::create_started(); const std::string trimmed_command_line = trim_path_from_command_line(Strings::to_utf8(GetCommandLineW())); diff --git a/toolsrc/src/vcpkg/base/checks.cpp b/toolsrc/src/vcpkg/base/checks.cpp new file mode 100644 index 000000000..73c7b9b1a --- /dev/null +++ b/toolsrc/src/vcpkg/base/checks.cpp @@ -0,0 +1,81 @@ +#include "pch.h" + +#include +#include + +#include +#include + +namespace vcpkg::Checks +{ + [[noreturn]] static void cleanup_and_exit(const int exit_code) + { + const auto elapsed_us = GlobalState::timer.lock()->microseconds(); + + auto metrics = Metrics::g_metrics.lock(); + metrics->track_metric("elapsed_us", elapsed_us); + GlobalState::debugging = false; + metrics->flush(); + + SetConsoleCP(GlobalState::g_init_console_cp); + SetConsoleOutputCP(GlobalState::g_init_console_output_cp); + + fflush(nullptr); + + ::TerminateProcess(::GetCurrentProcess(), exit_code); + } + + static BOOL ctrl_handler(DWORD fdw_ctrl_type) + { + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_property("CtrlHandler", std::to_string(fdw_ctrl_type)); + locked_metrics->track_property("error", "CtrlHandler was fired."); + } + cleanup_and_exit(EXIT_FAILURE); + } + + void register_console_ctrl_handler() + { + SetConsoleCtrlHandler(reinterpret_cast(ctrl_handler), TRUE); + } + + [[noreturn]] void unreachable(const LineInfo& line_info) + { + System::println(System::Color::error, "Error: Unreachable code was reached"); + System::println(System::Color::error, line_info.to_string()); // Always print line_info here +#ifndef NDEBUG + std::abort(); +#else + cleanup_and_exit(EXIT_FAILURE); +#endif + } + + [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code) + { + Debug::println(System::Color::error, line_info.to_string()); + cleanup_and_exit(exit_code); + } + + [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message) + { + System::println(System::Color::error, error_message); + exit_fail(line_info); + } + + void check_exit(const LineInfo& line_info, bool expression) + { + if (!expression) + { + exit_with_message(line_info, Strings::EMPTY); + } + } + + void check_exit(const LineInfo& line_info, bool expression, const CStringView error_message) + { + if (!expression) + { + exit_with_message(line_info, error_message); + } + } +} diff --git a/toolsrc/src/vcpkg/base/chrono.cpp b/toolsrc/src/vcpkg/base/chrono.cpp new file mode 100644 index 000000000..5d28909fc --- /dev/null +++ b/toolsrc/src/vcpkg/base/chrono.cpp @@ -0,0 +1,61 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg::Chrono +{ + static std::string format_time_userfriendly(const std::chrono::nanoseconds& nanos) + { + using std::chrono::duration_cast; + using std::chrono::hours; + using std::chrono::microseconds; + using std::chrono::milliseconds; + using std::chrono::minutes; + using std::chrono::nanoseconds; + using std::chrono::seconds; + + const double nanos_as_double = static_cast(nanos.count()); + + if (duration_cast(nanos) > hours()) + { + const auto t = nanos_as_double / duration_cast(hours(1)).count(); + return Strings::format("%.4g h", t); + } + + if (duration_cast(nanos) > minutes()) + { + const auto t = nanos_as_double / duration_cast(minutes(1)).count(); + return Strings::format("%.4g min", t); + } + + if (duration_cast(nanos) > seconds()) + { + const auto t = nanos_as_double / duration_cast(seconds(1)).count(); + return Strings::format("%.4g s", t); + } + + if (duration_cast(nanos) > milliseconds()) + { + const auto t = nanos_as_double / duration_cast(milliseconds(1)).count(); + return Strings::format("%.4g ms", t); + } + + if (duration_cast(nanos) > microseconds()) + { + const auto t = nanos_as_double / duration_cast(microseconds(1)).count(); + return Strings::format("%.4g us", t); + } + + return Strings::format("%.4g ns", nanos_as_double); + } + + ElapsedTime ElapsedTime::create_started() + { + ElapsedTime t; + t.m_start_tick = std::chrono::high_resolution_clock::now(); + return t; + } + + std::string ElapsedTime::to_string() const { return format_time_userfriendly(elapsed()); } +} diff --git a/toolsrc/src/vcpkg/base/cofffilereader.cpp b/toolsrc/src/vcpkg/base/cofffilereader.cpp new file mode 100644 index 000000000..5e9c86998 --- /dev/null +++ b/toolsrc/src/vcpkg/base/cofffilereader.cpp @@ -0,0 +1,308 @@ +#include "pch.h" + +#include +#include + +using namespace std; + +namespace vcpkg::CoffFileReader +{ + template + static T reinterpret_bytes(const char* data) + { + return (*reinterpret_cast(&data[0])); + } + + template + static T read_value_from_stream(fstream& fs) + { + T data; + fs.read(reinterpret_cast(&data), sizeof data); + return data; + } + + template + static T peek_value_from_stream(fstream& fs) + { + const fpos_t original_pos = fs.tellg().seekpos(); + T data; + fs.read(reinterpret_cast(&data), sizeof data); + fs.seekg(original_pos); + return data; + } + + static void verify_equal_strings( + const LineInfo& line_info, const char* expected, const char* actual, int size, const char* label) + { + Checks::check_exit(line_info, + memcmp(expected, actual, size) == 0, + "Incorrect string (%s) found. Expected: (%s) but found (%s)", + label, + expected, + actual); + } + + static void read_and_verify_PE_signature(fstream& fs) + { + static const size_t OFFSET_TO_PE_SIGNATURE_OFFSET = 0x3c; + + static const char* PE_SIGNATURE = "PE\0\0"; + static const size_t PE_SIGNATURE_SIZE = 4; + + fs.seekg(OFFSET_TO_PE_SIGNATURE_OFFSET, ios_base::beg); + const int32_t offset_to_PE_signature = read_value_from_stream(fs); + + fs.seekg(offset_to_PE_signature); + char signature[PE_SIGNATURE_SIZE]; + fs.read(signature, PE_SIGNATURE_SIZE); + verify_equal_strings(VCPKG_LINE_INFO, PE_SIGNATURE, signature, PE_SIGNATURE_SIZE, "PE_SIGNATURE"); + fs.seekg(offset_to_PE_signature + PE_SIGNATURE_SIZE, ios_base::beg); + } + + static fpos_t align_to_size(const uint64_t unaligned, const uint64_t alignment_size) + { + fpos_t aligned = unaligned - 1; + aligned /= alignment_size; + aligned += 1; + aligned *= alignment_size; + return aligned; + } + + struct CoffFileHeader + { + static const size_t HEADER_SIZE = 20; + + static CoffFileHeader read(fstream& fs) + { + CoffFileHeader ret; + ret.data.resize(HEADER_SIZE); + fs.read(&ret.data[0], HEADER_SIZE); + return ret; + } + + MachineType machine_type() const + { + static const size_t MACHINE_TYPE_OFFSET = 0; + static const size_t MACHINE_TYPE_SIZE = 2; + + std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE); + const uint16_t machine = reinterpret_bytes(machine_field_as_string.c_str()); + return to_machine_type(machine); + } + + private: + std::string data; + }; + + struct ArchiveMemberHeader + { + static const size_t HEADER_SIZE = 60; + + static ArchiveMemberHeader read(fstream& fs) + { + static const size_t HEADER_END_OFFSET = 58; + static const char* HEADER_END = "`\n"; + static const size_t HEADER_END_SIZE = 2; + + ArchiveMemberHeader ret; + ret.data.resize(HEADER_SIZE); + fs.read(&ret.data[0], HEADER_SIZE); + + if (ret.data[0] != '\0') // Due to freeglut. github issue #223 + { + const std::string header_end = ret.data.substr(HEADER_END_OFFSET, HEADER_END_SIZE); + verify_equal_strings( + VCPKG_LINE_INFO, HEADER_END, header_end.c_str(), HEADER_END_SIZE, "LIB HEADER_END"); + } + + return ret; + } + + std::string name() const + { + static const size_t HEADER_NAME_OFFSET = 0; + static const size_t HEADER_NAME_SIZE = 16; + return data.substr(HEADER_NAME_OFFSET, HEADER_NAME_SIZE); + } + + uint64_t member_size() const + { + static const size_t ALIGNMENT_SIZE = 2; + + static const size_t HEADER_SIZE_OFFSET = 48; + static const size_t HEADER_SIZE_FIELD_SIZE = 10; + const std::string as_string = data.substr(HEADER_SIZE_OFFSET, HEADER_SIZE_FIELD_SIZE); + // This is in ASCII decimal representation + const uint64_t value = std::strtoull(as_string.c_str(), nullptr, 10); + + const uint64_t aligned = align_to_size(value, ALIGNMENT_SIZE); + return aligned; + } + + std::string data; + }; + + struct OffsetsArray + { + static OffsetsArray read(fstream& fs, const uint32_t offset_count) + { + static const size_t OFFSET_WIDTH = 4; + + std::string raw_offsets; + const size_t raw_offset_size = offset_count * OFFSET_WIDTH; + raw_offsets.resize(raw_offset_size); + fs.read(&raw_offsets[0], raw_offset_size); + + OffsetsArray ret; + for (uint32_t i = 0; i < offset_count; ++i) + { + const std::string value_as_string = raw_offsets.substr(OFFSET_WIDTH * i, OFFSET_WIDTH * (i + 1)); + const uint32_t value = reinterpret_bytes(value_as_string.c_str()); + + // Ignore offsets that point to offset 0. See vcpkg github #223 #288 #292 + if (value != 0) + { + ret.data.push_back(value); + } + } + + // Sort the offsets, because it is possible for them to be unsorted. See vcpkg github #292 + std::sort(ret.data.begin(), ret.data.end()); + return ret; + } + + std::vector data; + }; + + struct ImportHeader + { + static const size_t HEADER_SIZE = 20; + + static ImportHeader read(fstream& fs) + { + static const size_t SIG1_OFFSET = 0; + static const uint16_t SIG1 = static_cast(MachineType::UNKNOWN); + static const size_t SIG1_SIZE = 2; + + static const size_t SIG2_OFFSET = 2; + static const uint16_t SIG2 = 0xFFFF; + static const size_t SIG2_SIZE = 2; + + ImportHeader ret; + ret.data.resize(HEADER_SIZE); + fs.read(&ret.data[0], HEADER_SIZE); + + const std::string sig1_as_string = ret.data.substr(SIG1_OFFSET, SIG1_SIZE); + const uint16_t sig1 = reinterpret_bytes(sig1_as_string.c_str()); + Checks::check_exit(VCPKG_LINE_INFO, sig1 == SIG1, "Sig1 was incorrect. Expected %s but got %s", SIG1, sig1); + + const std::string sig2_as_string = ret.data.substr(SIG2_OFFSET, SIG2_SIZE); + const uint16_t sig2 = reinterpret_bytes(sig2_as_string.c_str()); + Checks::check_exit(VCPKG_LINE_INFO, sig2 == SIG2, "Sig2 was incorrect. Expected %s but got %s", SIG2, sig2); + + return ret; + } + + MachineType machine_type() const + { + static const size_t MACHINE_TYPE_OFFSET = 6; + static const size_t MACHINE_TYPE_SIZE = 2; + + std::string machine_field_as_string = data.substr(MACHINE_TYPE_OFFSET, MACHINE_TYPE_SIZE); + const uint16_t machine = reinterpret_bytes(machine_field_as_string.c_str()); + return to_machine_type(machine); + } + + private: + std::string data; + }; + + static void read_and_verify_archive_file_signature(fstream& fs) + { + static const char* FILE_START = "!\n"; + static const size_t FILE_START_SIZE = 8; + + fs.seekg(fs.beg); + + char file_start[FILE_START_SIZE]; + fs.read(file_start, FILE_START_SIZE); + verify_equal_strings(VCPKG_LINE_INFO, FILE_START, file_start, FILE_START_SIZE, "LIB FILE_START"); + } + + DllInfo read_dll(const fs::path& path) + { + std::fstream fs(path, std::ios::in | std::ios::binary | std::ios::ate); + Checks::check_exit(VCPKG_LINE_INFO, fs.is_open(), "Could not open file %s for reading", path.generic_string()); + + read_and_verify_PE_signature(fs); + CoffFileHeader header = CoffFileHeader::read(fs); + const MachineType machine = header.machine_type(); + return {machine}; + } + + struct Marker + { + void set_to_offset(const fpos_t position) { this->m_absolute_position = position; } + + void set_to_current_pos(fstream& fs) { this->m_absolute_position = fs.tellg().seekpos(); } + + void seek_to_marker(fstream& fs) const { fs.seekg(this->m_absolute_position, ios_base::beg); } + + void advance_by(const uint64_t offset) { this->m_absolute_position += offset; } + + private: + fpos_t m_absolute_position = 0; + }; + + LibInfo read_lib(const fs::path& path) + { + std::fstream fs(path, std::ios::in | std::ios::binary | std::ios::ate); + Checks::check_exit(VCPKG_LINE_INFO, fs.is_open(), "Could not open file %s for reading", path.generic_string()); + + read_and_verify_archive_file_signature(fs); + + Marker marker; + marker.set_to_current_pos(fs); + + // First Linker Member + const ArchiveMemberHeader first_linker_member_header = ArchiveMemberHeader::read(fs); + Checks::check_exit(VCPKG_LINE_INFO, + first_linker_member_header.name().substr(0, 2) == "/ ", + "Could not find proper first linker member"); + marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + first_linker_member_header.member_size()); + marker.seek_to_marker(fs); + + const ArchiveMemberHeader second_linker_member_header = ArchiveMemberHeader::read(fs); + Checks::check_exit(VCPKG_LINE_INFO, + second_linker_member_header.name().substr(0, 2) == "/ ", + "Could not find proper second linker member"); + // The first 4 bytes contains the number of archive members + const uint32_t archive_member_count = read_value_from_stream(fs); + const OffsetsArray offsets = OffsetsArray::read(fs, archive_member_count); + marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + second_linker_member_header.member_size()); + marker.seek_to_marker(fs); + + const bool hasLongnameMemberHeader = peek_value_from_stream(fs) == 0x2F2F; + if (hasLongnameMemberHeader) + { + const ArchiveMemberHeader longnames_member_header = ArchiveMemberHeader::read(fs); + marker.advance_by(ArchiveMemberHeader::HEADER_SIZE + longnames_member_header.member_size()); + marker.seek_to_marker(fs); + } + + std::set machine_types; + // Next we have the obj and pseudo-object files + for (const uint32_t offset : offsets.data) + { + marker.set_to_offset(offset + ArchiveMemberHeader::HEADER_SIZE); // Skip the header, no need to read it. + marker.seek_to_marker(fs); + const uint16_t first_two_bytes = peek_value_from_stream(fs); + const bool isImportHeader = to_machine_type(first_two_bytes) == MachineType::UNKNOWN; + const MachineType machine = + isImportHeader ? ImportHeader::read(fs).machine_type() : CoffFileHeader::read(fs).machine_type(); + machine_types.insert(machine); + } + + return {std::vector(machine_types.cbegin(), machine_types.cend())}; + } +} diff --git a/toolsrc/src/vcpkg/base/enums.cpp b/toolsrc/src/vcpkg/base/enums.cpp new file mode 100644 index 000000000..aa124f3aa --- /dev/null +++ b/toolsrc/src/vcpkg/base/enums.cpp @@ -0,0 +1,14 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg::Enums +{ + std::string nullvalue_to_string(const CStringView enum_name) { return Strings::format("%s_NULLVALUE", enum_name); } + + [[noreturn]] void nullvalue_used(const LineInfo& line_info, const CStringView enum_name) + { + Checks::exit_with_message(line_info, "NULLVALUE of enum %s was used", enum_name); + } +} diff --git a/toolsrc/src/vcpkg/base/files.cpp b/toolsrc/src/vcpkg/base/files.cpp new file mode 100644 index 000000000..f8b239eaa --- /dev/null +++ b/toolsrc/src/vcpkg/base/files.cpp @@ -0,0 +1,208 @@ +#include "pch.h" + +#include +#include +#include + +namespace vcpkg::Files +{ + static const std::regex FILESYSTEM_INVALID_CHARACTERS_REGEX = std::regex(R"([\/:*?"<>|])"); + + struct RealFilesystem final : Filesystem + { + virtual Expected read_contents(const fs::path& file_path) const override + { + std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary); + if (file_stream.fail()) + { + return std::make_error_code(std::errc::no_such_file_or_directory); + } + + file_stream.seekg(0, file_stream.end); + auto length = file_stream.tellg(); + file_stream.seekg(0, file_stream.beg); + + if (length > SIZE_MAX) + { + return std::make_error_code(std::errc::file_too_large); + } + + std::string output; + output.resize(static_cast(length)); + file_stream.read(&output[0], length); + file_stream.close(); + + return std::move(output); + } + virtual Expected> read_lines(const fs::path& file_path) const override + { + std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary); + if (file_stream.fail()) + { + return std::make_error_code(std::errc::no_such_file_or_directory); + } + + std::vector output; + std::string line; + while (std::getline(file_stream, line)) + { + output.push_back(line); + } + file_stream.close(); + + return std::move(output); + } + virtual fs::path find_file_recursively_up(const fs::path& starting_dir, + const std::string& filename) const override + { + fs::path current_dir = starting_dir; + for (; !current_dir.empty(); current_dir = current_dir.parent_path()) + { + const fs::path candidate = current_dir / filename; + if (exists(candidate)) + { + break; + } + } + + return current_dir; + } + + virtual std::vector get_files_recursive(const fs::path& dir) const override + { + std::vector ret; + + fs::stdfs::recursive_directory_iterator b(dir), e{}; + for (; b != e; ++b) + { + ret.push_back(b->path()); + } + + return ret; + } + + virtual std::vector get_files_non_recursive(const fs::path& dir) const override + { + std::vector ret; + + fs::stdfs::directory_iterator b(dir), e{}; + for (; b != e; ++b) + { + ret.push_back(b->path()); + } + + return ret; + } + + virtual void write_lines(const fs::path& file_path, const std::vector& lines) override + { + std::fstream output(file_path, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc); + for (const std::string& line : lines) + { + output << line << "\n"; + } + output.close(); + } + + virtual void rename(const fs::path& oldpath, const fs::path& newpath) override + { + fs::stdfs::rename(oldpath, newpath); + } + virtual bool remove(const fs::path& path) override { return fs::stdfs::remove(path); } + virtual bool remove(const fs::path& path, std::error_code& ec) override { return fs::stdfs::remove(path, ec); } + virtual std::uintmax_t remove_all(const fs::path& path, std::error_code& ec) override + { + // Working around the currently buggy remove_all() + std::uintmax_t out = fs::stdfs::remove_all(path, ec); + + for (int i = 0; i < 5 && this->exists(path); i++) + { + using namespace std::chrono_literals; + std::this_thread::sleep_for(i * 100ms); + out += fs::stdfs::remove_all(path, ec); + } + + if (this->exists(path)) + { + System::println(System::Color::warning, + "Some files in %s were unable to be removed. Close any editors operating in this " + "directory and retry.", + path.string()); + } + + return out; + } + virtual bool exists(const fs::path& path) const override { return fs::stdfs::exists(path); } + virtual bool is_directory(const fs::path& path) const override { return fs::stdfs::is_directory(path); } + virtual bool is_regular_file(const fs::path& path) const override { return fs::stdfs::is_regular_file(path); } + virtual bool is_empty(const fs::path& path) const override { return fs::stdfs::is_empty(path); } + virtual bool create_directory(const fs::path& path, std::error_code& ec) override + { + return fs::stdfs::create_directory(path, ec); + } + virtual bool create_directories(const fs::path& path, std::error_code& ec) override + { + return fs::stdfs::create_directories(path, ec); + } + virtual void copy(const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts) override + { + fs::stdfs::copy(oldpath, newpath, opts); + } + virtual bool copy_file(const fs::path& oldpath, + const fs::path& newpath, + fs::copy_options opts, + std::error_code& ec) override + { + return fs::stdfs::copy_file(oldpath, newpath, opts, ec); + } + + virtual fs::file_status status(const fs::path& path, std::error_code& ec) const override + { + return fs::stdfs::status(path, ec); + } + virtual void write_contents(const fs::path& file_path, const std::string& data) override + { + FILE* f = nullptr; + auto ec = _wfopen_s(&f, file_path.native().c_str(), L"wb"); + Checks::check_exit( + VCPKG_LINE_INFO, ec == 0, "Error: Could not open file for writing: %s", file_path.u8string().c_str()); + auto count = fwrite(data.data(), sizeof(data[0]), data.size(), f); + fclose(f); + + Checks::check_exit(VCPKG_LINE_INFO, count == data.size()); + } + }; + + Filesystem& get_real_filesystem() + { + static RealFilesystem real_fs; + return real_fs; + } + + bool has_invalid_chars_for_filesystem(const std::string& s) + { + return std::regex_search(s, FILESYSTEM_INVALID_CHARACTERS_REGEX); + } + + void print_paths(const std::vector& paths) + { + System::println(); + for (const fs::path& p : paths) + { + System::println(" %s", p.generic_string()); + } + System::println(); + } + + std::vector find_from_PATH(const std::wstring& name) + { + const std::wstring cmd = Strings::wformat(L"where.exe %s", name); + auto out = System::cmd_execute_and_capture_output(cmd); + if (out.exit_code != 0) + { + return {}; + } + + return Util::fmap(Strings::split(out.output, "\n"), [](auto&& s) { return fs::path(s); }); + } +} diff --git a/toolsrc/src/vcpkg/base/lineinfo.cpp b/toolsrc/src/vcpkg/base/lineinfo.cpp new file mode 100644 index 000000000..7435ed666 --- /dev/null +++ b/toolsrc/src/vcpkg/base/lineinfo.cpp @@ -0,0 +1,9 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg +{ + std::string LineInfo::to_string() const { return Strings::format("%s(%d)", this->file_name, this->line_number); } +} diff --git a/toolsrc/src/vcpkg/base/machinetype.cpp b/toolsrc/src/vcpkg/base/machinetype.cpp new file mode 100644 index 000000000..2b7bd5e3a --- /dev/null +++ b/toolsrc/src/vcpkg/base/machinetype.cpp @@ -0,0 +1,41 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg +{ + MachineType to_machine_type(const uint16_t value) + { + const MachineType t = static_cast(value); + switch (t) + { + case MachineType::UNKNOWN: + case MachineType::AM33: + case MachineType::AMD64: + case MachineType::ARM: + case MachineType::ARM64: + case MachineType::ARMNT: + case MachineType::EBC: + case MachineType::I386: + case MachineType::IA64: + case MachineType::M32R: + case MachineType::MIPS16: + case MachineType::MIPSFPU: + case MachineType::MIPSFPU16: + case MachineType::POWERPC: + case MachineType::POWERPCFP: + case MachineType::R4000: + case MachineType::RISCV32: + case MachineType::RISCV64: + case MachineType::RISCV128: + case MachineType::SH3: + case MachineType::SH3DSP: + case MachineType::SH4: + case MachineType::SH5: + case MachineType::THUMB: + case MachineType::WCEMIPSV2: return t; + default: Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown machine type code 0x%x", value); + } + } +} diff --git a/toolsrc/src/vcpkg/base/strings.cpp b/toolsrc/src/vcpkg/base/strings.cpp new file mode 100644 index 000000000..2a6d3dff2 --- /dev/null +++ b/toolsrc/src/vcpkg/base/strings.cpp @@ -0,0 +1,174 @@ +#include "pch.h" + +#include +#include +#include + +namespace vcpkg::Strings::details +{ + // To disambiguate between two overloads + static const auto isspace = [](const char c) { return std::isspace(c); }; + + // Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower() + static char tolower_char(const char c) { return static_cast(std::tolower(c)); } + +#if defined(_WIN32) + static _locale_t& c_locale() + { + static _locale_t c_locale_impl = _create_locale(LC_ALL, "C"); + return c_locale_impl; + } +#endif + + std::string format_internal(const char* fmtstr, ...) + { + va_list args; + va_start(args, fmtstr); + +#if defined(_WIN32) + const int sz = _vscprintf_l(fmtstr, c_locale(), args); +#else + const int sz = vsnprintf(nullptr, 0, fmtstr, args); +#endif + Checks::check_exit(VCPKG_LINE_INFO, sz > 0); + + std::string output(sz, '\0'); + +#if defined(_WIN32) + _vsnprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args); +#else + vsnprintf(&output.at(0), output.size() + 1, fmtstr, args); +#endif + va_end(args); + + return output; + } + + std::wstring wformat_internal(const wchar_t* fmtstr, ...) + { + va_list args; + va_start(args, fmtstr); + +#if defined(_WIN32) + const int sz = _vscwprintf_l(fmtstr, c_locale(), args); +#else + const int sz = vswprintf(nullptr, 0, fmtstr, args); +#endif + Checks::check_exit(VCPKG_LINE_INFO, sz > 0); + + std::wstring output(sz, L'\0'); + +#if defined(_WIN32) + _vsnwprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args); +#else + vswprintf(&output.at(0), output.size() + 1, fmtstr, args); +#endif + va_end(args); + + return output; + } +} + +namespace vcpkg::Strings +{ + std::wstring to_utf16(const CStringView s) + { + const int size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0); + std::wstring output; + output.resize(size - 1); + MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, output.data(), size - 1); + return output; + } + + std::string to_utf8(const CWStringView w) + { + const int size = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, nullptr, 0, nullptr, nullptr); + std::string output; + output.resize(size - 1); + WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, output.data(), size - 1, nullptr, nullptr); + return output; + } + + std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern) + { + const std::string pattern_as_lower_case(ascii_to_lowercase(pattern)); + return search(s.begin(), + s.end(), + pattern_as_lower_case.begin(), + pattern_as_lower_case.end(), + [](const char a, const char b) { return details::tolower_char(a) == b; }); + } + + bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern) + { + return case_insensitive_ascii_find(s, pattern) != s.end(); + } + + bool case_insensitive_ascii_compare(const CStringView left, const CStringView right) + { + return _stricmp(left.c_str(), right.c_str()) == 0; + } + + std::string ascii_to_lowercase(const std::string& input) + { + std::string output(input); + std::transform(output.begin(), output.end(), output.begin(), &details::tolower_char); + return output; + } + + bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern) + { + return _strnicmp(s.c_str(), pattern.c_str(), pattern.size()) == 0; + } + + void trim(std::string* s) + { + s->erase(std::find_if_not(s->rbegin(), s->rend(), details::isspace).base(), s->end()); + s->erase(s->begin(), std::find_if_not(s->begin(), s->end(), details::isspace)); + } + + std::string trimmed(const std::string& s) + { + auto whitespace_back = std::find_if_not(s.rbegin(), s.rend(), details::isspace).base(); + auto whitespace_front = std::find_if_not(s.begin(), whitespace_back, details::isspace); + return std::string(whitespace_front, whitespace_back); + } + + void trim_all_and_remove_whitespace_strings(std::vector* strings) + { + for (std::string& s : *strings) + { + trim(&s); + } + + Util::erase_remove_if(*strings, [](const std::string& s) { return s.empty(); }); + } + + std::vector split(const std::string& s, const std::string& delimiter) + { + std::vector output; + + if (delimiter.empty()) + { + output.push_back(s); + return output; + } + + const size_t delimiter_length = delimiter.length(); + size_t i = 0; + for (size_t pos = s.find(delimiter); pos != std::string::npos; pos = s.find(delimiter, pos)) + { + output.push_back(s.substr(i, pos - i)); + pos += delimiter_length; + i = pos; + } + + // Add the rest of the string after the last delimiter, unless there is nothing after it + if (i != s.length()) + { + output.push_back(s.substr(i, s.length())); + } + + return output; + } +} diff --git a/toolsrc/src/vcpkg/base/system.cpp b/toolsrc/src/vcpkg/base/system.cpp new file mode 100644 index 000000000..716c2a6a6 --- /dev/null +++ b/toolsrc/src/vcpkg/base/system.cpp @@ -0,0 +1,350 @@ +#include "pch.h" + +#include +#include +#include + +#pragma comment(lib, "Advapi32") + +namespace vcpkg::System +{ + tm get_current_date_time() + { + using std::chrono::system_clock; + std::time_t now_time = system_clock::to_time_t(system_clock::now()); + tm parts; + localtime_s(&parts, &now_time); + return parts; + } + + fs::path get_exe_path_of_current_process() + { + wchar_t buf[_MAX_PATH]; + const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); + if (bytes == 0) std::abort(); + return fs::path(buf, buf + bytes); + } + + Optional to_cpu_architecture(CStringView arch) + { + if (Strings::case_insensitive_ascii_compare(arch, "x86")) return CPUArchitecture::X86; + if (Strings::case_insensitive_ascii_compare(arch, "x64")) return CPUArchitecture::X64; + if (Strings::case_insensitive_ascii_compare(arch, "amd64")) return CPUArchitecture::X64; + if (Strings::case_insensitive_ascii_compare(arch, "arm")) return CPUArchitecture::ARM; + if (Strings::case_insensitive_ascii_compare(arch, "arm64")) return CPUArchitecture::ARM64; + return nullopt; + } + + CPUArchitecture get_host_processor() + { + auto w6432 = get_environment_variable(L"PROCESSOR_ARCHITEW6432"); + if (const auto p = w6432.get()) return to_cpu_architecture(Strings::to_utf8(*p)).value_or_exit(VCPKG_LINE_INFO); + + const auto procarch = get_environment_variable(L"PROCESSOR_ARCHITECTURE").value_or_exit(VCPKG_LINE_INFO); + return to_cpu_architecture(Strings::to_utf8(procarch)).value_or_exit(VCPKG_LINE_INFO); + } + + std::vector get_supported_host_architectures() + { + std::vector supported_architectures; + supported_architectures.push_back(get_host_processor()); + + // AMD64 machines support to run x86 applications + if (supported_architectures.back() == CPUArchitecture::X64) + { + supported_architectures.push_back(CPUArchitecture::X86); + } + + return supported_architectures; + } + + int cmd_execute_clean(const CWStringView cmd_line) + { + static const std::wstring SYSTEM_ROOT = get_environment_variable(L"SystemRoot").value_or_exit(VCPKG_LINE_INFO); + static const std::wstring SYSTEM_32 = SYSTEM_ROOT + LR"(\system32)"; + static const std::wstring NEW_PATH = Strings::wformat( + LR"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", SYSTEM_32, SYSTEM_ROOT, SYSTEM_32, SYSTEM_32); + + std::vector env_wstrings = { + L"ALLUSERSPROFILE", + L"APPDATA", + L"CommonProgramFiles", + L"CommonProgramFiles(x86)", + L"CommonProgramW6432", + L"COMPUTERNAME", + L"ComSpec", + L"HOMEDRIVE", + L"HOMEPATH", + L"LOCALAPPDATA", + L"LOGONSERVER", + L"NUMBER_OF_PROCESSORS", + L"OS", + L"PATHEXT", + L"PROCESSOR_ARCHITECTURE", + L"PROCESSOR_ARCHITEW6432", + L"PROCESSOR_IDENTIFIER", + L"PROCESSOR_LEVEL", + L"PROCESSOR_REVISION", + L"ProgramData", + L"ProgramFiles", + L"ProgramFiles(x86)", + L"ProgramW6432", + L"PROMPT", + L"PSModulePath", + L"PUBLIC", + L"SystemDrive", + L"SystemRoot", + L"TEMP", + L"TMP", + L"USERDNSDOMAIN", + L"USERDOMAIN", + L"USERDOMAIN_ROAMINGPROFILE", + L"USERNAME", + L"USERPROFILE", + L"windir", + // Enables proxy information to be passed to Curl, the underlying download library in cmake.exe + L"HTTP_PROXY", + L"HTTPS_PROXY", + // Enables find_package(CUDA) in CMake + L"CUDA_PATH", + }; + + // Flush stdout before launching external process + fflush(nullptr); + + std::wstring env_cstr; + + for (auto&& env_wstring : env_wstrings) + { + const Optional value = System::get_environment_variable(env_wstring); + const auto v = value.get(); + if (!v || v->empty()) continue; + + env_cstr.append(env_wstring); + env_cstr.push_back(L'='); + env_cstr.append(*v); + env_cstr.push_back(L'\0'); + } + + env_cstr.append(NEW_PATH); + env_cstr.push_back(L'\0'); + + STARTUPINFOW startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFOW)); + startup_info.cb = sizeof(STARTUPINFOW); + + PROCESS_INFORMATION process_info; + memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); + + // Basically we are wrapping it in quotes + std::wstring actual_cmd_line = Strings::wformat(LR"###(cmd.exe /c "%s")###", cmd_line); + Debug::println("CreateProcessW(%s)", Strings::to_utf8(actual_cmd_line)); + bool succeeded = TRUE == CreateProcessW(nullptr, + actual_cmd_line.data(), + nullptr, + nullptr, + FALSE, + BELOW_NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, + env_cstr.data(), + nullptr, + &startup_info, + &process_info); + + Checks::check_exit(VCPKG_LINE_INFO, succeeded, "Process creation failed with error code: %lu", GetLastError()); + + CloseHandle(process_info.hThread); + + const DWORD result = WaitForSingleObject(process_info.hProcess, INFINITE); + Checks::check_exit(VCPKG_LINE_INFO, result != WAIT_FAILED, "WaitForSingleObject failed"); + + DWORD exit_code = 0; + GetExitCodeProcess(process_info.hProcess, &exit_code); + + Debug::println("CreateProcessW() returned %lu", exit_code); + return static_cast(exit_code); + } + + int cmd_execute(const CWStringView cmd_line) + { + // Flush stdout before launching external process + fflush(nullptr); + + // Basically we are wrapping it in quotes + const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line); + Debug::println("_wsystem(%s)", Strings::to_utf8(actual_cmd_line)); + const int exit_code = _wsystem(actual_cmd_line.c_str()); + Debug::println("_wsystem() returned %d", exit_code); + return exit_code; + } + + // On Win7, output from powershell calls contain a byte order mark, so we strip it out if it is present + static void remove_byte_order_marks(std::wstring* s) + { + const wchar_t* a = s->c_str(); + // This is the UTF-8 byte-order mark + while (s->size() >= 3 && a[0] == 0xEF && a[1] == 0xBB && a[2] == 0xBF) + { + s->erase(0, 3); + } + } + + ExitCodeAndOutput cmd_execute_and_capture_output(const CWStringView cmd_line) + { + // Flush stdout before launching external process + fflush(stdout); + + const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s 2>&1")###", cmd_line); + + Debug::println("_wpopen(%s)", Strings::to_utf8(actual_cmd_line)); + std::wstring output; + wchar_t buf[1024]; + const auto pipe = _wpopen(actual_cmd_line.c_str(), L"r"); + if (pipe == nullptr) + { + return {1, Strings::to_utf8(output)}; + } + while (fgetws(buf, 1024, pipe)) + { + output.append(buf); + } + if (!feof(pipe)) + { + return {1, Strings::to_utf8(output)}; + } + + const auto ec = _pclose(pipe); + Debug::println("_pclose() returned %d", ec); + remove_byte_order_marks(&output); + return {ec, Strings::to_utf8(output)}; + } + + std::wstring create_powershell_script_cmd(const fs::path& script_path, const CWStringView args) + { + // TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned + return Strings::wformat( + LR"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.native(), args); + } + + void println() { println(Strings::EMPTY); } + + void print(const CStringView message) { fputs(message.c_str(), stdout); } + + void println(const CStringView message) + { + print(message); + putchar('\n'); + } + + void print(const Color c, const CStringView message) + { + const HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info{}; + GetConsoleScreenBufferInfo(console_handle, &console_screen_buffer_info); + const auto original_color = console_screen_buffer_info.wAttributes; + + SetConsoleTextAttribute(console_handle, static_cast(c) | (original_color & 0xF0)); + print(message); + SetConsoleTextAttribute(console_handle, original_color); + } + + void println(const Color c, const CStringView message) + { + print(c, message); + putchar('\n'); + } + + Optional get_environment_variable(const CWStringView varname) noexcept + { + const auto sz = GetEnvironmentVariableW(varname.c_str(), nullptr, 0); + if (sz == 0) return nullopt; + + std::wstring ret(sz, L'\0'); + + Checks::check_exit(VCPKG_LINE_INFO, MAXDWORD >= ret.size()); + const auto sz2 = GetEnvironmentVariableW(varname.c_str(), ret.data(), static_cast(ret.size())); + Checks::check_exit(VCPKG_LINE_INFO, sz2 + 1 == sz); + ret.pop_back(); + return ret; + } + + static bool is_string_keytype(DWORD hkey_type) + { + return hkey_type == REG_SZ || hkey_type == REG_MULTI_SZ || hkey_type == REG_EXPAND_SZ; + } + + Optional get_registry_string(HKEY base, const CWStringView sub_key, const CWStringView valuename) + { + HKEY k = nullptr; + const LSTATUS ec = RegOpenKeyExW(base, sub_key.c_str(), NULL, KEY_READ, &k); + if (ec != ERROR_SUCCESS) return nullopt; + + DWORD dw_buffer_size = 0; + DWORD dw_type = 0; + auto rc = RegQueryValueExW(k, valuename.c_str(), nullptr, &dw_type, nullptr, &dw_buffer_size); + if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size == 0 || + dw_buffer_size % sizeof(wchar_t) != 0) + return nullopt; + std::wstring ret; + ret.resize(dw_buffer_size / sizeof(wchar_t)); + + rc = RegQueryValueExW( + k, valuename.c_str(), nullptr, &dw_type, reinterpret_cast(ret.data()), &dw_buffer_size); + if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size != sizeof(wchar_t) * ret.size()) + return nullopt; + + ret.pop_back(); // remove extra trailing null byte + return ret; + } + + static const fs::path& get_program_files() + { + static const fs::path PATH = System::get_environment_variable(L"PROGRAMFILES").value_or_exit(VCPKG_LINE_INFO); + return PATH; + } + + const fs::path& get_program_files_32_bit() + { + static const fs::path PATH = []() -> fs::path { + auto value = System::get_environment_variable(L"ProgramFiles(x86)"); + if (auto v = value.get()) + { + return std::move(*v); + } + return get_program_files(); + }(); + return PATH; + } + + const fs::path& get_program_files_platform_bitness() + { + static const fs::path PATH = []() -> fs::path { + auto value = System::get_environment_variable(L"ProgramW6432"); + if (auto v = value.get()) + { + return std::move(*v); + } + return get_program_files(); + }(); + return PATH; + } +} + +namespace vcpkg::Debug +{ + void println(const CStringView message) + { + if (GlobalState::debugging) + { + System::println("[DEBUG] %s", message); + } + } + + void println(const System::Color c, const CStringView message) + { + if (GlobalState::debugging) + { + System::println(c, "[DEBUG] %s", message); + } + } +} diff --git a/toolsrc/src/vcpkg/binaryparagraph.cpp b/toolsrc/src/vcpkg/binaryparagraph.cpp new file mode 100644 index 000000000..ef943011f --- /dev/null +++ b/toolsrc/src/vcpkg/binaryparagraph.cpp @@ -0,0 +1,123 @@ +#include "pch.h" + +#include +#include +#include + +namespace vcpkg +{ + namespace Fields + { + static const std::string PACKAGE = "Package"; + static const std::string VERSION = "Version"; + static const std::string ARCHITECTURE = "Architecture"; + static const std::string MULTI_ARCH = "Multi-Arch"; + } + + namespace Fields + { + static const std::string FEATURE = "Feature"; + static const std::string DESCRIPTION = "Description"; + static const std::string MAINTAINER = "Maintainer"; + static const std::string DEPENDS = "Depends"; + static const std::string DEFAULTFEATURES = "Default-Features"; + } + + BinaryParagraph::BinaryParagraph() = default; + + BinaryParagraph::BinaryParagraph(std::unordered_map fields) + { + using namespace vcpkg::Parse; + + ParagraphParser parser(std::move(fields)); + + { + std::string name; + parser.required_field(Fields::PACKAGE, name); + std::string architecture; + parser.required_field(Fields::ARCHITECTURE, architecture); + this->spec = PackageSpec::from_name_and_triplet(name, Triplet::from_canonical_name(architecture)) + .value_or_exit(VCPKG_LINE_INFO); + } + + // one or the other + this->version = parser.optional_field(Fields::VERSION); + this->feature = parser.optional_field(Fields::FEATURE); + + this->description = parser.optional_field(Fields::DESCRIPTION); + this->maintainer = parser.optional_field(Fields::MAINTAINER); + + std::string multi_arch; + parser.required_field(Fields::MULTI_ARCH, multi_arch); + + this->depends = parse_comma_list(parser.optional_field(Fields::DEPENDS)); + if (this->feature.empty()) + { + this->default_features = parse_comma_list(parser.optional_field(Fields::DEFAULTFEATURES)); + } + + if (const auto err = parser.error_info(this->spec.to_string())) + { + System::println( + System::Color::error, "Error: while parsing the Binary Paragraph for %s", this->spec.to_string()); + print_error_message(err); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + // prefer failing above when possible because it gives better information + Checks::check_exit(VCPKG_LINE_INFO, multi_arch == "same", "Multi-Arch must be 'same' but was %s", multi_arch); + } + + BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const Triplet& triplet) + { + this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO); + this->version = spgh.version; + this->description = spgh.description; + this->maintainer = spgh.maintainer; + this->depends = filter_dependencies(spgh.depends, triplet); + } + + BinaryParagraph::BinaryParagraph(const SourceParagraph& spgh, const FeatureParagraph& fpgh, const Triplet& triplet) + { + this->spec = PackageSpec::from_name_and_triplet(spgh.name, triplet).value_or_exit(VCPKG_LINE_INFO); + this->version = Strings::EMPTY; + this->feature = fpgh.name; + this->description = fpgh.description; + this->maintainer = Strings::EMPTY; + this->depends = filter_dependencies(fpgh.depends, triplet); + } + + std::string BinaryParagraph::displayname() const + { + const auto f = this->feature.empty() ? "core" : this->feature; + return Strings::format("%s[%s]:%s", this->spec.name(), f, this->spec.triplet()); + } + + std::string BinaryParagraph::dir() const { return this->spec.dir(); } + + std::string BinaryParagraph::fullstem() const + { + return Strings::format("%s_%s_%s", this->spec.name(), this->version, this->spec.triplet()); + } + + void serialize(const BinaryParagraph& pgh, std::string& out_str) + { + out_str.append("Package: ").append(pgh.spec.name()).push_back('\n'); + if (!pgh.version.empty()) + out_str.append("Version: ").append(pgh.version).push_back('\n'); + else if (!pgh.feature.empty()) + out_str.append("Feature: ").append(pgh.feature).push_back('\n'); + if (!pgh.depends.empty()) + { + out_str.append("Depends: "); + out_str.append(Strings::join(", ", pgh.depends)); + out_str.push_back('\n'); + } + + out_str.append("Architecture: ").append(pgh.spec.triplet().to_string()).push_back('\n'); + out_str.append("Multi-Arch: same\n"); + + if (!pgh.maintainer.empty()) out_str.append("Maintainer: ").append(pgh.maintainer).push_back('\n'); + if (!pgh.description.empty()) out_str.append("Description: ").append(pgh.description).push_back('\n'); + } +} diff --git a/toolsrc/src/vcpkg/build.cpp b/toolsrc/src/vcpkg/build.cpp new file mode 100644 index 000000000..99ec541c1 --- /dev/null +++ b/toolsrc/src/vcpkg/build.cpp @@ -0,0 +1,533 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using vcpkg::Build::BuildResult; +using vcpkg::Parse::ParseControlErrorInfo; +using vcpkg::Parse::ParseExpected; + +namespace vcpkg::Build::Command +{ + using Dependencies::InstallPlanAction; + using Dependencies::InstallPlanType; + + static const std::string OPTION_CHECKS_ONLY = "--checks-only"; + + void perform_and_exit(const FullPackageSpec& full_spec, + const fs::path& port_dir, + const std::unordered_set& options, + const VcpkgPaths& paths) + { + const PackageSpec& spec = full_spec.package_spec; + if (options.find(OPTION_CHECKS_ONLY) != options.end()) + { + const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, spec.triplet()); + const auto build_info = Build::read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); + const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); + Checks::check_exit(VCPKG_LINE_INFO, error_count == 0); + Checks::exit_success(VCPKG_LINE_INFO); + } + + const ParseExpected source_control_file = + Paragraphs::try_load_port(paths.get_filesystem(), port_dir); + + if (!source_control_file.has_value()) + { + print_error_message(source_control_file.error()); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + for (const std::string& str : full_spec.features) + { + System::println("%s \n", str); + } + const auto& scf = source_control_file.value_or_exit(VCPKG_LINE_INFO); + Checks::check_exit(VCPKG_LINE_INFO, + spec.name() == scf->core_paragraph->name, + "The Name: field inside the CONTROL does not match the port directory: '%s' != '%s'", + scf->core_paragraph->name, + spec.name()); + + const StatusParagraphs status_db = database_load_check(paths); + const Build::BuildPackageOptions build_package_options{Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; + + const Build::BuildPackageConfig build_config{ + *scf->core_paragraph, spec.triplet(), paths.port_dir(spec), build_package_options}; + + const auto result = Build::build_package(paths, build_config, status_db); + if (result.code == BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES) + { + System::println(System::Color::error, + "The build command requires all dependencies to be already installed."); + System::println("The following dependencies are missing:"); + System::println(); + for (const auto& p : result.unmet_dependencies) + { + System::println(" %s", p); + } + System::println(); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + if (result.code != BuildResult::SUCCEEDED) + { + System::println(System::Color::error, Build::create_error_message(result.code, spec)); + System::println(Build::create_user_troubleshooting_message(spec)); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + static const std::string EXAMPLE = Help::create_example_string("build zlib:x64-windows"); + // Build only takes a single package and all dependencies must already be installed + args.check_exact_arg_count(1, EXAMPLE); + const std::string command_argument = args.command_arguments.at(0); + const FullPackageSpec spec = Input::check_and_get_full_package_spec(command_argument, default_triplet, EXAMPLE); + Input::check_triplet(spec.package_spec.triplet(), paths); + const std::unordered_set options = + args.check_and_get_optional_command_arguments({OPTION_CHECKS_ONLY}); + perform_and_exit(spec, paths.port_dir(spec.package_spec), options, paths); + } +} + +namespace vcpkg::Build +{ + static const std::string NAME_EMPTY_PACKAGE = "PolicyEmptyPackage"; + static const std::string NAME_DLLS_WITHOUT_LIBS = "PolicyDLLsWithoutLIBs"; + static const std::string NAME_ONLY_RELEASE_CRT = "PolicyOnlyReleaseCRT"; + static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder"; + static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt"; + + const std::string& to_string(BuildPolicy policy) + { + switch (policy) + { + case BuildPolicy::EMPTY_PACKAGE: return NAME_EMPTY_PACKAGE; + case BuildPolicy::DLLS_WITHOUT_LIBS: return NAME_DLLS_WITHOUT_LIBS; + case BuildPolicy::ONLY_RELEASE_CRT: return NAME_ONLY_RELEASE_CRT; + case BuildPolicy::EMPTY_INCLUDE_FOLDER: return NAME_EMPTY_INCLUDE_FOLDER; + case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return NAME_ALLOW_OBSOLETE_MSVCRT; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + CStringView to_cmake_variable(BuildPolicy policy) + { + switch (policy) + { + case BuildPolicy::EMPTY_PACKAGE: return "VCPKG_POLICY_EMPTY_PACKAGE"; + case BuildPolicy::DLLS_WITHOUT_LIBS: return "VCPKG_POLICY_DLLS_WITHOUT_LIBS"; + case BuildPolicy::ONLY_RELEASE_CRT: return "VCPKG_POLICY_ONLY_RELEASE_CRT"; + case BuildPolicy::EMPTY_INCLUDE_FOLDER: return "VCPKG_POLICY_EMPTY_INCLUDE_FOLDER"; + case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return "VCPKG_POLICY_ALLOW_OBSOLETE_MSVCRT"; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + Optional to_linkage_type(const std::string& str) + { + if (str == "dynamic") return LinkageType::DYNAMIC; + if (str == "static") return LinkageType::STATIC; + return nullopt; + } + + namespace BuildInfoRequiredField + { + static const std::string CRT_LINKAGE = "CRTLinkage"; + static const std::string LIBRARY_LINKAGE = "LibraryLinkage"; + } + + CWStringView to_vcvarsall_target(const std::string& cmake_system_name) + { + if (cmake_system_name == Strings::EMPTY) return Strings::WEMPTY; + if (cmake_system_name == "Windows") return Strings::WEMPTY; + if (cmake_system_name == "WindowsStore") return L"store"; + + Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported vcvarsall target %s", cmake_system_name); + } + + CWStringView to_vcvarsall_toolchain(const std::string& target_architecture, const Toolset& toolset) + { + auto maybe_target_arch = System::to_cpu_architecture(target_architecture); + Checks::check_exit( + VCPKG_LINE_INFO, maybe_target_arch.has_value(), "Invalid architecture string: %s", target_architecture); + auto target_arch = maybe_target_arch.value_or_exit(VCPKG_LINE_INFO); + auto host_architectures = System::get_supported_host_architectures(); + + for (auto&& host : host_architectures) + { + auto it = Util::find_if(toolset.supported_architectures, [&](const ToolsetArchOption& opt) { + return host == opt.host_arch && target_arch == opt.target_arch; + }); + if (it != toolset.supported_architectures.end()) return it->name; + } + + Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported toolchain combination %s", target_architecture); + } + + std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset) + { + const wchar_t* tonull = L" >nul"; + if (GlobalState::debugging) + { + tonull = Strings::WEMPTY; + } + + const auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture, toolset); + const auto target = to_vcvarsall_target(pre_build_info.cmake_system_name); + + return Strings::wformat(LR"("%s" %s %s %s %s 2>&1)", + toolset.vcvarsall.native(), + Strings::join(L" ", toolset.vcvarsall_options), + arch, + target, + tonull); + } + + static void create_binary_feature_control_file(const SourceParagraph& source_paragraph, + const FeatureParagraph& feature_paragraph, + const Triplet& triplet, + BinaryControlFile& bcf) + { + BinaryParagraph bpgh(source_paragraph, feature_paragraph, triplet); + bcf.features.emplace_back(std::move(bpgh)); + } + + static void create_binary_control_file(const SourceParagraph& source_paragraph, + const Triplet& triplet, + const BuildInfo& build_info, + BinaryControlFile& bcf) + { + BinaryParagraph bpgh(source_paragraph, triplet); + if (const auto p_ver = build_info.version.get()) + { + bpgh.version = *p_ver; + } + bcf.core_paragraph = std::move(bpgh); + } + + static void write_binary_control_file(const VcpkgPaths& paths, BinaryControlFile bcf) + { + std::string start = Strings::serialize(bcf.core_paragraph); + for (auto&& feature : bcf.features) + { + start += "\n" + Strings::serialize(feature); + } + const fs::path binary_control_file = paths.packages / bcf.core_paragraph.dir() / "CONTROL"; + paths.get_filesystem().write_contents(binary_control_file, start); + } + + ExtendedBuildResult build_package(const VcpkgPaths& paths, + const BuildPackageConfig& config, + const StatusParagraphs& status_db) + { + const PackageSpec spec = + PackageSpec::from_name_and_triplet(config.src.name, config.triplet).value_or_exit(VCPKG_LINE_INFO); + + const Triplet& triplet = config.triplet; + { + std::vector missing_specs; + for (auto&& dep : filter_dependencies(config.src.depends, triplet)) + { + if (status_db.find_installed(dep, triplet) == status_db.end()) + { + missing_specs.push_back( + PackageSpec::from_name_and_triplet(dep, triplet).value_or_exit(VCPKG_LINE_INFO)); + } + } + // Fail the build if any dependencies were missing + if (!missing_specs.empty()) + { + return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(missing_specs)}; + } + } + + const fs::path& cmake_exe_path = paths.get_cmake_exe(); + const fs::path& git_exe_path = paths.get_git_exe(); + + const fs::path ports_cmake_script_path = paths.ports_cmake; + const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); + const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); + + std::string features; + if (GlobalState::feature_packages) + { + if (config.feature_list) + { + for (auto&& feature : *config.feature_list) + { + features.append(feature + ";"); + } + if (features.size() > 0) + { + features.pop_back(); + } + } + } + + const std::wstring cmd_launch_cmake = make_cmake_cmd( + cmake_exe_path, + ports_cmake_script_path, + { + {L"CMD", L"BUILD"}, + {L"PORT", config.src.name}, + {L"CURRENT_PORT_DIR", config.port_dir / "/."}, + {L"TARGET_TRIPLET", triplet.canonical_name()}, + {L"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, + {L"VCPKG_USE_HEAD_VERSION", to_bool(config.build_package_options.use_head_version) ? L"1" : L"0"}, + {L"_VCPKG_NO_DOWNLOADS", !to_bool(config.build_package_options.allow_downloads) ? L"1" : L"0"}, + {L"GIT", git_exe_path}, + {L"FEATURES", features}, + }); + + const std::wstring command = Strings::wformat(LR"(%s && %s)", cmd_set_environment, cmd_launch_cmake); + + const auto timer = Chrono::ElapsedTime::create_started(); + + const int return_code = System::cmd_execute_clean(command); + const auto buildtimeus = timer.microseconds(); + const auto spec_string = spec.to_string(); + + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_metric("buildtimeus-" + spec_string, buildtimeus); + if (return_code != 0) + { + locked_metrics->track_property("error", "build failed"); + locked_metrics->track_property("build_error", spec_string); + return {BuildResult::BUILD_FAILED, {}}; + } + } + + const BuildInfo build_info = read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); + const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); + + BinaryControlFile bcf; + + create_binary_control_file(config.src, triplet, build_info, bcf); + + if (error_count != 0) + { + return {BuildResult::POST_BUILD_CHECKS_FAILED, {}}; + } + if (GlobalState::feature_packages) + { + if (config.feature_list) + { + for (auto&& feature : *config.feature_list) + { + for (auto&& f_pgh : config.scf->feature_paragraphs) + { + if (f_pgh->name == feature) + create_binary_feature_control_file(*config.scf->core_paragraph, *f_pgh, triplet, bcf); + } + } + } + } + + write_binary_control_file(paths, bcf); + + // const fs::path port_buildtrees_dir = paths.buildtrees / spec.name; + // delete_directory(port_buildtrees_dir); + + return {BuildResult::SUCCEEDED, {}}; + } + + const std::string& to_string(const BuildResult build_result) + { + static const std::string NULLVALUE_STRING = Enums::nullvalue_to_string("vcpkg::Commands::Build::BuildResult"); + static const std::string SUCCEEDED_STRING = "SUCCEEDED"; + static const std::string BUILD_FAILED_STRING = "BUILD_FAILED"; + static const std::string FILE_CONFLICTS_STRING = "FILE_CONFLICTS"; + static const std::string POST_BUILD_CHECKS_FAILED_STRING = "POST_BUILD_CHECKS_FAILED"; + static const std::string CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING = "CASCADED_DUE_TO_MISSING_DEPENDENCIES"; + + switch (build_result) + { + case BuildResult::NULLVALUE: return NULLVALUE_STRING; + case BuildResult::SUCCEEDED: return SUCCEEDED_STRING; + case BuildResult::BUILD_FAILED: return BUILD_FAILED_STRING; + case BuildResult::POST_BUILD_CHECKS_FAILED: return POST_BUILD_CHECKS_FAILED_STRING; + case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: return CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING; + case BuildResult::FILE_CONFLICTS: return FILE_CONFLICTS_STRING; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + std::string create_error_message(const BuildResult build_result, const PackageSpec& spec) + { + return Strings::format("Error: Building package %s failed with: %s", spec, Build::to_string(build_result)); + } + + std::string create_user_troubleshooting_message(const PackageSpec& spec) + { + return Strings::format("Please ensure you're using the latest portfiles with `.\\vcpkg update`, then\n" + "submit an issue at https://github.com/Microsoft/vcpkg/issues including:\n" + " Package: %s\n" + " Vcpkg version: %s\n" + "\n" + "Additionally, attach any relevant sections from the log files above.", + spec, + Commands::Version::version()); + } + + static BuildInfo inner_create_buildinfo(std::unordered_map pgh) + { + Parse::ParagraphParser parser(std::move(pgh)); + + BuildInfo build_info; + + { + std::string crt_linkage_as_string; + parser.required_field(BuildInfoRequiredField::CRT_LINKAGE, crt_linkage_as_string); + + auto crtlinkage = to_linkage_type(crt_linkage_as_string); + if (const auto p = crtlinkage.get()) + build_info.crt_linkage = *p; + else + Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid crt linkage type: [%s]", crt_linkage_as_string); + } + + { + std::string library_linkage_as_string; + parser.required_field(BuildInfoRequiredField::LIBRARY_LINKAGE, library_linkage_as_string); + auto liblinkage = to_linkage_type(library_linkage_as_string); + if (const auto p = liblinkage.get()) + build_info.library_linkage = *p; + else + Checks::exit_with_message( + VCPKG_LINE_INFO, "Invalid library linkage type: [%s]", library_linkage_as_string); + } + std::string version = parser.optional_field("Version"); + if (!version.empty()) build_info.version = std::move(version); + + std::map policies; + for (auto policy : G_ALL_POLICIES) + { + const auto setting = parser.optional_field(to_string(policy)); + if (setting.empty()) continue; + if (setting == "enabled") + policies.emplace(policy, true); + else if (setting == "disabled") + policies.emplace(policy, false); + else + Checks::exit_with_message( + VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", to_string(policy), setting); + } + + if (const auto err = parser.error_info("PostBuildInformation")) + { + print_error_message(err); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + build_info.policies = BuildPolicies(std::move(policies)); + + return build_info; + } + + BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath) + { + const Expected> pghs = + Paragraphs::get_single_paragraph(fs, filepath); + Checks::check_exit(VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid BUILD_INFO file for package"); + return inner_create_buildinfo(*pghs.get()); + } + + PreBuildInfo PreBuildInfo::from_triplet_file(const VcpkgPaths& paths, const Triplet& triplet) + { + static constexpr CStringView FLAG_GUID = "c35112b6-d1ba-415b-aa5d-81de856ef8eb"; + + const fs::path& cmake_exe_path = paths.get_cmake_exe(); + const fs::path ports_cmake_script_path = paths.scripts / "get_triplet_environment.cmake"; + const fs::path triplet_file_path = paths.triplets / (triplet.canonical_name() + ".cmake"); + + const std::wstring cmd_launch_cmake = make_cmake_cmd(cmake_exe_path, + ports_cmake_script_path, + { + {L"CMAKE_TRIPLET_FILE", triplet_file_path}, + }); + + const std::wstring command = Strings::wformat(LR"(%s)", cmd_launch_cmake); + const auto ec_data = System::cmd_execute_and_capture_output(command); + Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0); + + const std::vector lines = Strings::split(ec_data.output, "\n"); + + PreBuildInfo pre_build_info; + + const auto e = lines.cend(); + auto cur = std::find(lines.cbegin(), e, FLAG_GUID); + if (cur != e) ++cur; + + for (; cur != e; ++cur) + { + auto&& line = *cur; + + const std::vector s = Strings::split(line, "="); + Checks::check_exit(VCPKG_LINE_INFO, + s.size() == 1 || s.size() == 2, + "Expected format is [VARIABLE_NAME=VARIABLE_VALUE], but was [%s]", + line); + + const bool variable_with_no_value = s.size() == 1; + const std::string variable_name = s.at(0); + const std::string variable_value = variable_with_no_value ? Strings::EMPTY : s.at(1); + + if (variable_name == "VCPKG_TARGET_ARCHITECTURE") + { + pre_build_info.target_architecture = variable_value; + continue; + } + + if (variable_name == "VCPKG_CMAKE_SYSTEM_NAME") + { + pre_build_info.cmake_system_name = variable_value; + continue; + } + + if (variable_name == "VCPKG_CMAKE_SYSTEM_VERSION") + { + pre_build_info.cmake_system_version = variable_value; + continue; + } + + if (variable_name == "VCPKG_PLATFORM_TOOLSET") + { + pre_build_info.platform_toolset = + variable_value.empty() ? nullopt : Optional{variable_value}; + continue; + } + + if (variable_name == "VCPKG_VISUAL_STUDIO_PATH") + { + pre_build_info.visual_studio_path = + variable_value.empty() ? nullopt : Optional{variable_value}; + continue; + } + + Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown variable name %s", line); + } + + return pre_build_info; + } +} diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp new file mode 100644 index 000000000..ad2a5b227 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -0,0 +1,78 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Autocomplete +{ + std::vector autocomplete_install( + const std::vector>& source_paragraphs, const std::string& start_with) + { + std::vector results; + const auto& istartswith = Strings::case_insensitive_ascii_starts_with; + + for (const auto& source_control_file : source_paragraphs) + { + auto&& sp = *source_control_file->core_paragraph; + + if (istartswith(sp.name, start_with)) + { + results.push_back(sp.name); + } + } + return results; + } + + std::vector autocomplete_remove(std::vector installed_packages, + const std::string& start_with) + { + std::vector results; + const auto& istartswith = Strings::case_insensitive_ascii_starts_with; + + for (const auto& installed_package : installed_packages) + { + auto sp = installed_package->package.displayname(); + + if (istartswith(sp, start_with)) + { + results.push_back(sp); + } + } + return results; + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Strings::format("The argument should be a command line to autocomplete.\n%s", + Help::create_example_string("autocomplete install z")); + + args.check_min_arg_count(1, EXAMPLE); + args.check_max_arg_count(2, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + const std::string requested_command = args.command_arguments.at(0); + const std::string start_with = + args.command_arguments.size() > 1 ? args.command_arguments.at(1) : Strings::EMPTY; + std::vector results; + if (requested_command == "install") + { + auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + auto& source_paragraphs = sources_and_errors.paragraphs; + + results = autocomplete_install(source_paragraphs, start_with); + } + else if (requested_command == "remove") + { + const StatusParagraphs status_db = database_load_check(paths); + std::vector installed_packages = get_installed_ports(status_db); + results = autocomplete_remove(installed_packages, start_with); + } + + System::println(Strings::join(" ", results)); + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.buildexternal.cpp b/toolsrc/src/vcpkg/commands.buildexternal.cpp new file mode 100644 index 000000000..3991beb62 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.buildexternal.cpp @@ -0,0 +1,23 @@ +#include "pch.h" + +#include +#include +#include +#include + +namespace vcpkg::Commands::BuildExternal +{ + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + static const std::string EXAMPLE = + Help::create_example_string(R"(build_external zlib2 C:\path\to\dir\with\controlfile\)"); + args.check_exact_arg_count(2, EXAMPLE); + const FullPackageSpec spec = + Input::check_and_get_full_package_spec(args.command_arguments.at(0), default_triplet, EXAMPLE); + Input::check_triplet(spec.package_spec.triplet(), paths); + const std::unordered_set options = args.check_and_get_optional_command_arguments({}); + + const fs::path port_dir = args.command_arguments.at(1); + Build::Command::perform_and_exit(spec, port_dir, options, paths); + } +} diff --git a/toolsrc/src/vcpkg/commands.cache.cpp b/toolsrc/src/vcpkg/commands.cache.cpp new file mode 100644 index 000000000..77f0a20f6 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.cache.cpp @@ -0,0 +1,69 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Cache +{ + static std::vector read_all_binary_paragraphs(const VcpkgPaths& paths) + { + std::vector output; + for (auto&& path : paths.get_filesystem().get_files_non_recursive(paths.packages)) + { + const Expected> pghs = + Paragraphs::get_single_paragraph(paths.get_filesystem(), path / "CONTROL"); + if (const auto p = pghs.get()) + { + const BinaryParagraph binary_paragraph = BinaryParagraph(*p); + output.push_back(binary_paragraph); + } + } + + return output; + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Strings::format( + "The argument should be a substring to search for, or no argument to display all cached libraries.\n%s", + Help::create_example_string("cache png")); + args.check_max_arg_count(1, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + const std::vector binary_paragraphs = read_all_binary_paragraphs(paths); + if (binary_paragraphs.empty()) + { + System::println("No packages are cached."); + Checks::exit_success(VCPKG_LINE_INFO); + } + + if (args.command_arguments.size() == 0) + { + for (const BinaryParagraph& binary_paragraph : binary_paragraphs) + { + const std::string displayname = binary_paragraph.displayname(); + System::println(displayname); + } + } + else + { + // At this point there is 1 argument + for (const BinaryParagraph& binary_paragraph : binary_paragraphs) + { + const std::string displayname = binary_paragraph.displayname(); + if (Strings::case_insensitive_ascii_find(displayname, args.command_arguments[0]) == displayname.end()) + { + continue; + } + + System::println(displayname); + } + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.ci.cpp b/toolsrc/src/vcpkg/commands.ci.cpp new file mode 100644 index 000000000..1c98d1d83 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.ci.cpp @@ -0,0 +1,62 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::CI +{ + using Build::BuildResult; + using Dependencies::InstallPlanAction; + using Dependencies::InstallPlanType; + + static std::vector load_all_package_specs(Files::Filesystem& fs, + const fs::path& ports_directory, + const Triplet& triplet) + { + auto ports = Paragraphs::load_all_ports(fs, ports_directory); + return Util::fmap(ports, [&](auto&& control_file) -> PackageSpec { + return PackageSpec::from_name_and_triplet(control_file->core_paragraph->name, triplet) + .value_or_exit(VCPKG_LINE_INFO); + }); + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + static const std::string EXAMPLE = Help::create_example_string("ci x64-windows"); + args.check_max_arg_count(1, EXAMPLE); + const Triplet triplet = args.command_arguments.size() == 1 + ? Triplet::from_canonical_name(args.command_arguments.at(0)) + : default_triplet; + Input::check_triplet(triplet, paths); + args.check_and_get_optional_command_arguments({}); + const std::vector specs = load_all_package_specs(paths.get_filesystem(), paths.ports, triplet); + + StatusParagraphs status_db = database_load_check(paths); + const auto& paths_port_file = Dependencies::PathsPortFile(paths); + std::vector install_plan = + Dependencies::create_install_plan(paths_port_file, specs, status_db); + Checks::check_exit(VCPKG_LINE_INFO, !install_plan.empty(), "Install plan cannot be empty"); + + const Build::BuildPackageOptions install_plan_options = {Build::UseHeadVersion::NO, Build::AllowDownloads::YES}; + + const std::vector action_plan = + Util::fmap(install_plan, [](InstallPlanAction& install_action) { + return Dependencies::AnyAction(std::move(install_action)); + }); + + Install::perform_and_exit_ex( + action_plan, install_plan_options, Install::KeepGoing::YES, Install::PrintSummary::YES, paths, status_db); + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.contact.cpp b/toolsrc/src/vcpkg/commands.contact.cpp new file mode 100644 index 000000000..421b8a230 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.contact.cpp @@ -0,0 +1,22 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg::Commands::Contact +{ + const std::string& email() + { + static const std::string S_EMAIL = R"(vcpkg@microsoft.com)"; + return S_EMAIL; + } + + void perform_and_exit(const VcpkgCmdArguments& args) + { + args.check_exact_arg_count(0); + args.check_and_get_optional_command_arguments({}); + + System::println("Send an email to %s with any feedback.", email()); + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.cpp b/toolsrc/src/vcpkg/commands.cpp new file mode 100644 index 000000000..9d969ea28 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.cpp @@ -0,0 +1,56 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands +{ + Span> get_available_commands_type_a() + { + static std::vector> t = { + {"install", &Install::perform_and_exit}, + {"ci", &CI::perform_and_exit}, + {"remove", &Remove::perform_and_exit}, + {"build", &Build::Command::perform_and_exit}, + {"env", &Env::perform_and_exit}, + {"build-external", &BuildExternal::perform_and_exit}, + {"export", &Export::perform_and_exit}, + }; + return t; + } + + Span> get_available_commands_type_b() + { + static std::vector> t = { + {"/?", &Help::perform_and_exit}, + {"help", &Help::perform_and_exit}, + {"search", &Search::perform_and_exit}, + {"list", &List::perform_and_exit}, + {"integrate", &Integrate::perform_and_exit}, + {"owns", &Owns::perform_and_exit}, + {"update", &Update::perform_and_exit}, + {"depend-info", &DependInfo::perform_and_exit}, + {"edit", &Edit::perform_and_exit}, + {"create", &Create::perform_and_exit}, + {"import", &Import::perform_and_exit}, + {"cache", &Cache::perform_and_exit}, + {"portsdiff", &PortsDiff::perform_and_exit}, + {"autocomplete", &Autocomplete::perform_and_exit}}; + return t; + } + + Span> get_available_commands_type_c() + { + static std::vector> t = { + {"version", &Version::perform_and_exit}, + {"contact", &Contact::perform_and_exit}, + {"hash", &Hash::perform_and_exit}, + }; + return t; + } +} diff --git a/toolsrc/src/vcpkg/commands.create.cpp b/toolsrc/src/vcpkg/commands.create.cpp new file mode 100644 index 000000000..d923cf555 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.create.cpp @@ -0,0 +1,39 @@ +#include "pch.h" + +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Create +{ + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Help::create_example_string( + R"###(create zlib2 http://zlib.net/zlib1211.zip "zlib1211-2.zip")###"); + args.check_max_arg_count(3, EXAMPLE); + args.check_min_arg_count(2, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + const std::string port_name = args.command_arguments.at(0); + const std::string url = args.command_arguments.at(1); + + const fs::path& cmake_exe = paths.get_cmake_exe(); + + std::vector cmake_args{{L"CMD", L"CREATE"}, {L"PORT", port_name}, {L"URL", url}}; + + if (args.command_arguments.size() >= 3) + { + const std::string& zip_file_name = args.command_arguments.at(2); + Checks::check_exit(VCPKG_LINE_INFO, + !Files::has_invalid_chars_for_filesystem(zip_file_name), + R"(Filename cannot contain invalid chars %s, but was %s)", + Files::FILESYSTEM_INVALID_CHARACTERS, + zip_file_name); + cmake_args.push_back({L"FILENAME", zip_file_name}); + } + + const std::wstring cmd_launch_cmake = make_cmake_cmd(cmake_exe, paths.ports_cmake, cmake_args); + Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute_clean(cmd_launch_cmake)); + } +} diff --git a/toolsrc/src/vcpkg/commands.dependinfo.cpp b/toolsrc/src/vcpkg/commands.dependinfo.cpp new file mode 100644 index 000000000..89c7e0c7f --- /dev/null +++ b/toolsrc/src/vcpkg/commands.dependinfo.cpp @@ -0,0 +1,56 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::DependInfo +{ + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Help::create_example_string(R"###(depend-info [pat])###"); + args.check_max_arg_count(1, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + std::vector> source_control_files = + Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); + + if (args.command_arguments.size() == 1) + { + const std::string filter = args.command_arguments.at(0); + + Util::erase_remove_if(source_control_files, + [&](const std::unique_ptr& source_control_file) { + + const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; + + if (Strings::case_insensitive_ascii_contains(source_paragraph.name, filter)) + { + return false; + } + + for (const Dependency& dependency : source_paragraph.depends) + { + if (Strings::case_insensitive_ascii_contains(dependency.name(), filter)) + { + return false; + } + } + + return true; + }); + } + + for (auto&& source_control_file : source_control_files) + { + const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; + const auto s = Strings::join(", ", source_paragraph.depends, [](const Dependency& d) { return d.name(); }); + System::println("%s: %s", source_paragraph.name, s); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp new file mode 100644 index 000000000..9497bd76e --- /dev/null +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -0,0 +1,87 @@ +#include "pch.h" + +#include +#include +#include +#include + +namespace vcpkg::Commands::Edit +{ + static std::vector find_from_registry() + { + static const std::array REGKEYS = { + LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{C26E74D1-022E-4238-8B9D-1E7564A36CC9}_is1)", + LR"(SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1287CAD5-7C8D-410D-88B9-0D1EE4A83FF2}_is1)", + LR"(SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F8A2A208-72B3-4D61-95FC-8A65D340689B}_is1)", + }; + + std::vector output; + for (auto&& keypath : REGKEYS) + { + const Optional code_installpath = + System::get_registry_string(HKEY_LOCAL_MACHINE, keypath, L"InstallLocation"); + if (const auto c = code_installpath.get()) + { + const fs::path install_path = fs::path(*c); + output.push_back(install_path / "Code - Insiders.exe"); + output.push_back(install_path / "Code.exe"); + } + } + return output; + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string OPTION_BUILDTREES = "--buildtrees"; + + static const fs::path VS_CODE_INSIDERS = fs::path{"Microsoft VS Code Insiders"} / "Code - Insiders.exe"; + static const fs::path VS_CODE = fs::path{"Microsoft VS Code"} / "Code.exe"; + + auto& fs = paths.get_filesystem(); + + static const std::string EXAMPLE = Help::create_example_string("edit zlib"); + args.check_exact_arg_count(1, EXAMPLE); + const std::unordered_set options = + args.check_and_get_optional_command_arguments({OPTION_BUILDTREES}); + const std::string port_name = args.command_arguments.at(0); + + const fs::path portpath = paths.ports / port_name; + Checks::check_exit(VCPKG_LINE_INFO, fs.is_directory(portpath), R"(Could not find port named "%s")", port_name); + + std::vector candidate_paths; + const std::vector from_path = Files::find_from_PATH(L"EDITOR"); + candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE_INSIDERS); + candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE_INSIDERS); + candidate_paths.push_back(System::get_program_files_platform_bitness() / VS_CODE); + candidate_paths.push_back(System::get_program_files_32_bit() / VS_CODE); + + const std::vector from_registry = find_from_registry(); + candidate_paths.insert(candidate_paths.end(), from_registry.cbegin(), from_registry.cend()); + + auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { return fs.exists(p); }); + if (it == candidate_paths.cend()) + { + System::println(System::Color::error, + "Error: Visual Studio Code was not found and the environment variable EDITOR is not set."); + System::println("The following paths were examined:"); + Files::print_paths(candidate_paths); + System::println("You can also set the environmental variable EDITOR to your editor of choice."); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + const fs::path env_editor = *it; + if (options.find(OPTION_BUILDTREES) != options.cend()) + { + const auto buildtrees_current_dir = paths.buildtrees / port_name; + + const std::wstring cmd_line = + Strings::wformat(LR"("%s" "%s" -n)", env_editor, buildtrees_current_dir.native()); + Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); + } + + const std::wstring cmd_line = Strings::wformat( + LR"("%s" "%s" "%s" -n)", env_editor, portpath.native(), (portpath / "portfile.cmake").native()); + Checks::exit_with_code(VCPKG_LINE_INFO, System::cmd_execute(cmd_line)); + } +} diff --git a/toolsrc/src/vcpkg/commands.env.cpp b/toolsrc/src/vcpkg/commands.env.cpp new file mode 100644 index 000000000..089881588 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.env.cpp @@ -0,0 +1,22 @@ +#include "pch.h" + +#include +#include +#include +#include + +namespace vcpkg::Commands::Env +{ + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + static const std::string EXAMPLE = Help::create_example_string(R"(env --triplet x64-windows)"); + args.check_exact_arg_count(0, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + const auto pre_build_info = Build::PreBuildInfo::from_triplet_file(paths, default_triplet); + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); + System::cmd_execute_clean(Build::make_build_env_cmd(pre_build_info, toolset) + L" && cmd"); + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.exportifw.cpp b/toolsrc/src/vcpkg/commands.exportifw.cpp new file mode 100644 index 000000000..35a3c97a7 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.exportifw.cpp @@ -0,0 +1,482 @@ +#include "pch.h" + +#include +#include +#include +#include + +namespace vcpkg::Export::IFW +{ + using Dependencies::ExportPlanAction; + using Dependencies::ExportPlanType; + using Install::InstallDir; + + static std::string create_release_date() + { + const tm date_time = System::get_current_date_time(); + + // Format is: YYYY-mm-dd + // 10 characters + 1 null terminating character will be written for a total of 11 chars + char mbstr[11]; + const size_t bytes_written = std::strftime(mbstr, sizeof(mbstr), "%Y-%m-%d", &date_time); + Checks::check_exit(VCPKG_LINE_INFO, + bytes_written == 10, + "Expected 10 bytes to be written, but %u were written", + bytes_written); + const std::string date_time_as_string(mbstr); + return date_time_as_string; + } + + fs::path get_packages_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_packages_dir_path.has_value() + ? fs::path(ifw_options.maybe_packages_dir_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-packages"); + } + + fs::path get_repository_dir_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_repository_dir_path.has_value() + ? fs::path(ifw_options.maybe_repository_dir_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-repository"); + } + + fs::path get_config_file_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_config_file_path.has_value() + ? fs::path(ifw_options.maybe_config_file_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-configuration.xml"); + } + + fs::path get_installer_file_path(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) + { + return ifw_options.maybe_installer_file_path.has_value() + ? fs::path(ifw_options.maybe_installer_file_path.value_or_exit(VCPKG_LINE_INFO)) + : paths.root / (export_id + "-ifw-installer.exe"); + } + + fs::path export_real_package(const fs::path& ifw_packages_dir_path, + const ExportPlanAction& action, + Files::Filesystem& fs) + { + std::error_code ec; + + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + // Prepare meta dir + const fs::path package_xml_file_path = + ifw_packages_dir_path / + Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "meta" / + "package.xml"; + const fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + + auto deps = Strings::join( + ",", binary_paragraph.depends, [](const std::string& dep) { return "packages." + dep + ":"; }); + + if (!deps.empty()) deps = "\n " + deps + ""; + + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + %s + %s + %s + packages.%s:,triplets.%s:%s + true + +)###", + action.spec.to_string(), + binary_paragraph.version, + create_release_date(), + action.spec.name(), + action.spec.triplet().canonical_name(), + deps)); + + // Return dir path for export package data + return ifw_packages_dir_path / + Strings::format("packages.%s.%s", action.spec.name(), action.spec.triplet().canonical_name()) / "data" / + "installed"; + } + + void export_unique_packages(const fs::path& raw_exported_dir_path, + std::map unique_packages, + Files::Filesystem& fs) + { + std::error_code ec; + + // packages + + fs::path package_xml_file_path = raw_exported_dir_path / "packages" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + Packages + 1.0.0 + %s + +)###", + create_release_date())); + + for (auto package = unique_packages.begin(); package != unique_packages.end(); ++package) + { + const ExportPlanAction& action = *(package->second); + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + package_xml_file_path = + raw_exported_dir_path / Strings::format("packages.%s", package->first) / "meta" / "package.xml"; + package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + %s + %s + %s + %s + +)###", + action.spec.name(), + binary_paragraph.description, + binary_paragraph.version, + create_release_date())); + } + } + + void export_unique_triplets(const fs::path& raw_exported_dir_path, + std::set unique_triplets, + Files::Filesystem& fs) + { + std::error_code ec; + + // triplets + + fs::path package_xml_file_path = raw_exported_dir_path / "triplets" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + Triplets + 1.0.0 + %s + +)###", + create_release_date())); + + for (const std::string& triplet : unique_triplets) + { + package_xml_file_path = + raw_exported_dir_path / Strings::format("triplets.%s", triplet) / "meta" / "package.xml"; + package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + %s + 1.0.0 + %s + +)###", + triplet, + create_release_date())); + } + } + + void export_integration(const fs::path& raw_exported_dir_path, Files::Filesystem& fs) + { + std::error_code ec; + + // integration + fs::path package_xml_file_path = raw_exported_dir_path / "integration" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + Integration + 1.0.0 + %s + +)###", + create_release_date())); + } + + void export_config(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) + { + std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + const fs::path config_xml_file_path = get_config_file_path(export_id, ifw_options, paths); + + fs::path config_xml_dir_path = config_xml_file_path.parent_path(); + fs.create_directories(config_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for configuration file %s", + config_xml_file_path.generic_string()); + + std::string formatted_repo_url; + std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); + if (!ifw_repo_url.empty()) + { + formatted_repo_url = Strings::format(R"###( + + + %s + + )###", + ifw_repo_url); + } + + fs.write_contents(config_xml_file_path, + Strings::format( + R"###( + + vcpkg + 1.0.0 + vcpkg + @RootDir@/src/vcpkg%s + +)###", + formatted_repo_url)); + } + + void export_maintenance_tool(const fs::path& ifw_packages_dir_path, const VcpkgPaths& paths) + { + System::println("Exporting maintenance tool... "); + + std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + const fs::path& installerbase_exe = paths.get_ifw_installerbase_exe(); + fs::path tempmaintenancetool = ifw_packages_dir_path / "maintenance" / "data" / "tempmaintenancetool.exe"; + fs.create_directories(tempmaintenancetool.parent_path(), ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + tempmaintenancetool.generic_string()); + fs.copy_file(installerbase_exe, tempmaintenancetool, fs::copy_options::overwrite_existing, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not write package file %s", tempmaintenancetool.generic_string()); + + fs::path package_xml_file_path = ifw_packages_dir_path / "maintenance" / "meta" / "package.xml"; + fs::path package_xml_dir_path = package_xml_file_path.parent_path(); + fs.create_directories(package_xml_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not create directory for package file %s", + package_xml_file_path.generic_string()); + fs.write_contents(package_xml_file_path, + Strings::format( + R"###( + + Maintenance Tool + Maintenance Tool + 1.0.0 + %s + + true + true + true + +)###", + create_release_date())); + const fs::path script_source = paths.root / "scripts" / "ifw" / "maintenance.qs"; + const fs::path script_destination = ifw_packages_dir_path / "maintenance" / "meta" / "maintenance.qs"; + fs.copy_file(script_source, script_destination, fs::copy_options::overwrite_existing, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not write package file %s", script_destination.generic_string()); + + System::println("Exporting maintenance tool... done"); + } + + void do_repository(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) + { + const fs::path& repogen_exe = paths.get_ifw_repogen_exe(); + const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); + const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); + + System::println("Generating repository %s...", repository_dir.generic_string()); + + std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + fs.remove_all(repository_dir, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not remove outdated repository directory %s", repository_dir.generic_string()); + + const std::wstring cmd_line = Strings::wformat(LR"("%s" --packages "%s" "%s" > nul)", + repogen_exe.native(), + packages_dir.native(), + repository_dir.native()); + + const int exit_code = System::cmd_execute_clean(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW repository generating failed"); + + System::println(System::Color::success, "Generating repository %s... done.", repository_dir.generic_string()); + } + + void do_installer(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths) + { + const fs::path& binarycreator_exe = paths.get_ifw_binarycreator_exe(); + const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); + const fs::path packages_dir = get_packages_dir_path(export_id, ifw_options, paths); + const fs::path repository_dir = get_repository_dir_path(export_id, ifw_options, paths); + const fs::path installer_file = get_installer_file_path(export_id, ifw_options, paths); + + System::println("Generating installer %s...", installer_file.generic_string()); + + std::wstring cmd_line; + + std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); + if (!ifw_repo_url.empty()) + { + cmd_line = Strings::wformat(LR"("%s" --online-only --config "%s" --repository "%s" "%s" > nul)", + binarycreator_exe.native(), + config_file.native(), + repository_dir.native(), + installer_file.native()); + } + else + { + cmd_line = Strings::wformat(LR"("%s" --config "%s" --packages "%s" "%s" > nul)", + binarycreator_exe.native(), + config_file.native(), + packages_dir.native(), + installer_file.native()); + } + + const int exit_code = System::cmd_execute_clean(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: IFW installer generating failed"); + + System::println(System::Color::success, "Generating installer %s... done.", installer_file.generic_string()); + } + + void do_export(const std::vector& export_plan, + const std::string& export_id, + const Options& ifw_options, + const VcpkgPaths& paths) + { + std::error_code ec; + Files::Filesystem& fs = paths.get_filesystem(); + + // Prepare packages directory + const fs::path ifw_packages_dir_path = get_packages_dir_path(export_id, ifw_options, paths); + + fs.remove_all(ifw_packages_dir_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + !ec, + "Could not remove outdated packages directory %s", + ifw_packages_dir_path.generic_string()); + + fs.create_directory(ifw_packages_dir_path, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create packages directory %s", ifw_packages_dir_path.generic_string()); + + // Export maintenance tool + export_maintenance_tool(ifw_packages_dir_path, paths); + + System::println("Exporting packages %s... ", ifw_packages_dir_path.generic_string()); + + // execute the plan + std::map unique_packages; + std::set unique_triplets; + for (const ExportPlanAction& action : export_plan) + { + if (action.plan_type != ExportPlanType::ALREADY_BUILT) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + const std::string display_name = action.spec.to_string(); + System::println("Exporting package %s... ", display_name); + + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + unique_packages[action.spec.name()] = &action; + unique_triplets.insert(action.spec.triplet().canonical_name()); + + // Export real package and return data dir for installation + fs::path ifw_package_dir_path = export_real_package(ifw_packages_dir_path, action, fs); + + // Copy package data + const InstallDir dirs = InstallDir::from_destination_root(ifw_package_dir_path, + action.spec.triplet().to_string(), + ifw_package_dir_path / "vcpkg" / "info" / + (binary_paragraph.fullstem() + ".list")); + + Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); + System::println("Exporting package %s... done", display_name); + } + + System::println("Exporting packages %s... done", ifw_packages_dir_path.generic_string()); + + const fs::path config_file = get_config_file_path(export_id, ifw_options, paths); + + System::println("Generating configuration %s...", config_file.generic_string()); + + // Unique packages + export_unique_packages(ifw_packages_dir_path, unique_packages, fs); + + // Unique triplets + export_unique_triplets(ifw_packages_dir_path, unique_triplets, fs); + + // Copy files needed for integration + export_integration_files(ifw_packages_dir_path / "integration" / "data", paths); + // Integration + export_integration(ifw_packages_dir_path, fs); + + // Configuration + export_config(export_id, ifw_options, paths); + + System::println("Generating configuration %s... done.", config_file.generic_string()); + + // Do repository (optional) + std::string ifw_repo_url = ifw_options.maybe_repository_url.value_or(""); + if (!ifw_repo_url.empty()) + { + do_repository(export_id, ifw_options, paths); + } + + // Do installer + do_installer(export_id, ifw_options, paths); + } +} diff --git a/toolsrc/src/vcpkg/commands.hash.cpp b/toolsrc/src/vcpkg/commands.hash.cpp new file mode 100644 index 000000000..394a02e23 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.hash.cpp @@ -0,0 +1,55 @@ +#include "pch.h" + +#include +#include +#include +#include + +namespace vcpkg::Commands::Hash +{ + static void do_file_hash(fs::path const& path, std::wstring const& hash_type) + { + const auto cmd_line = Strings::wformat(LR"(CertUtil.exe -hashfile "%s" %s)", path.c_str(), hash_type); + const auto ec_data = System::cmd_execute_and_capture_output(cmd_line); + Checks::check_exit( + VCPKG_LINE_INFO, ec_data.exit_code == 0, "Running command:\n %s\n failed", Strings::to_utf8(cmd_line)); + + std::string const& output = ec_data.output; + + const auto start = output.find_first_of("\r\n"); + Checks::check_exit(VCPKG_LINE_INFO, + start != std::string::npos, + "Unexpected output format from command: %s", + Strings::to_utf8(cmd_line)); + + const auto end = output.find_first_of("\r\n", start + 1); + Checks::check_exit(VCPKG_LINE_INFO, + end != std::string::npos, + "Unexpected output format from command: %s", + Strings::to_utf8(cmd_line)); + + auto hash = output.substr(start, end - start); + Util::erase_remove_if(hash, isspace); + System::println(hash); + } + + void perform_and_exit(const VcpkgCmdArguments& args) + { + static const std::string EXAMPLE = Strings::format("The argument should be a file path\n%s", + Help::create_example_string("hash boost_1_62_0.tar.bz2")); + args.check_min_arg_count(1, EXAMPLE); + args.check_max_arg_count(2, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + if (args.command_arguments.size() == 1) + { + do_file_hash(args.command_arguments[0], L"SHA512"); + } + if (args.command_arguments.size() == 2) + { + do_file_hash(args.command_arguments[0], Strings::to_utf16(args.command_arguments[1])); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.import.cpp b/toolsrc/src/vcpkg/commands.import.cpp new file mode 100644 index 000000000..119aee022 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.import.cpp @@ -0,0 +1,120 @@ +#include "pch.h" + +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Import +{ + struct Binaries + { + std::vector dlls; + std::vector libs; + }; + + static void check_is_directory(const LineInfo& line_info, const Files::Filesystem& fs, const fs::path& dirpath) + { + Checks::check_exit(line_info, fs.is_directory(dirpath), "The path %s is not a directory", dirpath.string()); + } + + static Binaries find_binaries_in_dir(const Files::Filesystem& fs, const fs::path& path) + { + auto files = fs.get_files_recursive(path); + + check_is_directory(VCPKG_LINE_INFO, fs, path); + + Binaries binaries; + for (auto&& file : files) + { + if (fs.is_directory(file)) continue; + const auto ext = file.extension(); + if (ext == ".dll") + binaries.dlls.push_back(std::move(file)); + else if (ext == ".lib") + binaries.libs.push_back(std::move(file)); + } + return binaries; + } + + static void copy_files_into_directory(Files::Filesystem& fs, + const std::vector& files, + const fs::path& destination_folder) + { + std::error_code ec; + fs.create_directory(destination_folder, ec); + + for (auto const& src_path : files) + { + const fs::path dest_path = destination_folder / src_path.filename(); + fs.copy(src_path, dest_path, fs::copy_options::overwrite_existing); + } + } + + static void place_library_files_in(Files::Filesystem& fs, + const fs::path& include_directory, + const fs::path& project_directory, + const fs::path& destination_path) + { + check_is_directory(VCPKG_LINE_INFO, fs, include_directory); + check_is_directory(VCPKG_LINE_INFO, fs, project_directory); + check_is_directory(VCPKG_LINE_INFO, fs, destination_path); + const Binaries debug_binaries = find_binaries_in_dir(fs, project_directory / "Debug"); + const Binaries release_binaries = find_binaries_in_dir(fs, project_directory / "Release"); + + const fs::path destination_include_directory = destination_path / "include"; + fs.copy(include_directory, + destination_include_directory, + fs::copy_options::recursive | fs::copy_options::overwrite_existing); + + copy_files_into_directory(fs, release_binaries.dlls, destination_path / "bin"); + copy_files_into_directory(fs, release_binaries.libs, destination_path / "lib"); + + std::error_code ec; + fs.create_directory(destination_path / "debug", ec); + copy_files_into_directory(fs, debug_binaries.dlls, destination_path / "debug" / "bin"); + copy_files_into_directory(fs, debug_binaries.libs, destination_path / "debug" / "lib"); + } + + static void do_import(const VcpkgPaths& paths, + const fs::path& include_directory, + const fs::path& project_directory, + const BinaryParagraph& control_file_data) + { + auto& fs = paths.get_filesystem(); + const fs::path library_destination_path = paths.package_dir(control_file_data.spec); + std::error_code ec; + fs.create_directory(library_destination_path, ec); + place_library_files_in(paths.get_filesystem(), include_directory, project_directory, library_destination_path); + + const fs::path control_file_path = library_destination_path / "CONTROL"; + fs.write_contents(control_file_path, Strings::serialize(control_file_data)); + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Help::create_example_string( + R"(import C:\path\to\CONTROLfile C:\path\to\includedir C:\path\to\projectdir)"); + args.check_exact_arg_count(3, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + const fs::path control_file_path(args.command_arguments[0]); + const fs::path include_directory(args.command_arguments[1]); + const fs::path project_directory(args.command_arguments[2]); + + const Expected> pghs = + Paragraphs::get_single_paragraph(paths.get_filesystem(), control_file_path); + Checks::check_exit(VCPKG_LINE_INFO, + pghs.get() != nullptr, + "Invalid control file %s for package", + control_file_path.generic_string()); + + StatusParagraph spgh; + spgh.package = BinaryParagraph(*pghs.get()); + auto& control_file_data = spgh.package; + + do_import(paths, include_directory, project_directory, control_file_data); + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp new file mode 100644 index 000000000..7f6639222 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -0,0 +1,342 @@ +#include "pch.h" + +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Integrate +{ + static const std::array OLD_SYSTEM_TARGET_FILES = { + System::get_program_files_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.nuget.targets", + System::get_program_files_32_bit() / "MSBuild/14.0/Microsoft.Common.Targets/ImportBefore/vcpkg.system.targets"}; + static const fs::path SYSTEM_WIDE_TARGETS_FILE = + System::get_program_files_32_bit() / "MSBuild/Microsoft.Cpp/v4.0/V140/ImportBefore/Default/vcpkg.system.props"; + + static std::string create_appdata_targets_shortcut(const std::string& target_path) noexcept + { + return Strings::format(R"###( + + + +)###", + target_path, + target_path); + } + + static std::string create_system_targets_shortcut() noexcept + { + return R"###( + + + + $(LOCALAPPDATA)\vcpkg\vcpkg.user + + + +)###"; + } + + static std::string create_nuget_targets_file_contents(const fs::path& msbuild_vcpkg_targets_file) noexcept + { + const std::string as_string = msbuild_vcpkg_targets_file.string(); + + return Strings::format(R"###( + + + + + + +)###", + as_string, + as_string); + } + + static std::string create_nuget_props_file_contents() noexcept + { + return R"###( + + + true + + +)###"; + } + + static std::string get_nuget_id(const fs::path& vcpkg_root_dir) + { + std::string dir_id = vcpkg_root_dir.generic_string(); + std::replace(dir_id.begin(), dir_id.end(), '/', '.'); + dir_id.erase(1, 1); // Erasing the ":" + + // NuGet id cannot have invalid characters. We will only use alphanumeric and dot. + Util::erase_remove_if(dir_id, [](char c) { return !isalnum(c) && (c != '.'); }); + + const std::string nuget_id = "vcpkg." + dir_id; + return nuget_id; + } + + static std::string create_nuspec_file_contents(const fs::path& vcpkg_root_dir, + const std::string& nuget_id, + const std::string& nupkg_version) + { + static constexpr auto CONTENT_TEMPLATE = R"( + + + @NUGET_ID@ + @VERSION@ + vcpkg + + This package imports all libraries currently installed in @VCPKG_DIR@. This package does not contain any libraries and instead refers to the folder directly (like a symlink). + + + + + + + +)"; + + std::string content = std::regex_replace(CONTENT_TEMPLATE, std::regex("@NUGET_ID@"), nuget_id); + content = std::regex_replace(content, std::regex("@VCPKG_DIR@"), vcpkg_root_dir.string()); + content = std::regex_replace(content, std::regex("@VERSION@"), nupkg_version); + return content; + } + + enum class ElevationPromptChoice + { + YES, + NO + }; + + static ElevationPromptChoice elevated_cmd_execute(const std::string& param) + { + SHELLEXECUTEINFOW sh_ex_info = {0}; + sh_ex_info.cbSize = sizeof(sh_ex_info); + sh_ex_info.fMask = SEE_MASK_NOCLOSEPROCESS; + sh_ex_info.hwnd = nullptr; + sh_ex_info.lpVerb = L"runas"; + sh_ex_info.lpFile = L"cmd"; // Application to start + + auto wparam = Strings::to_utf16(param); + sh_ex_info.lpParameters = wparam.c_str(); // Additional parameters + sh_ex_info.lpDirectory = nullptr; + sh_ex_info.nShow = SW_HIDE; + sh_ex_info.hInstApp = nullptr; + + if (!ShellExecuteExW(&sh_ex_info)) + { + return ElevationPromptChoice::NO; + } + if (sh_ex_info.hProcess == nullptr) + { + return ElevationPromptChoice::NO; + } + WaitForSingleObject(sh_ex_info.hProcess, INFINITE); + CloseHandle(sh_ex_info.hProcess); + return ElevationPromptChoice::YES; + } + + static fs::path get_appdata_targets_path() + { + static const fs::path LOCAL_APP_DATA = + fs::path(System::get_environment_variable(L"LOCALAPPDATA").value_or_exit(VCPKG_LINE_INFO)); + return LOCAL_APP_DATA / "vcpkg" / "vcpkg.user.targets"; + } + + static void integrate_install(const VcpkgPaths& paths) + { + auto& fs = paths.get_filesystem(); + + // TODO: This block of code should eventually be removed + for (auto&& old_system_wide_targets_file : OLD_SYSTEM_TARGET_FILES) + { + if (fs.exists(old_system_wide_targets_file)) + { + const std::string param = + Strings::format(R"(/c DEL "%s" /Q > nul)", old_system_wide_targets_file.string()); + const ElevationPromptChoice user_choice = elevated_cmd_execute(param); + switch (user_choice) + { + case ElevationPromptChoice::YES: break; + case ElevationPromptChoice::NO: + System::println(System::Color::warning, "Warning: Previous integration file was not removed"); + Checks::exit_fail(VCPKG_LINE_INFO); + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + } + + std::error_code ec; + const fs::path tmp_dir = paths.buildsystems / "tmp"; + fs.create_directory(paths.buildsystems, ec); + fs.create_directory(tmp_dir, ec); + + bool should_install_system = true; + const Expected system_wide_file_contents = fs.read_contents(SYSTEM_WIDE_TARGETS_FILE); + static const std::regex RE(R"###()###"); + if (const auto contents_data = system_wide_file_contents.get()) + { + std::match_results match; + const auto found = std::regex_search(*contents_data, match, RE); + if (found) + { + const int ver = atoi(match[1].str().c_str()); + if (ver >= 1) should_install_system = false; + } + } + + if (should_install_system) + { + const fs::path sys_src_path = tmp_dir / "vcpkg.system.targets"; + fs.write_contents(sys_src_path, create_system_targets_shortcut()); + + const std::string param = Strings::format(R"(/c mkdir "%s" & copy "%s" "%s" /Y > nul)", + SYSTEM_WIDE_TARGETS_FILE.parent_path().string(), + sys_src_path.string(), + SYSTEM_WIDE_TARGETS_FILE.string()); + const ElevationPromptChoice user_choice = elevated_cmd_execute(param); + switch (user_choice) + { + case ElevationPromptChoice::YES: break; + case ElevationPromptChoice::NO: + System::println(System::Color::warning, "Warning: integration was not applied"); + Checks::exit_fail(VCPKG_LINE_INFO); + default: Checks::unreachable(VCPKG_LINE_INFO); + } + + Checks::check_exit(VCPKG_LINE_INFO, + fs.exists(SYSTEM_WIDE_TARGETS_FILE), + "Error: failed to copy targets file to %s", + SYSTEM_WIDE_TARGETS_FILE.string()); + } + + const fs::path appdata_src_path = tmp_dir / "vcpkg.user.targets"; + fs.write_contents(appdata_src_path, + create_appdata_targets_shortcut(paths.buildsystems_msbuild_targets.string())); + auto appdata_dst_path = get_appdata_targets_path(); + + const auto rc = fs.copy_file(appdata_src_path, appdata_dst_path, fs::copy_options::overwrite_existing, ec); + + if (!rc || ec) + { + System::println(System::Color::error, + "Error: Failed to copy file: %s -> %s", + appdata_src_path.string(), + appdata_dst_path.string()); + Checks::exit_fail(VCPKG_LINE_INFO); + } + System::println(System::Color::success, "Applied user-wide integration for this vcpkg root."); + const fs::path cmake_toolchain = paths.buildsystems / "vcpkg.cmake"; + System::println("\n" + "All MSBuild C++ projects can now #include any installed libraries.\n" + "Linking will be handled automatically.\n" + "Installing new libraries will make them instantly available.\n" + "\n" + "CMake projects should use -DCMAKE_TOOLCHAIN_FILE=%s", + cmake_toolchain.generic_string()); + + Checks::exit_success(VCPKG_LINE_INFO); + } + + static void integrate_remove(Files::Filesystem& fs) + { + const fs::path path = get_appdata_targets_path(); + + std::error_code ec; + const bool was_deleted = fs.remove(path, ec); + + Checks::check_exit(VCPKG_LINE_INFO, !ec, "Error: Unable to remove user-wide integration: %d", ec.message()); + + if (was_deleted) + { + System::println(System::Color::success, "User-wide integration was removed"); + } + else + { + System::println(System::Color::success, "User-wide integration is not installed"); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } + + static void integrate_project(const VcpkgPaths& paths) + { + auto& fs = paths.get_filesystem(); + + const fs::path& nuget_exe = paths.get_nuget_exe(); + + const fs::path& buildsystems_dir = paths.buildsystems; + const fs::path tmp_dir = buildsystems_dir / "tmp"; + std::error_code ec; + fs.create_directory(buildsystems_dir, ec); + fs.create_directory(tmp_dir, ec); + + const fs::path targets_file_path = tmp_dir / "vcpkg.nuget.targets"; + const fs::path props_file_path = tmp_dir / "vcpkg.nuget.props"; + const fs::path nuspec_file_path = tmp_dir / "vcpkg.nuget.nuspec"; + const std::string nuget_id = get_nuget_id(paths.root); + const std::string nupkg_version = "1.0.0"; + + fs.write_contents(targets_file_path, create_nuget_targets_file_contents(paths.buildsystems_msbuild_targets)); + fs.write_contents(props_file_path, create_nuget_props_file_contents()); + fs.write_contents(nuspec_file_path, create_nuspec_file_contents(paths.root, nuget_id, nupkg_version)); + + // Using all forward slashes for the command line + const std::wstring cmd_line = Strings::wformat(LR"("%s" pack -OutputDirectory "%s" "%s" > nul)", + nuget_exe.native(), + buildsystems_dir.native(), + nuspec_file_path.native()); + + const int exit_code = System::cmd_execute_clean(cmd_line); + + const fs::path nuget_package = buildsystems_dir / Strings::format("%s.%s.nupkg", nuget_id, nupkg_version); + Checks::check_exit( + VCPKG_LINE_INFO, exit_code == 0 && fs.exists(nuget_package), "Error: NuGet package creation failed"); + System::println(System::Color::success, "Created nupkg: %s", nuget_package.string()); + + auto source_path = buildsystems_dir.u8string(); + source_path = std::regex_replace(source_path, std::regex("`"), "``"); + + System::println(R"( +With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: + Install-Package %s -Source "%s" +)", + nuget_id, + source_path); + + Checks::exit_success(VCPKG_LINE_INFO); + } + + const char* const INTEGRATE_COMMAND_HELPSTRING = + " vcpkg integrate install Make installed packages available user-wide. Requires admin privileges on " + "first use\n" + " vcpkg integrate remove Remove user-wide integration\n" + " vcpkg integrate project Generate a referencing nuget package for individual VS project use\n"; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Strings::format("Commands:\n" + "%s", + INTEGRATE_COMMAND_HELPSTRING); + args.check_exact_arg_count(1, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + if (args.command_arguments[0] == "install") + { + return integrate_install(paths); + } + if (args.command_arguments[0] == "remove") + { + return integrate_remove(paths.get_filesystem()); + } + if (args.command_arguments[0] == "project") + { + return integrate_project(paths); + } + + Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown parameter %s for integrate", args.command_arguments[0]); + } +} diff --git a/toolsrc/src/vcpkg/commands.list.cpp b/toolsrc/src/vcpkg/commands.list.cpp new file mode 100644 index 000000000..d0e8e00b4 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.list.cpp @@ -0,0 +1,75 @@ +#include "pch.h" + +#include +#include +#include +#include + +namespace vcpkg::Commands::List +{ + static const std::string OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually + + static void do_print(const StatusParagraph& pgh, bool full_desc) + { + if (full_desc) + { + System::println("%-30s %-16s %s", pgh.package.displayname(), pgh.package.version, pgh.package.description); + } + else + { + System::println("%-30s %-16s %s", + vcpkg::shorten_text(pgh.package.displayname(), 30), + vcpkg::shorten_text(pgh.package.version, 16), + vcpkg::shorten_text(pgh.package.description, 71)); + } + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Strings::format( + "The argument should be a substring to search for, or no argument to display all installed libraries.\n%s", + Help::create_example_string("list png")); + args.check_max_arg_count(1, EXAMPLE); + const std::unordered_set options = + args.check_and_get_optional_command_arguments({OPTION_FULLDESC}); + + const StatusParagraphs status_paragraphs = database_load_check(paths); + std::vector installed_packages = get_installed_ports(status_paragraphs); + + if (installed_packages.empty()) + { + System::println("No packages are installed. Did you mean `search`?"); + Checks::exit_success(VCPKG_LINE_INFO); + } + + std::sort(installed_packages.begin(), + installed_packages.end(), + [](const StatusParagraph* lhs, const StatusParagraph* rhs) -> bool { + return lhs->package.displayname() < rhs->package.displayname(); + }); + + if (args.command_arguments.size() == 0) + { + for (const StatusParagraph* status_paragraph : installed_packages) + { + do_print(*status_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + } + } + else + { + // At this point there is 1 argument + for (const StatusParagraph* status_paragraph : installed_packages) + { + const std::string displayname = status_paragraph->package.displayname(); + if (Strings::case_insensitive_ascii_find(displayname, args.command_arguments[0]) == displayname.end()) + { + continue; + } + + do_print(*status_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + } + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.owns.cpp b/toolsrc/src/vcpkg/commands.owns.cpp new file mode 100644 index 000000000..69079e829 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.owns.cpp @@ -0,0 +1,38 @@ +#include "pch.h" + +#include +#include +#include +#include + +namespace vcpkg::Commands::Owns +{ + static void search_file(const VcpkgPaths& paths, const std::string& file_substr, const StatusParagraphs& status_db) + { + const std::vector installed_files = get_installed_files(paths, status_db); + for (const StatusParagraphAndAssociatedFiles& pgh_and_file : installed_files) + { + const StatusParagraph& pgh = pgh_and_file.pgh; + + for (const std::string& file : pgh_and_file.files) + { + if (file.find(file_substr) != std::string::npos) + { + System::println("%s: %s", pgh.package.displayname(), file); + } + } + } + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Strings::format("The argument should be a pattern to search for. %s", + Help::create_example_string("owns zlib.dll")); + args.check_exact_arg_count(1, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + StatusParagraphs status_db = database_load_check(paths); + search_file(paths, args.command_arguments[0], status_db); + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.portsdiff.cpp b/toolsrc/src/vcpkg/commands.portsdiff.cpp new file mode 100644 index 000000000..b70ad2b80 --- /dev/null +++ b/toolsrc/src/vcpkg/commands.portsdiff.cpp @@ -0,0 +1,182 @@ +#include "pch.h" + +#include +#include +#include + +#include +#include +#include + +namespace vcpkg::Commands::PortsDiff +{ + struct UpdatedPort + { + static bool compare_by_name(const UpdatedPort& left, const UpdatedPort& right) + { + return left.port < right.port; + } + + std::string port; + VersionDiff version_diff; + }; + + template + struct SetElementPresence + { + static SetElementPresence create(std::vector left, std::vector right) + { + // TODO: This can be done with one pass instead of three passes + SetElementPresence output; + std::set_difference( + left.cbegin(), left.cend(), right.cbegin(), right.cend(), std::back_inserter(output.only_left)); + std::set_intersection( + left.cbegin(), left.cend(), right.cbegin(), right.cend(), std::back_inserter(output.both)); + std::set_difference( + right.cbegin(), right.cend(), left.cbegin(), left.cend(), std::back_inserter(output.only_right)); + + return output; + } + + std::vector only_left; + std::vector both; + std::vector only_right; + }; + + static std::vector find_updated_ports( + const std::vector& ports, + const std::map& previous_names_and_versions, + const std::map& current_names_and_versions) + { + std::vector output; + for (const std::string& name : ports) + { + const VersionT& previous_version = previous_names_and_versions.at(name); + const VersionT& current_version = current_names_and_versions.at(name); + if (previous_version == current_version) + { + continue; + } + + output.push_back({name, VersionDiff(previous_version, current_version)}); + } + + return output; + } + + static void do_print_name_and_version(const std::vector& ports_to_print, + const std::map& names_and_versions) + { + for (const std::string& name : ports_to_print) + { + const VersionT& version = names_and_versions.at(name); + System::println(" - %-14s %-16s", name, version); + } + } + + static std::map read_ports_from_commit(const VcpkgPaths& paths, + const std::wstring& git_commit_id) + { + std::error_code ec; + auto& fs = paths.get_filesystem(); + const fs::path& git_exe = paths.get_git_exe(); + const fs::path dot_git_dir = paths.root / ".git"; + const std::wstring ports_dir_name_as_string = paths.ports.filename().native(); + const fs::path temp_checkout_path = + paths.root / Strings::wformat(L"%s-%s", ports_dir_name_as_string, git_commit_id); + fs.create_directory(temp_checkout_path, ec); + const std::wstring checkout_this_dir = + Strings::wformat(LR"(.\%s)", ports_dir_name_as_string); // Must be relative to the root of the repository + + const std::wstring cmd = + Strings::wformat(LR"("%s" --git-dir="%s" --work-tree="%s" checkout %s -f -q -- %s %s & "%s" reset >NUL)", + git_exe.native(), + dot_git_dir.native(), + temp_checkout_path.native(), + git_commit_id, + checkout_this_dir, + L".vcpkg-root", + git_exe.native()); + System::cmd_execute_clean(cmd); + const std::map names_and_versions = Paragraphs::load_all_port_names_and_versions( + paths.get_filesystem(), temp_checkout_path / ports_dir_name_as_string); + fs.remove_all(temp_checkout_path, ec); + return names_and_versions; + } + + static void check_commit_exists(const fs::path& git_exe, const std::wstring& git_commit_id) + { + static const std::string VALID_COMMIT_OUTPUT = "commit\n"; + + const std::wstring cmd = Strings::wformat(LR"("%s" cat-file -t %s)", git_exe.native(), git_commit_id); + const System::ExitCodeAndOutput output = System::cmd_execute_and_capture_output(cmd); + Checks::check_exit(VCPKG_LINE_INFO, + output.output == VALID_COMMIT_OUTPUT, + "Invalid commit id %s", + Strings::to_utf8(git_commit_id)); + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Strings::format("The argument should be a branch/tag/hash to checkout.\n%s", + Help::create_example_string("portsdiff mybranchname")); + args.check_min_arg_count(1, EXAMPLE); + args.check_max_arg_count(2, EXAMPLE); + args.check_and_get_optional_command_arguments({}); + + const fs::path& git_exe = paths.get_git_exe(); + + const std::wstring git_commit_id_for_previous_snapshot = Strings::to_utf16(args.command_arguments.at(0)); + const std::wstring git_commit_id_for_current_snapshot = + args.command_arguments.size() < 2 ? L"HEAD" : Strings::to_utf16(args.command_arguments.at(1)); + + check_commit_exists(git_exe, git_commit_id_for_current_snapshot); + check_commit_exists(git_exe, git_commit_id_for_previous_snapshot); + + const std::map current_names_and_versions = + read_ports_from_commit(paths, git_commit_id_for_current_snapshot); + const std::map previous_names_and_versions = + read_ports_from_commit(paths, git_commit_id_for_previous_snapshot); + + // Already sorted, so set_difference can work on std::vector too + const std::vector current_ports = Util::extract_keys(current_names_and_versions); + const std::vector previous_ports = Util::extract_keys(previous_names_and_versions); + + const SetElementPresence setp = + SetElementPresence::create(current_ports, previous_ports); + + const std::vector& added_ports = setp.only_left; + if (!added_ports.empty()) + { + System::println("\nThe following %d ports were added:", added_ports.size()); + do_print_name_and_version(added_ports, current_names_and_versions); + } + + const std::vector& removed_ports = setp.only_right; + if (!removed_ports.empty()) + { + System::println("\nThe following %d ports were removed:", removed_ports.size()); + do_print_name_and_version(removed_ports, previous_names_and_versions); + } + + const std::vector& common_ports = setp.both; + const std::vector updated_ports = + find_updated_ports(common_ports, previous_names_and_versions, current_names_and_versions); + + if (!updated_ports.empty()) + { + System::println("\nThe following %d ports were updated:", updated_ports.size()); + for (const UpdatedPort& p : updated_ports) + { + System::println(" - %-14s %-16s", p.port, p.version_diff.to_string()); + } + } + + if (added_ports.empty() && removed_ports.empty() && updated_ports.empty()) + { + System::println("There were no changes in the ports between the two commits."); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.search.cpp b/toolsrc/src/vcpkg/commands.search.cpp new file mode 100644 index 000000000..3ba8707de --- /dev/null +++ b/toolsrc/src/vcpkg/commands.search.cpp @@ -0,0 +1,146 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Commands::Search +{ + static const std::string OPTION_GRAPH = "--graph"; // TODO: This should find a better home, eventually + static const std::string OPTION_FULLDESC = "--x-full-desc"; // TODO: This should find a better home, eventually + + static std::string replace_dashes_with_underscore(const std::string& input) + { + std::string output = input; + std::replace(output.begin(), output.end(), '-', '_'); + return output; + } + + static std::string create_graph_as_string( + const std::vector>& source_control_files) + { + int empty_node_count = 0; + + std::string s; + s.append("digraph G{ rankdir=LR; edge [minlen=3]; overlap=false;"); + + for (const auto& source_control_file : source_control_files) + { + const SourceParagraph& source_paragraph = *source_control_file->core_paragraph; + if (source_paragraph.depends.empty()) + { + empty_node_count++; + continue; + } + + const std::string name = replace_dashes_with_underscore(source_paragraph.name); + s.append(Strings::format("%s;", name)); + for (const Dependency& d : source_paragraph.depends) + { + const std::string dependency_name = replace_dashes_with_underscore(d.name()); + s.append(Strings::format("%s -> %s;", name, dependency_name)); + } + } + + s.append(Strings::format("empty [label=\"%d singletons...\"]; }", empty_node_count)); + return s; + } + static void do_print(const SourceParagraph& source_paragraph, bool full_desc) + { + if (full_desc) + { + System::println( + "%-20s %-16s %s", source_paragraph.name, source_paragraph.version, source_paragraph.description); + } + else + { + System::println("%-20s %-16s %s", + vcpkg::shorten_text(source_paragraph.name, 20), + vcpkg::shorten_text(source_paragraph.version, 16), + vcpkg::shorten_text(source_paragraph.description, 81)); + } + } + + static void do_print(const std::string& name, const FeatureParagraph& feature_paragraph, bool full_desc) + { + if (full_desc) + { + System::println("%-37s %s", name + "[" + feature_paragraph.name + "]", feature_paragraph.description); + } + else + { + System::println("%-37s %s", + vcpkg::shorten_text(name + "[" + feature_paragraph.name + "]", 37), + vcpkg::shorten_text(feature_paragraph.description, 81)); + } + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + static const std::string EXAMPLE = Strings::format( + "The argument should be a substring to search for, or no argument to display all libraries.\n%s", + Help::create_example_string("search png")); + args.check_max_arg_count(1, EXAMPLE); + const std::unordered_set options = + args.check_and_get_optional_command_arguments({OPTION_GRAPH, OPTION_FULLDESC}); + + auto source_paragraphs = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); + + if (options.find(OPTION_GRAPH) != options.cend()) + { + const std::string graph_as_string = create_graph_as_string(source_paragraphs); + System::println(graph_as_string); + Checks::exit_success(VCPKG_LINE_INFO); + } + + if (args.command_arguments.empty()) + { + for (const auto& source_control_file : source_paragraphs) + { + do_print(*source_control_file->core_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + for (auto&& feature_paragraph : source_control_file->feature_paragraphs) + { + do_print(source_control_file->core_paragraph->name, + *feature_paragraph, + options.find(OPTION_FULLDESC) != options.cend()); + } + } + } + else + { + const auto& icontains = Strings::case_insensitive_ascii_contains; + + // At this point there is 1 argument + auto&& args_zero = args.command_arguments[0]; + for (const auto& source_control_file : source_paragraphs) + { + auto&& sp = *source_control_file->core_paragraph; + + bool contains_name = icontains(sp.name, args_zero); + if (contains_name || icontains(sp.description, args_zero)) + { + do_print(sp, options.find(OPTION_FULLDESC) != options.cend()); + } + + for (auto&& feature_paragraph : source_control_file->feature_paragraphs) + { + if (contains_name || icontains(feature_paragraph->name, args_zero) || + icontains(feature_paragraph->description, args_zero)) + { + do_print(sp.name, *feature_paragraph, options.find(OPTION_FULLDESC) != options.cend()); + } + } + } + } + + System::println( + "\nIf your library is not listed, please open an issue at and/or consider making a pull request:\n" + " https://github.com/Microsoft/vcpkg/issues"); + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/commands.version.cpp b/toolsrc/src/vcpkg/commands.version.cpp new file mode 100644 index 000000000..c6cc82d1f --- /dev/null +++ b/toolsrc/src/vcpkg/commands.version.cpp @@ -0,0 +1,67 @@ +#include "pch.h" + +#include +#include +#include + +#define STRINGIFY(...) #__VA_ARGS__ +#define MACRO_TO_STRING(X) STRINGIFY(X) + +#define VCPKG_VERSION_AS_STRING MACRO_TO_STRING(VCPKG_VERSION) + +namespace vcpkg::Commands::Version +{ + const std::string& version() + { + static const std::string S_VERSION = +#include "../VERSION.txt" + + +std::string(VCPKG_VERSION_AS_STRING) +#ifndef NDEBUG + + std::string("-debug") +#endif + + std::string(Metrics::get_compiled_metrics_enabled() ? Strings::EMPTY : "-external"); + return S_VERSION; + } + + void warn_if_vcpkg_version_mismatch(const VcpkgPaths& paths) + { + auto version_file = paths.get_filesystem().read_contents(paths.root / "toolsrc" / "VERSION.txt"); + if (const auto version_contents = version_file.get()) + { + int maj1, min1, rev1; + const auto num1 = sscanf_s(version_contents->c_str(), "\"%d.%d.%d\"", &maj1, &min1, &rev1); + + int maj2, min2, rev2; + const auto num2 = sscanf_s(Version::version().c_str(), "%d.%d.%d-", &maj2, &min2, &rev2); + + if (num1 == 3 && num2 == 3) + { + if (maj1 != maj2 || min1 != min2 || rev1 != rev2) + { + System::println(System::Color::warning, + "Warning: Different source is available for vcpkg (%d.%d.%d -> %d.%d.%d). Use " + ".\\bootstrap-vcpkg.bat to update.", + maj2, + min2, + rev2, + maj1, + min1, + rev1); + } + } + } + } + + void perform_and_exit(const VcpkgCmdArguments& args) + { + args.check_exact_arg_count(0); + args.check_and_get_optional_command_arguments({}); + + System::println("Vcpkg package management program version %s\n" + "\n" + "See LICENSE.txt for license information.", + version()); + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/dependencies.cpp b/toolsrc/src/vcpkg/dependencies.cpp new file mode 100644 index 000000000..da8f1e178 --- /dev/null +++ b/toolsrc/src/vcpkg/dependencies.cpp @@ -0,0 +1,669 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Dependencies +{ + struct FeatureNodeEdges + { + std::vector remove_edges; + std::vector build_edges; + bool plus = false; + }; + + struct Cluster : Util::MoveOnlyBase + { + std::vector status_paragraphs; + Optional source_control_file; + PackageSpec spec; + std::unordered_map edges; + std::unordered_set to_install_features; + std::unordered_set original_features; + bool will_remove = false; + bool transient_uninstalled = true; + RequestType request_type = RequestType::AUTO_SELECTED; + }; + + struct ClusterPtr + { + Cluster* ptr; + + Cluster* operator->() const { return ptr; } + }; + + bool operator==(const ClusterPtr& l, const ClusterPtr& r) { return l.ptr == r.ptr; } +} + +template<> +struct std::hash +{ + size_t operator()(const vcpkg::Dependencies::ClusterPtr& value) const + { + return std::hash()(value.ptr->spec); + } +}; + +namespace vcpkg::Dependencies +{ + struct GraphPlan + { + Graphs::Graph remove_graph; + Graphs::Graph install_graph; + }; + + struct ClusterGraph : Util::MoveOnlyBase + { + explicit ClusterGraph(std::unordered_map&& ports) + : m_ports(std::move(ports)) + { + } + + Cluster& get(const PackageSpec& spec) + { + auto it = m_graph.find(spec); + if (it == m_graph.end()) + { + // Load on-demand from m_ports + auto it_ports = m_ports.find(spec.name()); + if (it_ports != m_ports.end()) + { + auto& clust = m_graph[spec]; + clust.spec = spec; + cluster_from_scf(*it_ports->second, clust); + return clust; + } + return m_graph[spec]; + } + return it->second; + } + + private: + void cluster_from_scf(const SourceControlFile& scf, Cluster& out_cluster) const + { + FeatureNodeEdges core_dependencies; + core_dependencies.build_edges = + filter_dependencies_to_specs(scf.core_paragraph->depends, out_cluster.spec.triplet()); + out_cluster.edges.emplace("core", std::move(core_dependencies)); + + for (const auto& feature : scf.feature_paragraphs) + { + FeatureNodeEdges added_edges; + added_edges.build_edges = filter_dependencies_to_specs(feature->depends, out_cluster.spec.triplet()); + out_cluster.edges.emplace(feature->name, std::move(added_edges)); + } + out_cluster.source_control_file = &scf; + } + + std::unordered_map m_graph; + std::unordered_map m_ports; + }; + + std::vector AnyParagraph::dependencies(const Triplet& triplet) const + { + auto to_package_specs = [&](const std::vector& dependencies_as_string) { + return Util::fmap(dependencies_as_string, [&](const std::string s) { + return PackageSpec::from_name_and_triplet(s, triplet).value_or_exit(VCPKG_LINE_INFO); + }); + }; + + if (auto p = this->status_paragraph.get()) + { + return to_package_specs(p->package.depends); + } + + if (auto p = this->binary_control_file.get()) + { + auto deps = Util::fmap_flatten(p->features, [](const BinaryParagraph& pgh) { return pgh.depends; }); + deps.insert(deps.end(), p->core_paragraph.depends.begin(), p->core_paragraph.depends.end()); + return to_package_specs(deps); + } + + if (auto p = this->source_paragraph.get()) + { + return to_package_specs(filter_dependencies(p->depends, triplet)); + } + + Checks::exit_with_message(VCPKG_LINE_INFO, + "Cannot get dependencies because there was none of: source/binary/status paragraphs"); + } + + std::string to_output_string(RequestType request_type, const CStringView s) + { + switch (request_type) + { + case RequestType::AUTO_SELECTED: return Strings::format(" * %s", s); + case RequestType::USER_REQUESTED: return Strings::format(" %s", s); + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + InstallPlanAction::InstallPlanAction() : plan_type(InstallPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} + + InstallPlanAction::InstallPlanAction(const PackageSpec& spec, + const SourceControlFile& any_paragraph, + const std::unordered_set& features, + const RequestType& request_type) + : spec(spec), plan_type(InstallPlanType::BUILD_AND_INSTALL), request_type(request_type), feature_list(features) + { + this->any_paragraph.source_control_file = &any_paragraph; + } + + InstallPlanAction::InstallPlanAction(const PackageSpec& spec, + const std::unordered_set& features, + const RequestType& request_type) + : spec(spec), plan_type(InstallPlanType::ALREADY_INSTALLED), request_type(request_type), feature_list(features) + { + } + + InstallPlanAction::InstallPlanAction(const PackageSpec& spec, + const AnyParagraph& any_paragraph, + const RequestType& request_type) + : spec(spec), any_paragraph(any_paragraph), plan_type(InstallPlanType::UNKNOWN), request_type(request_type) + { + if (auto p = any_paragraph.status_paragraph.get()) + { + this->plan_type = InstallPlanType::ALREADY_INSTALLED; + return; + } + + if (auto p = any_paragraph.binary_control_file.get()) + { + this->plan_type = InstallPlanType::INSTALL; + return; + } + + if (auto p = any_paragraph.source_paragraph.get()) + { + this->plan_type = InstallPlanType::BUILD_AND_INSTALL; + return; + } + } + + std::string InstallPlanAction::displayname() const + { + if (this->feature_list.empty()) + { + return this->spec.to_string(); + } + + const std::string features = Strings::join(",", this->feature_list); + return Strings::format("%s[%s]:%s", this->spec.name(), features, this->spec.triplet()); + } + + bool InstallPlanAction::compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right) + { + return left->spec.name() < right->spec.name(); + } + + RemovePlanAction::RemovePlanAction() : plan_type(RemovePlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} + + RemovePlanAction::RemovePlanAction(const PackageSpec& spec, + const RemovePlanType& plan_type, + const RequestType& request_type) + : spec(spec), plan_type(plan_type), request_type(request_type) + { + } + + const PackageSpec& AnyAction::spec() const + { + if (const auto p = install_plan.get()) + { + return p->spec; + } + + if (const auto p = remove_plan.get()) + { + return p->spec; + } + + Checks::exit_with_message(VCPKG_LINE_INFO, "Null action"); + } + + bool ExportPlanAction::compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right) + { + return left->spec.name() < right->spec.name(); + } + + ExportPlanAction::ExportPlanAction() : plan_type(ExportPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} + + ExportPlanAction::ExportPlanAction(const PackageSpec& spec, + const AnyParagraph& any_paragraph, + const RequestType& request_type) + : spec(spec), any_paragraph(any_paragraph), plan_type(ExportPlanType::UNKNOWN), request_type(request_type) + { + if (auto p = any_paragraph.binary_control_file.get()) + { + this->plan_type = ExportPlanType::ALREADY_BUILT; + return; + } + + if (auto p = any_paragraph.source_paragraph.get()) + { + this->plan_type = ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT; + return; + } + } + + bool RemovePlanAction::compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right) + { + return left->spec.name() < right->spec.name(); + } + + MapPortFile::MapPortFile(const std::unordered_map& map) : ports(map) {} + + const SourceControlFile& MapPortFile::get_control_file(const std::string& spec) const + { + auto scf = ports.find(spec); + if (scf == ports.end()) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } + return scf->second; + } + + PathsPortFile::PathsPortFile(const VcpkgPaths& paths) : ports(paths) {} + + const SourceControlFile& PathsPortFile::get_control_file(const std::string& spec) const + { + auto cache_it = cache.find(spec); + if (cache_it != cache.end()) + { + return cache_it->second; + } + Parse::ParseExpected source_control_file = + Paragraphs::try_load_port(ports.get_filesystem(), ports.port_dir(spec)); + + if (auto scf = source_control_file.get()) + { + auto it = cache.emplace(spec, std::move(*scf->get())); + return it.first->second; + } + print_error_message(source_control_file.error()); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + std::vector create_install_plan(const PortFileProvider& port_file_provider, + const std::vector& specs, + const StatusParagraphs& status_db) + { + struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider + { + const PortFileProvider& port_file_provider; + const StatusParagraphs& status_db; + const std::unordered_set& specs_as_set; + + InstallAdjacencyProvider(const PortFileProvider& port_file_provider, + const StatusParagraphs& s, + const std::unordered_set& specs_as_set) + : port_file_provider(port_file_provider), status_db(s), specs_as_set(specs_as_set) + { + } + + std::vector adjacency_list(const InstallPlanAction& plan) const override + { + if (plan.any_paragraph.status_paragraph.get()) return std::vector{}; + return plan.any_paragraph.dependencies(plan.spec.triplet()); + } + + InstallPlanAction load_vertex_data(const PackageSpec& spec) const override + { + const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() + ? RequestType::USER_REQUESTED + : RequestType::AUTO_SELECTED; + auto it = status_db.find_installed(spec); + if (it != status_db.end()) return InstallPlanAction{spec, {*it->get(), nullopt, nullopt}, request_type}; + return InstallPlanAction{ + spec, + {nullopt, nullopt, *port_file_provider.get_control_file(spec.name()).core_paragraph}, + request_type}; + } + }; + + const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); + std::vector toposort = + Graphs::topological_sort(specs, InstallAdjacencyProvider{port_file_provider, status_db, specs_as_set}); + Util::erase_remove_if(toposort, [](const InstallPlanAction& plan) { + return plan.request_type == RequestType::AUTO_SELECTED && + plan.plan_type == InstallPlanType::ALREADY_INSTALLED; + }); + + return toposort; + } + + std::vector create_remove_plan(const std::vector& specs, + const StatusParagraphs& status_db) + { + struct RemoveAdjacencyProvider final : Graphs::AdjacencyProvider + { + const StatusParagraphs& status_db; + const std::vector& installed_ports; + const std::unordered_set& specs_as_set; + + RemoveAdjacencyProvider(const StatusParagraphs& status_db, + const std::vector& installed_ports, + const std::unordered_set& specs_as_set) + : status_db(status_db), installed_ports(installed_ports), specs_as_set(specs_as_set) + { + } + + std::vector adjacency_list(const RemovePlanAction& plan) const override + { + if (plan.plan_type == RemovePlanType::NOT_INSTALLED) + { + return {}; + } + + const PackageSpec& spec = plan.spec; + std::vector dependents; + for (const StatusParagraph* an_installed_package : installed_ports) + { + if (an_installed_package->package.spec.triplet() != spec.triplet()) continue; + + const std::vector& deps = an_installed_package->package.depends; + if (std::find(deps.begin(), deps.end(), spec.name()) == deps.end()) continue; + + dependents.push_back(an_installed_package->package.spec); + } + + return dependents; + } + + RemovePlanAction load_vertex_data(const PackageSpec& spec) const override + { + const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() + ? RequestType::USER_REQUESTED + : RequestType::AUTO_SELECTED; + const StatusParagraphs::const_iterator it = status_db.find_installed(spec); + if (it == status_db.end()) + { + return RemovePlanAction{spec, RemovePlanType::NOT_INSTALLED, request_type}; + } + return RemovePlanAction{spec, RemovePlanType::REMOVE, request_type}; + } + }; + + const std::vector& installed_ports = get_installed_ports(status_db); + const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); + return Graphs::topological_sort(specs, RemoveAdjacencyProvider{status_db, installed_ports, specs_as_set}); + } + + std::vector create_export_plan(const VcpkgPaths& paths, + const std::vector& specs, + const StatusParagraphs& status_db) + { + struct ExportAdjacencyProvider final : Graphs::AdjacencyProvider + { + const VcpkgPaths& paths; + const StatusParagraphs& status_db; + const std::unordered_set& specs_as_set; + + ExportAdjacencyProvider(const VcpkgPaths& p, + const StatusParagraphs& s, + const std::unordered_set& specs_as_set) + : paths(p), status_db(s), specs_as_set(specs_as_set) + { + } + + std::vector adjacency_list(const ExportPlanAction& plan) const override + { + return plan.any_paragraph.dependencies(plan.spec.triplet()); + } + + ExportPlanAction load_vertex_data(const PackageSpec& spec) const override + { + const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() + ? RequestType::USER_REQUESTED + : RequestType::AUTO_SELECTED; + + Expected maybe_bpgh = Paragraphs::try_load_cached_control_package(paths, spec); + if (auto bcf = maybe_bpgh.get()) + return ExportPlanAction{spec, AnyParagraph{nullopt, std::move(*bcf), nullopt}, request_type}; + + auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); + if (auto scf = maybe_scf.get()) + return ExportPlanAction{spec, {nullopt, nullopt, *scf->get()->core_paragraph}, request_type}; + else + print_error_message(maybe_scf.error()); + + Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec); + } + }; + + const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); + std::vector toposort = + Graphs::topological_sort(specs, ExportAdjacencyProvider{paths, status_db, specs_as_set}); + return toposort; + } + + enum class MarkPlusResult + { + FEATURE_NOT_FOUND, + SUCCESS, + }; + + MarkPlusResult mark_plus(const std::string& feature, + Cluster& cluster, + ClusterGraph& pkg_to_cluster, + GraphPlan& graph_plan); + void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); + + MarkPlusResult mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) + { + if (feature.empty()) + { + // Indicates that core was not specified in the reference + return mark_plus("core", cluster, graph, graph_plan); + } + + auto it = cluster.edges.find(feature); + if (it == cluster.edges.end()) return MarkPlusResult::FEATURE_NOT_FOUND; + + if (cluster.edges[feature].plus) return MarkPlusResult::SUCCESS; + + if (cluster.original_features.find(feature) == cluster.original_features.end()) + { + cluster.transient_uninstalled = true; + } + + if (!cluster.transient_uninstalled) + { + return MarkPlusResult::SUCCESS; + } + cluster.edges[feature].plus = true; + + if (!cluster.original_features.empty()) + { + mark_minus(cluster, graph, graph_plan); + } + + graph_plan.install_graph.add_vertex({&cluster}); + auto& tracked = cluster.to_install_features; + tracked.insert(feature); + + if (feature != "core") + { + // All features implicitly depend on core + auto res = mark_plus("core", cluster, graph, graph_plan); + + // Should be impossible for "core" to not exist + Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS); + } + + for (auto&& depend : cluster.edges[feature].build_edges) + { + auto& depend_cluster = graph.get(depend.spec()); + auto res = mark_plus(depend.feature(), depend_cluster, graph, graph_plan); + + Checks::check_exit(VCPKG_LINE_INFO, + res == MarkPlusResult::SUCCESS, + "Error: Unable to satisfy dependency %s of %s", + depend, + FeatureSpec(cluster.spec, feature)); + + if (&depend_cluster == &cluster) continue; + graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster}); + } + + return MarkPlusResult::SUCCESS; + } + + void mark_minus(Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) + { + if (cluster.will_remove) return; + cluster.will_remove = true; + + graph_plan.remove_graph.add_vertex({&cluster}); + for (auto&& pair : cluster.edges) + { + auto& remove_edges_edges = pair.second.remove_edges; + for (auto&& depend : remove_edges_edges) + { + auto& depend_cluster = graph.get(depend.spec()); + graph_plan.remove_graph.add_edge({&cluster}, {&depend_cluster}); + mark_minus(depend_cluster, graph, graph_plan); + } + } + + cluster.transient_uninstalled = true; + for (auto&& original_feature : cluster.original_features) + { + auto res = mark_plus(original_feature, cluster, graph, graph_plan); + if (res != MarkPlusResult::SUCCESS) + { + System::println(System::Color::warning, + "Warning: could not reinstall feature %s", + FeatureSpec{cluster.spec, original_feature}); + } + } + } + + static ClusterGraph create_feature_install_graph(const std::unordered_map& map, + const StatusParagraphs& status_db) + { + std::unordered_map ptr_map; + for (auto&& p : map) + ptr_map.emplace(p.first, &p.second); + ClusterGraph graph(std::move(ptr_map)); + + auto installed_ports = get_installed_ports(status_db); + + for (auto&& status_paragraph : installed_ports) + { + Cluster& cluster = graph.get(status_paragraph->package.spec); + + cluster.transient_uninstalled = false; + + cluster.status_paragraphs.emplace_back(status_paragraph); + + auto& status_paragraph_feature = status_paragraph->package.feature; + // In this case, empty string indicates the "core" paragraph for a package. + if (status_paragraph_feature.empty()) + { + cluster.original_features.insert("core"); + } + else + { + cluster.original_features.insert(status_paragraph_feature); + } + } + + for (auto&& status_paragraph : installed_ports) + { + auto& spec = status_paragraph->package.spec; + auto& status_paragraph_feature = status_paragraph->package.feature; + auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, + status_paragraph->package.spec.triplet()); + + for (auto&& dependency : reverse_edges) + { + auto& dep_cluster = graph.get(dependency.spec()); + + auto depends_name = dependency.feature(); + if (depends_name.empty()) depends_name = "core"; + + auto& target_node = dep_cluster.edges[depends_name]; + target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); + } + } + return graph; + } + + std::vector create_feature_install_plan(const std::unordered_map& map, + const std::vector& specs, + const StatusParagraphs& status_db) + { + ClusterGraph graph = create_feature_install_graph(map, status_db); + + GraphPlan graph_plan; + for (auto&& spec : specs) + { + Cluster& spec_cluster = graph.get(spec.spec()); + spec_cluster.request_type = RequestType::USER_REQUESTED; + auto res = mark_plus(spec.feature(), spec_cluster, graph, graph_plan); + + Checks::check_exit( + VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); + + graph_plan.install_graph.add_vertex(ClusterPtr{&spec_cluster}); + } + + Graphs::GraphAdjacencyProvider adjacency_remove_graph(graph_plan.remove_graph.adjacency_list()); + auto remove_vertex_list = graph_plan.remove_graph.vertex_list(); + auto remove_toposort = Graphs::topological_sort(remove_vertex_list, adjacency_remove_graph); + + Graphs::GraphAdjacencyProvider adjacency_install_graph(graph_plan.install_graph.adjacency_list()); + auto insert_vertex_list = graph_plan.install_graph.vertex_list(); + auto insert_toposort = Graphs::topological_sort(insert_vertex_list, adjacency_install_graph); + + std::vector plan; + + for (auto&& p_cluster : remove_toposort) + { + auto scf = *p_cluster->source_control_file.get(); + auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, p_cluster->spec.triplet()) + .value_or_exit(VCPKG_LINE_INFO); + plan.emplace_back(RemovePlanAction{ + std::move(spec), + RemovePlanType::REMOVE, + p_cluster->request_type, + }); + } + + for (auto&& p_cluster : insert_toposort) + { + if (p_cluster->transient_uninstalled) + { + // If it will be transiently uninstalled, we need to issue a full installation command + auto pscf = p_cluster->source_control_file.value_or_exit(VCPKG_LINE_INFO); + Checks::check_exit(VCPKG_LINE_INFO, pscf != nullptr); + plan.emplace_back(InstallPlanAction{ + p_cluster->spec, + *pscf, + p_cluster->to_install_features, + p_cluster->request_type, + }); + } + else + { + // If the package isn't transitively installed, still include it if the user explicitly requested it + if (p_cluster->request_type != RequestType::USER_REQUESTED) continue; + plan.emplace_back(InstallPlanAction{ + p_cluster->spec, + p_cluster->original_features, + p_cluster->request_type, + }); + } + } + + return plan; + } +} diff --git a/toolsrc/src/vcpkg/export.cpp b/toolsrc/src/vcpkg/export.cpp new file mode 100644 index 000000000..de6464c87 --- /dev/null +++ b/toolsrc/src/vcpkg/export.cpp @@ -0,0 +1,528 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace vcpkg::Export +{ + using Dependencies::ExportPlanAction; + using Dependencies::ExportPlanType; + using Dependencies::RequestType; + using Install::InstallDir; + + static std::string create_nuspec_file_contents(const std::string& raw_exported_dir, + const std::string& targets_redirect_path, + const std::string& nuget_id, + const std::string& nupkg_version) + { + static constexpr auto CONTENT_TEMPLATE = R"( + + + @NUGET_ID@ + @VERSION@ + vcpkg + + Vcpkg NuGet export + + + + + + + + + +)"; + + std::string nuspec_file_content = std::regex_replace(CONTENT_TEMPLATE, std::regex("@NUGET_ID@"), nuget_id); + nuspec_file_content = std::regex_replace(nuspec_file_content, std::regex("@VERSION@"), nupkg_version); + nuspec_file_content = + std::regex_replace(nuspec_file_content, std::regex("@RAW_EXPORTED_DIR@"), raw_exported_dir); + nuspec_file_content = + std::regex_replace(nuspec_file_content, std::regex("@TARGETS_REDIRECT_PATH@"), targets_redirect_path); + return nuspec_file_content; + } + + static std::string create_targets_redirect(const std::string& target_path) noexcept + { + return Strings::format(R"###( + + + +)###", + target_path, + target_path); + } + + static void print_plan(const std::map>& group_by_plan_type) + { + static constexpr std::array ORDER = {ExportPlanType::ALREADY_BUILT, + ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT}; + + for (const ExportPlanType plan_type : ORDER) + { + const auto it = group_by_plan_type.find(plan_type); + if (it == group_by_plan_type.cend()) + { + continue; + } + + std::vector cont = it->second; + std::sort(cont.begin(), cont.end(), &ExportPlanAction::compare_by_name); + const std::string as_string = Strings::join("\n", cont, [](const ExportPlanAction* p) { + return Dependencies::to_output_string(p->request_type, p->spec.to_string()); + }); + + switch (plan_type) + { + case ExportPlanType::ALREADY_BUILT: + System::println("The following packages are already built and will be exported:\n%s", as_string); + continue; + case ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT: + System::println("The following packages need to be built:\n%s", as_string); + continue; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + } + + static std::string create_export_id() + { + const tm date_time = System::get_current_date_time(); + + // Format is: YYYYmmdd-HHMMSS + // 15 characters + 1 null terminating character will be written for a total of 16 chars + char mbstr[16]; + const size_t bytes_written = std::strftime(mbstr, sizeof(mbstr), "%Y%m%d-%H%M%S", &date_time); + Checks::check_exit(VCPKG_LINE_INFO, + bytes_written == 15, + "Expected 15 bytes to be written, but %u were written", + bytes_written); + const std::string date_time_as_string(mbstr); + return ("vcpkg-export-" + date_time_as_string); + } + + static fs::path do_nuget_export(const VcpkgPaths& paths, + const std::string& nuget_id, + const std::string& nuget_version, + const fs::path& raw_exported_dir, + const fs::path& output_dir) + { + Files::Filesystem& fs = paths.get_filesystem(); + const fs::path& nuget_exe = paths.get_nuget_exe(); + + // This file will be placed in "build\native" in the nuget package. Therefore, go up two dirs. + const std::string targets_redirect_content = + create_targets_redirect("../../scripts/buildsystems/msbuild/vcpkg.targets"); + const fs::path targets_redirect = paths.buildsystems / "tmp" / "vcpkg.export.nuget.targets"; + + std::error_code ec; + fs.create_directories(paths.buildsystems / "tmp", ec); + + fs.write_contents(targets_redirect, targets_redirect_content); + + const std::string nuspec_file_content = + create_nuspec_file_contents(raw_exported_dir.string(), targets_redirect.string(), nuget_id, nuget_version); + const fs::path nuspec_file_path = paths.buildsystems / "tmp" / "vcpkg.export.nuspec"; + fs.write_contents(nuspec_file_path, nuspec_file_content); + + // -NoDefaultExcludes is needed for ".vcpkg-root" + const std::wstring cmd_line = + Strings::wformat(LR"("%s" pack -OutputDirectory "%s" "%s" -NoDefaultExcludes > nul)", + nuget_exe.native(), + output_dir.native(), + nuspec_file_path.native()); + + const int exit_code = System::cmd_execute_clean(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Error: NuGet package creation failed"); + + const fs::path output_path = output_dir / (nuget_id + ".nupkg"); + return output_path; + } + + struct ArchiveFormat final + { + enum class BackingEnum + { + ZIP = 1, + SEVEN_ZIP, + }; + + constexpr ArchiveFormat() = delete; + + constexpr ArchiveFormat(BackingEnum backing_enum, const wchar_t* extension, const wchar_t* cmake_option) + : backing_enum(backing_enum), m_extension(extension), m_cmake_option(cmake_option) + { + } + + constexpr operator BackingEnum() const { return backing_enum; } + constexpr CWStringView extension() const { return this->m_extension; } + constexpr CWStringView cmake_option() const { return this->m_cmake_option; } + + private: + BackingEnum backing_enum; + const wchar_t* m_extension; + const wchar_t* m_cmake_option; + }; + + namespace ArchiveFormatC + { + constexpr const ArchiveFormat ZIP(ArchiveFormat::BackingEnum::ZIP, L"zip", L"zip"); + constexpr const ArchiveFormat SEVEN_ZIP(ArchiveFormat::BackingEnum::SEVEN_ZIP, L"7z", L"7zip"); + } + + static fs::path do_archive_export(const VcpkgPaths& paths, + const fs::path& raw_exported_dir, + const fs::path& output_dir, + const ArchiveFormat& format) + { + const fs::path& cmake_exe = paths.get_cmake_exe(); + + const std::wstring exported_dir_filename = raw_exported_dir.filename().native(); + const std::wstring exported_archive_filename = + Strings::wformat(L"%s.%s", exported_dir_filename, format.extension()); + const fs::path exported_archive_path = (output_dir / exported_archive_filename); + + // -NoDefaultExcludes is needed for ".vcpkg-root" + const std::wstring cmd_line = Strings::wformat(LR"("%s" -E tar "cf" "%s" --format=%s -- "%s")", + cmake_exe.native(), + exported_archive_path.native(), + format.cmake_option(), + raw_exported_dir.native()); + + const int exit_code = System::cmd_execute_clean(cmd_line); + Checks::check_exit( + VCPKG_LINE_INFO, exit_code == 0, "Error: %s creation failed", exported_archive_path.generic_string()); + return exported_archive_path; + } + + static Optional maybe_lookup(std::unordered_map const& m, + std::string const& key) + { + const auto it = m.find(key); + if (it != m.end()) return it->second; + return nullopt; + } + + void export_integration_files(const fs::path& raw_exported_dir_path, const VcpkgPaths& paths) + { + const std::vector integration_files_relative_to_root = { + {".vcpkg-root"}, + {fs::path{"scripts"} / "buildsystems" / "msbuild" / "applocal.ps1"}, + {fs::path{"scripts"} / "buildsystems" / "msbuild" / "vcpkg.targets"}, + {fs::path{"scripts"} / "buildsystems" / "vcpkg.cmake"}, + {fs::path{"scripts"} / "cmake" / "vcpkg_get_windows_sdk.cmake"}, + {fs::path{"scripts"} / "getWindowsSDK.ps1"}, + {fs::path{"scripts"} / "getProgramFilesPlatformBitness.ps1"}, + {fs::path{"scripts"} / "getProgramFiles32bit.ps1"}, + }; + + for (const fs::path& file : integration_files_relative_to_root) + { + const fs::path source = paths.root / file; + fs::path destination = raw_exported_dir_path / file; + Files::Filesystem& fs = paths.get_filesystem(); + std::error_code ec; + fs.create_directories(destination.parent_path(), ec); + Checks::check_exit(VCPKG_LINE_INFO, !ec); + fs.copy_file(source, destination, fs::copy_options::overwrite_existing, ec); + Checks::check_exit(VCPKG_LINE_INFO, !ec); + } + } + + struct ExportArguments + { + bool dry_run; + bool raw; + bool nuget; + bool ifw; + bool zip; + bool seven_zip; + + Optional maybe_nuget_id; + Optional maybe_nuget_version; + + IFW::Options ifw_options; + std::vector specs; + }; + + static ExportArguments handle_export_command_arguments(const VcpkgCmdArguments& args, + const Triplet& default_triplet) + { + ExportArguments ret; + + static const std::string OPTION_DRY_RUN = "--dry-run"; + static const std::string OPTION_RAW = "--raw"; + static const std::string OPTION_NUGET = "--nuget"; + static const std::string OPTION_IFW = "--ifw"; + static const std::string OPTION_ZIP = "--zip"; + static const std::string OPTION_SEVEN_ZIP = "--7zip"; + static const std::string OPTION_NUGET_ID = "--nuget-id"; + static const std::string OPTION_NUGET_VERSION = "--nuget-version"; + static const std::string OPTION_IFW_REPOSITORY_URL = "--ifw-repository-url"; + static const std::string OPTION_IFW_PACKAGES_DIR_PATH = "--ifw-packages-directory-path"; + static const std::string OPTION_IFW_REPOSITORY_DIR_PATH = "--ifw-repository-directory-path"; + static const std::string OPTION_IFW_CONFIG_FILE_PATH = "--ifw-configuration-file-path"; + static const std::string OPTION_IFW_INSTALLER_FILE_PATH = "--ifw-installer-file-path"; + + // input sanitization + static const std::string EXAMPLE = Help::create_example_string("export zlib zlib:x64-windows boost --nuget"); + args.check_min_arg_count(1, EXAMPLE); + + ret.specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE); + }); + + const auto options = args.check_and_get_optional_command_arguments( + { + OPTION_DRY_RUN, + OPTION_RAW, + OPTION_NUGET, + OPTION_IFW, + OPTION_ZIP, + OPTION_SEVEN_ZIP, + }, + { + OPTION_NUGET_ID, + OPTION_NUGET_VERSION, + OPTION_IFW_REPOSITORY_URL, + OPTION_IFW_PACKAGES_DIR_PATH, + OPTION_IFW_REPOSITORY_DIR_PATH, + OPTION_IFW_CONFIG_FILE_PATH, + OPTION_IFW_INSTALLER_FILE_PATH, + }); + ret.dry_run = options.switches.find(OPTION_DRY_RUN) != options.switches.cend(); + ret.raw = options.switches.find(OPTION_RAW) != options.switches.cend(); + ret.nuget = options.switches.find(OPTION_NUGET) != options.switches.cend(); + ret.ifw = options.switches.find(OPTION_IFW) != options.switches.cend(); + ret.zip = options.switches.find(OPTION_ZIP) != options.switches.cend(); + ret.seven_zip = options.switches.find(OPTION_SEVEN_ZIP) != options.switches.cend(); + + if (!ret.raw && !ret.nuget && !ret.ifw && !ret.zip && !ret.seven_zip && !ret.dry_run) + { + System::println(System::Color::error, + "Must provide at least one export type: --raw --nuget --ifw --zip --7zip"); + System::print(EXAMPLE); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + struct OptionPair + { + const std::string& name; + Optional& out_opt; + }; + const auto options_implies = + [&](const std::string& main_opt_name, bool main_opt, Span implying_opts) { + if (main_opt) + { + for (auto&& opt : implying_opts) + opt.out_opt = maybe_lookup(options.settings, opt.name); + } + else + { + for (auto&& opt : implying_opts) + Checks::check_exit(VCPKG_LINE_INFO, + !maybe_lookup(options.settings, opt.name), + "%s is only valid with %s", + opt.name, + main_opt_name); + } + }; + + options_implies(OPTION_NUGET, + ret.nuget, + { + {OPTION_NUGET_ID, ret.maybe_nuget_id}, + {OPTION_NUGET_VERSION, ret.maybe_nuget_version}, + }); + + options_implies(OPTION_IFW, + ret.ifw, + { + {OPTION_IFW_REPOSITORY_URL, ret.ifw_options.maybe_repository_url}, + {OPTION_IFW_PACKAGES_DIR_PATH, ret.ifw_options.maybe_packages_dir_path}, + {OPTION_IFW_REPOSITORY_DIR_PATH, ret.ifw_options.maybe_repository_dir_path}, + {OPTION_IFW_CONFIG_FILE_PATH, ret.ifw_options.maybe_config_file_path}, + {OPTION_IFW_INSTALLER_FILE_PATH, ret.ifw_options.maybe_installer_file_path}, + }); + return ret; + } + + static void print_next_step_info(const fs::path& prefix) + { + const fs::path cmake_toolchain = prefix / "scripts" / "buildsystems" / "vcpkg.cmake"; + const CMakeVariable cmake_variable = CMakeVariable(L"CMAKE_TOOLCHAIN_FILE", cmake_toolchain.generic_string()); + System::println("\n" + "To use the exported libraries in CMake projects use:" + "\n" + " %s" + "\n", + Strings::to_utf8(cmake_variable.s)); + }; + + static void handle_raw_based_export(Span export_plan, + const ExportArguments& opts, + const std::string& export_id, + const VcpkgPaths& paths) + { + Files::Filesystem& fs = paths.get_filesystem(); + const fs::path export_to_path = paths.root; + const fs::path raw_exported_dir_path = export_to_path / export_id; + std::error_code ec; + fs.remove_all(raw_exported_dir_path, ec); + fs.create_directory(raw_exported_dir_path, ec); + + // execute the plan + for (const ExportPlanAction& action : export_plan) + { + if (action.plan_type != ExportPlanType::ALREADY_BUILT) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + const std::string display_name = action.spec.to_string(); + System::println("Exporting package %s... ", display_name); + + const BinaryParagraph& binary_paragraph = + action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO).core_paragraph; + + const InstallDir dirs = InstallDir::from_destination_root( + raw_exported_dir_path / "installed", + action.spec.triplet().to_string(), + raw_exported_dir_path / "installed" / "vcpkg" / "info" / (binary_paragraph.fullstem() + ".list")); + + Install::install_files_and_write_listfile(paths.get_filesystem(), paths.package_dir(action.spec), dirs); + System::println(System::Color::success, "Exporting package %s... done", display_name); + } + + // Copy files needed for integration + export_integration_files(raw_exported_dir_path, paths); + + if (opts.raw) + { + System::println( + System::Color::success, R"(Files exported at: "%s")", raw_exported_dir_path.generic_string()); + print_next_step_info(export_to_path); + } + + if (opts.nuget) + { + System::println("Creating nuget package... "); + + const std::string nuget_id = opts.maybe_nuget_id.value_or(raw_exported_dir_path.filename().string()); + const std::string nuget_version = opts.maybe_nuget_version.value_or("1.0.0"); + const fs::path output_path = + do_nuget_export(paths, nuget_id, nuget_version, raw_exported_dir_path, export_to_path); + System::println(System::Color::success, "Creating nuget package... done"); + System::println(System::Color::success, "NuGet package exported at: %s", output_path.generic_string()); + + System::println(R"( +With a project open, go to Tools->NuGet Package Manager->Package Manager Console and paste: + Install-Package %s -Source "%s" +)" + "\n", + nuget_id, + output_path.parent_path().u8string()); + } + + if (opts.zip) + { + System::println("Creating zip archive... "); + const fs::path output_path = + do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::ZIP); + System::println(System::Color::success, "Creating zip archive... done"); + System::println(System::Color::success, "Zip archive exported at: %s", output_path.generic_string()); + print_next_step_info("[...]"); + } + + if (opts.seven_zip) + { + System::println("Creating 7zip archive... "); + const fs::path output_path = + do_archive_export(paths, raw_exported_dir_path, export_to_path, ArchiveFormatC::SEVEN_ZIP); + System::println(System::Color::success, "Creating 7zip archive... done"); + System::println(System::Color::success, "7zip archive exported at: %s", output_path.generic_string()); + print_next_step_info("[...]"); + } + + if (!opts.raw) + { + fs.remove_all(raw_exported_dir_path, ec); + } + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + const auto opts = handle_export_command_arguments(args, default_triplet); + for (auto&& spec : opts.specs) + Input::check_triplet(spec.triplet(), paths); + + // create the plan + const StatusParagraphs status_db = database_load_check(paths); + std::vector export_plan = Dependencies::create_export_plan(paths, opts.specs, status_db); + Checks::check_exit(VCPKG_LINE_INFO, !export_plan.empty(), "Export plan cannot be empty"); + + std::map> group_by_plan_type; + Util::group_by(export_plan, &group_by_plan_type, [](const ExportPlanAction& p) { return p.plan_type; }); + print_plan(group_by_plan_type); + + const bool has_non_user_requested_packages = + Util::find_if(export_plan, [](const ExportPlanAction& package) -> bool { + return package.request_type != RequestType::USER_REQUESTED; + }) != export_plan.cend(); + + if (has_non_user_requested_packages) + { + System::println(System::Color::warning, + "Additional packages (*) need to be exported to complete this operation."); + } + + const auto it = group_by_plan_type.find(ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT); + if (it != group_by_plan_type.cend() && !it->second.empty()) + { + System::println(System::Color::error, "There are packages that have not been built."); + + // No need to show all of them, just the user-requested ones. Dependency resolution will handle the rest. + std::vector unbuilt = it->second; + Util::erase_remove_if( + unbuilt, [](const ExportPlanAction* a) { return a->request_type != RequestType::USER_REQUESTED; }); + + const auto s = Strings::join(" ", unbuilt, [](const ExportPlanAction* a) { return a->spec.to_string(); }); + System::println("To build them, run:\n" + " vcpkg install %s", + s); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + if (opts.dry_run) + { + Checks::exit_success(VCPKG_LINE_INFO); + } + + std::string export_id = create_export_id(); + + if (opts.raw || opts.nuget || opts.zip || opts.seven_zip) + { + handle_raw_based_export(export_plan, opts, export_id, paths); + } + + if (opts.ifw) + { + IFW::do_export(export_plan, export_id, opts.ifw_options, paths); + + print_next_step_info("@RootDir@/src/vcpkg"); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/globalstate.cpp b/toolsrc/src/vcpkg/globalstate.cpp new file mode 100644 index 000000000..de564d357 --- /dev/null +++ b/toolsrc/src/vcpkg/globalstate.cpp @@ -0,0 +1,13 @@ +#include "pch.h" + +#include + +namespace vcpkg +{ + Util::LockGuarded GlobalState::timer; + std::atomic GlobalState::debugging = false; + std::atomic GlobalState::feature_packages = false; + + std::atomic GlobalState::g_init_console_cp = 0; + std::atomic GlobalState::g_init_console_output_cp = 0; +} diff --git a/toolsrc/src/vcpkg/help.cpp b/toolsrc/src/vcpkg/help.cpp new file mode 100644 index 000000000..7867f71d2 --- /dev/null +++ b/toolsrc/src/vcpkg/help.cpp @@ -0,0 +1,131 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg::Help +{ + void help_topics() + { + System::println("Available help topics:\n" + " triplet\n" + " integrate\n" + " export"); + } + + void help_topic_valid_triplet(const VcpkgPaths& paths) + { + System::println("Available architecture triplets:"); + for (auto&& path : paths.get_filesystem().get_files_non_recursive(paths.triplets)) + { + System::println(" %s", path.stem().filename().string()); + } + } + + void help_topic_export() + { + System::println("Summary:\n" + " vcpkg export [options] ...\n" + "\n" + "Options:\n" + " --7zip Export to a 7zip (.7z) file\n" + " --dry-run Do not actually export\n" + " --nuget Export a NuGet package\n" + " --nuget-id= Specify the id for the exported NuGet package\n" + " --nuget-version= Specify the version for the exported NuGet package\n" + " --raw Export to an uncompressed directory\n" + " --zip Export to a zip file"); + } + + void print_usage() + { + System::println( + "Commands:\n" + " vcpkg search [pat] Search for packages available to be built\n" + " vcpkg install ... Install a package\n" + " vcpkg remove ... Uninstall a package\n" + " vcpkg remove --outdated Uninstall all out-of-date packages\n" + " vcpkg list List installed packages\n" + " vcpkg update Display list of packages for updating\n" + " vcpkg hash [alg] Hash a file by specific algorithm, default SHA512\n" + " vcpkg help topics Display the list of help topics\n" + " vcpkg help Display help for a specific topic\n" + "\n" + "%s" // Integration help + "\n" + " vcpkg export ... [opt]... Exports a package\n" + " vcpkg edit Open up a port for editing (uses %%EDITOR%%, default 'code')\n" + " vcpkg import Import a pre-built library\n" + " vcpkg create \n" + " [archivename] Create a new package\n" + " vcpkg owns Search for files in installed packages\n" + " vcpkg cache List cached compiled packages\n" + " vcpkg version Display version information\n" + " vcpkg contact Display contact information to send feedback\n" + "\n" + //"internal commands:\n" + //" --check-build-deps \n" + //" --create-binary-control \n" + //"\n" + "Options:\n" + " --triplet Specify the target architecture triplet.\n" + " (default: %%VCPKG_DEFAULT_TRIPLET%%, see 'vcpkg help triplet')\n" + "\n" + " --vcpkg-root Specify the vcpkg root directory\n" + " (default: %%VCPKG_ROOT%%)\n" + "\n" + "For more help (including examples) see the accompanying README.md.", + Commands::Integrate::INTEGRATE_COMMAND_HELPSTRING); + } + + std::string create_example_string(const std::string& command_and_arguments) + { + std::string cs = Strings::format("Example:\n" + " vcpkg %s\n", + command_and_arguments); + return cs; + } + + void print_example(const std::string& command_and_arguments) + { + System::println(create_example_string(command_and_arguments)); + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + args.check_max_arg_count(1); + args.check_and_get_optional_command_arguments({}); + + if (args.command_arguments.empty()) + { + print_usage(); + Checks::exit_success(VCPKG_LINE_INFO); + } + const auto& topic = args.command_arguments[0]; + if (topic == "triplet" || topic == "triplets" || topic == "triple") + { + help_topic_valid_triplet(paths); + } + else if (topic == "export") + { + help_topic_export(); + } + else if (topic == "integrate") + { + System::print("Commands:\n" + "%s", + Commands::Integrate::INTEGRATE_COMMAND_HELPSTRING); + } + else if (topic == "topics") + { + help_topics(); + } + else + { + System::println(System::Color::error, "Error: unknown topic %s", topic); + help_topics(); + Checks::exit_fail(VCPKG_LINE_INFO); + } + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/input.cpp b/toolsrc/src/vcpkg/input.cpp new file mode 100644 index 000000000..aee0fac7f --- /dev/null +++ b/toolsrc/src/vcpkg/input.cpp @@ -0,0 +1,55 @@ +#include "pch.h" + +#include +#include +#include +#include +#include + +namespace vcpkg::Input +{ + PackageSpec check_and_get_package_spec(const std::string& package_spec_as_string, + const Triplet& default_triplet, + CStringView example_text) + { + const std::string as_lowercase = Strings::ascii_to_lowercase(package_spec_as_string); + auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet); + if (const auto spec = expected_spec.get()) + { + return PackageSpec{spec->package_spec}; + } + + // Intentionally show the lowercased string + System::println(System::Color::error, "Error: %s: %s", vcpkg::to_string(expected_spec.error()), as_lowercase); + System::print(example_text); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + void check_triplet(const Triplet& t, const VcpkgPaths& paths) + { + if (!paths.is_valid_triplet(t)) + { + System::println(System::Color::error, "Error: invalid triplet: %s", t); + Metrics::g_metrics.lock()->track_property("error", "invalid triplet: " + t.to_string()); + Help::help_topic_valid_triplet(paths); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + + FullPackageSpec check_and_get_full_package_spec(const std::string& full_package_spec_as_string, + const Triplet& default_triplet, + CStringView example_text) + { + const std::string as_lowercase = Strings::ascii_to_lowercase(full_package_spec_as_string); + auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet); + if (const auto spec = expected_spec.get()) + { + return *spec; + } + + // Intentionally show the lowercased string + System::println(System::Color::error, "Error: %s: %s", vcpkg::to_string(expected_spec.error()), as_lowercase); + System::print(example_text); + Checks::exit_fail(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp new file mode 100644 index 000000000..74bea0d5f --- /dev/null +++ b/toolsrc/src/vcpkg/install.cpp @@ -0,0 +1,615 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Install +{ + using namespace Dependencies; + + InstallDir InstallDir::from_destination_root(const fs::path& destination_root, + const std::string& destination_subdirectory, + const fs::path& listfile) + { + InstallDir dirs; + dirs.m_destination = destination_root / destination_subdirectory; + dirs.m_destination_subdirectory = destination_subdirectory; + dirs.m_listfile = listfile; + return dirs; + } + + const fs::path& InstallDir::destination() const { return this->m_destination; } + + const std::string& InstallDir::destination_subdirectory() const { return this->m_destination_subdirectory; } + + const fs::path& InstallDir::listfile() const { return this->m_listfile; } + + void install_files_and_write_listfile(Files::Filesystem& fs, + const fs::path& source_dir, + const InstallDir& destination_dir) + { + std::vector output; + std::error_code ec; + + const size_t prefix_length = source_dir.native().size(); + const fs::path& destination = destination_dir.destination(); + const std::string& destination_subdirectory = destination_dir.destination_subdirectory(); + const fs::path& listfile = destination_dir.listfile(); + + Checks::check_exit( + VCPKG_LINE_INFO, fs.exists(source_dir), "Source directory %s does not exist", source_dir.generic_string()); + fs.create_directories(destination, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create destination directory %s", destination.generic_string()); + const fs::path listfile_parent = listfile.parent_path(); + fs.create_directories(listfile_parent, ec); + Checks::check_exit( + VCPKG_LINE_INFO, !ec, "Could not create directory for listfile %s", listfile.generic_string()); + + output.push_back(Strings::format(R"(%s/)", destination_subdirectory)); + auto files = fs.get_files_recursive(source_dir); + for (auto&& file : files) + { + const auto status = fs.status(file, ec); + if (ec) + { + System::println(System::Color::error, "failed: %s: %s", file.u8string(), ec.message()); + continue; + } + + const std::string filename = file.filename().generic_string(); + if (fs::is_regular_file(status) && + (Strings::case_insensitive_ascii_compare(filename.c_str(), "CONTROL") || + Strings::case_insensitive_ascii_compare(filename.c_str(), "BUILD_INFO"))) + { + // Do not copy the control file + continue; + } + + const std::string suffix = file.generic_u8string().substr(prefix_length + 1); + const fs::path target = destination / suffix; + + if (fs::is_directory(status)) + { + fs.create_directory(target, ec); + if (ec) + { + System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); + } + + // Trailing backslash for directories + output.push_back(Strings::format(R"(%s/%s/)", destination_subdirectory, suffix)); + continue; + } + + if (fs::is_regular_file(status)) + { + if (fs.exists(target)) + { + System::println(System::Color::warning, + "File %s was already present and will be overwritten", + target.u8string(), + ec.message()); + } + fs.copy_file(file, target, fs::copy_options::overwrite_existing, ec); + if (ec) + { + System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); + } + output.push_back(Strings::format(R"(%s/%s)", destination_subdirectory, suffix)); + continue; + } + + if (!fs::status_known(status)) + { + System::println(System::Color::error, "failed: %s: unknown status", file.u8string()); + continue; + } + + System::println(System::Color::error, "failed: %s: cannot handle file type", file.u8string()); + } + + std::sort(output.begin(), output.end()); + + fs.write_lines(listfile, output); + } + + static void remove_first_n_chars(std::vector* strings, const size_t n) + { + for (std::string& s : *strings) + { + s.erase(0, n); + } + }; + + static std::vector extract_files_in_triplet( + const std::vector& pgh_and_files, const Triplet& triplet) + { + std::vector output; + for (const StatusParagraphAndAssociatedFiles& t : pgh_and_files) + { + if (t.pgh.package.spec.triplet() != triplet) + { + continue; + } + + output.insert(output.end(), t.files.begin(), t.files.end()); + } + + std::sort(output.begin(), output.end()); + return output; + } + + static SortedVector build_list_of_package_files(const Files::Filesystem& fs, + const fs::path& package_dir) + { + const std::vector package_file_paths = fs.get_files_recursive(package_dir); + const size_t package_remove_char_count = package_dir.generic_string().size() + 1; // +1 for the slash + auto package_files = Util::fmap(package_file_paths, [package_remove_char_count](const fs::path& path) { + std::string as_string = path.generic_string(); + as_string.erase(0, package_remove_char_count); + return std::move(as_string); + }); + + return SortedVector(std::move(package_files)); + } + + static SortedVector build_list_of_installed_files( + const std::vector& pgh_and_files, const Triplet& triplet) + { + std::vector installed_files = extract_files_in_triplet(pgh_and_files, triplet); + const size_t installed_remove_char_count = triplet.canonical_name().size() + 1; // +1 for the slash + remove_first_n_chars(&installed_files, installed_remove_char_count); + + return SortedVector(std::move(installed_files)); + } + + InstallResult install_package(const VcpkgPaths& paths, const BinaryControlFile& bcf, StatusParagraphs* status_db) + { + const fs::path package_dir = paths.package_dir(bcf.core_paragraph.spec); + const Triplet& triplet = bcf.core_paragraph.spec.triplet(); + const std::vector pgh_and_files = get_installed_files(paths, *status_db); + + const SortedVector package_files = + build_list_of_package_files(paths.get_filesystem(), package_dir); + const SortedVector installed_files = build_list_of_installed_files(pgh_and_files, triplet); + + std::vector intersection; + std::set_intersection(package_files.begin(), + package_files.end(), + installed_files.begin(), + installed_files.end(), + std::back_inserter(intersection)); + + if (!intersection.empty()) + { + const fs::path triplet_install_path = paths.installed / triplet.canonical_name(); + System::println(System::Color::error, + "The following files are already installed in %s and are in conflict with %s", + triplet_install_path.generic_string(), + bcf.core_paragraph.spec); + System::print("\n "); + System::println(Strings::join("\n ", intersection)); + System::println(); + return InstallResult::FILE_CONFLICTS; + } + + StatusParagraph source_paragraph; + source_paragraph.package = bcf.core_paragraph; + source_paragraph.want = Want::INSTALL; + source_paragraph.state = InstallState::HALF_INSTALLED; + + write_update(paths, source_paragraph); + status_db->insert(std::make_unique(source_paragraph)); + + std::vector features_spghs; + for (auto&& feature : bcf.features) + { + features_spghs.emplace_back(); + + StatusParagraph& feature_paragraph = features_spghs.back(); + feature_paragraph.package = feature; + feature_paragraph.want = Want::INSTALL; + feature_paragraph.state = InstallState::HALF_INSTALLED; + + write_update(paths, feature_paragraph); + status_db->insert(std::make_unique(feature_paragraph)); + } + + const InstallDir install_dir = InstallDir::from_destination_root( + paths.installed, triplet.to_string(), paths.listfile_path(bcf.core_paragraph)); + + install_files_and_write_listfile(paths.get_filesystem(), package_dir, install_dir); + + source_paragraph.state = InstallState::INSTALLED; + write_update(paths, source_paragraph); + status_db->insert(std::make_unique(source_paragraph)); + + for (auto&& feature_paragraph : features_spghs) + { + feature_paragraph.state = InstallState::INSTALLED; + write_update(paths, feature_paragraph); + status_db->insert(std::make_unique(feature_paragraph)); + } + + return InstallResult::SUCCESS; + } + + using Build::BuildResult; + + BuildResult perform_install_plan_action(const VcpkgPaths& paths, + const InstallPlanAction& action, + const Build::BuildPackageOptions& build_package_options, + StatusParagraphs& status_db) + { + const InstallPlanType& plan_type = action.plan_type; + const std::string display_name = action.spec.to_string(); + const std::string display_name_with_features = + GlobalState::feature_packages ? action.displayname() : display_name; + + const bool is_user_requested = action.request_type == RequestType::USER_REQUESTED; + const bool use_head_version = to_bool(build_package_options.use_head_version); + + if (plan_type == InstallPlanType::ALREADY_INSTALLED) + { + if (use_head_version && is_user_requested) + System::println( + System::Color::warning, "Package %s is already installed -- not building from HEAD", display_name); + else + System::println(System::Color::success, "Package %s is already installed", display_name); + return BuildResult::SUCCEEDED; + } + + if (plan_type == InstallPlanType::BUILD_AND_INSTALL) + { + if (use_head_version) + System::println("Building package %s from HEAD... ", display_name_with_features); + else + System::println("Building package %s... ", display_name_with_features); + + const auto result = [&]() -> Build::ExtendedBuildResult { + if (GlobalState::feature_packages) + { + const Build::BuildPackageConfig build_config{ + *action.any_paragraph.source_control_file.value_or_exit(VCPKG_LINE_INFO), + action.spec.triplet(), + paths.port_dir(action.spec), + build_package_options, + action.feature_list}; + return Build::build_package(paths, build_config, status_db); + } + else + { + const Build::BuildPackageConfig build_config{ + action.any_paragraph.source_paragraph.value_or_exit(VCPKG_LINE_INFO), + action.spec.triplet(), + paths.port_dir(action.spec), + build_package_options}; + return Build::build_package(paths, build_config, status_db); + } + }(); + + if (result.code != Build::BuildResult::SUCCEEDED) + { + System::println(System::Color::error, Build::create_error_message(result.code, action.spec)); + return result.code; + } + + System::println("Building package %s... done", display_name_with_features); + + const BinaryControlFile bcf = + Paragraphs::try_load_cached_control_package(paths, action.spec).value_or_exit(VCPKG_LINE_INFO); + System::println("Installing package %s... ", display_name_with_features); + const auto install_result = install_package(paths, bcf, &status_db); + switch (install_result) + { + case InstallResult::SUCCESS: + System::println(System::Color::success, "Installing package %s... done", display_name); + return BuildResult::SUCCEEDED; + case InstallResult::FILE_CONFLICTS: return BuildResult::FILE_CONFLICTS; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + if (plan_type == InstallPlanType::INSTALL) + { + if (use_head_version && is_user_requested) + { + System::println( + System::Color::warning, "Package %s is already built -- not building from HEAD", display_name); + } + System::println("Installing package %s... ", display_name); + const auto install_result = install_package( + paths, action.any_paragraph.binary_control_file.value_or_exit(VCPKG_LINE_INFO), &status_db); + switch (install_result) + { + case InstallResult::SUCCESS: + System::println(System::Color::success, "Installing package %s... done", display_name); + return BuildResult::SUCCEEDED; + case InstallResult::FILE_CONFLICTS: return BuildResult::FILE_CONFLICTS; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + Checks::unreachable(VCPKG_LINE_INFO); + } + + static void print_plan(const std::vector& action_plan, bool is_recursive) + { + std::vector remove_plans; + std::vector rebuilt_plans; + std::vector only_install_plans; + std::vector new_plans; + std::vector already_installed_plans; + + const bool has_non_user_requested_packages = Util::find_if(action_plan, [](const AnyAction& package) -> bool { + if (auto iplan = package.install_plan.get()) + return iplan->request_type != RequestType::USER_REQUESTED; + else + return false; + }) != action_plan.cend(); + + for (auto&& action : action_plan) + { + if (auto install_action = action.install_plan.get()) + { + // remove plans are guaranteed to come before install plans, so we know the plan will be contained if at + // all. + auto it = Util::find_if( + remove_plans, [&](const RemovePlanAction* plan) { return plan->spec == install_action->spec; }); + if (it != remove_plans.end()) + { + rebuilt_plans.emplace_back(install_action); + } + else + { + switch (install_action->plan_type) + { + case InstallPlanType::INSTALL: only_install_plans.emplace_back(install_action); break; + case InstallPlanType::ALREADY_INSTALLED: + if (install_action->request_type == RequestType::USER_REQUESTED) + already_installed_plans.emplace_back(install_action); + break; + case InstallPlanType::BUILD_AND_INSTALL: new_plans.emplace_back(install_action); break; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + } + else if (auto remove_action = action.remove_plan.get()) + { + remove_plans.emplace_back(remove_action); + } + } + + std::sort(remove_plans.begin(), remove_plans.end(), &RemovePlanAction::compare_by_name); + std::sort(rebuilt_plans.begin(), rebuilt_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(only_install_plans.begin(), only_install_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(new_plans.begin(), new_plans.end(), &InstallPlanAction::compare_by_name); + std::sort(already_installed_plans.begin(), already_installed_plans.end(), &InstallPlanAction::compare_by_name); + + if (already_installed_plans.size() > 0) + { + const std::string already_string = + Strings::join("\n", already_installed_plans, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname()); + }); + System::println("The following packages are already installed:\n%s", already_string); + } + + if (rebuilt_plans.size() > 0) + { + const std::string rebuilt_string = Strings::join("\n", rebuilt_plans, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname()); + }); + System::println("The following packages will be rebuilt:\n%s", rebuilt_string); + } + + if (new_plans.size() > 0) + { + const std::string new_string = Strings::join("\n", new_plans, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname()); + }); + System::println("The following packages will be built and installed:\n%s", new_string); + } + + if (only_install_plans.size() > 0) + { + const std::string only_install_string = + Strings::join("\n", only_install_plans, [](const InstallPlanAction* p) { + return to_output_string(p->request_type, p->displayname()); + }); + System::println("The following packages will be directly installed:\n%s", only_install_string); + } + + if (has_non_user_requested_packages) + System::println("Additional packages (*) will be installed to complete this operation."); + + if (remove_plans.size() > 0 && !is_recursive) + { + System::println(System::Color::warning, + "If you are sure you want to rebuild the above packages, run the command with the " + "--recurse option"); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + + void perform_and_exit_ex(const std::vector& action_plan, + const Build::BuildPackageOptions& install_plan_options, + const KeepGoing keep_going, + const PrintSummary print_summary, + const VcpkgPaths& paths, + StatusParagraphs& status_db) + { + std::vector results; + std::vector timing; + const auto timer = Chrono::ElapsedTime::create_started(); + size_t counter = 0; + const size_t package_count = action_plan.size(); + + for (const auto& action : action_plan) + { + const auto build_timer = Chrono::ElapsedTime::create_started(); + counter++; + + const std::string display_name = action.spec().to_string(); + System::println("Starting package %d/%d: %s", counter, package_count, display_name); + + timing.push_back("0"); + results.push_back(BuildResult::NULLVALUE); + + if (const auto install_action = action.install_plan.get()) + { + const BuildResult result = + perform_install_plan_action(paths, *install_action, install_plan_options, status_db); + if (result != BuildResult::SUCCEEDED && keep_going == KeepGoing::NO) + { + System::println(Build::create_user_troubleshooting_message(install_action->spec)); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + results.back() = result; + } + else if (const auto remove_action = action.remove_plan.get()) + { + Checks::check_exit(VCPKG_LINE_INFO, GlobalState::feature_packages); + Remove::perform_remove_plan_action(paths, *remove_action, Remove::Purge::YES, status_db); + } + else + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + timing.back() = build_timer.to_string(); + System::println("Elapsed time for package %s: %s", display_name, build_timer.to_string()); + } + + System::println("Total time taken: %s", timer.to_string()); + + if (print_summary == PrintSummary::YES) + { + for (size_t i = 0; i < results.size(); i++) + { + System::println("%s: %s: %s", action_plan[i].spec(), Build::to_string(results[i]), timing[i]); + } + + std::map summary; + for (const BuildResult& v : Build::BUILD_RESULT_VALUES) + { + summary[v] = 0; + } + + for (const BuildResult& r : results) + { + summary[r]++; + } + + System::println("\n\nSUMMARY"); + for (const std::pair& entry : summary) + { + System::println(" %s: %d", Build::to_string(entry.first), entry.second); + } + } + + Checks::exit_success(VCPKG_LINE_INFO); + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + static const std::string OPTION_DRY_RUN = "--dry-run"; + static const std::string OPTION_USE_HEAD_VERSION = "--head"; + static const std::string OPTION_NO_DOWNLOADS = "--no-downloads"; + static const std::string OPTION_RECURSE = "--recurse"; + static const std::string OPTION_KEEP_GOING = "--keep-going"; + + // input sanitization + static const std::string EXAMPLE = Help::create_example_string("install zlib zlib:x64-windows curl boost"); + args.check_min_arg_count(1, EXAMPLE); + + const std::vector specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + return Input::check_and_get_full_package_spec(arg, default_triplet, EXAMPLE); + }); + + for (auto&& spec : specs) + { + Input::check_triplet(spec.package_spec.triplet(), paths); + if (!spec.features.empty() && !GlobalState::feature_packages) + { + Checks::exit_with_message( + VCPKG_LINE_INFO, "Feature packages are experimentally available under the --featurepackages flag."); + } + } + + const std::unordered_set options = args.check_and_get_optional_command_arguments( + {OPTION_DRY_RUN, OPTION_USE_HEAD_VERSION, OPTION_NO_DOWNLOADS, OPTION_RECURSE, OPTION_KEEP_GOING}); + const bool dry_run = options.find(OPTION_DRY_RUN) != options.cend(); + const bool use_head_version = options.find(OPTION_USE_HEAD_VERSION) != options.cend(); + const bool no_downloads = options.find(OPTION_NO_DOWNLOADS) != options.cend(); + const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); + const KeepGoing keep_going = to_keep_going(options.find(OPTION_KEEP_GOING) != options.cend()); + + // create the plan + StatusParagraphs status_db = database_load_check(paths); + + const Build::BuildPackageOptions install_plan_options = {Build::to_use_head_version(use_head_version), + Build::to_allow_downloads(!no_downloads)}; + + std::vector action_plan; + + if (GlobalState::feature_packages) + { + std::unordered_map scf_map; + auto all_ports = Paragraphs::load_all_ports(paths.get_filesystem(), paths.ports); + for (auto&& port : all_ports) + { + scf_map[port->core_paragraph->name] = std::move(*port); + } + action_plan = create_feature_install_plan(scf_map, FullPackageSpec::to_feature_specs(specs), status_db); + } + else + { + Dependencies::PathsPortFile paths_port_file(paths); + auto install_plan = Dependencies::create_install_plan( + paths_port_file, Util::fmap(specs, [](auto&& spec) { return spec.package_spec; }), status_db); + + action_plan = Util::fmap( + install_plan, [](InstallPlanAction& install_action) { return AnyAction(std::move(install_action)); }); + } + + // install plan will be empty if it is already installed - need to change this at status paragraph part + Checks::check_exit(VCPKG_LINE_INFO, !action_plan.empty(), "Install plan cannot be empty"); + + // log the plan + const std::string specs_string = Strings::join(",", action_plan, [](const AnyAction& action) { + if (auto iaction = action.install_plan.get()) + return iaction->spec.to_string(); + else if (auto raction = action.remove_plan.get()) + return "R$" + raction->spec.to_string(); + Checks::unreachable(VCPKG_LINE_INFO); + }); + + Metrics::g_metrics.lock()->track_property("installplan", specs_string); + + print_plan(action_plan, is_recursive); + + if (dry_run) + { + Checks::exit_success(VCPKG_LINE_INFO); + } + + perform_and_exit_ex(action_plan, install_plan_options, keep_going, PrintSummary::NO, paths, status_db); + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/metrics.cpp b/toolsrc/src/vcpkg/metrics.cpp new file mode 100644 index 000000000..84c1ee208 --- /dev/null +++ b/toolsrc/src/vcpkg/metrics.cpp @@ -0,0 +1,398 @@ +#include "pch.h" + +#include + +#include +#include +#include + +#pragma comment(lib, "version") +#pragma comment(lib, "winhttp") + +namespace vcpkg::Metrics +{ + Util::LockGuarded g_metrics; + + static std::string get_current_date_time() + { + struct tm newtime; + std::array date; + date.fill(0); + + struct _timeb timebuffer; + + _ftime_s(&timebuffer); + time_t now = timebuffer.time; + const int milli = timebuffer.millitm; + + const errno_t err = gmtime_s(&newtime, &now); + if (err) + { + return Strings::EMPTY; + } + + strftime(&date[0], date.size(), "%Y-%m-%dT%H:%M:%S", &newtime); + return std::string(&date[0]) + "." + std::to_string(milli) + "Z"; + } + + static std::string generate_random_UUID() + { + int part_sizes[] = {8, 4, 4, 4, 12}; + char uuid[37]; + memset(uuid, 0, sizeof(uuid)); + int num; + srand(static_cast(time(nullptr))); + int index = 0; + for (int part = 0; part < 5; part++) + { + if (part > 0) + { + uuid[index] = '-'; + index++; + } + + // Generating UUID format version 4 + // http://en.wikipedia.org/wiki/Universally_unique_identifier + for (int i = 0; i < part_sizes[part]; i++, index++) + { + if (part == 2 && i == 0) + { + num = 4; + } + else if (part == 4 && i == 0) + { + num = (rand() % 4) + 8; + } + else + { + num = rand() % 16; + } + + if (num < 10) + { + uuid[index] = static_cast('0' + num); + } + else + { + uuid[index] = static_cast('a' + (num - 10)); + } + } + } + + return uuid; + } + + static const std::string& get_session_id() + { + static const std::string ID = generate_random_UUID(); + return ID; + } + + static std::string to_json_string(const std::string& str) + { + std::string encoded = "\""; + for (auto&& ch : str) + { + if (ch == '\\') + { + encoded.append("\\\\"); + } + else if (ch == '"') + { + encoded.append("\\\""); + } + else if (ch < 0x20 || ch >= 0x80) + { + // Note: this treats incoming Strings as Latin-1 + static constexpr const char HEX[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + encoded.append("\\u00"); + encoded.push_back(HEX[ch / 16]); + encoded.push_back(HEX[ch % 16]); + } + else + { + encoded.push_back(ch); + } + } + encoded.push_back('"'); + return encoded; + } + + static std::string get_os_version_string() + { + std::wstring path; + path.resize(MAX_PATH); + const auto n = GetSystemDirectoryW(&path[0], static_cast(path.size())); + path.resize(n); + path += L"\\kernel32.dll"; + + const auto versz = GetFileVersionInfoSizeW(path.c_str(), nullptr); + if (versz == 0) return Strings::EMPTY; + + std::vector verbuf; + verbuf.resize(versz); + + if (!GetFileVersionInfoW(path.c_str(), 0, static_cast(verbuf.size()), &verbuf[0])) return Strings::EMPTY; + + void* rootblock; + UINT rootblocksize; + if (!VerQueryValueW(&verbuf[0], L"\\", &rootblock, &rootblocksize)) return Strings::EMPTY; + + auto rootblock_ffi = static_cast(rootblock); + + return Strings::format("%d.%d.%d", + static_cast(HIWORD(rootblock_ffi->dwProductVersionMS)), + static_cast(LOWORD(rootblock_ffi->dwProductVersionMS)), + static_cast(HIWORD(rootblock_ffi->dwProductVersionLS))); + } + + struct MetricMessage + { + std::string user_id = generate_random_UUID(); + std::string user_timestamp; + std::string timestamp = get_current_date_time(); + std::string properties; + std::string measurements; + + void track_property(const std::string& name, const std::string& value) + { + if (properties.size() != 0) properties.push_back(','); + properties.append(to_json_string(name)); + properties.push_back(':'); + properties.append(to_json_string(value)); + } + + void track_metric(const std::string& name, double value) + { + if (measurements.size() != 0) measurements.push_back(','); + measurements.append(to_json_string(name)); + measurements.push_back(':'); + measurements.append(std::to_string(value)); + } + + std::string format_event_data_template() const + { + const std::string& session_id = get_session_id(); + return Strings::format(R"([{ + "ver": 1, + "name": "Microsoft.ApplicationInsights.Event", + "time": "%s", + "sampleRate": 100.000000, + "seq": "0:0", + "iKey": "b4e88960-4393-4dd9-ab8e-97e8fe6d7603", + "flags": 0.000000, + "tags": { + "ai.device.os": "Windows", + "ai.device.osVersion": "%s", + "ai.session.id": "%s", + "ai.user.id": "%s", + "ai.user.accountAcquisitionDate": "%s" + }, + "data": { + "baseType": "EventData", + "baseData": { + "ver": 2, + "name": "commandline_test7", + "properties": { %s }, + "measurements": { %s } + } + } +}])", + timestamp, + get_os_version_string(), + session_id, + user_id, + user_timestamp, + properties, + measurements); + } + }; + + static MetricMessage g_metricmessage; + static bool g_should_send_metrics = +#if defined(NDEBUG) && (DISABLE_METRICS == 0) + true +#else + false +#endif + ; + static bool g_should_print_metrics = false; + + bool get_compiled_metrics_enabled() { return DISABLE_METRICS == 0; } + + std::wstring get_SQM_user() + { + auto hkcu_sqmclient = + System::get_registry_string(HKEY_CURRENT_USER, LR"(Software\Microsoft\SQMClient)", L"UserId"); + return hkcu_sqmclient.value_or(L"{}"); + } + + void Metrics::set_user_information(const std::string& user_id, const std::string& first_use_time) + { + g_metricmessage.user_id = user_id; + g_metricmessage.user_timestamp = first_use_time; + } + + void Metrics::init_user_information(std::string& user_id, std::string& first_use_time) + { + user_id = generate_random_UUID(); + first_use_time = get_current_date_time(); + } + + void Metrics::set_send_metrics(bool should_send_metrics) { g_should_send_metrics = should_send_metrics; } + + void Metrics::set_print_metrics(bool should_print_metrics) { g_should_print_metrics = should_print_metrics; } + + void Metrics::track_metric(const std::string& name, double value) { g_metricmessage.track_metric(name, value); } + + void Metrics::track_property(const std::string& name, const std::wstring& value) + { + // Note: this is not valid UTF-16 -> UTF-8, it just yields a close enough approximation for our purposes. + std::string converted_value; + converted_value.resize(value.size()); + std::transform( + value.begin(), value.end(), converted_value.begin(), [](wchar_t ch) { return static_cast(ch); }); + + g_metricmessage.track_property(name, converted_value); + } + + void Metrics::track_property(const std::string& name, const std::string& value) + { + g_metricmessage.track_property(name, value); + } + + void Metrics::upload(const std::string& payload) + { + HINTERNET connect = nullptr, request = nullptr; + BOOL results = FALSE; + + const HINTERNET session = WinHttpOpen( + L"vcpkg/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); + if (session) connect = WinHttpConnect(session, L"dc.services.visualstudio.com", INTERNET_DEFAULT_HTTPS_PORT, 0); + + if (connect) + request = WinHttpOpenRequest(connect, + L"POST", + L"/v2/track", + nullptr, + WINHTTP_NO_REFERER, + WINHTTP_DEFAULT_ACCEPT_TYPES, + WINHTTP_FLAG_SECURE); + + if (request) + { + if (MAXDWORD <= payload.size()) abort(); + std::wstring hdrs = L"Content-Type: application/json\r\n"; + std::string& p = const_cast(payload); + results = WinHttpSendRequest(request, + hdrs.c_str(), + static_cast(hdrs.size()), + static_cast(&p[0]), + static_cast(payload.size()), + static_cast(payload.size()), + 0); + } + + if (results) + { + results = WinHttpReceiveResponse(request, nullptr); + } + + DWORD http_code = 0, junk = sizeof(DWORD); + + if (results) + { + results = WinHttpQueryHeaders(request, + WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, + nullptr, + &http_code, + &junk, + WINHTTP_NO_HEADER_INDEX); + } + + std::vector response_buffer; + if (results) + { + DWORD available_data = 0, read_data = 0, total_data = 0; + while ((results = WinHttpQueryDataAvailable(request, &available_data)) == TRUE && available_data > 0) + { + response_buffer.resize(response_buffer.size() + available_data); + + results = WinHttpReadData(request, &response_buffer.data()[total_data], available_data, &read_data); + + if (!results) + { + break; + } + + total_data += read_data; + + response_buffer.resize(total_data); + } + } + + if (!results) + { +#ifndef NDEBUG + __debugbreak(); + auto err = GetLastError(); + std::cerr << "[DEBUG] failed to connect to server: " << err << "\n"; +#endif + } + + if (request) WinHttpCloseHandle(request); + if (connect) WinHttpCloseHandle(connect); + if (session) WinHttpCloseHandle(session); + } + + static fs::path get_bindir() + { + wchar_t buf[_MAX_PATH]; + const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); + if (bytes == 0) std::abort(); + return fs::path(buf, buf + bytes); + } + + void Metrics::flush() + { + const std::string payload = g_metricmessage.format_event_data_template(); + if (g_should_print_metrics) std::cerr << payload << "\n"; + if (!g_should_send_metrics) return; + + // upload(payload); + + wchar_t temp_folder[MAX_PATH]; + GetTempPathW(MAX_PATH, temp_folder); + + const fs::path temp_folder_path = temp_folder; + const fs::path temp_folder_path_exe = temp_folder_path / "vcpkgmetricsuploader.exe"; + + auto& fs = Files::get_real_filesystem(); + + if (true) + { + const fs::path exe_path = [&fs]() -> fs::path { + auto vcpkgdir = get_bindir().parent_path(); + auto path = vcpkgdir / "vcpkgmetricsuploader.exe"; + if (fs.exists(path)) return path; + + path = vcpkgdir / "scripts" / "vcpkgmetricsuploader.exe"; + if (fs.exists(path)) return path; + + return Strings::WEMPTY; + }(); + + std::error_code ec; + fs.copy_file(exe_path, temp_folder_path_exe, fs::copy_options::skip_existing, ec); + if (ec) return; + } + + const fs::path vcpkg_metrics_txt_path = temp_folder_path / ("vcpkg" + generate_random_UUID() + ".txt"); + fs.write_contents(vcpkg_metrics_txt_path, payload); + + const std::wstring cmd_line = + Strings::wformat(L"start %s %s", temp_folder_path_exe.native(), vcpkg_metrics_txt_path.native()); + System::cmd_execute_clean(cmd_line); + } +} diff --git a/toolsrc/src/vcpkg/packagespec.cpp b/toolsrc/src/vcpkg/packagespec.cpp new file mode 100644 index 000000000..01a09618d --- /dev/null +++ b/toolsrc/src/vcpkg/packagespec.cpp @@ -0,0 +1,175 @@ +#include "pch.h" + +#include +#include +#include + +using vcpkg::Parse::parse_comma_list; + +namespace vcpkg +{ + static bool is_valid_package_spec_char(char c) + { + return (c == '-') || isdigit(c) || (isalpha(c) && islower(c)) || (c == '[') || (c == ']'); + } + + std::string FeatureSpec::to_string() const + { + if (feature().empty()) return spec().to_string(); + return Strings::format("%s[%s]:%s", name(), feature(), triplet()); + } + + std::vector FeatureSpec::from_strings_and_triplet(const std::vector& depends, + const Triplet& triplet) + { + std::vector f_specs; + for (auto&& depend : depends) + { + auto maybe_spec = ParsedSpecifier::from_string(depend); + if (auto spec = maybe_spec.get()) + { + Checks::check_exit(VCPKG_LINE_INFO, + spec->triplet.empty(), + "error: triplets cannot currently be specified in this context: %s", + depend); + PackageSpec pspec = + PackageSpec::from_name_and_triplet(spec->name, triplet).value_or_exit(VCPKG_LINE_INFO); + + for (auto&& feature : spec->features) + f_specs.push_back(FeatureSpec{pspec, feature}); + + if (spec->features.empty()) f_specs.push_back(FeatureSpec{pspec, Strings::EMPTY}); + } + else + { + Checks::exit_with_message(VCPKG_LINE_INFO, + "error while parsing feature list: %s: %s", + vcpkg::to_string(maybe_spec.error()), + depend); + } + } + return f_specs; + } + + std::vector FullPackageSpec::to_feature_specs(const std::vector& specs) + { + std::vector ret; + for (auto&& spec : specs) + { + ret.emplace_back(spec.package_spec, Strings::EMPTY); + for (auto&& feature : spec.features) + ret.emplace_back(spec.package_spec, feature); + } + return ret; + } + + ExpectedT FullPackageSpec::from_string(const std::string& spec_as_string, + const Triplet& default_triplet) + { + auto res = ParsedSpecifier::from_string(spec_as_string); + if (auto p = res.get()) + { + FullPackageSpec fspec; + Triplet t = p->triplet.empty() ? default_triplet : Triplet::from_canonical_name(p->triplet); + fspec.package_spec = PackageSpec::from_name_and_triplet(p->name, t).value_or_exit(VCPKG_LINE_INFO); + fspec.features = std::move(p->features); + return fspec; + } + return res.error(); + } + + ExpectedT PackageSpec::from_name_and_triplet(const std::string& name, + const Triplet& triplet) + { + if (Util::find_if_not(name, is_valid_package_spec_char) != name.end()) + { + return PackageSpecParseResult::INVALID_CHARACTERS; + } + + PackageSpec p; + p.m_name = name; + p.m_triplet = triplet; + return p; + } + + const std::string& PackageSpec::name() const { return this->m_name; } + + const Triplet& PackageSpec::triplet() const { return this->m_triplet; } + + std::string PackageSpec::dir() const { return Strings::format("%s_%s", this->m_name, this->m_triplet); } + + std::string PackageSpec::to_string() const { return Strings::format("%s:%s", this->name(), this->triplet()); } + + bool operator==(const PackageSpec& left, const PackageSpec& right) + { + return left.name() == right.name() && left.triplet() == right.triplet(); + } + + bool operator!=(const PackageSpec& left, const PackageSpec& right) { return !(left == right); } + + ExpectedT ParsedSpecifier::from_string(const std::string& input) + { + auto pos = input.find(':'); + auto pos_l_bracket = input.find('['); + auto pos_r_bracket = input.find(']'); + + ParsedSpecifier f; + if (pos == std::string::npos && pos_l_bracket == std::string::npos) + { + f.name = input; + return f; + } + else if (pos == std::string::npos) + { + if (pos_r_bracket == std::string::npos || pos_l_bracket >= pos_r_bracket) + { + return PackageSpecParseResult::INVALID_CHARACTERS; + } + const std::string name = input.substr(0, pos_l_bracket); + f.name = name; + f.features = parse_comma_list(input.substr(pos_l_bracket + 1, pos_r_bracket - pos_l_bracket - 1)); + return f; + } + else if (pos_l_bracket == std::string::npos && pos_r_bracket == std::string::npos) + { + const std::string name = input.substr(0, pos); + f.triplet = input.substr(pos + 1); + f.name = name; + } + else + { + if (pos_r_bracket == std::string::npos || pos_l_bracket >= pos_r_bracket) + { + return PackageSpecParseResult::INVALID_CHARACTERS; + } + const std::string name = input.substr(0, pos_l_bracket); + f.features = parse_comma_list(input.substr(pos_l_bracket + 1, pos_r_bracket - pos_l_bracket - 1)); + f.triplet = input.substr(pos + 1); + f.name = name; + } + + auto pos2 = input.find(':', pos + 1); + if (pos2 != std::string::npos) + { + return PackageSpecParseResult::TOO_MANY_COLONS; + } + return f; + } + + ExpectedT Features::from_string(const std::string& name) + { + auto maybe_spec = ParsedSpecifier::from_string(name); + if (auto spec = maybe_spec.get()) + { + Checks::check_exit( + VCPKG_LINE_INFO, spec->triplet.empty(), "error: triplet not allowed in specifier: %s", name); + + Features f; + f.name = spec->name; + f.features = spec->features; + return f; + } + + return maybe_spec.error(); + } +} diff --git a/toolsrc/src/vcpkg/packagespecparseresult.cpp b/toolsrc/src/vcpkg/packagespecparseresult.cpp new file mode 100644 index 000000000..b12bd12d0 --- /dev/null +++ b/toolsrc/src/vcpkg/packagespecparseresult.cpp @@ -0,0 +1,21 @@ +#include "pch.h" + +#include + +#include + +namespace vcpkg +{ + CStringView to_string(PackageSpecParseResult ev) noexcept + { + switch (ev) + { + case PackageSpecParseResult::SUCCESS: return "OK"; + case PackageSpecParseResult::TOO_MANY_COLONS: return "Too many colons"; + case PackageSpecParseResult::INVALID_CHARACTERS: + return "Contains invalid characters. Only alphanumeric lowercase ASCII characters and dashes are " + "allowed"; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } +} diff --git a/toolsrc/src/vcpkg/paragraphparseresult.cpp b/toolsrc/src/vcpkg/paragraphparseresult.cpp new file mode 100644 index 000000000..920a4b16b --- /dev/null +++ b/toolsrc/src/vcpkg/paragraphparseresult.cpp @@ -0,0 +1,34 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg +{ + const char* ParagraphParseResultCategoryImpl::name() const noexcept { return "ParagraphParseResult"; } + + std::string ParagraphParseResultCategoryImpl::message(int ev) const noexcept + { + switch (static_cast(ev)) + { + case ParagraphParseResult::SUCCESS: return "OK"; + case ParagraphParseResult::EXPECTED_ONE_PARAGRAPH: return "There should be exactly one paragraph"; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + const std::error_category& paragraph_parse_result_category() + { + static ParagraphParseResultCategoryImpl instance; + return instance; + } + + std::error_code make_error_code(ParagraphParseResult e) + { + return std::error_code(static_cast(e), paragraph_parse_result_category()); + } + + ParagraphParseResult to_paragraph_parse_result(int i) { return static_cast(i); } + + ParagraphParseResult to_paragraph_parse_result(std::error_code ec) { return to_paragraph_parse_result(ec.value()); } +} diff --git a/toolsrc/src/vcpkg/paragraphs.cpp b/toolsrc/src/vcpkg/paragraphs.cpp new file mode 100644 index 000000000..b93de190c --- /dev/null +++ b/toolsrc/src/vcpkg/paragraphs.cpp @@ -0,0 +1,304 @@ +#include "pch.h" + +#include +#include +#include +#include +#include + +using namespace vcpkg::Parse; + +namespace vcpkg::Paragraphs +{ + struct Parser + { + Parser(const char* c, const char* e) : cur(c), end(e) {} + + private: + const char* cur; + const char* const end; + + void peek(char& ch) const + { + if (cur == end) + ch = 0; + else + ch = *cur; + } + + void next(char& ch) + { + if (cur == end) + ch = 0; + else + { + ++cur; + peek(ch); + } + } + + void skip_comment(char& ch) + { + while (ch != '\r' && ch != '\n' && ch != '\0') + next(ch); + if (ch == '\r') next(ch); + if (ch == '\n') next(ch); + } + + void skip_spaces(char& ch) + { + while (ch == ' ' || ch == '\t') + next(ch); + } + + static bool is_alphanum(char ch) + { + return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'); + } + + static bool is_comment(char ch) { return (ch == '#'); } + + static bool is_lineend(char ch) { return ch == '\r' || ch == '\n' || ch == 0; } + + void get_fieldvalue(char& ch, std::string& fieldvalue) + { + fieldvalue.clear(); + + auto beginning_of_line = cur; + do + { + // scan to end of current line (it is part of the field value) + while (!is_lineend(ch)) + next(ch); + + fieldvalue.append(beginning_of_line, cur); + + if (ch == '\r') next(ch); + if (ch == '\n') next(ch); + + if (is_alphanum(ch) || is_comment(ch)) + { + // Line begins a new field. + return; + } + + beginning_of_line = cur; + + // Line may continue the current field with data or terminate the paragraph, + // depending on first nonspace character. + skip_spaces(ch); + + if (is_lineend(ch)) + { + // Line was whitespace or empty. + // This terminates the field and the paragraph. + // We leave the blank line's whitespace consumed, because it doesn't matter. + return; + } + + // First nonspace is not a newline. This continues the current field value. + // We forcibly convert all newlines into single '\n' for ease of text handling later on. + fieldvalue.push_back('\n'); + } while (true); + } + + void get_fieldname(char& ch, std::string& fieldname) + { + auto begin_fieldname = cur; + while (is_alphanum(ch) || ch == '-') + next(ch); + Checks::check_exit(VCPKG_LINE_INFO, ch == ':', "Expected ':'"); + fieldname = std::string(begin_fieldname, cur); + + // skip ': ' + next(ch); + skip_spaces(ch); + } + + void get_paragraph(char& ch, std::unordered_map& fields) + { + fields.clear(); + std::string fieldname; + std::string fieldvalue; + do + { + if (is_comment(ch)) + { + skip_comment(ch); + continue; + } + + get_fieldname(ch, fieldname); + + auto it = fields.find(fieldname); + Checks::check_exit(VCPKG_LINE_INFO, it == fields.end(), "Duplicate field"); + + get_fieldvalue(ch, fieldvalue); + + fields.emplace(fieldname, fieldvalue); + } while (!is_lineend(ch)); + } + + public: + std::vector> get_paragraphs() + { + std::vector> paragraphs; + + char ch; + peek(ch); + + while (ch != 0) + { + if (ch == '\n' || ch == '\r' || ch == ' ' || ch == '\t') + { + next(ch); + continue; + } + + paragraphs.emplace_back(); + get_paragraph(ch, paragraphs.back()); + } + + return paragraphs; + } + }; + + Expected> get_single_paragraph(const Files::Filesystem& fs, + const fs::path& control_path) + { + const Expected contents = fs.read_contents(control_path); + if (auto spgh = contents.get()) + { + return parse_single_paragraph(*spgh); + } + + return contents.error(); + } + + Expected>> get_paragraphs(const Files::Filesystem& fs, + const fs::path& control_path) + { + const Expected contents = fs.read_contents(control_path); + if (auto spgh = contents.get()) + { + return parse_paragraphs(*spgh); + } + + return contents.error(); + } + + Expected> parse_single_paragraph(const std::string& str) + { + const std::vector> p = + Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs(); + + if (p.size() == 1) + { + return p.at(0); + } + + return std::error_code(ParagraphParseResult::EXPECTED_ONE_PARAGRAPH); + } + + Expected>> parse_paragraphs(const std::string& str) + { + return Parser(str.c_str(), str.c_str() + str.size()).get_paragraphs(); + } + + ParseExpected try_load_port(const Files::Filesystem& fs, const fs::path& path) + { + Expected>> pghs = get_paragraphs(fs, path / "CONTROL"); + if (auto vector_pghs = pghs.get()) + { + auto csf = SourceControlFile::parse_control_file(std::move(*vector_pghs)); + if (!GlobalState::feature_packages) + { + if (auto ptr = csf.get()) + { + Checks::check_exit(VCPKG_LINE_INFO, ptr->get() != nullptr); + ptr->get()->core_paragraph->default_features.clear(); + ptr->get()->feature_paragraphs.clear(); + } + } + return csf; + } + auto error_info = std::make_unique(); + error_info->name = path.filename().generic_u8string(); + error_info->error = pghs.error(); + return error_info; + } + + Expected try_load_cached_control_package(const VcpkgPaths& paths, const PackageSpec& spec) + { + Expected>> pghs = + get_paragraphs(paths.get_filesystem(), paths.package_dir(spec) / "CONTROL"); + + if (auto p = pghs.get()) + { + BinaryControlFile bcf; + bcf.core_paragraph = BinaryParagraph(p->front()); + p->erase(p->begin()); + + bcf.features = + Util::fmap(*p, [&](auto&& raw_feature) -> BinaryParagraph { return BinaryParagraph(raw_feature); }); + + return bcf; + } + + return pghs.error(); + } + + LoadResults try_load_all_ports(const Files::Filesystem& fs, const fs::path& ports_dir) + { + LoadResults ret; + for (auto&& path : fs.get_files_non_recursive(ports_dir)) + { + auto maybe_spgh = try_load_port(fs, path); + if (const auto spgh = maybe_spgh.get()) + { + ret.paragraphs.emplace_back(std::move(*spgh)); + } + else + { + ret.errors.emplace_back(std::move(maybe_spgh).error()); + } + } + return ret; + } + + std::vector> load_all_ports(const Files::Filesystem& fs, + const fs::path& ports_dir) + { + auto results = try_load_all_ports(fs, ports_dir); + if (!results.errors.empty()) + { + if (GlobalState::debugging) + { + print_error_message(results.errors); + } + else + { + for (auto&& error : results.errors) + { + System::println( + System::Color::warning, "Warning: an error occurred while parsing '%s'", error->name); + } + System::println(System::Color::warning, + "Use '--debug' to get more information about the parse failures.\n"); + } + } + return std::move(results.paragraphs); + } + + std::map load_all_port_names_and_versions(const Files::Filesystem& fs, + const fs::path& ports_dir) + { + auto all_ports = load_all_ports(fs, ports_dir); + + std::map names_and_versions; + for (auto&& port : all_ports) + names_and_versions.emplace(port->core_paragraph->name, port->core_paragraph->version); + + return names_and_versions; + } +} diff --git a/toolsrc/src/vcpkg/parse.cpp b/toolsrc/src/vcpkg/parse.cpp new file mode 100644 index 000000000..116a7f5c8 --- /dev/null +++ b/toolsrc/src/vcpkg/parse.cpp @@ -0,0 +1,81 @@ +#include "pch.h" + +#include + +#include +#include + +namespace vcpkg::Parse +{ + static Optional remove_field(std::unordered_map* fields, + const std::string& fieldname) + { + auto it = fields->find(fieldname); + if (it == fields->end()) + { + return nullopt; + } + + const std::string value = std::move(it->second); + fields->erase(it); + return value; + } + + void ParagraphParser::required_field(const std::string& fieldname, std::string& out) + { + auto maybe_field = remove_field(&fields, fieldname); + if (const auto field = maybe_field.get()) + out = std::move(*field); + else + missing_fields.push_back(fieldname); + } + std::string ParagraphParser::optional_field(const std::string& fieldname) const + { + return remove_field(&fields, fieldname).value_or(Strings::EMPTY); + } + std::unique_ptr ParagraphParser::error_info(const std::string& name) const + { + if (!fields.empty() || !missing_fields.empty()) + { + auto err = std::make_unique(); + err->name = name; + err->extra_fields = Util::extract_keys(fields); + err->missing_fields = std::move(missing_fields); + return err; + } + return nullptr; + } + + std::vector parse_comma_list(const std::string& str) + { + if (str.empty()) + { + return {}; + } + + std::vector out; + + size_t cur = 0; + do + { + auto pos = str.find(',', cur); + if (pos == std::string::npos) + { + out.push_back(str.substr(cur)); + break; + } + out.push_back(str.substr(cur, pos - cur)); + + // skip comma and space + ++pos; + if (str[pos] == ' ') + { + ++pos; + } + + cur = pos; + } while (cur != std::string::npos); + + return out; + } +} diff --git a/toolsrc/src/vcpkg/postbuildlint.buildtype.cpp b/toolsrc/src/vcpkg/postbuildlint.buildtype.cpp new file mode 100644 index 000000000..2baaddb5e --- /dev/null +++ b/toolsrc/src/vcpkg/postbuildlint.buildtype.cpp @@ -0,0 +1,70 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg::PostBuildLint +{ + BuildType BuildType::value_of(const ConfigurationType& config, const Build::LinkageType& linkage) + { + if (config == ConfigurationType::DEBUG && linkage == Build::LinkageType::STATIC) + { + return BuildTypeC::DEBUG_STATIC; + } + + if (config == ConfigurationType::DEBUG && linkage == Build::LinkageType::DYNAMIC) + { + return BuildTypeC::DEBUG_DYNAMIC; + } + + if (config == ConfigurationType::RELEASE && linkage == Build::LinkageType::STATIC) + { + return BuildTypeC::RELEASE_STATIC; + } + + if (config == ConfigurationType::RELEASE && linkage == Build::LinkageType::DYNAMIC) + { + return BuildTypeC::RELEASE_DYNAMIC; + } + + Checks::unreachable(VCPKG_LINE_INFO); + } + + const ConfigurationType& BuildType::config() const { return this->m_config; } + + const Build::LinkageType& BuildType::linkage() const { return this->m_linkage; } + + const std::regex& BuildType::crt_regex() const + { + static const std::regex REGEX_DEBUG_STATIC(R"(/DEFAULTLIB:LIBCMTD)", std::regex_constants::icase); + static const std::regex REGEX_DEBUG_DYNAMIC(R"(/DEFAULTLIB:MSVCRTD)", std::regex_constants::icase); + static const std::regex REGEX_RELEASE_STATIC(R"(/DEFAULTLIB:LIBCMT[^D])", std::regex_constants::icase); + static const std::regex REGEX_RELEASE_DYNAMIC(R"(/DEFAULTLIB:MSVCRT[^D])", std::regex_constants::icase); + + switch (backing_enum) + { + case BuildTypeC::DEBUG_STATIC: return REGEX_DEBUG_STATIC; + case BuildTypeC::DEBUG_DYNAMIC: return REGEX_DEBUG_DYNAMIC; + case BuildTypeC::RELEASE_STATIC: return REGEX_RELEASE_STATIC; + case BuildTypeC::RELEASE_DYNAMIC: return REGEX_RELEASE_DYNAMIC; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + const std::string& BuildType::to_string() const + { + static const std::string NAME_DEBUG_STATIC("Debug,Static"); + static const std::string NAME_DEBUG_DYNAMIC("Debug,Dynamic"); + static const std::string NAME_RELEASE_STATIC("Release,Static"); + static const std::string NAME_RELEASE_DYNAMIC("Release,Dynamic"); + + switch (backing_enum) + { + case BuildTypeC::DEBUG_STATIC: return NAME_DEBUG_STATIC; + case BuildTypeC::DEBUG_DYNAMIC: return NAME_DEBUG_DYNAMIC; + case BuildTypeC::RELEASE_STATIC: return NAME_RELEASE_STATIC; + case BuildTypeC::RELEASE_DYNAMIC: return NAME_RELEASE_DYNAMIC; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } +} diff --git a/toolsrc/src/vcpkg/postbuildlint.cpp b/toolsrc/src/vcpkg/postbuildlint.cpp new file mode 100644 index 000000000..5f55249df --- /dev/null +++ b/toolsrc/src/vcpkg/postbuildlint.cpp @@ -0,0 +1,846 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using vcpkg::Build::BuildInfo; +using vcpkg::Build::BuildPolicy; +using vcpkg::Build::PreBuildInfo; + +namespace vcpkg::PostBuildLint +{ + static auto has_extension_pred(const Files::Filesystem& fs, const std::string& ext) + { + return [&fs, ext](const fs::path& path) { return !fs.is_directory(path) && path.extension() == ext; }; + } + + enum class LintStatus + { + SUCCESS = 0, + ERROR_DETECTED = 1 + }; + + struct OutdatedDynamicCrt + { + std::string name; + std::regex regex; + + OutdatedDynamicCrt(const std::string& name, const std::string& regex_as_string) + : name(name), regex(std::regex(regex_as_string, std::regex_constants::icase)) + { + } + }; + + Span get_outdated_dynamic_crts(CStringView toolset) + { + static const std::vector V_NO_MSVCRT = { + {"msvcp100.dll", R"(msvcp100\.dll)"}, + {"msvcp100d.dll", R"(msvcp100d\.dll)"}, + {"msvcp110.dll", R"(msvcp110\.dll)"}, + {"msvcp110_win.dll", R"(msvcp110_win\.dll)"}, + {"msvcp120.dll", R"(msvcp120\.dll)"}, + {"msvcp120_clr0400.dll", R"(msvcp120_clr0400\.dll)"}, + {"msvcp60.dll", R"(msvcp60\.dll)"}, + {"msvcp60.dll", R"(msvcp60\.dll)"}, + + {"msvcr100.dll", R"(msvcr100\.dll)"}, + {"msvcr100d.dll", R"(msvcr100d\.dll)"}, + {"msvcr100_clr0400.dll", R"(msvcr100_clr0400\.dll)"}, + {"msvcr110.dll", R"(msvcr110\.dll)"}, + {"msvcr120.dll", R"(msvcr120\.dll)"}, + {"msvcr120_clr0400.dll", R"(msvcr120_clr0400\.dll)"}, + {"msvcrt20.dll", R"(msvcrt20\.dll)"}, + {"msvcrt40.dll", R"(msvcrt40\.dll)"}}; + + return V_NO_MSVCRT; + } + + static LintStatus check_for_files_in_include_directory(const Files::Filesystem& fs, + const Build::BuildPolicies& policies, + const fs::path& package_dir) + { + if (policies.is_enabled(BuildPolicy::EMPTY_INCLUDE_FOLDER)) + { + return LintStatus::SUCCESS; + } + + const fs::path include_dir = package_dir / "include"; + if (!fs.exists(include_dir) || fs.is_empty(include_dir)) + { + System::println(System::Color::warning, + "The folder /include is empty. This indicates the library was not correctly installed."); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_for_files_in_debug_include_directory(const Files::Filesystem& fs, + const fs::path& package_dir) + { + const fs::path debug_include_dir = package_dir / "debug" / "include"; + + std::vector files_found = fs.get_files_recursive(debug_include_dir); + + Util::unstable_keep_if( + files_found, [&fs](const fs::path& path) { return !fs.is_directory(path) && path.extension() != ".ifc"; }); + + if (!files_found.empty()) + { + System::println(System::Color::warning, + "Include files should not be duplicated into the /debug/include directory. If this cannot " + "be disabled in the project cmake, use\n" + " file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include)"); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_for_files_in_debug_share_directory(const Files::Filesystem& fs, const fs::path& package_dir) + { + const fs::path debug_share = package_dir / "debug" / "share"; + + if (fs.exists(debug_share)) + { + System::println(System::Color::warning, + "/debug/share should not exist. Please reorganize any important files, then use\n" + " file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/share)"); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_folder_lib_cmake(const Files::Filesystem& fs, + const fs::path& package_dir, + const PackageSpec& spec) + { + const fs::path lib_cmake = package_dir / "lib" / "cmake"; + if (fs.exists(lib_cmake)) + { + System::println( + System::Color::warning, + "The /lib/cmake folder should be merged with /debug/lib/cmake and moved to /share/%s/cmake.", + spec.name()); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_for_misplaced_cmake_files(const Files::Filesystem& fs, + const fs::path& package_dir, + const PackageSpec& spec) + { + std::vector dirs = { + package_dir / "cmake", + package_dir / "debug" / "cmake", + package_dir / "lib" / "cmake", + package_dir / "debug" / "lib" / "cmake", + }; + + std::vector misplaced_cmake_files; + for (auto&& dir : dirs) + { + auto files = fs.get_files_recursive(dir); + for (auto&& file : files) + { + if (!fs.is_directory(file) && file.extension() == ".cmake") + misplaced_cmake_files.push_back(std::move(file)); + } + } + + if (!misplaced_cmake_files.empty()) + { + System::println( + System::Color::warning, + "The following cmake files were found outside /share/%s. Please place cmake files in /share/%s.", + spec.name(), + spec.name()); + Files::print_paths(misplaced_cmake_files); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_folder_debug_lib_cmake(const Files::Filesystem& fs, + const fs::path& package_dir, + const PackageSpec& spec) + { + const fs::path lib_cmake_debug = package_dir / "debug" / "lib" / "cmake"; + if (fs.exists(lib_cmake_debug)) + { + System::println(System::Color::warning, + "The /debug/lib/cmake folder should be merged with /lib/cmake into /share/%s", + spec.name()); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_for_dlls_in_lib_dir(const Files::Filesystem& fs, const fs::path& package_dir) + { + std::vector dlls = fs.get_files_recursive(package_dir / "lib"); + Util::unstable_keep_if(dlls, has_extension_pred(fs, ".dll")); + + if (!dlls.empty()) + { + System::println(System::Color::warning, + "\nThe following dlls were found in /lib or /debug/lib. Please move them to /bin or " + "/debug/bin, respectively."); + Files::print_paths(dlls); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_for_copyright_file(const Files::Filesystem& fs, + const PackageSpec& spec, + const VcpkgPaths& paths) + { + const fs::path packages_dir = paths.packages / spec.dir(); + const fs::path copyright_file = packages_dir / "share" / spec.name() / "copyright"; + if (fs.exists(copyright_file)) + { + return LintStatus::SUCCESS; + } + const fs::path current_buildtrees_dir = paths.buildtrees / spec.name(); + const fs::path current_buildtrees_dir_src = current_buildtrees_dir / "src"; + + std::vector potential_copyright_files; + // We only search in the root of each unpacked source archive to reduce false positives + auto src_dirs = fs.get_files_non_recursive(current_buildtrees_dir_src); + for (auto&& src_dir : src_dirs) + { + if (!fs.is_directory(src_dir)) continue; + + for (auto&& src_file : fs.get_files_non_recursive(src_dir)) + { + const std::string filename = src_file.filename().string(); + + if (filename == "LICENSE" || filename == "LICENSE.txt" || filename == "COPYING") + { + potential_copyright_files.push_back(src_file); + } + } + } + + System::println(System::Color::warning, + "The software license must be available at ${CURRENT_PACKAGES_DIR}/share/%s/copyright", + spec.name()); + if (potential_copyright_files.size() == + 1) // if there is only one candidate, provide the cmake lines needed to place it in the proper location + { + const fs::path found_file = potential_copyright_files[0]; + const fs::path relative_path = found_file.string().erase( + 0, current_buildtrees_dir.string().size() + 1); // The +1 is needed to remove the "/" + System::println( + "\n file(COPY ${CURRENT_BUILDTREES_DIR}/%s DESTINATION ${CURRENT_PACKAGES_DIR}/share/%s)\n" + " file(RENAME ${CURRENT_PACKAGES_DIR}/share/%s/%s ${CURRENT_PACKAGES_DIR}/share/%s/copyright)", + relative_path.generic_string(), + spec.name(), + spec.name(), + found_file.filename().generic_string(), + spec.name()); + } + else if (potential_copyright_files.size() > 1) + { + System::println(System::Color::warning, "The following files are potential copyright files:"); + Files::print_paths(potential_copyright_files); + } + return LintStatus::ERROR_DETECTED; + } + + static LintStatus check_for_exes(const Files::Filesystem& fs, const fs::path& package_dir) + { + std::vector exes = fs.get_files_recursive(package_dir / "bin"); + Util::unstable_keep_if(exes, has_extension_pred(fs, ".exe")); + + if (!exes.empty()) + { + System::println( + System::Color::warning, + "The following EXEs were found in /bin or /debug/bin. EXEs are not valid distribution targets."); + Files::print_paths(exes); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_exports_of_dlls(const std::vector& dlls, const fs::path& dumpbin_exe) + { + std::vector dlls_with_no_exports; + for (const fs::path& dll : dlls) + { + const std::wstring cmd_line = + Strings::wformat(LR"("%s" /exports "%s")", dumpbin_exe.native(), dll.native()); + System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, + ec_data.exit_code == 0, + "Running command:\n %s\n failed", + Strings::to_utf8(cmd_line)); + + if (ec_data.output.find("ordinal hint RVA name") == std::string::npos) + { + dlls_with_no_exports.push_back(dll); + } + } + + if (!dlls_with_no_exports.empty()) + { + System::println(System::Color::warning, "The following DLLs have no exports:"); + Files::print_paths(dlls_with_no_exports); + System::println(System::Color::warning, "DLLs without any exports are likely a bug in the build script."); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_uwp_bit_of_dlls(const std::string& expected_system_name, + const std::vector& dlls, + const fs::path dumpbin_exe) + { + if (expected_system_name != "WindowsStore") + { + return LintStatus::SUCCESS; + } + + std::vector dlls_with_improper_uwp_bit; + for (const fs::path& dll : dlls) + { + const std::wstring cmd_line = + Strings::wformat(LR"("%s" /headers "%s")", dumpbin_exe.native(), dll.native()); + System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, + ec_data.exit_code == 0, + "Running command:\n %s\n failed", + Strings::to_utf8(cmd_line)); + + if (ec_data.output.find("App Container") == std::string::npos) + { + dlls_with_improper_uwp_bit.push_back(dll); + } + } + + if (!dlls_with_improper_uwp_bit.empty()) + { + System::println(System::Color::warning, "The following DLLs do not have the App Container bit set:"); + Files::print_paths(dlls_with_improper_uwp_bit); + System::println(System::Color::warning, "This bit is required for Windows Store apps."); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + struct FileAndArch + { + fs::path file; + std::string actual_arch; + }; + + static std::string get_actual_architecture(const MachineType& machine_type) + { + switch (machine_type) + { + case MachineType::AMD64: + case MachineType::IA64: return "x64"; + case MachineType::I386: return "x86"; + case MachineType::ARM: + case MachineType::ARMNT: return "arm"; + default: return "Machine Type Code = " + std::to_string(static_cast(machine_type)); + } + } + + static void print_invalid_architecture_files(const std::string& expected_architecture, + std::vector binaries_with_invalid_architecture) + { + System::println(System::Color::warning, "The following files were built for an incorrect architecture:"); + System::println(); + for (const FileAndArch& b : binaries_with_invalid_architecture) + { + System::println(" %s", b.file.generic_string()); + System::println("Expected %s, but was: %s", expected_architecture, b.actual_arch); + System::println(); + } + } + + static LintStatus check_dll_architecture(const std::string& expected_architecture, + const std::vector& files) + { + std::vector binaries_with_invalid_architecture; + + for (const fs::path& file : files) + { + Checks::check_exit(VCPKG_LINE_INFO, + file.extension() == ".dll", + "The file extension was not .dll: %s", + file.generic_string()); + const CoffFileReader::DllInfo info = CoffFileReader::read_dll(file); + const std::string actual_architecture = get_actual_architecture(info.machine_type); + + if (expected_architecture != actual_architecture) + { + binaries_with_invalid_architecture.push_back({file, actual_architecture}); + } + } + + if (!binaries_with_invalid_architecture.empty()) + { + print_invalid_architecture_files(expected_architecture, binaries_with_invalid_architecture); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_lib_architecture(const std::string& expected_architecture, + const std::vector& files) + { + std::vector binaries_with_invalid_architecture; + + for (const fs::path& file : files) + { + Checks::check_exit(VCPKG_LINE_INFO, + file.extension() == ".lib", + "The file extension was not .lib: %s", + file.generic_string()); + CoffFileReader::LibInfo info = CoffFileReader::read_lib(file); + + // This is zero for folly's debug library + // TODO: Why? + if (info.machine_types.size() == 0) return LintStatus::SUCCESS; + + Checks::check_exit(VCPKG_LINE_INFO, + info.machine_types.size() == 1, + "Found more than 1 architecture in file %s", + file.generic_string()); + + const std::string actual_architecture = get_actual_architecture(info.machine_types.at(0)); + if (expected_architecture != actual_architecture) + { + binaries_with_invalid_architecture.push_back({file, actual_architecture}); + } + } + + if (!binaries_with_invalid_architecture.empty()) + { + print_invalid_architecture_files(expected_architecture, binaries_with_invalid_architecture); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_no_dlls_present(const std::vector& dlls) + { + if (dlls.empty()) + { + return LintStatus::SUCCESS; + } + + System::println(System::Color::warning, + "DLLs should not be present in a static build, but the following DLLs were found:"); + Files::print_paths(dlls); + return LintStatus::ERROR_DETECTED; + } + + static LintStatus check_matching_debug_and_release_binaries(const std::vector& debug_binaries, + const std::vector& release_binaries) + { + const size_t debug_count = debug_binaries.size(); + const size_t release_count = release_binaries.size(); + if (debug_count == release_count) + { + return LintStatus::SUCCESS; + } + + System::println(System::Color::warning, + "Mismatching number of debug and release binaries. Found %d for debug but %d for release.", + debug_count, + release_count); + System::println("Debug binaries"); + Files::print_paths(debug_binaries); + + System::println("Release binaries"); + Files::print_paths(release_binaries); + + if (debug_count == 0) + { + System::println(System::Color::warning, "Debug binaries were not found"); + } + if (release_count == 0) + { + System::println(System::Color::warning, "Release binaries were not found"); + } + + System::println(); + + return LintStatus::ERROR_DETECTED; + } + + static LintStatus check_lib_files_are_available_if_dlls_are_available(const Build::BuildPolicies& policies, + const size_t lib_count, + const size_t dll_count, + const fs::path& lib_dir) + { + if (policies.is_enabled(BuildPolicy::DLLS_WITHOUT_LIBS)) return LintStatus::SUCCESS; + + if (lib_count == 0 && dll_count != 0) + { + System::println(System::Color::warning, "Import libs were not present in %s", lib_dir.u8string()); + System::println(System::Color::warning, + "If this is intended, add the following line in the portfile:\n" + " SET(%s enabled)", + to_cmake_variable(BuildPolicy::DLLS_WITHOUT_LIBS)); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_bin_folders_are_not_present_in_static_build(const Files::Filesystem& fs, + const fs::path& package_dir) + { + const fs::path bin = package_dir / "bin"; + const fs::path debug_bin = package_dir / "debug" / "bin"; + + if (!fs.exists(bin) && !fs.exists(debug_bin)) + { + return LintStatus::SUCCESS; + } + + if (fs.exists(bin)) + { + System::println(System::Color::warning, + R"(There should be no bin\ directory in a static build, but %s is present.)", + bin.u8string()); + } + + if (fs.exists(debug_bin)) + { + System::println(System::Color::warning, + R"(There should be no debug\bin\ directory in a static build, but %s is present.)", + debug_bin.u8string()); + } + + System::println( + System::Color::warning, + R"(If the creation of bin\ and/or debug\bin\ cannot be disabled, use this in the portfile to remove them)" + "\n" + "\n" + R"###( if(VCPKG_LIBRARY_LINKAGE STREQUAL static))###" + "\n" + R"###( file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/bin ${CURRENT_PACKAGES_DIR}/debug/bin))###" + "\n" + R"###( endif())###" + "\n"); + + return LintStatus::ERROR_DETECTED; + } + + static LintStatus check_no_empty_folders(const Files::Filesystem& fs, const fs::path& dir) + { + std::vector empty_directories = fs.get_files_recursive(dir); + + Util::unstable_keep_if(empty_directories, [&fs](const fs::path& current) { + return fs.is_directory(current) && fs.is_empty(current); + }); + + if (!empty_directories.empty()) + { + System::println(System::Color::warning, "There should be no empty directories in %s", dir.generic_string()); + System::println("The following empty directories were found: "); + Files::print_paths(empty_directories); + System::println( + System::Color::warning, + "If a directory should be populated but is not, this might indicate an error in the portfile.\n" + "If the directories are not needed and their creation cannot be disabled, use something like this in " + "the portfile to remove them:\n" + "\n" + R"###( file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/a/dir ${CURRENT_PACKAGES_DIR}/some/other/dir))###" + "\n" + "\n"); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + struct BuildTypeAndFile + { + fs::path file; + BuildType build_type; + }; + + static LintStatus check_crt_linkage_of_libs(const BuildType& expected_build_type, + const std::vector& libs, + const fs::path dumpbin_exe) + { + std::vector bad_build_types(BuildTypeC::VALUES.cbegin(), BuildTypeC::VALUES.cend()); + bad_build_types.erase(std::remove(bad_build_types.begin(), bad_build_types.end(), expected_build_type), + bad_build_types.end()); + + std::vector libs_with_invalid_crt; + + for (const fs::path& lib : libs) + { + const std::wstring cmd_line = + Strings::wformat(LR"("%s" /directives "%s")", dumpbin_exe.native(), lib.native()); + System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, + ec_data.exit_code == 0, + "Running command:\n %s\n failed", + Strings::to_utf8(cmd_line)); + + for (const BuildType& bad_build_type : bad_build_types) + { + if (std::regex_search(ec_data.output.cbegin(), ec_data.output.cend(), bad_build_type.crt_regex())) + { + libs_with_invalid_crt.push_back({lib, bad_build_type}); + break; + } + } + } + + if (!libs_with_invalid_crt.empty()) + { + System::println(System::Color::warning, + "Expected %s crt linkage, but the following libs had invalid crt linkage:", + expected_build_type.to_string()); + System::println(); + for (const BuildTypeAndFile btf : libs_with_invalid_crt) + { + System::println(" %s: %s", btf.file.generic_string(), btf.build_type.to_string()); + } + System::println(); + + System::println(System::Color::warning, + "To inspect the lib files, use:\n dumpbin.exe /directives mylibfile.lib"); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + struct OutdatedDynamicCrtAndFile + { + fs::path file; + OutdatedDynamicCrt outdated_crt; + + OutdatedDynamicCrtAndFile() = delete; + }; + + static LintStatus check_outdated_crt_linkage_of_dlls(const std::vector& dlls, + const fs::path dumpbin_exe, + const BuildInfo& build_info) + { + if (build_info.policies.is_enabled(BuildPolicy::ALLOW_OBSOLETE_MSVCRT)) return LintStatus::SUCCESS; + + std::vector dlls_with_outdated_crt; + + for (const fs::path& dll : dlls) + { + const std::wstring cmd_line = + Strings::wformat(LR"("%s" /dependents "%s")", dumpbin_exe.native(), dll.native()); + System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd_line); + Checks::check_exit(VCPKG_LINE_INFO, + ec_data.exit_code == 0, + "Running command:\n %s\n failed", + Strings::to_utf8(cmd_line)); + + for (const OutdatedDynamicCrt& outdated_crt : get_outdated_dynamic_crts("v141")) + { + if (std::regex_search(ec_data.output.cbegin(), ec_data.output.cend(), outdated_crt.regex)) + { + dlls_with_outdated_crt.push_back({dll, outdated_crt}); + break; + } + } + } + + if (!dlls_with_outdated_crt.empty()) + { + System::println(System::Color::warning, "Detected outdated dynamic CRT in the following files:"); + System::println(); + for (const OutdatedDynamicCrtAndFile btf : dlls_with_outdated_crt) + { + System::println(" %s: %s", btf.file.generic_string(), btf.outdated_crt.name); + } + System::println(); + + System::println(System::Color::warning, + "To inspect the dll files, use:\n dumpbin.exe /dependents mydllfile.dll"); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static LintStatus check_no_files_in_dir(const Files::Filesystem& fs, const fs::path& dir) + { + std::vector misplaced_files = fs.get_files_non_recursive(dir); + Util::unstable_keep_if(misplaced_files, [&fs](const fs::path& path) { + const std::string filename = path.filename().generic_string(); + if (Strings::case_insensitive_ascii_compare(filename.c_str(), "CONTROL") || + Strings::case_insensitive_ascii_compare(filename.c_str(), "BUILD_INFO")) + return false; + return !fs.is_directory(path); + }); + + if (!misplaced_files.empty()) + { + System::println(System::Color::warning, "The following files are placed in\n%s: ", dir.u8string()); + Files::print_paths(misplaced_files); + System::println(System::Color::warning, "Files cannot be present in those directories.\n"); + return LintStatus::ERROR_DETECTED; + } + + return LintStatus::SUCCESS; + } + + static void operator+=(size_t& left, const LintStatus& right) { left += static_cast(right); } + + static size_t perform_all_checks_and_return_error_count(const PackageSpec& spec, + const VcpkgPaths& paths, + const PreBuildInfo& pre_build_info, + const BuildInfo& build_info) + { + const auto& fs = paths.get_filesystem(); + + // for dumpbin + const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); + const fs::path package_dir = paths.package_dir(spec); + + size_t error_count = 0; + + if (build_info.policies.is_enabled(BuildPolicy::EMPTY_PACKAGE)) + { + return error_count; + } + + error_count += check_for_files_in_include_directory(fs, build_info.policies, package_dir); + error_count += check_for_files_in_debug_include_directory(fs, package_dir); + error_count += check_for_files_in_debug_share_directory(fs, package_dir); + error_count += check_folder_lib_cmake(fs, package_dir, spec); + error_count += check_for_misplaced_cmake_files(fs, package_dir, spec); + error_count += check_folder_debug_lib_cmake(fs, package_dir, spec); + error_count += check_for_dlls_in_lib_dir(fs, package_dir); + error_count += check_for_dlls_in_lib_dir(fs, package_dir / "debug"); + error_count += check_for_copyright_file(fs, spec, paths); + error_count += check_for_exes(fs, package_dir); + error_count += check_for_exes(fs, package_dir / "debug"); + + const fs::path debug_lib_dir = package_dir / "debug" / "lib"; + const fs::path release_lib_dir = package_dir / "lib"; + const fs::path debug_bin_dir = package_dir / "debug" / "bin"; + const fs::path release_bin_dir = package_dir / "bin"; + + std::vector debug_libs = fs.get_files_recursive(debug_lib_dir); + Util::unstable_keep_if(debug_libs, has_extension_pred(fs, ".lib")); + std::vector release_libs = fs.get_files_recursive(release_lib_dir); + Util::unstable_keep_if(release_libs, has_extension_pred(fs, ".lib")); + + error_count += check_matching_debug_and_release_binaries(debug_libs, release_libs); + + { + std::vector libs; + libs.insert(libs.cend(), debug_libs.cbegin(), debug_libs.cend()); + libs.insert(libs.cend(), release_libs.cbegin(), release_libs.cend()); + + error_count += check_lib_architecture(pre_build_info.target_architecture, libs); + } + + std::vector debug_dlls = fs.get_files_recursive(debug_bin_dir); + Util::unstable_keep_if(debug_dlls, has_extension_pred(fs, ".dll")); + std::vector release_dlls = fs.get_files_recursive(release_bin_dir); + Util::unstable_keep_if(release_dlls, has_extension_pred(fs, ".dll")); + + switch (build_info.library_linkage) + { + case Build::LinkageType::DYNAMIC: + { + error_count += check_matching_debug_and_release_binaries(debug_dlls, release_dlls); + + error_count += check_lib_files_are_available_if_dlls_are_available( + build_info.policies, debug_libs.size(), debug_dlls.size(), debug_lib_dir); + error_count += check_lib_files_are_available_if_dlls_are_available( + build_info.policies, release_libs.size(), release_dlls.size(), release_lib_dir); + + std::vector dlls; + dlls.insert(dlls.cend(), debug_dlls.cbegin(), debug_dlls.cend()); + dlls.insert(dlls.cend(), release_dlls.cbegin(), release_dlls.cend()); + + error_count += check_exports_of_dlls(dlls, toolset.dumpbin); + error_count += check_uwp_bit_of_dlls(pre_build_info.cmake_system_name, dlls, toolset.dumpbin); + error_count += check_dll_architecture(pre_build_info.target_architecture, dlls); + + error_count += check_outdated_crt_linkage_of_dlls(dlls, toolset.dumpbin, build_info); + break; + } + case Build::LinkageType::STATIC: + { + auto dlls = release_dlls; + dlls.insert(dlls.end(), debug_dlls.begin(), debug_dlls.end()); + error_count += check_no_dlls_present(dlls); + + error_count += check_bin_folders_are_not_present_in_static_build(fs, package_dir); + + if (!build_info.policies.is_enabled(BuildPolicy::ONLY_RELEASE_CRT)) + { + error_count += + check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::DEBUG, build_info.crt_linkage), + debug_libs, + toolset.dumpbin); + } + error_count += + check_crt_linkage_of_libs(BuildType::value_of(ConfigurationType::RELEASE, build_info.crt_linkage), + release_libs, + toolset.dumpbin); + break; + } + default: Checks::unreachable(VCPKG_LINE_INFO); + } + + error_count += check_no_empty_folders(fs, package_dir); + error_count += check_no_files_in_dir(fs, package_dir); + error_count += check_no_files_in_dir(fs, package_dir / "debug"); + + return error_count; + } + + size_t perform_all_checks(const PackageSpec& spec, + const VcpkgPaths& paths, + const PreBuildInfo& pre_build_info, + const BuildInfo& build_info) + { + System::println("-- Performing post-build validation"); + const size_t error_count = perform_all_checks_and_return_error_count(spec, paths, pre_build_info, build_info); + + if (error_count != 0) + { + const fs::path portfile = paths.ports / spec.name() / "portfile.cmake"; + System::println(System::Color::error, + "Found %u error(s). Please correct the portfile:\n %s", + error_count, + portfile.string()); + } + + System::println("-- Performing post-build validation done"); + + return error_count; + } +} diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp new file mode 100644 index 000000000..3751566f7 --- /dev/null +++ b/toolsrc/src/vcpkg/remove.cpp @@ -0,0 +1,251 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Remove +{ + using Dependencies::RemovePlanAction; + using Dependencies::RemovePlanType; + using Dependencies::RequestType; + using Update::OutdatedPackage; + + void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db) + { + auto& fs = paths.get_filesystem(); + auto spghs = status_db->find_all(spec.name(), spec.triplet()); + const auto core_pkg = **status_db->find(spec.name(), spec.triplet(), Strings::EMPTY); + + for (auto&& spgh : spghs) + { + StatusParagraph& pkg = **spgh; + if (pkg.state != InstallState::INSTALLED) continue; + pkg.want = Want::PURGE; + pkg.state = InstallState::HALF_INSTALLED; + write_update(paths, pkg); + } + + auto maybe_lines = fs.read_lines(paths.listfile_path(core_pkg.package)); + + if (const auto lines = maybe_lines.get()) + { + std::vector dirs_touched; + for (auto&& suffix : *lines) + { + if (!suffix.empty() && suffix.back() == '\r') suffix.pop_back(); + + std::error_code ec; + + auto target = paths.installed / suffix; + + const auto status = fs.status(target, ec); + if (ec) + { + System::println(System::Color::error, "failed: %s", ec.message()); + continue; + } + + if (fs::is_directory(status)) + { + dirs_touched.push_back(target); + } + else if (fs::is_regular_file(status)) + { + fs.remove(target, ec); + if (ec) + { + System::println(System::Color::error, "failed: %s: %s", target.u8string(), ec.message()); + } + } + else if (!fs::status_known(status)) + { + System::println(System::Color::warning, "Warning: unknown status: %s", target.u8string()); + } + else + { + System::println(System::Color::warning, "Warning: %s: cannot handle file type", target.u8string()); + } + } + + auto b = dirs_touched.rbegin(); + const auto e = dirs_touched.rend(); + for (; b != e; ++b) + { + if (fs.is_empty(*b)) + { + std::error_code ec; + fs.remove(*b, ec); + if (ec) + { + System::println(System::Color::error, "failed: %s", ec.message()); + } + } + } + + fs.remove(paths.listfile_path(core_pkg.package)); + } + + for (auto&& spgh : spghs) + { + StatusParagraph& pkg = **spgh; + if (pkg.state != InstallState::HALF_INSTALLED) continue; + pkg.state = InstallState::NOT_INSTALLED; + write_update(paths, pkg); + } + } + + static void print_plan(const std::map>& group_by_plan_type) + { + static constexpr std::array ORDER = {RemovePlanType::NOT_INSTALLED, RemovePlanType::REMOVE}; + + for (const RemovePlanType plan_type : ORDER) + { + const auto it = group_by_plan_type.find(plan_type); + if (it == group_by_plan_type.cend()) + { + continue; + } + + std::vector cont = it->second; + std::sort(cont.begin(), cont.end(), &RemovePlanAction::compare_by_name); + const std::string as_string = Strings::join("\n", cont, [](const RemovePlanAction* p) { + return Dependencies::to_output_string(p->request_type, p->spec.to_string()); + }); + + switch (plan_type) + { + case RemovePlanType::NOT_INSTALLED: + System::println("The following packages are not installed, so not removed:\n%s", as_string); + continue; + case RemovePlanType::REMOVE: + System::println("The following packages will be removed:\n%s", as_string); + continue; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + } + + void perform_remove_plan_action(const VcpkgPaths& paths, + const RemovePlanAction& action, + const Purge purge, + StatusParagraphs& status_db) + { + const std::string display_name = action.spec.to_string(); + + switch (action.plan_type) + { + case RemovePlanType::NOT_INSTALLED: + System::println(System::Color::success, "Package %s is not installed", display_name); + break; + case RemovePlanType::REMOVE: + System::println("Removing package %s... ", display_name); + remove_package(paths, action.spec, &status_db); + System::println(System::Color::success, "Removing package %s... done", display_name); + break; + case RemovePlanType::UNKNOWN: + default: Checks::unreachable(VCPKG_LINE_INFO); + } + + if (purge == Purge::YES) + { + System::println("Purging package %s... ", display_name); + Files::Filesystem& fs = paths.get_filesystem(); + std::error_code ec; + fs.remove_all(paths.packages / action.spec.dir(), ec); + System::println(System::Color::success, "Purging package %s... done", display_name); + } + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { + static const std::string OPTION_PURGE = "--purge"; + static const std::string OPTION_NO_PURGE = "--no-purge"; + static const std::string OPTION_RECURSE = "--recurse"; + static const std::string OPTION_DRY_RUN = "--dry-run"; + static const std::string OPTION_OUTDATED = "--outdated"; + static const std::string EXAMPLE = Help::create_example_string("remove zlib zlib:x64-windows curl boost"); + const std::unordered_set options = args.check_and_get_optional_command_arguments( + {OPTION_PURGE, OPTION_NO_PURGE, OPTION_RECURSE, OPTION_DRY_RUN, OPTION_OUTDATED}); + + StatusParagraphs status_db = database_load_check(paths); + std::vector specs; + if (options.find(OPTION_OUTDATED) != options.cend()) + { + args.check_exact_arg_count(0, EXAMPLE); + specs = Util::fmap(Update::find_outdated_packages(paths, status_db), + [](auto&& outdated) { return outdated.spec; }); + + if (specs.empty()) + { + System::println(System::Color::success, "There are no outdated packages."); + Checks::exit_success(VCPKG_LINE_INFO); + } + } + else + { + args.check_min_arg_count(1, EXAMPLE); + specs = Util::fmap(args.command_arguments, [&](auto&& arg) { + return Input::check_and_get_package_spec(arg, default_triplet, EXAMPLE); + }); + + for (auto&& spec : specs) + Input::check_triplet(spec.triplet(), paths); + } + + const bool no_purge_was_passed = options.find(OPTION_NO_PURGE) != options.end(); + const bool purge_was_passed = options.find(OPTION_PURGE) != options.end(); + if (purge_was_passed && no_purge_was_passed) + { + System::println(System::Color::error, "Error: cannot specify both --no-purge and --purge."); + System::print(EXAMPLE); + Checks::exit_fail(VCPKG_LINE_INFO); + } + const Purge purge = to_purge(purge_was_passed || !no_purge_was_passed); + const bool is_recursive = options.find(OPTION_RECURSE) != options.cend(); + const bool dry_run = options.find(OPTION_DRY_RUN) != options.cend(); + + const std::vector remove_plan = Dependencies::create_remove_plan(specs, status_db); + Checks::check_exit(VCPKG_LINE_INFO, !remove_plan.empty(), "Remove plan cannot be empty"); + + std::map> group_by_plan_type; + Util::group_by(remove_plan, &group_by_plan_type, [](const RemovePlanAction& p) { return p.plan_type; }); + print_plan(group_by_plan_type); + + const bool has_non_user_requested_packages = + Util::find_if(remove_plan, [](const RemovePlanAction& package) -> bool { + return package.request_type != RequestType::USER_REQUESTED; + }) != remove_plan.cend(); + + if (has_non_user_requested_packages) + { + System::println(System::Color::warning, + "Additional packages (*) need to be removed to complete this operation."); + + if (!is_recursive) + { + System::println(System::Color::warning, + "If you are sure you want to remove them, run the command with the --recurse option"); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + + if (dry_run) + { + Checks::exit_success(VCPKG_LINE_INFO); + } + + for (const RemovePlanAction& action : remove_plan) + { + perform_remove_plan_action(paths, action, purge, status_db); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/sourceparagraph.cpp b/toolsrc/src/vcpkg/sourceparagraph.cpp new file mode 100644 index 000000000..d766dcb72 --- /dev/null +++ b/toolsrc/src/vcpkg/sourceparagraph.cpp @@ -0,0 +1,264 @@ +#include "pch.h" + +#include +#include +#include + +#include +#include +#include +#include + +namespace vcpkg +{ + using namespace vcpkg::Parse; + + namespace SourceParagraphFields + { + static const std::string BUILD_DEPENDS = "Build-Depends"; + static const std::string DEFAULTFEATURES = "Default-Features"; + static const std::string DESCRIPTION = "Description"; + static const std::string FEATURE = "Feature"; + static const std::string MAINTAINER = "Maintainer"; + static const std::string SOURCE = "Source"; + static const std::string SUPPORTS = "Supports"; + static const std::string VERSION = "Version"; + } + + static Span get_list_of_valid_fields() + { + static const std::string valid_fields[] = { + SourceParagraphFields::SOURCE, + SourceParagraphFields::VERSION, + SourceParagraphFields::DESCRIPTION, + SourceParagraphFields::MAINTAINER, + SourceParagraphFields::BUILD_DEPENDS, + }; + + return valid_fields; + } + + void print_error_message(Span> error_info_list) + { + Checks::check_exit(VCPKG_LINE_INFO, error_info_list.size() > 0); + + for (auto&& error_info : error_info_list) + { + Checks::check_exit(VCPKG_LINE_INFO, error_info != nullptr); + if (error_info->error) + { + System::println( + System::Color::error, "Error: while loading %s: %s", error_info->name, error_info->error.message()); + } + } + + bool have_remaining_fields = false; + for (auto&& error_info : error_info_list) + { + if (!error_info->extra_fields.empty()) + { + System::println(System::Color::error, + "Error: There are invalid fields in the control file of %s", + error_info->name); + System::println("The following fields were not expected:\n\n %s\n", + Strings::join("\n ", error_info->extra_fields)); + have_remaining_fields = true; + } + } + + if (have_remaining_fields) + { + System::println("This is the list of valid fields (case-sensitive): \n\n %s\n", + Strings::join("\n ", get_list_of_valid_fields())); + System::println("Different source may be available for vcpkg. Use .\\bootstrap-vcpkg.bat to update.\n"); + } + + for (auto&& error_info : error_info_list) + { + if (!error_info->missing_fields.empty()) + { + System::println(System::Color::error, + "Error: There are missing fields in the control file of %s", + error_info->name); + System::println("The following fields were missing:\n\n %s\n", + Strings::join("\n ", error_info->missing_fields)); + } + } + } + + static ParseExpected parse_source_paragraph(RawParagraph&& fields) + { + ParagraphParser parser(std::move(fields)); + + auto spgh = std::make_unique(); + + parser.required_field(SourceParagraphFields::SOURCE, spgh->name); + parser.required_field(SourceParagraphFields::VERSION, spgh->version); + + spgh->description = parser.optional_field(SourceParagraphFields::DESCRIPTION); + spgh->maintainer = parser.optional_field(SourceParagraphFields::MAINTAINER); + spgh->depends = expand_qualified_dependencies( + parse_comma_list(parser.optional_field(SourceParagraphFields::BUILD_DEPENDS))); + spgh->supports = parse_comma_list(parser.optional_field(SourceParagraphFields::SUPPORTS)); + spgh->default_features = parse_comma_list(parser.optional_field(SourceParagraphFields::DEFAULTFEATURES)); + + auto err = parser.error_info(spgh->name); + if (err) + return std::move(err); + else + return std::move(spgh); + } + + static ParseExpected parse_feature_paragraph(RawParagraph&& fields) + { + ParagraphParser parser(std::move(fields)); + + auto fpgh = std::make_unique(); + + parser.required_field(SourceParagraphFields::FEATURE, fpgh->name); + parser.required_field(SourceParagraphFields::DESCRIPTION, fpgh->description); + + fpgh->depends = expand_qualified_dependencies( + parse_comma_list(parser.optional_field(SourceParagraphFields::BUILD_DEPENDS))); + + auto err = parser.error_info(fpgh->name); + if (err) + return std::move(err); + else + return std::move(fpgh); + } + + ParseExpected SourceControlFile::parse_control_file( + std::vector>&& control_paragraphs) + { + if (control_paragraphs.size() == 0) + { + return std::make_unique(); + } + + auto control_file = std::make_unique(); + + auto maybe_source = parse_source_paragraph(std::move(control_paragraphs.front())); + if (const auto source = maybe_source.get()) + control_file->core_paragraph = std::move(*source); + else + return std::move(maybe_source).error(); + + control_paragraphs.erase(control_paragraphs.begin()); + + for (auto&& feature_pgh : control_paragraphs) + { + auto maybe_feature = parse_feature_paragraph(std::move(feature_pgh)); + if (const auto feature = maybe_feature.get()) + control_file->feature_paragraphs.emplace_back(std::move(*feature)); + else + return std::move(maybe_feature).error(); + } + + return std::move(control_file); + } + + Dependency Dependency::parse_dependency(std::string name, std::string qualifier) + { + Dependency dep; + dep.qualifier = qualifier; + if (auto maybe_features = Features::from_string(name)) + dep.depend = *maybe_features.get(); + else + Checks::exit_with_message( + VCPKG_LINE_INFO, "error while parsing dependency: %s: %s", to_string(maybe_features.error()), name); + return dep; + } + + std::string Dependency::name() const + { + if (this->depend.features.empty()) return this->depend.name; + + const std::string features = Strings::join(",", this->depend.features); + return Strings::format("%s[%s]", this->depend.name, features); + } + + std::vector vcpkg::expand_qualified_dependencies(const std::vector& depends) + { + return Util::fmap(depends, [&](const std::string& depend_string) -> Dependency { + auto pos = depend_string.find(' '); + if (pos == std::string::npos) return Dependency::parse_dependency(depend_string, Strings::EMPTY); + // expect of the form "\w+ \[\w+\]" + Dependency dep; + + dep.depend.name = depend_string.substr(0, pos); + if (depend_string.c_str()[pos + 1] != '(' || depend_string[depend_string.size() - 1] != ')') + { + // Error, but for now just slurp the entire string. + return Dependency::parse_dependency(depend_string, Strings::EMPTY); + } + dep.qualifier = depend_string.substr(pos + 2, depend_string.size() - pos - 3); + return dep; + }); + } + + std::vector filter_dependencies(const std::vector& deps, const Triplet& t) + { + std::vector ret; + for (auto&& dep : deps) + { + if (dep.qualifier.empty() || t.canonical_name().find(dep.qualifier) != std::string::npos) + { + ret.emplace_back(dep.name()); + } + } + return ret; + } + + std::vector filter_dependencies_to_specs(const std::vector& deps, const Triplet& t) + { + return FeatureSpec::from_strings_and_triplet(filter_dependencies(deps, t), t); + } + + std::string to_string(const Dependency& dep) { return dep.name(); } + + ExpectedT> Supports::parse(const std::vector& strs) + { + Supports ret; + std::vector unrecognized; + + for (auto&& str : strs) + { + if (str == "x64") + ret.architectures.push_back(Architecture::X64); + else if (str == "x86") + ret.architectures.push_back(Architecture::X86); + else if (str == "arm") + ret.architectures.push_back(Architecture::ARM); + else if (str == "windows") + ret.platforms.push_back(Platform::WINDOWS); + else if (str == "uwp") + ret.platforms.push_back(Platform::UWP); + else if (str == "v140") + ret.toolsets.push_back(ToolsetVersion::V140); + else if (str == "v141") + ret.toolsets.push_back(ToolsetVersion::V141); + else if (str == "crt-static") + ret.crt_linkages.push_back(Linkage::STATIC); + else if (str == "crt-dynamic") + ret.crt_linkages.push_back(Linkage::DYNAMIC); + else + unrecognized.push_back(str); + } + + if (unrecognized.empty()) + return std::move(ret); + else + return std::move(unrecognized); + } + + bool Supports::is_supported(Architecture arch, Platform plat, Linkage crt, ToolsetVersion tools) + { + const auto is_in_or_empty = [](auto v, auto&& c) -> bool { return c.empty() || c.end() != Util::find(c, v); }; + if (!is_in_or_empty(arch, architectures)) return false; + if (!is_in_or_empty(plat, platforms)) return false; + if (!is_in_or_empty(crt, crt_linkages)) return false; + if (!is_in_or_empty(tools, toolsets)) return false; + return true; + } +} diff --git a/toolsrc/src/vcpkg/statusparagraph.cpp b/toolsrc/src/vcpkg/statusparagraph.cpp new file mode 100644 index 000000000..5f00825e1 --- /dev/null +++ b/toolsrc/src/vcpkg/statusparagraph.cpp @@ -0,0 +1,86 @@ +#include "pch.h" + +#include + +using namespace vcpkg::Parse; + +namespace vcpkg +{ + namespace BinaryParagraphRequiredField + { + static const std::string STATUS = "Status"; + } + + StatusParagraph::StatusParagraph() : want(Want::ERROR_STATE), state(InstallState::ERROR_STATE) {} + + void serialize(const StatusParagraph& pgh, std::string& out_str) + { + serialize(pgh.package, out_str); + out_str.append("Status: ") + .append(to_string(pgh.want)) + .append(" ok ") + .append(to_string(pgh.state)) + .push_back('\n'); + } + + StatusParagraph::StatusParagraph(std::unordered_map&& fields) + { + auto status_it = fields.find(BinaryParagraphRequiredField::STATUS); + Checks::check_exit(VCPKG_LINE_INFO, status_it != fields.end(), "Expected 'Status' field in status paragraph"); + std::string status_field = std::move(status_it->second); + fields.erase(status_it); + + this->package = BinaryParagraph(std::move(fields)); + + auto b = status_field.begin(); + const auto mark = b; + const auto e = status_field.end(); + + // Todo: improve error handling + while (b != e && *b != ' ') + ++b; + + want = [](const std::string& text) { + if (text == "unknown") return Want::UNKNOWN; + if (text == "install") return Want::INSTALL; + if (text == "hold") return Want::HOLD; + if (text == "deinstall") return Want::DEINSTALL; + if (text == "purge") return Want::PURGE; + return Want::ERROR_STATE; + }(std::string(mark, b)); + + if (std::distance(b, e) < 4) return; + b += 4; + + state = [](const std::string& text) { + if (text == "not-installed") return InstallState::NOT_INSTALLED; + if (text == "installed") return InstallState::INSTALLED; + if (text == "half-installed") return InstallState::HALF_INSTALLED; + return InstallState::ERROR_STATE; + }(std::string(b, e)); + } + + std::string to_string(InstallState f) + { + switch (f) + { + case InstallState::HALF_INSTALLED: return "half-installed"; + case InstallState::INSTALLED: return "installed"; + case InstallState::NOT_INSTALLED: return "not-installed"; + default: return "error"; + } + } + + std::string to_string(Want f) + { + switch (f) + { + case Want::DEINSTALL: return "deinstall"; + case Want::HOLD: return "hold"; + case Want::INSTALL: return "install"; + case Want::PURGE: return "purge"; + case Want::UNKNOWN: return "unknown"; + default: return "error"; + } + } +} diff --git a/toolsrc/src/vcpkg/statusparagraphs.cpp b/toolsrc/src/vcpkg/statusparagraphs.cpp new file mode 100644 index 000000000..647ed6d3f --- /dev/null +++ b/toolsrc/src/vcpkg/statusparagraphs.cpp @@ -0,0 +1,89 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg +{ + StatusParagraphs::StatusParagraphs() = default; + + StatusParagraphs::StatusParagraphs(std::vector>&& ps) + : paragraphs(std::move(ps)){}; + + StatusParagraphs::const_iterator StatusParagraphs::find(const std::string& name, const Triplet& triplet) const + { + return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { + const PackageSpec& spec = pgh->package.spec; + return spec.name() == name && spec.triplet() == triplet; + }); + } + + StatusParagraphs::iterator StatusParagraphs::find(const std::string& name, const Triplet& triplet) + { + return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { + const PackageSpec& spec = pgh->package.spec; + return spec.name() == name && spec.triplet() == triplet; + }); + } + + std::vector*> StatusParagraphs::find_all(const std::string& name, + const Triplet& triplet) + { + std::vector*> spghs; + for (auto&& p : *this) + { + if (p->package.spec.name() == name && p->package.spec.triplet() == triplet) + { + spghs.emplace_back(&p); + } + } + return spghs; + } + + StatusParagraphs::iterator StatusParagraphs::find(const std::string& name, + const Triplet& triplet, + const std::string& feature) + { + return std::find_if(begin(), end(), [&](const std::unique_ptr& pgh) { + const PackageSpec& spec = pgh->package.spec; + return spec.name() == name && spec.triplet() == triplet && pgh->package.feature == feature; + }); + } + + StatusParagraphs::const_iterator StatusParagraphs::find_installed(const std::string& name, + const Triplet& triplet) const + { + const const_iterator it = find(name, triplet); + if (it != end() && (*it)->want == Want::INSTALL && (*it)->state == InstallState::INSTALLED) + { + return it; + } + + return end(); + } + + StatusParagraphs::iterator StatusParagraphs::insert(std::unique_ptr pgh) + { + Checks::check_exit(VCPKG_LINE_INFO, pgh != nullptr, "Inserted null paragraph"); + const PackageSpec& spec = pgh->package.spec; + const auto ptr = find(spec.name(), spec.triplet(), pgh->package.feature); + if (ptr == end()) + { + paragraphs.push_back(std::move(pgh)); + return paragraphs.rbegin(); + } + + // consume data from provided pgh. + **ptr = std::move(*pgh); + return ptr; + } + + void serialize(const StatusParagraphs& pghs, std::string& out_str) + { + for (auto& pgh : pghs.paragraphs) + { + serialize(*pgh, out_str); + out_str.push_back('\n'); + } + } +} diff --git a/toolsrc/src/vcpkg/triplet.cpp b/toolsrc/src/vcpkg/triplet.cpp new file mode 100644 index 000000000..8a84ee2b2 --- /dev/null +++ b/toolsrc/src/vcpkg/triplet.cpp @@ -0,0 +1,55 @@ +#include "pch.h" + +#include +#include +#include + +namespace vcpkg +{ + struct TripletInstance + { + TripletInstance(std::string&& s) : value(std::move(s)), hash(std::hash()(value)) {} + + const std::string value; + const size_t hash = 0; + + bool operator==(const TripletInstance& o) const { return o.value == value; } + }; + const TripletInstance Triplet::DEFAULT_INSTANCE({}); +} + +template<> +struct std::hash +{ + size_t operator()(const vcpkg::TripletInstance& t) const { return t.hash; } +}; + +namespace vcpkg +{ + static std::unordered_set g_triplet_instances; + + const Triplet Triplet::X86_WINDOWS = from_canonical_name("x86-windows"); + const Triplet Triplet::X64_WINDOWS = from_canonical_name("x64-windows"); + const Triplet Triplet::X86_UWP = from_canonical_name("x86-uwp"); + const Triplet Triplet::X64_UWP = from_canonical_name("x64-uwp"); + const Triplet Triplet::ARM_UWP = from_canonical_name("arm-uwp"); + + bool Triplet::operator==(const Triplet& other) const { return this->m_instance == other.m_instance; } + + bool operator!=(const Triplet& left, const Triplet& right) { return !(left == right); } + + Triplet Triplet::from_canonical_name(const std::string& triplet_as_string) + { + std::string s(Strings::ascii_to_lowercase(triplet_as_string)); + const auto it = std::find(s.cbegin(), s.cend(), '-'); + Checks::check_exit(VCPKG_LINE_INFO, it != s.cend(), "Invalid triplet: %s", triplet_as_string); + + const auto p = g_triplet_instances.emplace(std::move(s)); + return &*p.first; + } + + const std::string& Triplet::canonical_name() const { return this->m_instance->value; } + + const std::string& Triplet::to_string() const { return this->canonical_name(); } + size_t Triplet::hash_code() const { return m_instance->hash; } +} diff --git a/toolsrc/src/vcpkg/update.cpp b/toolsrc/src/vcpkg/update.cpp new file mode 100644 index 000000000..168949bc1 --- /dev/null +++ b/toolsrc/src/vcpkg/update.cpp @@ -0,0 +1,75 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include + +namespace vcpkg::Update +{ + bool OutdatedPackage::compare_by_name(const OutdatedPackage& left, const OutdatedPackage& right) + { + return left.spec.name() < right.spec.name(); + } + + std::vector find_outdated_packages(const VcpkgPaths& paths, const StatusParagraphs& status_db) + { + const std::map src_names_to_versions = + Paragraphs::load_all_port_names_and_versions(paths.get_filesystem(), paths.ports); + const std::vector installed_packages = get_installed_ports(status_db); + + std::vector output; + for (const StatusParagraph* pgh : installed_packages) + { + const auto it = src_names_to_versions.find(pgh->package.spec.name()); + if (it == src_names_to_versions.end()) + { + // Package was not installed from portfile + continue; + } + if (it->second != pgh->package.version) + { + output.push_back({pgh->package.spec, VersionDiff(pgh->package.version, it->second)}); + } + } + + return output; + } + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + args.check_exact_arg_count(0); + args.check_and_get_optional_command_arguments({}); + System::println("Using local portfile versions. To update the local portfiles, use `git pull`."); + + const StatusParagraphs status_db = database_load_check(paths); + + const auto outdated_packages = + SortedVector(find_outdated_packages(paths, status_db), &OutdatedPackage::compare_by_name); + + if (outdated_packages.empty()) + { + System::println("No packages need updating."); + } + else + { + std::string install_line; + System::println("The following packages differ from their port versions:"); + for (auto&& package : outdated_packages) + { + install_line += package.spec.to_string(); + install_line += " "; + System::println(" %-32s %s", package.spec, package.version_diff.to_string()); + } + System::println("\n" + "To update these packages, run\n" + " .\\vcpkg remove --outdated\n" + " .\\vcpkg install " + + install_line); + } + + Checks::exit_success(VCPKG_LINE_INFO); + } +} diff --git a/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp new file mode 100644 index 000000000..522961693 --- /dev/null +++ b/toolsrc/src/vcpkg/vcpkgcmdarguments.cpp @@ -0,0 +1,284 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include + +namespace vcpkg +{ + static void parse_value(const std::string* arg_begin, + const std::string* arg_end, + const std::string& option_name, + std::unique_ptr& option_field) + { + if (arg_begin == arg_end) + { + System::println(System::Color::error, "Error: expected value after %s", option_name); + Metrics::g_metrics.lock()->track_property("error", "error option name"); + Help::print_usage(); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + if (option_field != nullptr) + { + System::println(System::Color::error, "Error: %s specified multiple times", option_name); + Metrics::g_metrics.lock()->track_property("error", "error option specified multiple times"); + Help::print_usage(); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + option_field = std::make_unique(*arg_begin); + } + + static void parse_switch(bool new_setting, const std::string& option_name, Optional& option_field) + { + if (option_field && option_field != new_setting) + { + System::println(System::Color::error, "Error: conflicting values specified for --%s", option_name); + Metrics::g_metrics.lock()->track_property("error", "error conflicting switches"); + Help::print_usage(); + Checks::exit_fail(VCPKG_LINE_INFO); + } + option_field = new_setting; + } + + VcpkgCmdArguments VcpkgCmdArguments::create_from_command_line(const int argc, const wchar_t* const* const argv) + { + std::vector v; + for (int i = 1; i < argc; ++i) + { + v.push_back(Strings::to_utf8(argv[i])); + } + + return VcpkgCmdArguments::create_from_arg_sequence(v.data(), v.data() + v.size()); + } + + VcpkgCmdArguments VcpkgCmdArguments::create_from_arg_sequence(const std::string* arg_begin, + const std::string* arg_end) + { + VcpkgCmdArguments args; + + for (; arg_begin != arg_end; ++arg_begin) + { + std::string arg = *arg_begin; + + if (arg.empty()) + { + continue; + } + + if (arg[0] == '-' && arg[1] != '-') + { + Metrics::g_metrics.lock()->track_property("error", "error short options are not supported"); + Checks::exit_with_message(VCPKG_LINE_INFO, "Error: short options are not supported: %s", arg); + } + + if (arg[0] == '-' && arg[1] == '-') + { + // make argument case insensitive + auto& f = std::use_facet>(std::locale()); + f.tolower(&arg[0], &arg[0] + arg.size()); + // command switch + if (arg == "--vcpkg-root") + { + ++arg_begin; + parse_value(arg_begin, arg_end, "--vcpkg-root", args.vcpkg_root_dir); + continue; + } + if (arg == "--triplet") + { + ++arg_begin; + parse_value(arg_begin, arg_end, "--triplet", args.triplet); + continue; + } + if (arg == "--debug") + { + parse_switch(true, "debug", args.debug); + continue; + } + if (arg == "--sendmetrics") + { + parse_switch(true, "sendmetrics", args.sendmetrics); + continue; + } + if (arg == "--printmetrics") + { + parse_switch(true, "printmetrics", args.printmetrics); + continue; + } + if (arg == "--no-sendmetrics") + { + parse_switch(false, "sendmetrics", args.sendmetrics); + continue; + } + if (arg == "--no-printmetrics") + { + parse_switch(false, "printmetrics", args.printmetrics); + continue; + } + if (arg == "--featurepackages") + { + GlobalState::feature_packages = true; + continue; + } + + const auto eq_pos = arg.find('='); + if (eq_pos != std::string::npos) + { + args.optional_command_arguments.emplace(arg.substr(0, eq_pos), arg.substr(eq_pos + 1)); + } + else + { + args.optional_command_arguments.emplace(arg, nullopt); + } + continue; + } + + if (args.command.empty()) + { + args.command = arg; + } + else + { + args.command_arguments.push_back(arg); + } + } + + return args; + } + + ParsedArguments VcpkgCmdArguments::check_and_get_optional_command_arguments( + const std::vector& valid_switches, const std::vector& valid_settings) const + { + bool failed = false; + ParsedArguments output; + + auto options_copy = this->optional_command_arguments; + for (const std::string& option : valid_switches) + { + const auto it = options_copy.find(option); + if (it != options_copy.end()) + { + if (it->second.has_value()) + { + // Having a string value indicates it was passed like '--a=xyz' + System::println(System::Color::error, "The option '%s' does not accept an argument.", option); + failed = true; + } + else + { + output.switches.insert(option); + options_copy.erase(it); + } + } + } + + for (const std::string& option : valid_settings) + { + const auto it = options_copy.find(option); + if (it != options_copy.end()) + { + if (!it->second.has_value()) + { + // Not having a string value indicates it was passed like '--a' + System::println(System::Color::error, "The option '%s' must be passed an argument.", option); + failed = true; + } + else + { + output.settings.emplace(option, it->second.value_or_exit(VCPKG_LINE_INFO)); + options_copy.erase(it); + } + } + } + + if (!options_copy.empty()) + { + System::println(System::Color::error, "Unknown option(s) for command '%s':", this->command); + for (auto&& option : options_copy) + { + System::println(" %s", option.first); + } + System::println("\nValid options are:", this->command); + for (auto&& option : valid_switches) + { + System::println(" %s", option); + } + for (auto&& option : valid_settings) + { + System::println(" %s=...", option); + } + System::println(" --triplet "); + System::println(" --vcpkg-root "); + + Checks::exit_fail(VCPKG_LINE_INFO); + } + if (failed) Checks::exit_fail(VCPKG_LINE_INFO); + + return output; + } + + void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count) const + { + return check_max_arg_count(expected_arg_count, Strings::EMPTY); + } + + void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count) const + { + return check_min_arg_count(expected_arg_count, Strings::EMPTY); + } + + void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count) const + { + return check_exact_arg_count(expected_arg_count, Strings::EMPTY); + } + + void VcpkgCmdArguments::check_max_arg_count(const size_t expected_arg_count, const std::string& example_text) const + { + const size_t actual_arg_count = command_arguments.size(); + if (actual_arg_count > expected_arg_count) + { + System::println(System::Color::error, + "Error: `%s` requires at most %u arguments, but %u were provided", + this->command, + expected_arg_count, + actual_arg_count); + System::print(example_text); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + + void VcpkgCmdArguments::check_min_arg_count(const size_t expected_arg_count, const std::string& example_text) const + { + const size_t actual_arg_count = command_arguments.size(); + if (actual_arg_count < expected_arg_count) + { + System::println(System::Color::error, + "Error: `%s` requires at least %u arguments, but %u were provided", + this->command, + expected_arg_count, + actual_arg_count); + System::print(example_text); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + + void VcpkgCmdArguments::check_exact_arg_count(const size_t expected_arg_count, + const std::string& example_text) const + { + const size_t actual_arg_count = command_arguments.size(); + if (actual_arg_count != expected_arg_count) + { + System::println(System::Color::error, + "Error: `%s` requires %u arguments, but %u were provided", + this->command, + expected_arg_count, + actual_arg_count); + System::print(example_text); + Checks::exit_fail(VCPKG_LINE_INFO); + } + } +} diff --git a/toolsrc/src/vcpkg/vcpkglib.cpp b/toolsrc/src/vcpkg/vcpkglib.cpp new file mode 100644 index 000000000..23c774210 --- /dev/null +++ b/toolsrc/src/vcpkg/vcpkglib.cpp @@ -0,0 +1,247 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include + +namespace vcpkg +{ + static StatusParagraphs load_current_database(Files::Filesystem& fs, + const fs::path& vcpkg_dir_status_file, + const fs::path& vcpkg_dir_status_file_old) + { + if (!fs.exists(vcpkg_dir_status_file)) + { + if (!fs.exists(vcpkg_dir_status_file_old)) + { + // no status file, use empty db + return StatusParagraphs(); + } + + fs.rename(vcpkg_dir_status_file_old, vcpkg_dir_status_file); + } + + auto pghs = Paragraphs::get_paragraphs(fs, vcpkg_dir_status_file).value_or_exit(VCPKG_LINE_INFO); + + std::vector> status_pghs; + for (auto&& p : pghs) + { + status_pghs.push_back(std::make_unique(std::move(p))); + } + + return StatusParagraphs(std::move(status_pghs)); + } + + StatusParagraphs database_load_check(const VcpkgPaths& paths) + { + auto& fs = paths.get_filesystem(); + + const auto updates_dir = paths.vcpkg_dir_updates; + + std::error_code ec; + fs.create_directory(paths.installed, ec); + fs.create_directory(paths.vcpkg_dir, ec); + fs.create_directory(paths.vcpkg_dir_info, ec); + fs.create_directory(updates_dir, ec); + + const fs::path& status_file = paths.vcpkg_dir_status_file; + const fs::path status_file_old = status_file.parent_path() / "status-old"; + const fs::path status_file_new = status_file.parent_path() / "status-new"; + + StatusParagraphs current_status_db = load_current_database(fs, status_file, status_file_old); + + auto update_files = fs.get_files_non_recursive(updates_dir); + if (update_files.empty()) + { + // updates directory is empty, control file is up-to-date. + return current_status_db; + } + for (auto&& file : update_files) + { + if (!fs.is_regular_file(file)) continue; + if (file.filename() == "incomplete") continue; + + auto pghs = Paragraphs::get_paragraphs(fs, file).value_or_exit(VCPKG_LINE_INFO); + for (auto&& p : pghs) + { + current_status_db.insert(std::make_unique(std::move(p))); + } + } + + fs.write_contents(status_file_new, Strings::serialize(current_status_db)); + + fs.rename(status_file_new, status_file); + + for (auto&& file : update_files) + { + if (!fs.is_regular_file(file)) continue; + + fs.remove(file); + } + + return current_status_db; + } + + void write_update(const VcpkgPaths& paths, const StatusParagraph& p) + { + static int update_id = 0; + auto& fs = paths.get_filesystem(); + + const auto my_update_id = update_id++; + const auto tmp_update_filename = paths.vcpkg_dir_updates / "incomplete"; + const auto update_filename = paths.vcpkg_dir_updates / std::to_string(my_update_id); + + fs.write_contents(tmp_update_filename, Strings::serialize(p)); + fs.rename(tmp_update_filename, update_filename); + } + + static void upgrade_to_slash_terminated_sorted_format(Files::Filesystem& fs, + std::vector* lines, + const fs::path& listfile_path) + { + static bool was_tracked = false; + + if (lines->empty()) + { + return; + } + + if (lines->at(0).back() == '/') + { + return; // File already in the new format + } + + if (!was_tracked) + { + was_tracked = true; + Metrics::g_metrics.lock()->track_property("listfile", "update to new format"); + } + + // The files are sorted such that directories are placed just before the files they contain + // (They are not necessarily sorted alphabetically, e.g. libflac) + // Therefore we can detect the entries that represent directories by comparing every element with the next one + // and checking if the next has a slash immediately after the current one's length + for (size_t i = 0; i < lines->size() - 1; i++) + { + std::string& current_string = lines->at(i); + const std::string& next_string = lines->at(i + 1); + + const size_t potential_slash_char_index = current_string.length(); + // Make sure the index exists first + if (next_string.size() > potential_slash_char_index && next_string.at(potential_slash_char_index) == '/') + { + current_string += '/'; // Mark as a directory + } + } + + // After suffixing the directories with a slash, we can now sort. + // We cannot sort before adding the suffixes because the following (actual example): + /* + x86-windows/include/FLAC <<<<<< This would be separated from its group due to sorting + x86-windows/include/FLAC/all.h + x86-windows/include/FLAC/assert.h + x86-windows/include/FLAC/callback.h + x86-windows/include/FLAC++ + x86-windows/include/FLAC++/all.h + x86-windows/include/FLAC++/decoder.h + x86-windows/include/FLAC++/encoder.h + * + x86-windows/include/FLAC/ <<<<<< This will now be kept with its group when sorting + x86-windows/include/FLAC/all.h + x86-windows/include/FLAC/assert.h + x86-windows/include/FLAC/callback.h + x86-windows/include/FLAC++/ + x86-windows/include/FLAC++/all.h + x86-windows/include/FLAC++/decoder.h + x86-windows/include/FLAC++/encoder.h + */ + // Note that after sorting, the FLAC++/ group will be placed before the FLAC/ group + // The new format is lexicographically sorted + std::sort(lines->begin(), lines->end()); + + // Replace the listfile on disk + const fs::path updated_listfile_path = listfile_path.generic_string() + "_updated"; + fs.write_lines(updated_listfile_path, *lines); + fs.rename(updated_listfile_path, listfile_path); + } + + std::vector get_installed_ports(const StatusParagraphs& status_db) + { + std::vector installed_packages; + for (auto&& pgh : status_db) + { + if (pgh->state != InstallState::INSTALLED || pgh->want != Want::INSTALL) continue; + installed_packages.push_back(pgh.get()); + } + + return installed_packages; + } + + std::vector get_installed_files(const VcpkgPaths& paths, + const StatusParagraphs& status_db) + { + auto& fs = paths.get_filesystem(); + + std::vector installed_files; + + for (const std::unique_ptr& pgh : status_db) + { + if (pgh->state != InstallState::INSTALLED || !pgh->package.feature.empty()) + { + continue; + } + + const fs::path listfile_path = paths.listfile_path(pgh->package); + std::vector installed_files_of_current_pgh = + fs.read_lines(listfile_path).value_or_exit(VCPKG_LINE_INFO); + Strings::trim_all_and_remove_whitespace_strings(&installed_files_of_current_pgh); + upgrade_to_slash_terminated_sorted_format(fs, &installed_files_of_current_pgh, listfile_path); + + // Remove the directories + Util::erase_remove_if(installed_files_of_current_pgh, + [](const std::string& file) { return file.back() == '/'; }); + + StatusParagraphAndAssociatedFiles pgh_and_files = { + *pgh, SortedVector(std::move(installed_files_of_current_pgh))}; + installed_files.push_back(std::move(pgh_and_files)); + } + + return installed_files; + } + + CMakeVariable::CMakeVariable(const CWStringView varname, const wchar_t* varvalue) + : s(Strings::wformat(LR"("-D%s=%s")", varname, varvalue)) + { + } + CMakeVariable::CMakeVariable(const CWStringView varname, const std::string& varvalue) + : CMakeVariable(varname, Strings::to_utf16(varvalue).c_str()) + { + } + CMakeVariable::CMakeVariable(const CWStringView varname, const std::wstring& varvalue) + : CMakeVariable(varname, varvalue.c_str()) + { + } + CMakeVariable::CMakeVariable(const CWStringView varname, const fs::path& path) + : CMakeVariable(varname, path.generic_wstring()) + { + } + + std::wstring make_cmake_cmd(const fs::path& cmake_exe, + const fs::path& cmake_script, + const std::vector& pass_variables) + { + const std::wstring cmd_cmake_pass_variables = Strings::join(L" ", pass_variables, [](auto&& v) { return v.s; }); + return Strings::wformat( + LR"("%s" %s -P "%s")", cmake_exe.native(), cmd_cmake_pass_variables, cmake_script.generic_wstring()); + } + + std::string shorten_text(const std::string& desc, size_t length) + { + Checks::check_exit(VCPKG_LINE_INFO, length >= 3); + auto simple_desc = std::regex_replace(desc, std::regex("\\s+"), " "); + return simple_desc.size() <= length ? simple_desc : simple_desc.substr(0, length - 3) + "..."; + } +} diff --git a/toolsrc/src/vcpkg/vcpkgpaths.cpp b/toolsrc/src/vcpkg/vcpkgpaths.cpp new file mode 100644 index 000000000..e1a4acd69 --- /dev/null +++ b/toolsrc/src/vcpkg/vcpkgpaths.cpp @@ -0,0 +1,519 @@ +#include "pch.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace vcpkg +{ + static constexpr CWStringView V_120 = L"v120"; + static constexpr CWStringView V_140 = L"v140"; + static constexpr CWStringView V_141 = L"v141"; + + static bool exists_and_has_equal_or_greater_version(const std::wstring& version_cmd, + const std::array& expected_version) + { + static const std::regex RE(R"###((\d+)\.(\d+)\.(\d+))###"); + + const auto rc = System::cmd_execute_and_capture_output(Strings::wformat(LR"(%s)", version_cmd)); + if (rc.exit_code != 0) + { + return false; + } + + std::match_results match; + const auto found = std::regex_search(rc.output, match, RE); + if (!found) + { + return false; + } + + const int d1 = atoi(match[1].str().c_str()); + const int d2 = atoi(match[2].str().c_str()); + const int d3 = atoi(match[3].str().c_str()); + if (d1 > expected_version[0] || (d1 == expected_version[0] && d2 > expected_version[1]) || + (d1 == expected_version[0] && d2 == expected_version[1] && d3 >= expected_version[2])) + { + // satisfactory version found + return true; + } + + return false; + } + + static Optional find_if_has_equal_or_greater_version(const std::vector& candidate_paths, + const std::wstring& version_check_arguments, + const std::array& expected_version) + { + auto it = Util::find_if(candidate_paths, [&](const fs::path& p) { + const std::wstring cmd = Strings::wformat(LR"("%s" %s)", p.native(), version_check_arguments); + return exists_and_has_equal_or_greater_version(cmd, expected_version); + }); + + if (it != candidate_paths.cend()) + { + return std::move(*it); + } + + return nullopt; + } + + static fs::path fetch_dependency(const fs::path& scripts_folder, + const std::wstring& tool_name, + const fs::path& expected_downloaded_path, + const std::array& version) + { + const std::string tool_name_utf8 = Strings::to_utf8(tool_name); + const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]); + System::println("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...", + tool_name_utf8, + version_as_string, + tool_name_utf8, + version_as_string); + const fs::path script = scripts_folder / "fetchDependency.ps1"; + const auto install_cmd = + System::create_powershell_script_cmd(script, Strings::wformat(L"-Dependency %s", tool_name)); + const System::ExitCodeAndOutput rc = System::cmd_execute_and_capture_output(install_cmd); + if (rc.exit_code) + { + System::println(System::Color::error, + "Launching powershell failed or was denied when trying to fetch %s version %s.\n" + "(No sufficient installed version was found)", + tool_name_utf8, + version_as_string); + { + auto locked_metrics = Metrics::g_metrics.lock(); + locked_metrics->track_property("error", "powershell install failed"); + locked_metrics->track_property("dependency", tool_name); + } + Checks::exit_with_code(VCPKG_LINE_INFO, rc.exit_code); + } + + const fs::path actual_downloaded_path = Strings::trimmed(rc.output); + std::error_code ec; + const auto eq = fs::stdfs::equivalent(expected_downloaded_path, actual_downloaded_path, ec); + Checks::check_exit(VCPKG_LINE_INFO, + eq && !ec, + "Expected dependency downloaded path to be %s, but was %s", + expected_downloaded_path.u8string(), + actual_downloaded_path.u8string()); + return actual_downloaded_path; + } + + static fs::path get_cmake_path(const fs::path& downloads_folder, const fs::path& scripts_folder) + { + static constexpr std::array EXPECTED_VERSION = {3, 9, 3}; + static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version"; + + const fs::path downloaded_copy = downloads_folder / "cmake-3.9.3-win32-x86" / "bin" / "cmake.exe"; + const std::vector from_path = Files::find_from_PATH(L"cmake"); + + std::vector candidate_paths; + candidate_paths.push_back(downloaded_copy); + candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + candidate_paths.push_back(System::get_program_files_platform_bitness() / "CMake" / "bin" / "cmake.exe"); + candidate_paths.push_back(System::get_program_files_32_bit() / "CMake" / "bin"); + + const Optional path = + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_dependency(scripts_folder, L"cmake", downloaded_copy, EXPECTED_VERSION); + } + + fs::path get_nuget_path(const fs::path& downloads_folder, const fs::path& scripts_folder) + { + static constexpr std::array EXPECTED_VERSION = {4, 3, 0}; + static const std::wstring VERSION_CHECK_ARGUMENTS = Strings::WEMPTY; + + const fs::path downloaded_copy = downloads_folder / "nuget-4.3.0" / "nuget.exe"; + const std::vector from_path = Files::find_from_PATH(L"nuget"); + + std::vector candidate_paths; + candidate_paths.push_back(downloaded_copy); + candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + + auto path = find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_dependency(scripts_folder, L"nuget", downloaded_copy, EXPECTED_VERSION); + } + + fs::path get_git_path(const fs::path& downloads_folder, const fs::path& scripts_folder) + { + static constexpr std::array EXPECTED_VERSION = {2, 14, 1}; + static const std::wstring VERSION_CHECK_ARGUMENTS = L"--version"; + + const fs::path downloaded_copy = downloads_folder / "MinGit-2.14.1-32-bit" / "cmd" / "git.exe"; + const std::vector from_path = Files::find_from_PATH(L"git"); + + std::vector candidate_paths; + candidate_paths.push_back(downloaded_copy); + candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + candidate_paths.push_back(System::get_program_files_platform_bitness() / "git" / "cmd" / "git.exe"); + candidate_paths.push_back(System::get_program_files_32_bit() / "git" / "cmd" / "git.exe"); + + const Optional path = + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_dependency(scripts_folder, L"git", downloaded_copy, EXPECTED_VERSION); + } + + static fs::path get_ifw_installerbase_path(const fs::path& downloads_folder, const fs::path& scripts_folder) + { + static constexpr std::array EXPECTED_VERSION = {3, 1, 81}; + static const std::wstring VERSION_CHECK_ARGUMENTS = L"--framework-version"; + + const fs::path downloaded_copy = + downloads_folder / "QtInstallerFramework-win-x86" / "bin" / "installerbase.exe"; + + std::vector candidate_paths; + candidate_paths.push_back(downloaded_copy); + // TODO: Uncomment later + // const std::vector from_path = Files::find_from_PATH(L"installerbase"); + // candidate_paths.insert(candidate_paths.end(), from_path.cbegin(), from_path.cend()); + // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / + // "Tools" / "QtInstallerFramework" / "3.1" / "bin" / "installerbase.exe"); + // candidate_paths.push_back(fs::path(System::get_environment_variable(L"HOMEDRIVE").value_or("C:")) / "Qt" / + // "QtIFW-3.1.0" / "bin" / "installerbase.exe"); + + const Optional path = + find_if_has_equal_or_greater_version(candidate_paths, VERSION_CHECK_ARGUMENTS, EXPECTED_VERSION); + if (const auto p = path.get()) + { + return *p; + } + + return fetch_dependency(scripts_folder, L"installerbase", downloaded_copy, EXPECTED_VERSION); + } + + Expected VcpkgPaths::create(const fs::path& vcpkg_root_dir) + { + std::error_code ec; + const fs::path canonical_vcpkg_root_dir = fs::stdfs::canonical(vcpkg_root_dir, ec); + if (ec) + { + return ec; + } + + VcpkgPaths paths; + paths.root = canonical_vcpkg_root_dir; + + if (paths.root.empty()) + { + Metrics::g_metrics.lock()->track_property("error", "Invalid vcpkg root directory"); + Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid vcpkg root directory: %s", paths.root.string()); + } + + paths.packages = paths.root / "packages"; + paths.buildtrees = paths.root / "buildtrees"; + paths.downloads = paths.root / "downloads"; + paths.ports = paths.root / "ports"; + paths.installed = paths.root / "installed"; + paths.triplets = paths.root / "triplets"; + paths.scripts = paths.root / "scripts"; + + paths.buildsystems = paths.scripts / "buildsystems"; + paths.buildsystems_msbuild_targets = paths.buildsystems / "msbuild" / "vcpkg.targets"; + + paths.vcpkg_dir = paths.installed / "vcpkg"; + paths.vcpkg_dir_status_file = paths.vcpkg_dir / "status"; + paths.vcpkg_dir_info = paths.vcpkg_dir / "info"; + paths.vcpkg_dir_updates = paths.vcpkg_dir / "updates"; + + paths.ports_cmake = paths.scripts / "ports.cmake"; + + return paths; + } + + fs::path VcpkgPaths::package_dir(const PackageSpec& spec) const { return this->packages / spec.dir(); } + + fs::path VcpkgPaths::port_dir(const PackageSpec& spec) const { return this->ports / spec.name(); } + fs::path VcpkgPaths::port_dir(const std::string& name) const { return this->ports / name; } + + fs::path VcpkgPaths::build_info_file_path(const PackageSpec& spec) const + { + return this->package_dir(spec) / "BUILD_INFO"; + } + + fs::path VcpkgPaths::listfile_path(const BinaryParagraph& pgh) const + { + return this->vcpkg_dir_info / (pgh.fullstem() + ".list"); + } + + bool VcpkgPaths::is_valid_triplet(const Triplet& t) const + { + for (auto&& path : get_filesystem().get_files_non_recursive(this->triplets)) + { + const std::string triplet_file_name = path.stem().generic_u8string(); + if (t.canonical_name() == triplet_file_name) // TODO: fuzzy compare + { + // t.value = triplet_file_name; // NOTE: uncomment when implementing fuzzy compare + return true; + } + } + return false; + } + + const fs::path& VcpkgPaths::get_cmake_exe() const + { + return this->cmake_exe.get_lazy([this]() { return get_cmake_path(this->downloads, this->scripts); }); + } + + const fs::path& VcpkgPaths::get_git_exe() const + { + return this->git_exe.get_lazy([this]() { return get_git_path(this->downloads, this->scripts); }); + } + + const fs::path& VcpkgPaths::get_nuget_exe() const + { + return this->nuget_exe.get_lazy([this]() { return get_nuget_path(this->downloads, this->scripts); }); + } + + const fs::path& VcpkgPaths::get_ifw_installerbase_exe() const + { + return this->ifw_installerbase_exe.get_lazy( + [this]() { return get_ifw_installerbase_path(this->downloads, this->scripts); }); + } + + const fs::path& VcpkgPaths::get_ifw_binarycreator_exe() const + { + return this->ifw_binarycreator_exe.get_lazy( + [this]() { return get_ifw_installerbase_exe().parent_path() / "binarycreator.exe"; }); + } + + const fs::path& VcpkgPaths::get_ifw_repogen_exe() const + { + return this->ifw_repogen_exe.get_lazy( + [this]() { return get_ifw_installerbase_exe().parent_path() / "repogen.exe"; }); + } + + struct VisualStudioInstance + { + fs::path root_path; + std::string version; + std::string release_type; + std::string preference_weight; // Mostly unused, just for verification that order is as intended + + std::string major_version() const { return version.substr(0, 2); } + }; + + static std::vector get_visual_studio_instances(const VcpkgPaths& paths) + { + const fs::path script = paths.scripts / "findVisualStudioInstallationInstances.ps1"; + const std::wstring cmd = System::create_powershell_script_cmd(script); + const System::ExitCodeAndOutput ec_data = System::cmd_execute_and_capture_output(cmd); + Checks::check_exit( + VCPKG_LINE_INFO, ec_data.exit_code == 0, "Could not run script to detect Visual Studio instances"); + + const std::vector instances_as_strings = Strings::split(ec_data.output, "\n"); + std::vector output; + for (const std::string& instance_as_string : instances_as_strings) + { + const std::vector split = Strings::split(instance_as_string, "::"); + output.push_back({split.at(3), split.at(2), split.at(1), split.at(0)}); + } + + return output; + } + + static std::vector find_toolset_instances(const VcpkgPaths& paths) + { + using CPU = System::CPUArchitecture; + + const auto& fs = paths.get_filesystem(); + + // Note: this will contain a mix of vcvarsall.bat locations and dumpbin.exe locations. + std::vector paths_examined; + + std::vector found_toolsets; + + const std::vector vs_instances = get_visual_studio_instances(paths); + const bool v140_is_available = Util::find_if(vs_instances, [&](const VisualStudioInstance& vs_instance) { + return vs_instance.major_version() == "14"; + }) != vs_instances.cend(); + + for (const VisualStudioInstance& vs_instance : vs_instances) + { + const std::string major_version = vs_instance.major_version(); + if (major_version == "15") + { + const fs::path vc_dir = vs_instance.root_path / "VC"; + + // Skip any instances that do not have vcvarsall. + const fs::path vcvarsall_dir = vc_dir / "Auxiliary" / "Build"; + const fs::path vcvarsall_bat = vcvarsall_dir / "vcvarsall.bat"; + paths_examined.push_back(vcvarsall_bat); + if (!fs.exists(vcvarsall_bat)) continue; + + // Get all supported architectures + std::vector supported_architectures; + if (fs.exists(vcvarsall_dir / "vcvars32.bat")) + supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); + if (fs.exists(vcvarsall_dir / "vcvars64.bat")) + supported_architectures.push_back({L"amd64", CPU::X64, CPU::X64}); + if (fs.exists(vcvarsall_dir / "vcvarsx86_amd64.bat")) + supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); + if (fs.exists(vcvarsall_dir / "vcvarsx86_arm.bat")) + supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); + if (fs.exists(vcvarsall_dir / "vcvarsamd64_x86.bat")) + supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); + if (fs.exists(vcvarsall_dir / "vcvarsamd64_arm.bat")) + supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + + // Locate the "best" MSVC toolchain version + const fs::path msvc_path = vc_dir / "Tools" / "MSVC"; + std::vector msvc_subdirectories = fs.get_files_non_recursive(msvc_path); + Util::unstable_keep_if(msvc_subdirectories, + [&fs](const fs::path& path) { return fs.is_directory(path); }); + + // Sort them so that latest comes first + std::sort( + msvc_subdirectories.begin(), + msvc_subdirectories.end(), + [](const fs::path& left, const fs::path& right) { return left.filename() > right.filename(); }); + + for (const fs::path& subdir : msvc_subdirectories) + { + const fs::path dumpbin_path = subdir / "bin" / "HostX86" / "x86" / "dumpbin.exe"; + paths_examined.push_back(dumpbin_path); + if (fs.exists(dumpbin_path)) + { + found_toolsets.push_back(Toolset{ + vs_instance.root_path, dumpbin_path, vcvarsall_bat, {}, V_141, supported_architectures}); + + if (v140_is_available) + { + found_toolsets.push_back(Toolset{vs_instance.root_path, + dumpbin_path, + vcvarsall_bat, + {L"-vcvars_ver=14.0"}, + V_140, + supported_architectures}); + } + + break; + } + } + + continue; + } + + if (major_version == "14") + { + const fs::path vcvarsall_bat = vs_instance.root_path / "VC" / "vcvarsall.bat"; + + paths_examined.push_back(vcvarsall_bat); + if (fs.exists(vcvarsall_bat)) + { + const fs::path vs2015_dumpbin_exe = vs_instance.root_path / "VC" / "bin" / "dumpbin.exe"; + paths_examined.push_back(vs2015_dumpbin_exe); + + const fs::path vs2015_bin_dir = vcvarsall_bat.parent_path() / "bin"; + std::vector supported_architectures; + if (fs.exists(vs2015_bin_dir / "vcvars32.bat")) + supported_architectures.push_back({L"x86", CPU::X86, CPU::X86}); + if (fs.exists(vs2015_bin_dir / "amd64\\vcvars64.bat")) + supported_architectures.push_back({L"x64", CPU::X64, CPU::X64}); + if (fs.exists(vs2015_bin_dir / "x86_amd64\\vcvarsx86_amd64.bat")) + supported_architectures.push_back({L"x86_amd64", CPU::X86, CPU::X64}); + if (fs.exists(vs2015_bin_dir / "x86_arm\\vcvarsx86_arm.bat")) + supported_architectures.push_back({L"x86_arm", CPU::X86, CPU::ARM}); + if (fs.exists(vs2015_bin_dir / "amd64_x86\\vcvarsamd64_x86.bat")) + supported_architectures.push_back({L"amd64_x86", CPU::X64, CPU::X86}); + if (fs.exists(vs2015_bin_dir / "amd64_arm\\vcvarsamd64_arm.bat")) + supported_architectures.push_back({L"amd64_arm", CPU::X64, CPU::ARM}); + + if (fs.exists(vs2015_dumpbin_exe)) + { + found_toolsets.push_back({vs_instance.root_path, + vs2015_dumpbin_exe, + vcvarsall_bat, + {}, + V_140, + supported_architectures}); + } + } + } + } + + if (found_toolsets.empty()) + { + System::println(System::Color::error, "Could not locate a complete toolset."); + System::println("The following paths were examined:"); + for (const fs::path& path : paths_examined) + { + System::println(" %s", path.u8string()); + } + Checks::exit_fail(VCPKG_LINE_INFO); + } + + return found_toolsets; + } + + const Toolset& VcpkgPaths::get_toolset(const Optional& toolset_version, + const Optional& visual_studio_path) const + { + // Invariant: toolsets are non-empty and sorted with newest at back() + const std::vector& vs_toolsets = + this->toolsets.get_lazy([this]() { return find_toolset_instances(*this); }); + + std::vector candidates = Util::element_pointers(vs_toolsets); + const auto tsv = toolset_version.get(); + const auto vsp = visual_studio_path.get(); + + if (tsv && vsp) + { + const std::wstring w_toolset_version = Strings::to_utf16(*tsv); + const fs::path vs_root_path = *vsp; + Util::stable_keep_if(candidates, [&](const Toolset* t) { + return w_toolset_version == t->version && vs_root_path == t->visual_studio_root_path; + }); + Checks::check_exit(VCPKG_LINE_INFO, + !candidates.empty(), + "Could not find Visual Studio instace at %s with %s toolset.", + vs_root_path.generic_string(), + *tsv); + + Checks::check_exit(VCPKG_LINE_INFO, candidates.size() == 1); + return *candidates.back(); + } + + if (tsv) + { + const std::wstring w_toolset_version = Strings::to_utf16(*tsv); + Util::stable_keep_if(candidates, [&](const Toolset* t) { return w_toolset_version == t->version; }); + Checks::check_exit( + VCPKG_LINE_INFO, !candidates.empty(), "Could not find Visual Studio instace with %s toolset.", *tsv); + } + + if (vsp) + { + const fs::path vs_root_path = *vsp; + Util::stable_keep_if(candidates, + [&](const Toolset* t) { return vs_root_path == t->visual_studio_root_path; }); + Checks::check_exit(VCPKG_LINE_INFO, + !candidates.empty(), + "Could not find Visual Studio instace at %s.", + vs_root_path.generic_string()); + } + + return *candidates.front(); + } + + Files::Filesystem& VcpkgPaths::get_filesystem() const { return Files::get_real_filesystem(); } +} diff --git a/toolsrc/src/vcpkg/versiont.cpp b/toolsrc/src/vcpkg/versiont.cpp new file mode 100644 index 000000000..1c52d674a --- /dev/null +++ b/toolsrc/src/vcpkg/versiont.cpp @@ -0,0 +1,19 @@ +#include "pch.h" + +#include +#include + +namespace vcpkg +{ + VersionT::VersionT() : value("0.0.0") {} + VersionT::VersionT(const std::string& value) : value(value) {} + std::string VersionT::to_string() const { return value; } + bool operator==(const VersionT& left, const VersionT& right) { return left.value == right.value; } + bool operator!=(const VersionT& left, const VersionT& right) { return left.value != right.value; } + std::string to_printf_arg(const VersionT& version) { return version.value; } + + VersionDiff::VersionDiff() : left(), right() {} + VersionDiff::VersionDiff(const VersionT& left, const VersionT& right) : left(left), right(right) {} + + std::string VersionDiff::to_string() const { return Strings::format("%s -> %s", left.value, right.value); } +} diff --git a/toolsrc/src/vcpkg_Build.cpp b/toolsrc/src/vcpkg_Build.cpp deleted file mode 100644 index 9be20629d..000000000 --- a/toolsrc/src/vcpkg_Build.cpp +++ /dev/null @@ -1,406 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "PostBuildLint.h" -#include "metrics.h" -#include "vcpkg_Build.h" -#include "vcpkg_Checks.h" -#include "vcpkg_Chrono.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Enums.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_System.h" -#include "vcpkg_optional.h" -#include "vcpkglib.h" - -namespace vcpkg::Build -{ - Optional to_linkage_type(const std::string& str) - { - if (str == "dynamic") return LinkageType::DYNAMIC; - if (str == "static") return LinkageType::STATIC; - return nullopt; - } - - namespace BuildInfoRequiredField - { - static const std::string CRT_LINKAGE = "CRTLinkage"; - static const std::string LIBRARY_LINKAGE = "LibraryLinkage"; - } - - CWStringView to_vcvarsall_target(const std::string& cmake_system_name) - { - if (cmake_system_name == Strings::EMPTY) return Strings::WEMPTY; - if (cmake_system_name == "Windows") return Strings::WEMPTY; - if (cmake_system_name == "WindowsStore") return L"store"; - - Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported vcvarsall target %s", cmake_system_name); - } - - CWStringView to_vcvarsall_toolchain(const std::string& target_architecture, const Toolset& toolset) - { - auto maybe_target_arch = System::to_cpu_architecture(target_architecture); - Checks::check_exit( - VCPKG_LINE_INFO, maybe_target_arch.has_value(), "Invalid architecture string: %s", target_architecture); - auto target_arch = maybe_target_arch.value_or_exit(VCPKG_LINE_INFO); - auto host_architectures = System::get_supported_host_architectures(); - - for (auto&& host : host_architectures) - { - auto it = Util::find_if(toolset.supported_architectures, [&](const ToolsetArchOption& opt) { - return host == opt.host_arch && target_arch == opt.target_arch; - }); - if (it != toolset.supported_architectures.end()) return it->name; - } - - Checks::exit_with_message(VCPKG_LINE_INFO, "Unsupported toolchain combination %s", target_architecture); - } - - std::wstring make_build_env_cmd(const PreBuildInfo& pre_build_info, const Toolset& toolset) - { - const wchar_t* tonull = L" >nul"; - if (GlobalState::debugging) - { - tonull = Strings::WEMPTY; - } - - const auto arch = to_vcvarsall_toolchain(pre_build_info.target_architecture, toolset); - const auto target = to_vcvarsall_target(pre_build_info.cmake_system_name); - - return Strings::wformat(LR"("%s" %s %s %s %s 2>&1)", - toolset.vcvarsall.native(), - Strings::join(L" ", toolset.vcvarsall_options), - arch, - target, - tonull); - } - - static void create_binary_feature_control_file(const SourceParagraph& source_paragraph, - const FeatureParagraph& feature_paragraph, - const Triplet& triplet, - BinaryControlFile& bcf) - { - BinaryParagraph bpgh(source_paragraph, feature_paragraph, triplet); - bcf.features.emplace_back(std::move(bpgh)); - } - - static void create_binary_control_file(const SourceParagraph& source_paragraph, - const Triplet& triplet, - const BuildInfo& build_info, - BinaryControlFile& bcf) - { - BinaryParagraph bpgh(source_paragraph, triplet); - if (const auto p_ver = build_info.version.get()) - { - bpgh.version = *p_ver; - } - bcf.core_paragraph = std::move(bpgh); - } - - static void write_binary_control_file(const VcpkgPaths& paths, BinaryControlFile bcf) - { - std::string start = Strings::serialize(bcf.core_paragraph); - for (auto&& feature : bcf.features) - { - start += "\n" + Strings::serialize(feature); - } - const fs::path binary_control_file = paths.packages / bcf.core_paragraph.dir() / "CONTROL"; - paths.get_filesystem().write_contents(binary_control_file, start); - } - - ExtendedBuildResult build_package(const VcpkgPaths& paths, - const BuildPackageConfig& config, - const StatusParagraphs& status_db) - { - const PackageSpec spec = - PackageSpec::from_name_and_triplet(config.src.name, config.triplet).value_or_exit(VCPKG_LINE_INFO); - - const Triplet& triplet = config.triplet; - { - std::vector missing_specs; - for (auto&& dep : filter_dependencies(config.src.depends, triplet)) - { - if (status_db.find_installed(dep, triplet) == status_db.end()) - { - missing_specs.push_back( - PackageSpec::from_name_and_triplet(dep, triplet).value_or_exit(VCPKG_LINE_INFO)); - } - } - // Fail the build if any dependencies were missing - if (!missing_specs.empty()) - { - return {BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES, std::move(missing_specs)}; - } - } - - const fs::path& cmake_exe_path = paths.get_cmake_exe(); - const fs::path& git_exe_path = paths.get_git_exe(); - - const fs::path ports_cmake_script_path = paths.ports_cmake; - const auto pre_build_info = PreBuildInfo::from_triplet_file(paths, triplet); - const Toolset& toolset = paths.get_toolset(pre_build_info.platform_toolset, pre_build_info.visual_studio_path); - const auto cmd_set_environment = make_build_env_cmd(pre_build_info, toolset); - - std::string features; - if (GlobalState::feature_packages) - { - if (config.feature_list) - { - for (auto&& feature : *config.feature_list) - { - features.append(feature + ";"); - } - if (features.size() > 0) - { - features.pop_back(); - } - } - } - - const std::wstring cmd_launch_cmake = make_cmake_cmd( - cmake_exe_path, - ports_cmake_script_path, - { - {L"CMD", L"BUILD"}, - {L"PORT", config.src.name}, - {L"CURRENT_PORT_DIR", config.port_dir / "/."}, - {L"TARGET_TRIPLET", triplet.canonical_name()}, - {L"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()}, - {L"VCPKG_USE_HEAD_VERSION", to_bool(config.build_package_options.use_head_version) ? L"1" : L"0"}, - {L"_VCPKG_NO_DOWNLOADS", !to_bool(config.build_package_options.allow_downloads) ? L"1" : L"0"}, - {L"GIT", git_exe_path}, - {L"FEATURES", features}, - }); - - const std::wstring command = Strings::wformat(LR"(%s && %s)", cmd_set_environment, cmd_launch_cmake); - - const ElapsedTime timer = ElapsedTime::create_started(); - - const int return_code = System::cmd_execute_clean(command); - const auto buildtimeus = timer.microseconds(); - const auto spec_string = spec.to_string(); - - { - auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->track_metric("buildtimeus-" + spec_string, buildtimeus); - if (return_code != 0) - { - locked_metrics->track_property("error", "build failed"); - locked_metrics->track_property("build_error", spec_string); - return {BuildResult::BUILD_FAILED, {}}; - } - } - - const BuildInfo build_info = read_build_info(paths.get_filesystem(), paths.build_info_file_path(spec)); - const size_t error_count = PostBuildLint::perform_all_checks(spec, paths, pre_build_info, build_info); - - BinaryControlFile bcf; - - create_binary_control_file(config.src, triplet, build_info, bcf); - - if (error_count != 0) - { - return {BuildResult::POST_BUILD_CHECKS_FAILED, {}}; - } - if (GlobalState::feature_packages) - { - if (config.feature_list) - { - for (auto&& feature : *config.feature_list) - { - for (auto&& f_pgh : config.scf->feature_paragraphs) - { - if (f_pgh->name == feature) - create_binary_feature_control_file(*config.scf->core_paragraph, *f_pgh, triplet, bcf); - } - } - } - } - - write_binary_control_file(paths, bcf); - - // const fs::path port_buildtrees_dir = paths.buildtrees / spec.name; - // delete_directory(port_buildtrees_dir); - - return {BuildResult::SUCCEEDED, {}}; - } - - const std::string& to_string(const BuildResult build_result) - { - static const std::string NULLVALUE_STRING = Enums::nullvalue_to_string("vcpkg::Commands::Build::BuildResult"); - static const std::string SUCCEEDED_STRING = "SUCCEEDED"; - static const std::string BUILD_FAILED_STRING = "BUILD_FAILED"; - static const std::string FILE_CONFLICTS_STRING = "FILE_CONFLICTS"; - static const std::string POST_BUILD_CHECKS_FAILED_STRING = "POST_BUILD_CHECKS_FAILED"; - static const std::string CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING = "CASCADED_DUE_TO_MISSING_DEPENDENCIES"; - - switch (build_result) - { - case BuildResult::NULLVALUE: return NULLVALUE_STRING; - case BuildResult::SUCCEEDED: return SUCCEEDED_STRING; - case BuildResult::BUILD_FAILED: return BUILD_FAILED_STRING; - case BuildResult::POST_BUILD_CHECKS_FAILED: return POST_BUILD_CHECKS_FAILED_STRING; - case BuildResult::CASCADED_DUE_TO_MISSING_DEPENDENCIES: return CASCADED_DUE_TO_MISSING_DEPENDENCIES_STRING; - case BuildResult::FILE_CONFLICTS: return FILE_CONFLICTS_STRING; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - std::string create_error_message(const BuildResult build_result, const PackageSpec& spec) - { - return Strings::format("Error: Building package %s failed with: %s", spec, Build::to_string(build_result)); - } - - std::string create_user_troubleshooting_message(const PackageSpec& spec) - { - return Strings::format("Please ensure you're using the latest portfiles with `.\\vcpkg update`, then\n" - "submit an issue at https://github.com/Microsoft/vcpkg/issues including:\n" - " Package: %s\n" - " Vcpkg version: %s\n" - "\n" - "Additionally, attach any relevant sections from the log files above.", - spec, - Commands::Version::version()); - } - - static BuildInfo inner_create_buildinfo(std::unordered_map pgh) - { - Parse::ParagraphParser parser(std::move(pgh)); - - BuildInfo build_info; - - { - std::string crt_linkage_as_string; - parser.required_field(BuildInfoRequiredField::CRT_LINKAGE, crt_linkage_as_string); - - auto crtlinkage = to_linkage_type(crt_linkage_as_string); - if (const auto p = crtlinkage.get()) - build_info.crt_linkage = *p; - else - Checks::exit_with_message(VCPKG_LINE_INFO, "Invalid crt linkage type: [%s]", crt_linkage_as_string); - } - - { - std::string library_linkage_as_string; - parser.required_field(BuildInfoRequiredField::LIBRARY_LINKAGE, library_linkage_as_string); - auto liblinkage = to_linkage_type(library_linkage_as_string); - if (const auto p = liblinkage.get()) - build_info.library_linkage = *p; - else - Checks::exit_with_message( - VCPKG_LINE_INFO, "Invalid library linkage type: [%s]", library_linkage_as_string); - } - std::string version = parser.optional_field("Version"); - if (!version.empty()) build_info.version = std::move(version); - - std::map policies; - for (auto policy : G_ALL_POLICIES) - { - const auto setting = parser.optional_field(to_string(policy)); - if (setting.empty()) continue; - if (setting == "enabled") - policies.emplace(policy, true); - else if (setting == "disabled") - policies.emplace(policy, false); - else - Checks::exit_with_message( - VCPKG_LINE_INFO, "Unknown setting for policy '%s': %s", to_string(policy), setting); - } - - if (const auto err = parser.error_info("PostBuildInformation")) - { - print_error_message(err); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - build_info.policies = BuildPolicies(std::move(policies)); - - return build_info; - } - - BuildInfo read_build_info(const Files::Filesystem& fs, const fs::path& filepath) - { - const Expected> pghs = - Paragraphs::get_single_paragraph(fs, filepath); - Checks::check_exit(VCPKG_LINE_INFO, pghs.get() != nullptr, "Invalid BUILD_INFO file for package"); - return inner_create_buildinfo(*pghs.get()); - } - - PreBuildInfo PreBuildInfo::from_triplet_file(const VcpkgPaths& paths, const Triplet& triplet) - { - static constexpr CStringView FLAG_GUID = "c35112b6-d1ba-415b-aa5d-81de856ef8eb"; - - const fs::path& cmake_exe_path = paths.get_cmake_exe(); - const fs::path ports_cmake_script_path = paths.scripts / "get_triplet_environment.cmake"; - const fs::path triplet_file_path = paths.triplets / (triplet.canonical_name() + ".cmake"); - - const std::wstring cmd_launch_cmake = make_cmake_cmd(cmake_exe_path, - ports_cmake_script_path, - { - {L"CMAKE_TRIPLET_FILE", triplet_file_path}, - }); - - const std::wstring command = Strings::wformat(LR"(%s)", cmd_launch_cmake); - const auto ec_data = System::cmd_execute_and_capture_output(command); - Checks::check_exit(VCPKG_LINE_INFO, ec_data.exit_code == 0); - - const std::vector lines = Strings::split(ec_data.output, "\n"); - - PreBuildInfo pre_build_info; - - const auto e = lines.cend(); - auto cur = std::find(lines.cbegin(), e, FLAG_GUID); - if (cur != e) ++cur; - - for (; cur != e; ++cur) - { - auto&& line = *cur; - - const std::vector s = Strings::split(line, "="); - Checks::check_exit(VCPKG_LINE_INFO, - s.size() == 1 || s.size() == 2, - "Expected format is [VARIABLE_NAME=VARIABLE_VALUE], but was [%s]", - line); - - const bool variable_with_no_value = s.size() == 1; - const std::string variable_name = s.at(0); - const std::string variable_value = variable_with_no_value ? Strings::EMPTY : s.at(1); - - if (variable_name == "VCPKG_TARGET_ARCHITECTURE") - { - pre_build_info.target_architecture = variable_value; - continue; - } - - if (variable_name == "VCPKG_CMAKE_SYSTEM_NAME") - { - pre_build_info.cmake_system_name = variable_value; - continue; - } - - if (variable_name == "VCPKG_CMAKE_SYSTEM_VERSION") - { - pre_build_info.cmake_system_version = variable_value; - continue; - } - - if (variable_name == "VCPKG_PLATFORM_TOOLSET") - { - pre_build_info.platform_toolset = - variable_value.empty() ? nullopt : Optional{variable_value}; - continue; - } - - if (variable_name == "VCPKG_VISUAL_STUDIO_PATH") - { - pre_build_info.visual_studio_path = - variable_value.empty() ? nullopt : Optional{variable_value}; - continue; - } - - Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown variable name %s", line); - } - - return pre_build_info; - } -} diff --git a/toolsrc/src/vcpkg_Build_BuildPolicy.cpp b/toolsrc/src/vcpkg_Build_BuildPolicy.cpp deleted file mode 100644 index b3bb778dc..000000000 --- a/toolsrc/src/vcpkg_Build_BuildPolicy.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Build.h" -#include "vcpkg_Checks.h" -#include "vcpkg_Enums.h" - -namespace vcpkg::Build -{ - static const std::string NAME_EMPTY_PACKAGE = "PolicyEmptyPackage"; - static const std::string NAME_DLLS_WITHOUT_LIBS = "PolicyDLLsWithoutLIBs"; - static const std::string NAME_ONLY_RELEASE_CRT = "PolicyOnlyReleaseCRT"; - static const std::string NAME_EMPTY_INCLUDE_FOLDER = "PolicyEmptyIncludeFolder"; - static const std::string NAME_ALLOW_OBSOLETE_MSVCRT = "PolicyAllowObsoleteMsvcrt"; - - const std::string& to_string(BuildPolicy policy) - { - switch (policy) - { - case BuildPolicy::EMPTY_PACKAGE: return NAME_EMPTY_PACKAGE; - case BuildPolicy::DLLS_WITHOUT_LIBS: return NAME_DLLS_WITHOUT_LIBS; - case BuildPolicy::ONLY_RELEASE_CRT: return NAME_ONLY_RELEASE_CRT; - case BuildPolicy::EMPTY_INCLUDE_FOLDER: return NAME_EMPTY_INCLUDE_FOLDER; - case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return NAME_ALLOW_OBSOLETE_MSVCRT; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - CStringView to_cmake_variable(BuildPolicy policy) - { - switch (policy) - { - case BuildPolicy::EMPTY_PACKAGE: return "VCPKG_POLICY_EMPTY_PACKAGE"; - case BuildPolicy::DLLS_WITHOUT_LIBS: return "VCPKG_POLICY_DLLS_WITHOUT_LIBS"; - case BuildPolicy::ONLY_RELEASE_CRT: return "VCPKG_POLICY_ONLY_RELEASE_CRT"; - case BuildPolicy::EMPTY_INCLUDE_FOLDER: return "VCPKG_POLICY_EMPTY_INCLUDE_FOLDER"; - case BuildPolicy::ALLOW_OBSOLETE_MSVCRT: return "VCPKG_POLICY_ALLOW_OBSOLETE_MSVCRT"; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } -} diff --git a/toolsrc/src/vcpkg_Checks.cpp b/toolsrc/src/vcpkg_Checks.cpp deleted file mode 100644 index e7c9046a4..000000000 --- a/toolsrc/src/vcpkg_Checks.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "pch.h" - -#include "metrics.h" -#include "vcpkg_Checks.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::Checks -{ - [[noreturn]] static void cleanup_and_exit(const int exit_code) - { - const auto elapsed_us = GlobalState::timer.lock()->microseconds(); - - auto metrics = Metrics::g_metrics.lock(); - metrics->track_metric("elapsed_us", elapsed_us); - GlobalState::debugging = false; - metrics->flush(); - - SetConsoleCP(GlobalState::g_init_console_cp); - SetConsoleOutputCP(GlobalState::g_init_console_output_cp); - - fflush(nullptr); - - ::TerminateProcess(::GetCurrentProcess(), exit_code); - } - - static BOOL ctrl_handler(DWORD fdw_ctrl_type) - { - { - auto locked_metrics = Metrics::g_metrics.lock(); - locked_metrics->track_property("CtrlHandler", std::to_string(fdw_ctrl_type)); - locked_metrics->track_property("error", "CtrlHandler was fired."); - } - cleanup_and_exit(EXIT_FAILURE); - } - - void register_console_ctrl_handler() - { - SetConsoleCtrlHandler(reinterpret_cast(ctrl_handler), TRUE); - } - - [[noreturn]] void unreachable(const LineInfo& line_info) - { - System::println(System::Color::error, "Error: Unreachable code was reached"); - System::println(System::Color::error, line_info.to_string()); // Always print line_info here -#ifndef NDEBUG - std::abort(); -#else - cleanup_and_exit(EXIT_FAILURE); -#endif - } - - [[noreturn]] void exit_with_code(const LineInfo& line_info, const int exit_code) - { - Debug::println(System::Color::error, line_info.to_string()); - cleanup_and_exit(exit_code); - } - - [[noreturn]] void exit_with_message(const LineInfo& line_info, const CStringView error_message) - { - System::println(System::Color::error, error_message); - exit_fail(line_info); - } - - void check_exit(const LineInfo& line_info, bool expression) - { - if (!expression) - { - exit_with_message(line_info, Strings::EMPTY); - } - } - - void check_exit(const LineInfo& line_info, bool expression, const CStringView error_message) - { - if (!expression) - { - exit_with_message(line_info, error_message); - } - } -} diff --git a/toolsrc/src/vcpkg_Chrono.cpp b/toolsrc/src/vcpkg_Chrono.cpp deleted file mode 100644 index d96f30987..000000000 --- a/toolsrc/src/vcpkg_Chrono.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Checks.h" -#include "vcpkg_Chrono.h" - -namespace vcpkg -{ - static std::string format_time_userfriendly(const std::chrono::nanoseconds& nanos) - { - using std::chrono::duration_cast; - using std::chrono::hours; - using std::chrono::microseconds; - using std::chrono::milliseconds; - using std::chrono::minutes; - using std::chrono::nanoseconds; - using std::chrono::seconds; - - const double nanos_as_double = static_cast(nanos.count()); - - if (duration_cast(nanos) > hours()) - { - const auto t = nanos_as_double / duration_cast(hours(1)).count(); - return Strings::format("%.4g h", t); - } - - if (duration_cast(nanos) > minutes()) - { - const auto t = nanos_as_double / duration_cast(minutes(1)).count(); - return Strings::format("%.4g min", t); - } - - if (duration_cast(nanos) > seconds()) - { - const auto t = nanos_as_double / duration_cast(seconds(1)).count(); - return Strings::format("%.4g s", t); - } - - if (duration_cast(nanos) > milliseconds()) - { - const auto t = nanos_as_double / duration_cast(milliseconds(1)).count(); - return Strings::format("%.4g ms", t); - } - - if (duration_cast(nanos) > microseconds()) - { - const auto t = nanos_as_double / duration_cast(microseconds(1)).count(); - return Strings::format("%.4g us", t); - } - - return Strings::format("%.4g ns", nanos_as_double); - } - - ElapsedTime ElapsedTime::create_started() - { - ElapsedTime t; - t.m_start_tick = std::chrono::high_resolution_clock::now(); - return t; - } - - std::string ElapsedTime::to_string() const { return format_time_userfriendly(elapsed()); } -} diff --git a/toolsrc/src/vcpkg_Dependencies.cpp b/toolsrc/src/vcpkg_Dependencies.cpp deleted file mode 100644 index 8dd60a2eb..000000000 --- a/toolsrc/src/vcpkg_Dependencies.cpp +++ /dev/null @@ -1,669 +0,0 @@ -#include "pch.h" - -#include "PackageSpec.h" -#include "Paragraphs.h" -#include "StatusParagraphs.h" -#include "VcpkgPaths.h" -#include "vcpkg_Dependencies.h" -#include "vcpkg_Files.h" -#include "vcpkg_Graphs.h" -#include "vcpkg_Strings.h" -#include "vcpkg_Util.h" -#include "vcpkglib.h" - -namespace vcpkg::Dependencies -{ - struct FeatureNodeEdges - { - std::vector remove_edges; - std::vector build_edges; - bool plus = false; - }; - - struct Cluster : Util::MoveOnlyBase - { - std::vector status_paragraphs; - Optional source_control_file; - PackageSpec spec; - std::unordered_map edges; - std::unordered_set to_install_features; - std::unordered_set original_features; - bool will_remove = false; - bool transient_uninstalled = true; - RequestType request_type = RequestType::AUTO_SELECTED; - }; - - struct ClusterPtr - { - Cluster* ptr; - - Cluster* operator->() const { return ptr; } - }; - - bool operator==(const ClusterPtr& l, const ClusterPtr& r) { return l.ptr == r.ptr; } -} - -template<> -struct std::hash -{ - size_t operator()(const vcpkg::Dependencies::ClusterPtr& value) const - { - return std::hash()(value.ptr->spec); - } -}; - -namespace vcpkg::Dependencies -{ - struct GraphPlan - { - Graphs::Graph remove_graph; - Graphs::Graph install_graph; - }; - - struct ClusterGraph : Util::MoveOnlyBase - { - explicit ClusterGraph(std::unordered_map&& ports) - : m_ports(std::move(ports)) - { - } - - Cluster& get(const PackageSpec& spec) - { - auto it = m_graph.find(spec); - if (it == m_graph.end()) - { - // Load on-demand from m_ports - auto it_ports = m_ports.find(spec.name()); - if (it_ports != m_ports.end()) - { - auto& clust = m_graph[spec]; - clust.spec = spec; - cluster_from_scf(*it_ports->second, clust); - return clust; - } - return m_graph[spec]; - } - return it->second; - } - - private: - void cluster_from_scf(const SourceControlFile& scf, Cluster& out_cluster) const - { - FeatureNodeEdges core_dependencies; - core_dependencies.build_edges = - filter_dependencies_to_specs(scf.core_paragraph->depends, out_cluster.spec.triplet()); - out_cluster.edges.emplace("core", std::move(core_dependencies)); - - for (const auto& feature : scf.feature_paragraphs) - { - FeatureNodeEdges added_edges; - added_edges.build_edges = filter_dependencies_to_specs(feature->depends, out_cluster.spec.triplet()); - out_cluster.edges.emplace(feature->name, std::move(added_edges)); - } - out_cluster.source_control_file = &scf; - } - - std::unordered_map m_graph; - std::unordered_map m_ports; - }; - - std::vector AnyParagraph::dependencies(const Triplet& triplet) const - { - auto to_package_specs = [&](const std::vector& dependencies_as_string) { - return Util::fmap(dependencies_as_string, [&](const std::string s) { - return PackageSpec::from_name_and_triplet(s, triplet).value_or_exit(VCPKG_LINE_INFO); - }); - }; - - if (auto p = this->status_paragraph.get()) - { - return to_package_specs(p->package.depends); - } - - if (auto p = this->binary_control_file.get()) - { - auto deps = Util::fmap_flatten(p->features, [](const BinaryParagraph& pgh) { return pgh.depends; }); - deps.insert(deps.end(), p->core_paragraph.depends.begin(), p->core_paragraph.depends.end()); - return to_package_specs(deps); - } - - if (auto p = this->source_paragraph.get()) - { - return to_package_specs(filter_dependencies(p->depends, triplet)); - } - - Checks::exit_with_message(VCPKG_LINE_INFO, - "Cannot get dependencies because there was none of: source/binary/status paragraphs"); - } - - std::string to_output_string(RequestType request_type, const CStringView s) - { - switch (request_type) - { - case RequestType::AUTO_SELECTED: return Strings::format(" * %s", s); - case RequestType::USER_REQUESTED: return Strings::format(" %s", s); - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - InstallPlanAction::InstallPlanAction() : plan_type(InstallPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} - - InstallPlanAction::InstallPlanAction(const PackageSpec& spec, - const SourceControlFile& any_paragraph, - const std::unordered_set& features, - const RequestType& request_type) - : spec(spec), plan_type(InstallPlanType::BUILD_AND_INSTALL), request_type(request_type), feature_list(features) - { - this->any_paragraph.source_control_file = &any_paragraph; - } - - InstallPlanAction::InstallPlanAction(const PackageSpec& spec, - const std::unordered_set& features, - const RequestType& request_type) - : spec(spec), plan_type(InstallPlanType::ALREADY_INSTALLED), request_type(request_type), feature_list(features) - { - } - - InstallPlanAction::InstallPlanAction(const PackageSpec& spec, - const AnyParagraph& any_paragraph, - const RequestType& request_type) - : spec(spec), any_paragraph(any_paragraph), plan_type(InstallPlanType::UNKNOWN), request_type(request_type) - { - if (auto p = any_paragraph.status_paragraph.get()) - { - this->plan_type = InstallPlanType::ALREADY_INSTALLED; - return; - } - - if (auto p = any_paragraph.binary_control_file.get()) - { - this->plan_type = InstallPlanType::INSTALL; - return; - } - - if (auto p = any_paragraph.source_paragraph.get()) - { - this->plan_type = InstallPlanType::BUILD_AND_INSTALL; - return; - } - } - - std::string InstallPlanAction::displayname() const - { - if (this->feature_list.empty()) - { - return this->spec.to_string(); - } - - const std::string features = Strings::join(",", this->feature_list); - return Strings::format("%s[%s]:%s", this->spec.name(), features, this->spec.triplet()); - } - - bool InstallPlanAction::compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right) - { - return left->spec.name() < right->spec.name(); - } - - RemovePlanAction::RemovePlanAction() : plan_type(RemovePlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} - - RemovePlanAction::RemovePlanAction(const PackageSpec& spec, - const RemovePlanType& plan_type, - const RequestType& request_type) - : spec(spec), plan_type(plan_type), request_type(request_type) - { - } - - const PackageSpec& AnyAction::spec() const - { - if (const auto p = install_plan.get()) - { - return p->spec; - } - - if (const auto p = remove_plan.get()) - { - return p->spec; - } - - Checks::exit_with_message(VCPKG_LINE_INFO, "Null action"); - } - - bool ExportPlanAction::compare_by_name(const ExportPlanAction* left, const ExportPlanAction* right) - { - return left->spec.name() < right->spec.name(); - } - - ExportPlanAction::ExportPlanAction() : plan_type(ExportPlanType::UNKNOWN), request_type(RequestType::UNKNOWN) {} - - ExportPlanAction::ExportPlanAction(const PackageSpec& spec, - const AnyParagraph& any_paragraph, - const RequestType& request_type) - : spec(spec), any_paragraph(any_paragraph), plan_type(ExportPlanType::UNKNOWN), request_type(request_type) - { - if (auto p = any_paragraph.binary_control_file.get()) - { - this->plan_type = ExportPlanType::ALREADY_BUILT; - return; - } - - if (auto p = any_paragraph.source_paragraph.get()) - { - this->plan_type = ExportPlanType::PORT_AVAILABLE_BUT_NOT_BUILT; - return; - } - } - - bool RemovePlanAction::compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right) - { - return left->spec.name() < right->spec.name(); - } - - MapPortFile::MapPortFile(const std::unordered_map& map) : ports(map) {} - - const SourceControlFile& MapPortFile::get_control_file(const std::string& spec) const - { - auto scf = ports.find(spec); - if (scf == ports.end()) - { - Checks::exit_fail(VCPKG_LINE_INFO); - } - return scf->second; - } - - PathsPortFile::PathsPortFile(const VcpkgPaths& paths) : ports(paths) {} - - const SourceControlFile& PathsPortFile::get_control_file(const std::string& spec) const - { - auto cache_it = cache.find(spec); - if (cache_it != cache.end()) - { - return cache_it->second; - } - Parse::ParseExpected source_control_file = - Paragraphs::try_load_port(ports.get_filesystem(), ports.port_dir(spec)); - - if (auto scf = source_control_file.get()) - { - auto it = cache.emplace(spec, std::move(*scf->get())); - return it.first->second; - } - print_error_message(source_control_file.error()); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - std::vector create_install_plan(const PortFileProvider& port_file_provider, - const std::vector& specs, - const StatusParagraphs& status_db) - { - struct InstallAdjacencyProvider final : Graphs::AdjacencyProvider - { - const PortFileProvider& port_file_provider; - const StatusParagraphs& status_db; - const std::unordered_set& specs_as_set; - - InstallAdjacencyProvider(const PortFileProvider& port_file_provider, - const StatusParagraphs& s, - const std::unordered_set& specs_as_set) - : port_file_provider(port_file_provider), status_db(s), specs_as_set(specs_as_set) - { - } - - std::vector adjacency_list(const InstallPlanAction& plan) const override - { - if (plan.any_paragraph.status_paragraph.get()) return std::vector{}; - return plan.any_paragraph.dependencies(plan.spec.triplet()); - } - - InstallPlanAction load_vertex_data(const PackageSpec& spec) const override - { - const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() - ? RequestType::USER_REQUESTED - : RequestType::AUTO_SELECTED; - auto it = status_db.find_installed(spec); - if (it != status_db.end()) return InstallPlanAction{spec, {*it->get(), nullopt, nullopt}, request_type}; - return InstallPlanAction{ - spec, - {nullopt, nullopt, *port_file_provider.get_control_file(spec.name()).core_paragraph}, - request_type}; - } - }; - - const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - std::vector toposort = - Graphs::topological_sort(specs, InstallAdjacencyProvider{port_file_provider, status_db, specs_as_set}); - Util::erase_remove_if(toposort, [](const InstallPlanAction& plan) { - return plan.request_type == RequestType::AUTO_SELECTED && - plan.plan_type == InstallPlanType::ALREADY_INSTALLED; - }); - - return toposort; - } - - std::vector create_remove_plan(const std::vector& specs, - const StatusParagraphs& status_db) - { - struct RemoveAdjacencyProvider final : Graphs::AdjacencyProvider - { - const StatusParagraphs& status_db; - const std::vector& installed_ports; - const std::unordered_set& specs_as_set; - - RemoveAdjacencyProvider(const StatusParagraphs& status_db, - const std::vector& installed_ports, - const std::unordered_set& specs_as_set) - : status_db(status_db), installed_ports(installed_ports), specs_as_set(specs_as_set) - { - } - - std::vector adjacency_list(const RemovePlanAction& plan) const override - { - if (plan.plan_type == RemovePlanType::NOT_INSTALLED) - { - return {}; - } - - const PackageSpec& spec = plan.spec; - std::vector dependents; - for (const StatusParagraph* an_installed_package : installed_ports) - { - if (an_installed_package->package.spec.triplet() != spec.triplet()) continue; - - const std::vector& deps = an_installed_package->package.depends; - if (std::find(deps.begin(), deps.end(), spec.name()) == deps.end()) continue; - - dependents.push_back(an_installed_package->package.spec); - } - - return dependents; - } - - RemovePlanAction load_vertex_data(const PackageSpec& spec) const override - { - const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() - ? RequestType::USER_REQUESTED - : RequestType::AUTO_SELECTED; - const StatusParagraphs::const_iterator it = status_db.find_installed(spec); - if (it == status_db.end()) - { - return RemovePlanAction{spec, RemovePlanType::NOT_INSTALLED, request_type}; - } - return RemovePlanAction{spec, RemovePlanType::REMOVE, request_type}; - } - }; - - const std::vector& installed_ports = get_installed_ports(status_db); - const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - return Graphs::topological_sort(specs, RemoveAdjacencyProvider{status_db, installed_ports, specs_as_set}); - } - - std::vector create_export_plan(const VcpkgPaths& paths, - const std::vector& specs, - const StatusParagraphs& status_db) - { - struct ExportAdjacencyProvider final : Graphs::AdjacencyProvider - { - const VcpkgPaths& paths; - const StatusParagraphs& status_db; - const std::unordered_set& specs_as_set; - - ExportAdjacencyProvider(const VcpkgPaths& p, - const StatusParagraphs& s, - const std::unordered_set& specs_as_set) - : paths(p), status_db(s), specs_as_set(specs_as_set) - { - } - - std::vector adjacency_list(const ExportPlanAction& plan) const override - { - return plan.any_paragraph.dependencies(plan.spec.triplet()); - } - - ExportPlanAction load_vertex_data(const PackageSpec& spec) const override - { - const RequestType request_type = specs_as_set.find(spec) != specs_as_set.end() - ? RequestType::USER_REQUESTED - : RequestType::AUTO_SELECTED; - - Expected maybe_bpgh = Paragraphs::try_load_cached_control_package(paths, spec); - if (auto bcf = maybe_bpgh.get()) - return ExportPlanAction{spec, AnyParagraph{nullopt, std::move(*bcf), nullopt}, request_type}; - - auto maybe_scf = Paragraphs::try_load_port(paths.get_filesystem(), paths.port_dir(spec)); - if (auto scf = maybe_scf.get()) - return ExportPlanAction{spec, {nullopt, nullopt, *scf->get()->core_paragraph}, request_type}; - else - print_error_message(maybe_scf.error()); - - Checks::exit_with_message(VCPKG_LINE_INFO, "Could not find package %s", spec); - } - }; - - const std::unordered_set specs_as_set(specs.cbegin(), specs.cend()); - std::vector toposort = - Graphs::topological_sort(specs, ExportAdjacencyProvider{paths, status_db, specs_as_set}); - return toposort; - } - - enum class MarkPlusResult - { - FEATURE_NOT_FOUND, - SUCCESS, - }; - - MarkPlusResult mark_plus(const std::string& feature, - Cluster& cluster, - ClusterGraph& pkg_to_cluster, - GraphPlan& graph_plan); - void mark_minus(Cluster& cluster, ClusterGraph& pkg_to_cluster, GraphPlan& graph_plan); - - MarkPlusResult mark_plus(const std::string& feature, Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) - { - if (feature.empty()) - { - // Indicates that core was not specified in the reference - return mark_plus("core", cluster, graph, graph_plan); - } - - auto it = cluster.edges.find(feature); - if (it == cluster.edges.end()) return MarkPlusResult::FEATURE_NOT_FOUND; - - if (cluster.edges[feature].plus) return MarkPlusResult::SUCCESS; - - if (cluster.original_features.find(feature) == cluster.original_features.end()) - { - cluster.transient_uninstalled = true; - } - - if (!cluster.transient_uninstalled) - { - return MarkPlusResult::SUCCESS; - } - cluster.edges[feature].plus = true; - - if (!cluster.original_features.empty()) - { - mark_minus(cluster, graph, graph_plan); - } - - graph_plan.install_graph.add_vertex({&cluster}); - auto& tracked = cluster.to_install_features; - tracked.insert(feature); - - if (feature != "core") - { - // All features implicitly depend on core - auto res = mark_plus("core", cluster, graph, graph_plan); - - // Should be impossible for "core" to not exist - Checks::check_exit(VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS); - } - - for (auto&& depend : cluster.edges[feature].build_edges) - { - auto& depend_cluster = graph.get(depend.spec()); - auto res = mark_plus(depend.feature(), depend_cluster, graph, graph_plan); - - Checks::check_exit(VCPKG_LINE_INFO, - res == MarkPlusResult::SUCCESS, - "Error: Unable to satisfy dependency %s of %s", - depend, - FeatureSpec(cluster.spec, feature)); - - if (&depend_cluster == &cluster) continue; - graph_plan.install_graph.add_edge({&cluster}, {&depend_cluster}); - } - - return MarkPlusResult::SUCCESS; - } - - void mark_minus(Cluster& cluster, ClusterGraph& graph, GraphPlan& graph_plan) - { - if (cluster.will_remove) return; - cluster.will_remove = true; - - graph_plan.remove_graph.add_vertex({&cluster}); - for (auto&& pair : cluster.edges) - { - auto& remove_edges_edges = pair.second.remove_edges; - for (auto&& depend : remove_edges_edges) - { - auto& depend_cluster = graph.get(depend.spec()); - graph_plan.remove_graph.add_edge({&cluster}, {&depend_cluster}); - mark_minus(depend_cluster, graph, graph_plan); - } - } - - cluster.transient_uninstalled = true; - for (auto&& original_feature : cluster.original_features) - { - auto res = mark_plus(original_feature, cluster, graph, graph_plan); - if (res != MarkPlusResult::SUCCESS) - { - System::println(System::Color::warning, - "Warning: could not reinstall feature %s", - FeatureSpec{cluster.spec, original_feature}); - } - } - } - - static ClusterGraph create_feature_install_graph(const std::unordered_map& map, - const StatusParagraphs& status_db) - { - std::unordered_map ptr_map; - for (auto&& p : map) - ptr_map.emplace(p.first, &p.second); - ClusterGraph graph(std::move(ptr_map)); - - auto installed_ports = get_installed_ports(status_db); - - for (auto&& status_paragraph : installed_ports) - { - Cluster& cluster = graph.get(status_paragraph->package.spec); - - cluster.transient_uninstalled = false; - - cluster.status_paragraphs.emplace_back(status_paragraph); - - auto& status_paragraph_feature = status_paragraph->package.feature; - // In this case, empty string indicates the "core" paragraph for a package. - if (status_paragraph_feature.empty()) - { - cluster.original_features.insert("core"); - } - else - { - cluster.original_features.insert(status_paragraph_feature); - } - } - - for (auto&& status_paragraph : installed_ports) - { - auto& spec = status_paragraph->package.spec; - auto& status_paragraph_feature = status_paragraph->package.feature; - auto reverse_edges = FeatureSpec::from_strings_and_triplet(status_paragraph->package.depends, - status_paragraph->package.spec.triplet()); - - for (auto&& dependency : reverse_edges) - { - auto& dep_cluster = graph.get(dependency.spec()); - - auto depends_name = dependency.feature(); - if (depends_name.empty()) depends_name = "core"; - - auto& target_node = dep_cluster.edges[depends_name]; - target_node.remove_edges.emplace_back(FeatureSpec{spec, status_paragraph_feature}); - } - } - return graph; - } - - std::vector create_feature_install_plan(const std::unordered_map& map, - const std::vector& specs, - const StatusParagraphs& status_db) - { - ClusterGraph graph = create_feature_install_graph(map, status_db); - - GraphPlan graph_plan; - for (auto&& spec : specs) - { - Cluster& spec_cluster = graph.get(spec.spec()); - spec_cluster.request_type = RequestType::USER_REQUESTED; - auto res = mark_plus(spec.feature(), spec_cluster, graph, graph_plan); - - Checks::check_exit( - VCPKG_LINE_INFO, res == MarkPlusResult::SUCCESS, "Error: Unable to locate feature %s", spec); - - graph_plan.install_graph.add_vertex(ClusterPtr{&spec_cluster}); - } - - Graphs::GraphAdjacencyProvider adjacency_remove_graph(graph_plan.remove_graph.adjacency_list()); - auto remove_vertex_list = graph_plan.remove_graph.vertex_list(); - auto remove_toposort = Graphs::topological_sort(remove_vertex_list, adjacency_remove_graph); - - Graphs::GraphAdjacencyProvider adjacency_install_graph(graph_plan.install_graph.adjacency_list()); - auto insert_vertex_list = graph_plan.install_graph.vertex_list(); - auto insert_toposort = Graphs::topological_sort(insert_vertex_list, adjacency_install_graph); - - std::vector plan; - - for (auto&& p_cluster : remove_toposort) - { - auto scf = *p_cluster->source_control_file.get(); - auto spec = PackageSpec::from_name_and_triplet(scf->core_paragraph->name, p_cluster->spec.triplet()) - .value_or_exit(VCPKG_LINE_INFO); - plan.emplace_back(RemovePlanAction{ - std::move(spec), - RemovePlanType::REMOVE, - p_cluster->request_type, - }); - } - - for (auto&& p_cluster : insert_toposort) - { - if (p_cluster->transient_uninstalled) - { - // If it will be transiently uninstalled, we need to issue a full installation command - auto pscf = p_cluster->source_control_file.value_or_exit(VCPKG_LINE_INFO); - Checks::check_exit(VCPKG_LINE_INFO, pscf != nullptr); - plan.emplace_back(InstallPlanAction{ - p_cluster->spec, - *pscf, - p_cluster->to_install_features, - p_cluster->request_type, - }); - } - else - { - // If the package isn't transitively installed, still include it if the user explicitly requested it - if (p_cluster->request_type != RequestType::USER_REQUESTED) continue; - plan.emplace_back(InstallPlanAction{ - p_cluster->spec, - p_cluster->original_features, - p_cluster->request_type, - }); - } - } - - return plan; - } -} diff --git a/toolsrc/src/vcpkg_Enums.cpp b/toolsrc/src/vcpkg_Enums.cpp deleted file mode 100644 index 51ba9d5dc..000000000 --- a/toolsrc/src/vcpkg_Enums.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Checks.h" -#include "vcpkg_Enums.h" - -namespace vcpkg::Enums -{ - std::string nullvalue_to_string(const CStringView enum_name) { return Strings::format("%s_NULLVALUE", enum_name); } - - [[noreturn]] void nullvalue_used(const LineInfo& line_info, const CStringView enum_name) - { - Checks::exit_with_message(line_info, "NULLVALUE of enum %s was used", enum_name); - } -} diff --git a/toolsrc/src/vcpkg_Files.cpp b/toolsrc/src/vcpkg_Files.cpp deleted file mode 100644 index ad1fcebc6..000000000 --- a/toolsrc/src/vcpkg_Files.cpp +++ /dev/null @@ -1,209 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Files.h" -#include "vcpkg_System.h" -#include "vcpkg_Util.h" -#include - -namespace vcpkg::Files -{ - static const std::regex FILESYSTEM_INVALID_CHARACTERS_REGEX = std::regex(R"([\/:*?"<>|])"); - - struct RealFilesystem final : Filesystem - { - virtual Expected read_contents(const fs::path& file_path) const override - { - std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary); - if (file_stream.fail()) - { - return std::make_error_code(std::errc::no_such_file_or_directory); - } - - file_stream.seekg(0, file_stream.end); - auto length = file_stream.tellg(); - file_stream.seekg(0, file_stream.beg); - - if (length > SIZE_MAX) - { - return std::make_error_code(std::errc::file_too_large); - } - - std::string output; - output.resize(static_cast(length)); - file_stream.read(&output[0], length); - file_stream.close(); - - return std::move(output); - } - virtual Expected> read_lines(const fs::path& file_path) const override - { - std::fstream file_stream(file_path, std::ios_base::in | std::ios_base::binary); - if (file_stream.fail()) - { - return std::make_error_code(std::errc::no_such_file_or_directory); - } - - std::vector output; - std::string line; - while (std::getline(file_stream, line)) - { - output.push_back(line); - } - file_stream.close(); - - return std::move(output); - } - virtual fs::path find_file_recursively_up(const fs::path& starting_dir, - const std::string& filename) const override - { - fs::path current_dir = starting_dir; - for (; !current_dir.empty(); current_dir = current_dir.parent_path()) - { - const fs::path candidate = current_dir / filename; - if (exists(candidate)) - { - break; - } - } - - return current_dir; - } - - virtual std::vector get_files_recursive(const fs::path& dir) const override - { - std::vector ret; - - fs::stdfs::recursive_directory_iterator b(dir), e{}; - for (; b != e; ++b) - { - ret.push_back(b->path()); - } - - return ret; - } - - virtual std::vector get_files_non_recursive(const fs::path& dir) const override - { - std::vector ret; - - fs::stdfs::directory_iterator b(dir), e{}; - for (; b != e; ++b) - { - ret.push_back(b->path()); - } - - return ret; - } - - virtual void write_lines(const fs::path& file_path, const std::vector& lines) override - { - std::fstream output(file_path, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc); - for (const std::string& line : lines) - { - output << line << "\n"; - } - output.close(); - } - - virtual void rename(const fs::path& oldpath, const fs::path& newpath) override - { - fs::stdfs::rename(oldpath, newpath); - } - virtual bool remove(const fs::path& path) override { return fs::stdfs::remove(path); } - virtual bool remove(const fs::path& path, std::error_code& ec) override { return fs::stdfs::remove(path, ec); } - virtual std::uintmax_t remove_all(const fs::path& path, std::error_code& ec) override - { - // Working around the currently buggy remove_all() - std::uintmax_t out = fs::stdfs::remove_all(path, ec); - - for (int i = 0; i < 5 && this->exists(path); i++) - { - using namespace std::chrono_literals; - std::this_thread::sleep_for(i * 100ms); - out += fs::stdfs::remove_all(path, ec); - } - - if (this->exists(path)) - { - System::println(System::Color::warning, - "Some files in %s were unable to be removed. Close any editors operating in this " - "directory and retry.", - path.string()); - } - - return out; - } - virtual bool exists(const fs::path& path) const override { return fs::stdfs::exists(path); } - virtual bool is_directory(const fs::path& path) const override { return fs::stdfs::is_directory(path); } - virtual bool is_regular_file(const fs::path& path) const override { return fs::stdfs::is_regular_file(path); } - virtual bool is_empty(const fs::path& path) const override { return fs::stdfs::is_empty(path); } - virtual bool create_directory(const fs::path& path, std::error_code& ec) override - { - return fs::stdfs::create_directory(path, ec); - } - virtual bool create_directories(const fs::path& path, std::error_code& ec) override - { - return fs::stdfs::create_directories(path, ec); - } - virtual void copy(const fs::path& oldpath, const fs::path& newpath, fs::copy_options opts) override - { - fs::stdfs::copy(oldpath, newpath, opts); - } - virtual bool copy_file(const fs::path& oldpath, - const fs::path& newpath, - fs::copy_options opts, - std::error_code& ec) override - { - return fs::stdfs::copy_file(oldpath, newpath, opts, ec); - } - - virtual fs::file_status status(const fs::path& path, std::error_code& ec) const override - { - return fs::stdfs::status(path, ec); - } - virtual void write_contents(const fs::path& file_path, const std::string& data) override - { - FILE* f = nullptr; - auto ec = _wfopen_s(&f, file_path.native().c_str(), L"wb"); - Checks::check_exit( - VCPKG_LINE_INFO, ec == 0, "Error: Could not open file for writing: %s", file_path.u8string().c_str()); - auto count = fwrite(data.data(), sizeof(data[0]), data.size(), f); - fclose(f); - - Checks::check_exit(VCPKG_LINE_INFO, count == data.size()); - } - }; - - Filesystem& get_real_filesystem() - { - static RealFilesystem real_fs; - return real_fs; - } - - bool has_invalid_chars_for_filesystem(const std::string& s) - { - return std::regex_search(s, FILESYSTEM_INVALID_CHARACTERS_REGEX); - } - - void print_paths(const std::vector& paths) - { - System::println(); - for (const fs::path& p : paths) - { - System::println(" %s", p.generic_string()); - } - System::println(); - } - - std::vector find_from_PATH(const std::wstring& name) - { - const std::wstring cmd = Strings::wformat(L"where.exe %s", name); - auto out = System::cmd_execute_and_capture_output(cmd); - if (out.exit_code != 0) - { - return {}; - } - - return Util::fmap(Strings::split(out.output, "\n"), [](auto&& s) { return fs::path(s); }); - } -} diff --git a/toolsrc/src/vcpkg_GlobalState.cpp b/toolsrc/src/vcpkg_GlobalState.cpp deleted file mode 100644 index 2221222c0..000000000 --- a/toolsrc/src/vcpkg_GlobalState.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "pch.h" - -#include "vcpkg_GlobalState.h" - -namespace vcpkg -{ - Util::LockGuarded GlobalState::timer; - std::atomic GlobalState::debugging = false; - std::atomic GlobalState::feature_packages = false; - - std::atomic GlobalState::g_init_console_cp = 0; - std::atomic GlobalState::g_init_console_output_cp = 0; -} diff --git a/toolsrc/src/vcpkg_Input.cpp b/toolsrc/src/vcpkg_Input.cpp deleted file mode 100644 index f1cac9632..000000000 --- a/toolsrc/src/vcpkg_Input.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "pch.h" - -#include "metrics.h" -#include "vcpkg_Commands.h" -#include "vcpkg_Input.h" -#include "vcpkg_System.h" - -namespace vcpkg::Input -{ - PackageSpec check_and_get_package_spec(const std::string& package_spec_as_string, - const Triplet& default_triplet, - CStringView example_text) - { - const std::string as_lowercase = Strings::ascii_to_lowercase(package_spec_as_string); - auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet); - if (const auto spec = expected_spec.get()) - { - return PackageSpec{spec->package_spec}; - } - - // Intentionally show the lowercased string - System::println(System::Color::error, "Error: %s: %s", vcpkg::to_string(expected_spec.error()), as_lowercase); - System::print(example_text); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - void check_triplet(const Triplet& t, const VcpkgPaths& paths) - { - if (!paths.is_valid_triplet(t)) - { - System::println(System::Color::error, "Error: invalid triplet: %s", t); - Metrics::g_metrics.lock()->track_property("error", "invalid triplet: " + t.to_string()); - Commands::Help::help_topic_valid_triplet(paths); - Checks::exit_fail(VCPKG_LINE_INFO); - } - } - - FullPackageSpec check_and_get_full_package_spec(const std::string& full_package_spec_as_string, - const Triplet& default_triplet, - CStringView example_text) - { - const std::string as_lowercase = Strings::ascii_to_lowercase(full_package_spec_as_string); - auto expected_spec = FullPackageSpec::from_string(as_lowercase, default_triplet); - if (const auto spec = expected_spec.get()) - { - return *spec; - } - - // Intentionally show the lowercased string - System::println(System::Color::error, "Error: %s: %s", vcpkg::to_string(expected_spec.error()), as_lowercase); - System::print(example_text); - Checks::exit_fail(VCPKG_LINE_INFO); - } -} diff --git a/toolsrc/src/vcpkg_Parse.cpp b/toolsrc/src/vcpkg_Parse.cpp deleted file mode 100644 index e671a1a05..000000000 --- a/toolsrc/src/vcpkg_Parse.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Checks.h" -#include "vcpkg_Maps.h" -#include "vcpkg_Parse.h" - -namespace vcpkg::Parse -{ - static Optional remove_field(std::unordered_map* fields, - const std::string& fieldname) - { - auto it = fields->find(fieldname); - if (it == fields->end()) - { - return nullopt; - } - - const std::string value = std::move(it->second); - fields->erase(it); - return value; - } - - void ParagraphParser::required_field(const std::string& fieldname, std::string& out) - { - auto maybe_field = remove_field(&fields, fieldname); - if (const auto field = maybe_field.get()) - out = std::move(*field); - else - missing_fields.push_back(fieldname); - } - std::string ParagraphParser::optional_field(const std::string& fieldname) const - { - return remove_field(&fields, fieldname).value_or(Strings::EMPTY); - } - std::unique_ptr ParagraphParser::error_info(const std::string& name) const - { - if (!fields.empty() || !missing_fields.empty()) - { - auto err = std::make_unique(); - err->name = name; - err->extra_fields = Maps::extract_keys(fields); - err->missing_fields = std::move(missing_fields); - return err; - } - return nullptr; - } - - std::vector parse_comma_list(const std::string& str) - { - if (str.empty()) - { - return {}; - } - - std::vector out; - - size_t cur = 0; - do - { - auto pos = str.find(',', cur); - if (pos == std::string::npos) - { - out.push_back(str.substr(cur)); - break; - } - out.push_back(str.substr(cur, pos - cur)); - - // skip comma and space - ++pos; - if (str[pos] == ' ') - { - ++pos; - } - - cur = pos; - } while (cur != std::string::npos); - - return out; - } -} diff --git a/toolsrc/src/vcpkg_Strings.cpp b/toolsrc/src/vcpkg_Strings.cpp deleted file mode 100644 index bbe6b29cd..000000000 --- a/toolsrc/src/vcpkg_Strings.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Checks.h" -#include "vcpkg_Strings.h" -#include "vcpkg_Util.h" - -namespace vcpkg::Strings::details -{ - // To disambiguate between two overloads - static const auto isspace = [](const char c) { return std::isspace(c); }; - - // Avoids C4244 warnings because of char<->int conversion that occur when using std::tolower() - static char tolower_char(const char c) { return static_cast(std::tolower(c)); } - -#if defined(_WIN32) - static _locale_t& c_locale() - { - static _locale_t c_locale_impl = _create_locale(LC_ALL, "C"); - return c_locale_impl; - } -#endif - - std::string format_internal(const char* fmtstr, ...) - { - va_list args; - va_start(args, fmtstr); - -#if defined(_WIN32) - const int sz = _vscprintf_l(fmtstr, c_locale(), args); -#else - const int sz = vsnprintf(nullptr, 0, fmtstr, args); -#endif - Checks::check_exit(VCPKG_LINE_INFO, sz > 0); - - std::string output(sz, '\0'); - -#if defined(_WIN32) - _vsnprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args); -#else - vsnprintf(&output.at(0), output.size() + 1, fmtstr, args); -#endif - va_end(args); - - return output; - } - - std::wstring wformat_internal(const wchar_t* fmtstr, ...) - { - va_list args; - va_start(args, fmtstr); - -#if defined(_WIN32) - const int sz = _vscwprintf_l(fmtstr, c_locale(), args); -#else - const int sz = vswprintf(nullptr, 0, fmtstr, args); -#endif - Checks::check_exit(VCPKG_LINE_INFO, sz > 0); - - std::wstring output(sz, L'\0'); - -#if defined(_WIN32) - _vsnwprintf_s_l(&output.at(0), output.size() + 1, output.size(), fmtstr, c_locale(), args); -#else - vswprintf(&output.at(0), output.size() + 1, fmtstr, args); -#endif - va_end(args); - - return output; - } -} - -namespace vcpkg::Strings -{ - std::wstring to_utf16(const CStringView s) - { - const int size = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0); - std::wstring output; - output.resize(size - 1); - MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, output.data(), size - 1); - return output; - } - - std::string to_utf8(const CWStringView w) - { - const int size = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, nullptr, 0, nullptr, nullptr); - std::string output; - output.resize(size - 1); - WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, output.data(), size - 1, nullptr, nullptr); - return output; - } - - std::string::const_iterator case_insensitive_ascii_find(const std::string& s, const std::string& pattern) - { - const std::string pattern_as_lower_case(ascii_to_lowercase(pattern)); - return search(s.begin(), - s.end(), - pattern_as_lower_case.begin(), - pattern_as_lower_case.end(), - [](const char a, const char b) { return details::tolower_char(a) == b; }); - } - - bool case_insensitive_ascii_contains(const std::string& s, const std::string& pattern) - { - return case_insensitive_ascii_find(s, pattern) != s.end(); - } - - int case_insensitive_ascii_compare(const CStringView left, const CStringView right) - { - return _stricmp(left.c_str(), right.c_str()); - } - - std::string ascii_to_lowercase(const std::string& input) - { - std::string output(input); - std::transform(output.begin(), output.end(), output.begin(), &details::tolower_char); - return output; - } - - bool case_insensitive_ascii_starts_with(const std::string& s, const std::string& pattern) - { - return _strnicmp(s.c_str(), pattern.c_str(), pattern.size()) == 0; - } - - void trim(std::string* s) - { - s->erase(std::find_if_not(s->rbegin(), s->rend(), details::isspace).base(), s->end()); - s->erase(s->begin(), std::find_if_not(s->begin(), s->end(), details::isspace)); - } - - std::string trimmed(const std::string& s) - { - auto whitespace_back = std::find_if_not(s.rbegin(), s.rend(), details::isspace).base(); - auto whitespace_front = std::find_if_not(s.begin(), whitespace_back, details::isspace); - return std::string(whitespace_front, whitespace_back); - } - - void trim_all_and_remove_whitespace_strings(std::vector* strings) - { - for (std::string& s : *strings) - { - trim(&s); - } - - Util::erase_remove_if(*strings, [](const std::string& s) { return s.empty(); }); - } - - std::vector split(const std::string& s, const std::string& delimiter) - { - std::vector output; - - if (delimiter.empty()) - { - output.push_back(s); - return output; - } - - const size_t delimiter_length = delimiter.length(); - size_t i = 0; - for (size_t pos = s.find(delimiter); pos != std::string::npos; pos = s.find(delimiter, pos)) - { - output.push_back(s.substr(i, pos - i)); - pos += delimiter_length; - i = pos; - } - - // Add the rest of the string after the last delimiter, unless there is nothing after it - if (i != s.length()) - { - output.push_back(s.substr(i, s.length())); - } - - return output; - } -} diff --git a/toolsrc/src/vcpkg_System.cpp b/toolsrc/src/vcpkg_System.cpp deleted file mode 100644 index 3b4c440d8..000000000 --- a/toolsrc/src/vcpkg_System.cpp +++ /dev/null @@ -1,349 +0,0 @@ -#include "pch.h" - -#include "vcpkg_Checks.h" -#include "vcpkg_GlobalState.h" -#include "vcpkg_System.h" -#include "vcpkglib.h" - -namespace vcpkg::System -{ - tm get_current_date_time() - { - using std::chrono::system_clock; - std::time_t now_time = system_clock::to_time_t(system_clock::now()); - tm parts; - localtime_s(&parts, &now_time); - return parts; - } - - fs::path get_exe_path_of_current_process() - { - wchar_t buf[_MAX_PATH]; - const int bytes = GetModuleFileNameW(nullptr, buf, _MAX_PATH); - if (bytes == 0) std::abort(); - return fs::path(buf, buf + bytes); - } - - Optional to_cpu_architecture(CStringView arch) - { - if (Strings::case_insensitive_ascii_compare(arch, "x86") == 0) return CPUArchitecture::X86; - if (Strings::case_insensitive_ascii_compare(arch, "x64") == 0) return CPUArchitecture::X64; - if (Strings::case_insensitive_ascii_compare(arch, "amd64") == 0) return CPUArchitecture::X64; - if (Strings::case_insensitive_ascii_compare(arch, "arm") == 0) return CPUArchitecture::ARM; - if (Strings::case_insensitive_ascii_compare(arch, "arm64") == 0) return CPUArchitecture::ARM64; - return nullopt; - } - - CPUArchitecture get_host_processor() - { - auto w6432 = get_environment_variable(L"PROCESSOR_ARCHITEW6432"); - if (const auto p = w6432.get()) return to_cpu_architecture(Strings::to_utf8(*p)).value_or_exit(VCPKG_LINE_INFO); - - const auto procarch = get_environment_variable(L"PROCESSOR_ARCHITECTURE").value_or_exit(VCPKG_LINE_INFO); - return to_cpu_architecture(Strings::to_utf8(procarch)).value_or_exit(VCPKG_LINE_INFO); - } - - std::vector get_supported_host_architectures() - { - std::vector supported_architectures; - supported_architectures.push_back(get_host_processor()); - - // AMD64 machines support to run x86 applications - if (supported_architectures.back() == CPUArchitecture::X64) - { - supported_architectures.push_back(CPUArchitecture::X86); - } - - return supported_architectures; - } - - int cmd_execute_clean(const CWStringView cmd_line) - { - static const std::wstring SYSTEM_ROOT = get_environment_variable(L"SystemRoot").value_or_exit(VCPKG_LINE_INFO); - static const std::wstring SYSTEM_32 = SYSTEM_ROOT + LR"(\system32)"; - static const std::wstring NEW_PATH = Strings::wformat( - LR"(Path=%s;%s;%s\Wbem;%s\WindowsPowerShell\v1.0\)", SYSTEM_32, SYSTEM_ROOT, SYSTEM_32, SYSTEM_32); - - std::vector env_wstrings = { - L"ALLUSERSPROFILE", - L"APPDATA", - L"CommonProgramFiles", - L"CommonProgramFiles(x86)", - L"CommonProgramW6432", - L"COMPUTERNAME", - L"ComSpec", - L"HOMEDRIVE", - L"HOMEPATH", - L"LOCALAPPDATA", - L"LOGONSERVER", - L"NUMBER_OF_PROCESSORS", - L"OS", - L"PATHEXT", - L"PROCESSOR_ARCHITECTURE", - L"PROCESSOR_ARCHITEW6432", - L"PROCESSOR_IDENTIFIER", - L"PROCESSOR_LEVEL", - L"PROCESSOR_REVISION", - L"ProgramData", - L"ProgramFiles", - L"ProgramFiles(x86)", - L"ProgramW6432", - L"PROMPT", - L"PSModulePath", - L"PUBLIC", - L"SystemDrive", - L"SystemRoot", - L"TEMP", - L"TMP", - L"USERDNSDOMAIN", - L"USERDOMAIN", - L"USERDOMAIN_ROAMINGPROFILE", - L"USERNAME", - L"USERPROFILE", - L"windir", - // Enables proxy information to be passed to Curl, the underlying download library in cmake.exe - L"HTTP_PROXY", - L"HTTPS_PROXY", - // Enables find_package(CUDA) in CMake - L"CUDA_PATH", - }; - - // Flush stdout before launching external process - fflush(nullptr); - - std::wstring env_cstr; - - for (auto&& env_wstring : env_wstrings) - { - const Optional value = System::get_environment_variable(env_wstring); - const auto v = value.get(); - if (!v || v->empty()) continue; - - env_cstr.append(env_wstring); - env_cstr.push_back(L'='); - env_cstr.append(*v); - env_cstr.push_back(L'\0'); - } - - env_cstr.append(NEW_PATH); - env_cstr.push_back(L'\0'); - - STARTUPINFOW startup_info; - memset(&startup_info, 0, sizeof(STARTUPINFOW)); - startup_info.cb = sizeof(STARTUPINFOW); - - PROCESS_INFORMATION process_info; - memset(&process_info, 0, sizeof(PROCESS_INFORMATION)); - - // Basically we are wrapping it in quotes - std::wstring actual_cmd_line = Strings::wformat(LR"###(cmd.exe /c "%s")###", cmd_line); - Debug::println("CreateProcessW(%s)", Strings::to_utf8(actual_cmd_line)); - bool succeeded = TRUE == CreateProcessW(nullptr, - actual_cmd_line.data(), - nullptr, - nullptr, - FALSE, - BELOW_NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT, - env_cstr.data(), - nullptr, - &startup_info, - &process_info); - - Checks::check_exit(VCPKG_LINE_INFO, succeeded, "Process creation failed with error code: %lu", GetLastError()); - - CloseHandle(process_info.hThread); - - const DWORD result = WaitForSingleObject(process_info.hProcess, INFINITE); - Checks::check_exit(VCPKG_LINE_INFO, result != WAIT_FAILED, "WaitForSingleObject failed"); - - DWORD exit_code = 0; - GetExitCodeProcess(process_info.hProcess, &exit_code); - - Debug::println("CreateProcessW() returned %lu", exit_code); - return static_cast(exit_code); - } - - int cmd_execute(const CWStringView cmd_line) - { - // Flush stdout before launching external process - fflush(nullptr); - - // Basically we are wrapping it in quotes - const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s")###", cmd_line); - Debug::println("_wsystem(%s)", Strings::to_utf8(actual_cmd_line)); - const int exit_code = _wsystem(actual_cmd_line.c_str()); - Debug::println("_wsystem() returned %d", exit_code); - return exit_code; - } - - // On Win7, output from powershell calls contain a byte order mark, so we strip it out if it is present - static void remove_byte_order_marks(std::wstring* s) - { - const wchar_t* a = s->c_str(); - // This is the UTF-8 byte-order mark - while (s->size() >= 3 && a[0] == 0xEF && a[1] == 0xBB && a[2] == 0xBF) - { - s->erase(0, 3); - } - } - - ExitCodeAndOutput cmd_execute_and_capture_output(const CWStringView cmd_line) - { - // Flush stdout before launching external process - fflush(stdout); - - const std::wstring& actual_cmd_line = Strings::wformat(LR"###("%s 2>&1")###", cmd_line); - - Debug::println("_wpopen(%s)", Strings::to_utf8(actual_cmd_line)); - std::wstring output; - wchar_t buf[1024]; - const auto pipe = _wpopen(actual_cmd_line.c_str(), L"r"); - if (pipe == nullptr) - { - return {1, Strings::to_utf8(output)}; - } - while (fgetws(buf, 1024, pipe)) - { - output.append(buf); - } - if (!feof(pipe)) - { - return {1, Strings::to_utf8(output)}; - } - - const auto ec = _pclose(pipe); - Debug::println("_pclose() returned %d", ec); - remove_byte_order_marks(&output); - return {ec, Strings::to_utf8(output)}; - } - - std::wstring create_powershell_script_cmd(const fs::path& script_path, const CWStringView args) - { - // TODO: switch out ExecutionPolicy Bypass with "Remove Mark Of The Web" code and restore RemoteSigned - return Strings::wformat( - LR"(powershell -NoProfile -ExecutionPolicy Bypass -Command "& {& '%s' %s}")", script_path.native(), args); - } - - void println() { println(Strings::EMPTY); } - - void print(const CStringView message) { fputs(message.c_str(), stdout); } - - void println(const CStringView message) - { - print(message); - putchar('\n'); - } - - void print(const Color c, const CStringView message) - { - const HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE); - - CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info{}; - GetConsoleScreenBufferInfo(console_handle, &console_screen_buffer_info); - const auto original_color = console_screen_buffer_info.wAttributes; - - SetConsoleTextAttribute(console_handle, static_cast(c) | (original_color & 0xF0)); - print(message); - SetConsoleTextAttribute(console_handle, original_color); - } - - void println(const Color c, const CStringView message) - { - print(c, message); - putchar('\n'); - } - - Optional get_environment_variable(const CWStringView varname) noexcept - { - const auto sz = GetEnvironmentVariableW(varname.c_str(), nullptr, 0); - if (sz == 0) return nullopt; - - std::wstring ret(sz, L'\0'); - - Checks::check_exit(VCPKG_LINE_INFO, MAXDWORD >= ret.size()); - const auto sz2 = GetEnvironmentVariableW(varname.c_str(), ret.data(), static_cast(ret.size())); - Checks::check_exit(VCPKG_LINE_INFO, sz2 + 1 == sz); - ret.pop_back(); - return ret; - } - - static bool is_string_keytype(DWORD hkey_type) - { - return hkey_type == REG_SZ || hkey_type == REG_MULTI_SZ || hkey_type == REG_EXPAND_SZ; - } - - Optional get_registry_string(HKEY base, const CWStringView sub_key, const CWStringView valuename) - { - HKEY k = nullptr; - const LSTATUS ec = RegOpenKeyExW(base, sub_key.c_str(), NULL, KEY_READ, &k); - if (ec != ERROR_SUCCESS) return nullopt; - - DWORD dw_buffer_size = 0; - DWORD dw_type = 0; - auto rc = RegQueryValueExW(k, valuename.c_str(), nullptr, &dw_type, nullptr, &dw_buffer_size); - if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size == 0 || - dw_buffer_size % sizeof(wchar_t) != 0) - return nullopt; - std::wstring ret; - ret.resize(dw_buffer_size / sizeof(wchar_t)); - - rc = RegQueryValueExW( - k, valuename.c_str(), nullptr, &dw_type, reinterpret_cast(ret.data()), &dw_buffer_size); - if (rc != ERROR_SUCCESS || !is_string_keytype(dw_type) || dw_buffer_size != sizeof(wchar_t) * ret.size()) - return nullopt; - - ret.pop_back(); // remove extra trailing null byte - return ret; - } - - static const fs::path& get_program_files() - { - static const fs::path PATH = System::get_environment_variable(L"PROGRAMFILES").value_or_exit(VCPKG_LINE_INFO); - return PATH; - } - - const fs::path& get_program_files_32_bit() - { - static const fs::path PATH = []() -> fs::path { - auto value = System::get_environment_variable(L"ProgramFiles(x86)"); - if (auto v = value.get()) - { - return std::move(*v); - } - return get_program_files(); - }(); - return PATH; - } - - const fs::path& get_program_files_platform_bitness() - { - static const fs::path PATH = []() -> fs::path { - auto value = System::get_environment_variable(L"ProgramW6432"); - if (auto v = value.get()) - { - return std::move(*v); - } - return get_program_files(); - }(); - return PATH; - } -} - -namespace vcpkg::Debug -{ - void println(const CStringView message) - { - if (GlobalState::debugging) - { - System::println("[DEBUG] %s", message); - } - } - - void println(const System::Color c, const CStringView message) - { - if (GlobalState::debugging) - { - System::println(c, "[DEBUG] %s", message); - } - } -} diff --git a/toolsrc/src/vcpkg_metrics_uploader.cpp b/toolsrc/src/vcpkg_metrics_uploader.cpp deleted file mode 100644 index cef4f4756..000000000 --- a/toolsrc/src/vcpkg_metrics_uploader.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "metrics.h" -#include "vcpkg_Checks.h" -#include "vcpkg_Files.h" -#include - -using namespace vcpkg; - -int WINAPI WinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPSTR, _In_ int) -{ - int argCount; - LPWSTR* szArgList = CommandLineToArgvW(GetCommandLineW(), &argCount); - - Checks::check_exit(VCPKG_LINE_INFO, argCount == 2, "Requires exactly one argument, the path to the payload file"); - auto v = Files::get_real_filesystem().read_contents(szArgList[1]).value_or_exit(VCPKG_LINE_INFO); - Metrics::g_metrics.lock()->upload(v); - LocalFree(szArgList); - return 0; -} diff --git a/toolsrc/src/vcpkglib.cpp b/toolsrc/src/vcpkglib.cpp deleted file mode 100644 index 5cdafdbc8..000000000 --- a/toolsrc/src/vcpkglib.cpp +++ /dev/null @@ -1,247 +0,0 @@ -#include "pch.h" - -#include "Paragraphs.h" -#include "metrics.h" -#include "vcpkg_Files.h" -#include "vcpkg_Strings.h" -#include "vcpkg_Util.h" -#include "vcpkglib.h" - -namespace vcpkg -{ - static StatusParagraphs load_current_database(Files::Filesystem& fs, - const fs::path& vcpkg_dir_status_file, - const fs::path& vcpkg_dir_status_file_old) - { - if (!fs.exists(vcpkg_dir_status_file)) - { - if (!fs.exists(vcpkg_dir_status_file_old)) - { - // no status file, use empty db - return StatusParagraphs(); - } - - fs.rename(vcpkg_dir_status_file_old, vcpkg_dir_status_file); - } - - auto pghs = Paragraphs::get_paragraphs(fs, vcpkg_dir_status_file).value_or_exit(VCPKG_LINE_INFO); - - std::vector> status_pghs; - for (auto&& p : pghs) - { - status_pghs.push_back(std::make_unique(std::move(p))); - } - - return StatusParagraphs(std::move(status_pghs)); - } - - StatusParagraphs database_load_check(const VcpkgPaths& paths) - { - auto& fs = paths.get_filesystem(); - - const auto updates_dir = paths.vcpkg_dir_updates; - - std::error_code ec; - fs.create_directory(paths.installed, ec); - fs.create_directory(paths.vcpkg_dir, ec); - fs.create_directory(paths.vcpkg_dir_info, ec); - fs.create_directory(updates_dir, ec); - - const fs::path& status_file = paths.vcpkg_dir_status_file; - const fs::path status_file_old = status_file.parent_path() / "status-old"; - const fs::path status_file_new = status_file.parent_path() / "status-new"; - - StatusParagraphs current_status_db = load_current_database(fs, status_file, status_file_old); - - auto update_files = fs.get_files_non_recursive(updates_dir); - if (update_files.empty()) - { - // updates directory is empty, control file is up-to-date. - return current_status_db; - } - for (auto&& file : update_files) - { - if (!fs.is_regular_file(file)) continue; - if (file.filename() == "incomplete") continue; - - auto pghs = Paragraphs::get_paragraphs(fs, file).value_or_exit(VCPKG_LINE_INFO); - for (auto&& p : pghs) - { - current_status_db.insert(std::make_unique(std::move(p))); - } - } - - fs.write_contents(status_file_new, Strings::serialize(current_status_db)); - - fs.rename(status_file_new, status_file); - - for (auto&& file : update_files) - { - if (!fs.is_regular_file(file)) continue; - - fs.remove(file); - } - - return current_status_db; - } - - void write_update(const VcpkgPaths& paths, const StatusParagraph& p) - { - static int update_id = 0; - auto& fs = paths.get_filesystem(); - - const auto my_update_id = update_id++; - const auto tmp_update_filename = paths.vcpkg_dir_updates / "incomplete"; - const auto update_filename = paths.vcpkg_dir_updates / std::to_string(my_update_id); - - fs.write_contents(tmp_update_filename, Strings::serialize(p)); - fs.rename(tmp_update_filename, update_filename); - } - - static void upgrade_to_slash_terminated_sorted_format(Files::Filesystem& fs, - std::vector* lines, - const fs::path& listfile_path) - { - static bool was_tracked = false; - - if (lines->empty()) - { - return; - } - - if (lines->at(0).back() == '/') - { - return; // File already in the new format - } - - if (!was_tracked) - { - was_tracked = true; - Metrics::g_metrics.lock()->track_property("listfile", "update to new format"); - } - - // The files are sorted such that directories are placed just before the files they contain - // (They are not necessarily sorted alphabetically, e.g. libflac) - // Therefore we can detect the entries that represent directories by comparing every element with the next one - // and checking if the next has a slash immediately after the current one's length - for (size_t i = 0; i < lines->size() - 1; i++) - { - std::string& current_string = lines->at(i); - const std::string& next_string = lines->at(i + 1); - - const size_t potential_slash_char_index = current_string.length(); - // Make sure the index exists first - if (next_string.size() > potential_slash_char_index && next_string.at(potential_slash_char_index) == '/') - { - current_string += '/'; // Mark as a directory - } - } - - // After suffixing the directories with a slash, we can now sort. - // We cannot sort before adding the suffixes because the following (actual example): - /* - x86-windows/include/FLAC <<<<<< This would be separated from its group due to sorting - x86-windows/include/FLAC/all.h - x86-windows/include/FLAC/assert.h - x86-windows/include/FLAC/callback.h - x86-windows/include/FLAC++ - x86-windows/include/FLAC++/all.h - x86-windows/include/FLAC++/decoder.h - x86-windows/include/FLAC++/encoder.h - * - x86-windows/include/FLAC/ <<<<<< This will now be kept with its group when sorting - x86-windows/include/FLAC/all.h - x86-windows/include/FLAC/assert.h - x86-windows/include/FLAC/callback.h - x86-windows/include/FLAC++/ - x86-windows/include/FLAC++/all.h - x86-windows/include/FLAC++/decoder.h - x86-windows/include/FLAC++/encoder.h - */ - // Note that after sorting, the FLAC++/ group will be placed before the FLAC/ group - // The new format is lexicographically sorted - std::sort(lines->begin(), lines->end()); - - // Replace the listfile on disk - const fs::path updated_listfile_path = listfile_path.generic_string() + "_updated"; - fs.write_lines(updated_listfile_path, *lines); - fs.rename(updated_listfile_path, listfile_path); - } - - std::vector get_installed_ports(const StatusParagraphs& status_db) - { - std::vector installed_packages; - for (auto&& pgh : status_db) - { - if (pgh->state != InstallState::INSTALLED || pgh->want != Want::INSTALL) continue; - installed_packages.push_back(pgh.get()); - } - - return installed_packages; - } - - std::vector get_installed_files(const VcpkgPaths& paths, - const StatusParagraphs& status_db) - { - auto& fs = paths.get_filesystem(); - - std::vector installed_files; - - for (const std::unique_ptr& pgh : status_db) - { - if (pgh->state != InstallState::INSTALLED || !pgh->package.feature.empty()) - { - continue; - } - - const fs::path listfile_path = paths.listfile_path(pgh->package); - std::vector installed_files_of_current_pgh = - fs.read_lines(listfile_path).value_or_exit(VCPKG_LINE_INFO); - Strings::trim_all_and_remove_whitespace_strings(&installed_files_of_current_pgh); - upgrade_to_slash_terminated_sorted_format(fs, &installed_files_of_current_pgh, listfile_path); - - // Remove the directories - Util::erase_remove_if(installed_files_of_current_pgh, - [](const std::string& file) { return file.back() == '/'; }); - - StatusParagraphAndAssociatedFiles pgh_and_files = { - *pgh, SortedVector(std::move(installed_files_of_current_pgh))}; - installed_files.push_back(std::move(pgh_and_files)); - } - - return installed_files; - } - - CMakeVariable::CMakeVariable(const CWStringView varname, const wchar_t* varvalue) - : s(Strings::wformat(LR"("-D%s=%s")", varname, varvalue)) - { - } - CMakeVariable::CMakeVariable(const CWStringView varname, const std::string& varvalue) - : CMakeVariable(varname, Strings::to_utf16(varvalue).c_str()) - { - } - CMakeVariable::CMakeVariable(const CWStringView varname, const std::wstring& varvalue) - : CMakeVariable(varname, varvalue.c_str()) - { - } - CMakeVariable::CMakeVariable(const CWStringView varname, const fs::path& path) - : CMakeVariable(varname, path.generic_wstring()) - { - } - - std::wstring make_cmake_cmd(const fs::path& cmake_exe, - const fs::path& cmake_script, - const std::vector& pass_variables) - { - const std::wstring cmd_cmake_pass_variables = Strings::join(L" ", pass_variables, [](auto&& v) { return v.s; }); - return Strings::wformat( - LR"("%s" %s -P "%s")", cmake_exe.native(), cmd_cmake_pass_variables, cmake_script.generic_wstring()); - } - - std::string shorten_text(const std::string& desc, size_t length) - { - Checks::check_exit(VCPKG_LINE_INFO, length >= 3); - auto simple_desc = std::regex_replace(desc, std::regex("\\s+"), " "); - return simple_desc.size() <= length ? simple_desc : simple_desc.substr(0, length - 3) + "..."; - } -} diff --git a/toolsrc/src/vcpkgmetricsuploader.cpp b/toolsrc/src/vcpkgmetricsuploader.cpp new file mode 100644 index 000000000..2239fe750 --- /dev/null +++ b/toolsrc/src/vcpkgmetricsuploader.cpp @@ -0,0 +1,20 @@ +#include + +#include +#include + +#include + +using namespace vcpkg; + +int WINAPI WinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPSTR, _In_ int) +{ + int argCount; + LPWSTR* szArgList = CommandLineToArgvW(GetCommandLineW(), &argCount); + + Checks::check_exit(VCPKG_LINE_INFO, argCount == 2, "Requires exactly one argument, the path to the payload file"); + auto v = Files::get_real_filesystem().read_contents(szArgList[1]).value_or_exit(VCPKG_LINE_INFO); + Metrics::g_metrics.lock()->upload(v); + LocalFree(szArgList); + return 0; +} diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj b/toolsrc/vcpkglib/vcpkglib.vcxproj index 3bb945e85..ae332e015 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj @@ -136,114 +136,114 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create Create Create Create - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters index 918f83b0a..e902bffbb 100644 --- a/toolsrc/vcpkglib/vcpkglib.vcxproj.filters +++ b/toolsrc/vcpkglib/vcpkglib.vcxproj.filters @@ -13,312 +13,324 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + {69f6b6e6-5ac4-4419-a256-b8a6b0392720} + + + {4a229410-0d09-4dab-953b-f434d6483f96} + + + {75592043-ab63-4905-beee-568a6ab8bf93} + + + {fa1f10e7-58d2-4f7c-ac26-a979baa70061} + - + Source Files - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg - - Source Files + + Source Files\vcpkg\base - - Source Files + + Source Files\vcpkg\base - - Source Files + + Source Files\vcpkg\base - - Source Files + + Source Files\vcpkg\base - - Source Files + + Source Files\vcpkg\base - - Source Files - - - Source Files + + Source Files\vcpkg\base - - Source Files + + Source Files\vcpkg\base - - Source Files - - - Source Files + + Source Files\vcpkg\base - - Source Files + + Source Files\vcpkg\base - + Header Files - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg\base - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg - - Header Files + + Header Files\vcpkg + + + Header Files\vcpkg + + + Header Files\vcpkg \ No newline at end of file diff --git a/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj b/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj index 472d74e30..4b59c5ace 100644 --- a/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj +++ b/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj @@ -131,7 +131,7 @@ - + diff --git a/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj.filters b/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj.filters index a50df7250..847921000 100644 --- a/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj.filters +++ b/toolsrc/vcpkgmetricsuploader/vcpkgmetricsuploader.vcxproj.filters @@ -15,7 +15,7 @@ - + Source Files diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj b/toolsrc/vcpkgtest/vcpkgtest.vcxproj index 041e74d31..d25748124 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj @@ -19,11 +19,11 @@ - - - - - + + + + + diff --git a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters index b31dbd951..42691c614 100644 --- a/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters +++ b/toolsrc/vcpkgtest/vcpkgtest.vcxproj.filters @@ -15,19 +15,19 @@ - + Source Files - + Source Files - + Source Files - + Source Files - + Source Files -- cgit v1.2.3 From bea4c2ff4936f22b4024c2afef5e403533c7b291 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Fri, 13 Oct 2017 20:58:00 -0700 Subject: [vcpkg] Begin refactor to use CommandStructure to represent command parsing --- toolsrc/include/vcpkg/install.h | 2 + toolsrc/include/vcpkg/remove.h | 2 + toolsrc/include/vcpkg/vcpkgcmdarguments.h | 17 +++++++ toolsrc/src/vcpkg/commands.autocomplete.cpp | 77 ++++++++++++++++++----------- toolsrc/src/vcpkg/install.cpp | 38 +++++++++++--- toolsrc/src/vcpkg/remove.cpp | 37 ++++++++++++-- 6 files changed, 133 insertions(+), 40 deletions(-) diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h index 02600b7f5..72643ff37 100644 --- a/toolsrc/include/vcpkg/install.h +++ b/toolsrc/include/vcpkg/install.h @@ -65,5 +65,7 @@ namespace vcpkg::Install const VcpkgPaths& paths, StatusParagraphs& status_db); + extern const CommandStructure INSTALL_COMMAND_STRUCTURE; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); } diff --git a/toolsrc/include/vcpkg/remove.h b/toolsrc/include/vcpkg/remove.h index f4d381ca3..04f2461be 100644 --- a/toolsrc/include/vcpkg/remove.h +++ b/toolsrc/include/vcpkg/remove.h @@ -19,6 +19,8 @@ namespace vcpkg::Remove const Purge purge, StatusParagraphs& status_db); + extern const CommandStructure REMOVE_COMMAND_STRUCTURE; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db); } diff --git a/toolsrc/include/vcpkg/vcpkgcmdarguments.h b/toolsrc/include/vcpkg/vcpkgcmdarguments.h index 6c47b98f6..8b1d766b6 100644 --- a/toolsrc/include/vcpkg/vcpkgcmdarguments.h +++ b/toolsrc/include/vcpkg/vcpkgcmdarguments.h @@ -1,6 +1,8 @@ #pragma once +#include #include +#include #include #include @@ -47,4 +49,19 @@ namespace vcpkg private: std::unordered_map> optional_command_arguments; }; + + struct VcpkgPaths; + + struct CommandStructure + { + CStringView example_text; + + size_t minimum_arity; + size_t maximum_arity; + + Span switches; + Span settings; + + std::vector (*valid_arguments)(const VcpkgPaths& paths); + }; } diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index b8c633142..2e191b428 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -2,8 +2,10 @@ #include #include +#include #include #include +#include #include namespace vcpkg::Commands::Autocomplete @@ -47,6 +49,7 @@ namespace vcpkg::Commands::Autocomplete { const SortedVector sorted_results(results); System::println(Strings::join("\n", sorted_results)); + Checks::exit_success(line_info); } @@ -63,21 +66,23 @@ namespace vcpkg::Commands::Autocomplete { const std::string requested_command = match[1].str(); - std::vector valid_commands = {"install", - "search", - "remove", - "list", - "update", - "hash", - "help", - "integrate", - "export", - "edit", - "create", - "owns", - "cache", - "version", - "contact"}; + std::vector valid_commands = { + "install", + "search", + "remove", + "list", + "update", + "hash", + "help", + "integrate", + "export", + "edit", + "create", + "owns", + "cache", + "version", + "contact", + }; Util::unstable_keep_if(valid_commands, [&](const std::string& s) { return Strings::case_insensitive_ascii_starts_with(s, requested_command); @@ -86,22 +91,36 @@ namespace vcpkg::Commands::Autocomplete output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(valid_commands)); } - // Handles vcpkg install - if (std::regex_match(to_autocomplete, match, std::regex{R"###(^install.* (\S*)$)###"})) + struct CommandEntry { - const std::string start_with = match[1].str(); - auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); - auto& source_paragraphs = sources_and_errors.paragraphs; - output_sorted_results_and_exit(VCPKG_LINE_INFO, autocomplete_install(source_paragraphs, start_with)); - } - - // Handles vcpkg remove - if (std::regex_match(to_autocomplete, match, std::regex{R"###(^remove.* (\S*)$)###"})) + CStringView regex; + const CommandStructure& structure; + }; + static constexpr CommandEntry commands[] = { + {R"###(^install\s(.*\s|)(\S*)$)###", Install::INSTALL_COMMAND_STRUCTURE}, + {R"###(^remove\s(.*\s|)(\S*)$)###", Remove::REMOVE_COMMAND_STRUCTURE}, + }; + + for (auto&& command : commands) { - const std::string start_with = match[1].str(); - const StatusParagraphs status_db = database_load_check(paths); - const std::vector installed_packages = get_installed_ports(status_db); - output_sorted_results_and_exit(VCPKG_LINE_INFO, autocomplete_remove(installed_packages, start_with)); + if (std::regex_match(to_autocomplete, match, std::regex{command.regex.c_str()})) + { + auto prefix = match[2].str(); + std::vector v; + if (Strings::case_insensitive_ascii_starts_with(prefix, "-")) + { + v = Util::fmap(command.structure.switches, [](auto&& s) -> std::string { return s; }); + } + else + { + v = command.structure.valid_arguments(paths); + } + + Util::unstable_keep_if( + v, [&](const std::string& s) { return Strings::case_insensitive_ascii_starts_with(s, prefix); }); + + output_sorted_results_and_exit(VCPKG_LINE_INFO, std::move(v)); + } } Checks::exit_success(VCPKG_LINE_INFO); diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 28d6d1cc6..6a564b00c 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -525,14 +525,40 @@ namespace vcpkg::Install Checks::exit_success(VCPKG_LINE_INFO); } - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + static const std::string OPTION_DRY_RUN = "--dry-run"; + static const std::string OPTION_USE_HEAD_VERSION = "--head"; + static const std::string OPTION_NO_DOWNLOADS = "--no-downloads"; + static const std::string OPTION_RECURSE = "--recurse"; + static const std::string OPTION_KEEP_GOING = "--keep-going"; + + static const std::array INSTALL_SWITCHES = { + OPTION_DRY_RUN, + OPTION_USE_HEAD_VERSION, + OPTION_NO_DOWNLOADS, + OPTION_RECURSE, + OPTION_KEEP_GOING, + }; + static const std::array INSTALL_SETTINGS; + + static std::vector valid_arguments(const VcpkgPaths& paths) { - static const std::string OPTION_DRY_RUN = "--dry-run"; - static const std::string OPTION_USE_HEAD_VERSION = "--head"; - static const std::string OPTION_NO_DOWNLOADS = "--no-downloads"; - static const std::string OPTION_RECURSE = "--recurse"; - static const std::string OPTION_KEEP_GOING = "--keep-going"; + auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + + return Util::fmap(sources_and_errors.paragraphs, + [](auto&& pgh) -> std::string { return pgh->core_paragraph->name; }); + } + const CommandStructure INSTALL_COMMAND_STRUCTURE = { + "install zlib zlib:x64-windows curl boost", + 1, + SIZE_MAX, + INSTALL_SWITCHES, + INSTALL_SETTINGS, + &valid_arguments, + }; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) + { // input sanitization static const std::string EXAMPLE = Help::create_example_string("install zlib zlib:x64-windows curl boost"); args.check_min_arg_count(1, EXAMPLE); diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 3751566f7..30b3d6cd8 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -163,13 +163,40 @@ namespace vcpkg::Remove } } + static const std::string OPTION_PURGE = "--purge"; + static const std::string OPTION_NO_PURGE = "--no-purge"; + static const std::string OPTION_RECURSE = "--recurse"; + static const std::string OPTION_DRY_RUN = "--dry-run"; + static const std::string OPTION_OUTDATED = "--outdated"; + + static const std::array REMOVE_SWITCHES = { + OPTION_PURGE, + OPTION_NO_PURGE, + OPTION_RECURSE, + OPTION_DRY_RUN, + OPTION_OUTDATED, + }; + static const std::array REMOVE_SETTINGS; + + static std::vector valid_arguments(const VcpkgPaths& paths) + { + const StatusParagraphs status_db = database_load_check(paths); + const std::vector installed_packages = get_installed_ports(status_db); + + return Util::fmap(installed_packages, [](auto&& pgh) -> std::string { return pgh->package.spec.to_string(); }); + } + + const CommandStructure REMOVE_COMMAND_STRUCTURE = { + "remove zlib zlib:x64-windows curl boost", + 1, + SIZE_MAX, + REMOVE_SWITCHES, + REMOVE_SETTINGS, + &valid_arguments, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet) { - static const std::string OPTION_PURGE = "--purge"; - static const std::string OPTION_NO_PURGE = "--no-purge"; - static const std::string OPTION_RECURSE = "--recurse"; - static const std::string OPTION_DRY_RUN = "--dry-run"; - static const std::string OPTION_OUTDATED = "--outdated"; static const std::string EXAMPLE = Help::create_example_string("remove zlib zlib:x64-windows curl boost"); const std::unordered_set options = args.check_and_get_optional_command_arguments( {OPTION_PURGE, OPTION_NO_PURGE, OPTION_RECURSE, OPTION_DRY_RUN, OPTION_OUTDATED}); -- cgit v1.2.3 From fc1a24ad8bb3187d17341c967353c3cc9742317a Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 14 Oct 2017 01:45:28 -0700 Subject: [vcpkg] Initial commit of powershell integration --- scripts/posh-vcpkg/0.0.1/posh-vcpkg.psd1 | 31 +++++++++++++++++++++++++ scripts/posh-vcpkg/0.0.1/posh-vcpkg.psm1 | 39 ++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 scripts/posh-vcpkg/0.0.1/posh-vcpkg.psd1 create mode 100644 scripts/posh-vcpkg/0.0.1/posh-vcpkg.psm1 diff --git a/scripts/posh-vcpkg/0.0.1/posh-vcpkg.psd1 b/scripts/posh-vcpkg/0.0.1/posh-vcpkg.psd1 new file mode 100644 index 000000000..3fb94fe7d --- /dev/null +++ b/scripts/posh-vcpkg/0.0.1/posh-vcpkg.psd1 @@ -0,0 +1,31 @@ +@{ + +# Script module or binary module file associated with this manifest. +ModuleToProcess = 'posh-vcpkg.psm1' + +# Version number of this module. +ModuleVersion = '0.0.1' + +# ID used to uniquely identify this module +GUID = '948f02ab-fc99-4a53-8335-b6556eef129b' + +# Minimum version of the Windows PowerShell engine required by this module +PowerShellVersion = '5.0' + +FunctionsToExport = @('TabExpansion') +CmdletsToExport = @() +VariablesToExport = @() +AliasesToExport = @() + +# Private data to pass to the module specified in RootModule/ModuleToProcess. +# This may also contain a PSData hashtable with additional module metadata used by PowerShell. +PrivateData = +@{ + PSData = + @{ + # Tags applied to this module. These help with module discovery in online galleries. + Tags = @('vcpkg', 'tab', 'tab-completion', 'tab-expansion', 'tabexpansion') + } +} + +} diff --git a/scripts/posh-vcpkg/0.0.1/posh-vcpkg.psm1 b/scripts/posh-vcpkg/0.0.1/posh-vcpkg.psm1 new file mode 100644 index 000000000..25ef99609 --- /dev/null +++ b/scripts/posh-vcpkg/0.0.1/posh-vcpkg.psm1 @@ -0,0 +1,39 @@ +param() + +if (Get-Module posh-vcpkg) { return } + +if ($PSVersionTable.PSVersion.Major -lt 5) { + Write-Warning ("posh-vcpkg does not support PowerShell versions before 5.0.") + return +} + +if (Test-Path Function:\TabExpansion) { + Rename-Item Function:\TabExpansion VcpkgTabExpansionBackup +} + +function TabExpansion($line, $lastWord) { + $lastBlock = [regex]::Split($line, '[|;]')[-1].TrimStart() + + switch -regex ($lastBlock) { + "^(?(\./|\.\\|)vcpkg(\.exe|)) (?.*)$" + { + & $matches['vcpkgexe'] autocomplete $matches['remaining'] + return + } + + # Fall back on existing tab expansion + default { + if (Test-Path Function:\VcpkgTabExpansionBackup) { + VcpkgTabExpansionBackup $line $lastWord + } + } + } +} + +$exportModuleMemberParams = @{ + Function = @( + 'TabExpansion' + ) +} + +Export-ModuleMember @exportModuleMemberParams -- cgit v1.2.3 From bf41a93b9de45f5d407fd03a36096f2cd37902b4 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 14 Oct 2017 02:07:42 -0700 Subject: [vcpkg] Prefer the current vcpkg directory over the one the vcpkg.exe is located in --- toolsrc/src/vcpkg.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/toolsrc/src/vcpkg.cpp b/toolsrc/src/vcpkg.cpp index 748b4f0ee..f1a86ae22 100644 --- a/toolsrc/src/vcpkg.cpp +++ b/toolsrc/src/vcpkg.cpp @@ -74,8 +74,14 @@ static void inner(const VcpkgCmdArguments& args) } else { - vcpkg_root_dir = Files::get_real_filesystem().find_file_recursively_up( - fs::stdfs::absolute(System::get_exe_path_of_current_process()), ".vcpkg-root"); + const fs::path current_path = fs::stdfs::current_path(); + vcpkg_root_dir = Files::get_real_filesystem().find_file_recursively_up(current_path, ".vcpkg-root"); + + if (vcpkg_root_dir.empty()) + { + vcpkg_root_dir = Files::get_real_filesystem().find_file_recursively_up( + fs::stdfs::absolute(System::get_exe_path_of_current_process()), ".vcpkg-root"); + } } } @@ -88,6 +94,7 @@ static void inner(const VcpkgCmdArguments& args) vcpkg_root_dir.string(), expected_paths.error().message()); const VcpkgPaths paths = expected_paths.value_or_exit(VCPKG_LINE_INFO); + const int exit_code = _wchdir(paths.root.c_str()); Checks::check_exit(VCPKG_LINE_INFO, exit_code == 0, "Changing the working dir failed"); Commands::Version::warn_if_vcpkg_version_mismatch(paths); -- cgit v1.2.3 From b73327558ba79354769961a8c3f68e61fe9b673e Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 14 Oct 2017 02:07:56 -0700 Subject: `integrate` Fix quotes in command (in case of space in the path) --- toolsrc/src/vcpkg/commands.integrate.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/toolsrc/src/vcpkg/commands.integrate.cpp b/toolsrc/src/vcpkg/commands.integrate.cpp index 7f6639222..85b567adb 100644 --- a/toolsrc/src/vcpkg/commands.integrate.cpp +++ b/toolsrc/src/vcpkg/commands.integrate.cpp @@ -230,13 +230,14 @@ namespace vcpkg::Commands::Integrate } System::println(System::Color::success, "Applied user-wide integration for this vcpkg root."); const fs::path cmake_toolchain = paths.buildsystems / "vcpkg.cmake"; - System::println("\n" - "All MSBuild C++ projects can now #include any installed libraries.\n" - "Linking will be handled automatically.\n" - "Installing new libraries will make them instantly available.\n" - "\n" - "CMake projects should use -DCMAKE_TOOLCHAIN_FILE=%s", - cmake_toolchain.generic_string()); + System::println( + R"( +All MSBuild C++ projects can now #include any installed libraries. +Linking will be handled automatically. +Installing new libraries will make them instantly available. + +CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s")", + cmake_toolchain.generic_string()); Checks::exit_success(VCPKG_LINE_INFO); } -- cgit v1.2.3 From 58fd38c8200ce4c96ebe1aae3f85b324456b0ff7 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 14 Oct 2017 02:16:55 -0700 Subject: [vcpkg-autocomplete] Add edit completion --- toolsrc/include/vcpkg/commands.h | 1 + toolsrc/include/vcpkg/install.h | 2 +- toolsrc/include/vcpkg/remove.h | 2 +- toolsrc/src/vcpkg/commands.autocomplete.cpp | 5 +++-- toolsrc/src/vcpkg/commands.edit.cpp | 27 +++++++++++++++++++++++++-- toolsrc/src/vcpkg/install.cpp | 2 +- toolsrc/src/vcpkg/remove.cpp | 2 +- 7 files changed, 33 insertions(+), 8 deletions(-) diff --git a/toolsrc/include/vcpkg/commands.h b/toolsrc/include/vcpkg/commands.h index 64b2118ce..e00812c98 100644 --- a/toolsrc/include/vcpkg/commands.h +++ b/toolsrc/include/vcpkg/commands.h @@ -38,6 +38,7 @@ namespace vcpkg::Commands namespace Edit { + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } diff --git a/toolsrc/include/vcpkg/install.h b/toolsrc/include/vcpkg/install.h index 72643ff37..db6055f4f 100644 --- a/toolsrc/include/vcpkg/install.h +++ b/toolsrc/include/vcpkg/install.h @@ -65,7 +65,7 @@ namespace vcpkg::Install const VcpkgPaths& paths, StatusParagraphs& status_db); - extern const CommandStructure INSTALL_COMMAND_STRUCTURE; + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); } diff --git a/toolsrc/include/vcpkg/remove.h b/toolsrc/include/vcpkg/remove.h index 04f2461be..6d8a3ebe9 100644 --- a/toolsrc/include/vcpkg/remove.h +++ b/toolsrc/include/vcpkg/remove.h @@ -19,7 +19,7 @@ namespace vcpkg::Remove const Purge purge, StatusParagraphs& status_db); - extern const CommandStructure REMOVE_COMMAND_STRUCTURE; + extern const CommandStructure COMMAND_STRUCTURE; void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet); void remove_package(const VcpkgPaths& paths, const PackageSpec& spec, StatusParagraphs* status_db); diff --git a/toolsrc/src/vcpkg/commands.autocomplete.cpp b/toolsrc/src/vcpkg/commands.autocomplete.cpp index 2e191b428..23c2c2f7e 100644 --- a/toolsrc/src/vcpkg/commands.autocomplete.cpp +++ b/toolsrc/src/vcpkg/commands.autocomplete.cpp @@ -97,8 +97,9 @@ namespace vcpkg::Commands::Autocomplete const CommandStructure& structure; }; static constexpr CommandEntry commands[] = { - {R"###(^install\s(.*\s|)(\S*)$)###", Install::INSTALL_COMMAND_STRUCTURE}, - {R"###(^remove\s(.*\s|)(\S*)$)###", Remove::REMOVE_COMMAND_STRUCTURE}, + {R"###(^install\s(.*\s|)(\S*)$)###", Install::COMMAND_STRUCTURE}, + {R"###(^edit\s(.*\s|)(\S*)$)###", Edit::COMMAND_STRUCTURE}, + {R"###(^remove\s(.*\s|)(\S*)$)###", Remove::COMMAND_STRUCTURE}, }; for (auto&& command : commands) diff --git a/toolsrc/src/vcpkg/commands.edit.cpp b/toolsrc/src/vcpkg/commands.edit.cpp index 9497bd76e..a90ae1bc3 100644 --- a/toolsrc/src/vcpkg/commands.edit.cpp +++ b/toolsrc/src/vcpkg/commands.edit.cpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace vcpkg::Commands::Edit { @@ -30,10 +31,32 @@ namespace vcpkg::Commands::Edit return output; } - void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + static const std::string OPTION_BUILDTREES = "--buildtrees"; + + static const std::array SWITCHES = { + OPTION_BUILDTREES, + }; + static const std::array SETTINGS; + + static std::vector valid_arguments(const VcpkgPaths& paths) { - static const std::string OPTION_BUILDTREES = "--buildtrees"; + auto sources_and_errors = Paragraphs::try_load_all_ports(paths.get_filesystem(), paths.ports); + + return Util::fmap(sources_and_errors.paragraphs, + [](auto&& pgh) -> std::string { return pgh->core_paragraph->name; }); + } + + const CommandStructure COMMAND_STRUCTURE = { + "edit zlib", + 1, + 1, + SWITCHES, + SETTINGS, + &valid_arguments, + }; + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { static const fs::path VS_CODE_INSIDERS = fs::path{"Microsoft VS Code Insiders"} / "Code - Insiders.exe"; static const fs::path VS_CODE = fs::path{"Microsoft VS Code"} / "Code.exe"; diff --git a/toolsrc/src/vcpkg/install.cpp b/toolsrc/src/vcpkg/install.cpp index 6a564b00c..26f729a57 100644 --- a/toolsrc/src/vcpkg/install.cpp +++ b/toolsrc/src/vcpkg/install.cpp @@ -548,7 +548,7 @@ namespace vcpkg::Install [](auto&& pgh) -> std::string { return pgh->core_paragraph->name; }); } - const CommandStructure INSTALL_COMMAND_STRUCTURE = { + const CommandStructure COMMAND_STRUCTURE = { "install zlib zlib:x64-windows curl boost", 1, SIZE_MAX, diff --git a/toolsrc/src/vcpkg/remove.cpp b/toolsrc/src/vcpkg/remove.cpp index 30b3d6cd8..04ddba1e4 100644 --- a/toolsrc/src/vcpkg/remove.cpp +++ b/toolsrc/src/vcpkg/remove.cpp @@ -186,7 +186,7 @@ namespace vcpkg::Remove return Util::fmap(installed_packages, [](auto&& pgh) -> std::string { return pgh->package.spec.to_string(); }); } - const CommandStructure REMOVE_COMMAND_STRUCTURE = { + const CommandStructure COMMAND_STRUCTURE = { "remove zlib zlib:x64-windows curl boost", 1, SIZE_MAX, -- cgit v1.2.3 From ab48a71c9af25041ab29a0d8e62a3cdf380638a5 Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 14 Oct 2017 05:38:43 -0700 Subject: [cctz][abseil] Initial commit of cctz, improvement of abseil to build synch and time. --- ports/abseil/CMakeLists.txt | 32 ++++++++++++++++++++++++-------- ports/abseil/CONTROL | 3 ++- ports/abseil/portfile.cmake | 5 ++--- ports/cctz/CMakeLists.txt | 36 ++++++++++++++++++++++++++++++++++++ ports/cctz/CONTROL | 3 +++ ports/cctz/portfile.cmake | 24 ++++++++++++++++++++++++ 6 files changed, 91 insertions(+), 12 deletions(-) create mode 100644 ports/cctz/CMakeLists.txt create mode 100644 ports/cctz/CONTROL create mode 100644 ports/cctz/portfile.cmake diff --git a/ports/abseil/CMakeLists.txt b/ports/abseil/CMakeLists.txt index 34b69817a..4a96b3fde 100644 --- a/ports/abseil/CMakeLists.txt +++ b/ports/abseil/CMakeLists.txt @@ -1,21 +1,29 @@ cmake_minimum_required(VERSION 3.8) project(abseil CXX) -add_definitions(-DNOMINMAX) +add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN) set(CMAKE_DEBUG_POSTFIX d) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) -option(INSTALL_HEADERS "Install header files" ON) +if(CMAKE_BUILD_TYPE STREQUAL "Release") + option(INSTALL_HEADERS "Install header files" ON) +else() + option(INSTALL_HEADERS "Install header files" OFF) +endif() function(add_sublibrary LIB) file(GLOB_RECURSE SOURCES "absl/${LIB}/*.cc") - list(FILTER SOURCES EXCLUDE REGEX "_test") + list(FILTER SOURCES EXCLUDE REGEX "_test(_.+)?.cc$|_nonprod.cc$") file(GLOB HEADERS "absl/${LIB}/*.h") file(GLOB INTERNAL_HEADERS "absl/${LIB}/internal/*.h") if(SOURCES) - add_library(${LIB} ${SOURCES}) + if("STATIC" IN_LIST ARGN) + add_library(${LIB} STATIC ${SOURCES}) + else() + add_library(${LIB} ${SOURCES}) + endif() set_target_properties(${LIB} PROPERTIES OUTPUT_NAME "absl_${LIB}") target_include_directories(${LIB} PUBLIC $ $) else() @@ -49,14 +57,17 @@ function(target_link_public_libraries A) endif() endfunction() -add_sublibrary(base) -add_sublibrary(meta) add_sublibrary(algorithm) +add_sublibrary(base) add_sublibrary(container) -add_sublibrary(memory) -add_sublibrary(strings) add_sublibrary(debugging) +add_sublibrary(memory) +add_sublibrary(meta) add_sublibrary(numeric) +add_sublibrary(strings) +add_sublibrary(synchronization STATIC) +# Time must be static because there are global variables intended for export +add_sublibrary(time STATIC) add_sublibrary(types) add_sublibrary(utility) @@ -68,6 +79,11 @@ target_link_public_libraries(numeric base) target_link_public_libraries(strings base memory meta numeric) target_link_public_libraries(types base utility meta algorithm strings) target_link_public_libraries(utility base meta) +target_link_public_libraries(time base numeric) +target_link_public_libraries(synchronization base time) + +find_package(unofficial-cctz REQUIRED) +targeT_link_libraries(time PUBLIC unofficial::cctz) install( EXPORT unofficial-abseil-targets diff --git a/ports/abseil/CONTROL b/ports/abseil/CONTROL index fb37a8cae..44684b6b8 100644 --- a/ports/abseil/CONTROL +++ b/ports/abseil/CONTROL @@ -1,6 +1,7 @@ Source: abseil -Version: 2017-09-28 +Version: 2017-10-14 Description: an open-source collection designed to augment the C++ standard library. Abseil is an open-source collection of C++ library code designed to augment the C++ standard library. The Abseil library code is collected from Google's own C++ code base, has been extensively tested and used in production, and is the same code we depend on in our daily coding lives. In some cases, Abseil provides pieces missing from the C++ standard; in others, Abseil provides alternatives to the standard for special needs we've found through usage in the Google code base. We denote those cases clearly within the library code we provide you. Abseil is not meant to be a competitor to the standard library; we've just found that many of these utilities serve a purpose within our code base, and we now want to provide those resources to the C++ community as a whole. +Build-Depends: cctz diff --git a/ports/abseil/portfile.cmake b/ports/abseil/portfile.cmake index 8c9e81aa3..8273f80e3 100644 --- a/ports/abseil/portfile.cmake +++ b/ports/abseil/portfile.cmake @@ -10,8 +10,8 @@ message("To use from cmake:\n find_package(unofficial-abseil REQUIRED)\n link_ vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH REPO abseil/abseil-cpp - REF cdf20caa491f59c0a35a8d8fbec0d948e4bc7e4c - SHA512 04889e7804b644821d0bf5d1b13f15a072e748bf0465442c64528e014c71f415544e9146c9518f9fe7bb14a295b18f293c3f7b672f6a51dba9909f3b74667fae + REF 1a9ba5e2e5a14413704f0c913fac53359576d3b6 + SHA512 756e494c30324c937ca655d91afdee9acb923c7ee837a7c685441305bea2d54a75b3b21be7355abe416660984ba51ace9d234d70168fb029c601b7442397e8ff HEAD_REF master ) @@ -25,7 +25,6 @@ file(COPY ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt DESTINATION ${SOURCE_PATH}) vcpkg_configure_cmake( SOURCE_PATH ${SOURCE_PATH} PREFER_NINJA - OPTIONS_DEBUG -DINSTALL_HEADERS=OFF ) vcpkg_install_cmake() diff --git a/ports/cctz/CMakeLists.txt b/ports/cctz/CMakeLists.txt new file mode 100644 index 000000000..99322d05e --- /dev/null +++ b/ports/cctz/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.8) +project(cctz CXX) + +set(CMAKE_DEBUG_POSTFIX d) +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + +if(CMAKE_BUILD_TYPE STREQUAL "Release") + option(INSTALL_HEADERS "Install header files" ON) +else() + option(INSTALL_HEADERS "Install header files" OFF) +endif() + +file(GLOB SOURCES src/*.cc) +list(FILTER SOURCES EXCLUDE REGEX "_test.cc$|benchmarks|_tool.cc$") + +file(GLOB HEADERS include/cctz/*.h) + +add_library(cctz ${SOURCES}) +target_include_directories(cctz PUBLIC $ $) + +if(INSTALL_HEADERS) + install(FILES ${HEADERS} DESTINATION "include/cctz") +endif() + +install(TARGETS cctz EXPORT unofficial-cctz-targets + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) + +install( + EXPORT unofficial-cctz-targets + FILE unofficial-cctz-config.cmake + NAMESPACE unofficial:: + DESTINATION share/unofficial-cctz +) diff --git a/ports/cctz/CONTROL b/ports/cctz/CONTROL new file mode 100644 index 000000000..fb125fa13 --- /dev/null +++ b/ports/cctz/CONTROL @@ -0,0 +1,3 @@ +Source: cctz +Version: v2.1 +Description: two libraries that cooperate with to give C++ programmers all the necessary tools for computing with dates, times, and time zones in a simple and correct manner. diff --git a/ports/cctz/portfile.cmake b/ports/cctz/portfile.cmake new file mode 100644 index 000000000..11955b365 --- /dev/null +++ b/ports/cctz/portfile.cmake @@ -0,0 +1,24 @@ +include(vcpkg_common_functions) +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO google/cctz + REF v2.1 + SHA512 b6531ce64fdd8581944457cdeff7f9ff9c00958af51ddb262c74e08fcc076466c59c7bef1ce7edccc9512a7f4cb204e04581d287c4a9a684057fe39421c3fbc6 + HEAD_REF master +) + +file(COPY ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt DESTINATION ${SOURCE_PATH}) + +vcpkg_configure_cmake( + SOURCE_PATH ${SOURCE_PATH} + PREFER_NINJA +) + +vcpkg_install_cmake() + +vcpkg_fixup_cmake_targets(CONFIG_PATH share/unofficial-cctz) +file(RENAME ${CURRENT_PACKAGES_DIR}/share/cctz ${CURRENT_PACKAGES_DIR}/share/unofficial-cctz) + +vcpkg_copy_pdbs() + +file(INSTALL ${SOURCE_PATH}/LICENSE.txt DESTINATION ${CURRENT_PACKAGES_DIR}/share/cctz RENAME copyright) -- cgit v1.2.3 From 561cfe89e653aef903488f7af7d4d17cfb11a26c Mon Sep 17 00:00:00 2001 From: Robert Schumacher Date: Sat, 14 Oct 2017 05:45:57 -0700 Subject: [eastl] Initial commit --- ports/eastl/CONTROL | 4 ++++ ports/eastl/portfile.cmake | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 ports/eastl/CONTROL create mode 100644 ports/eastl/portfile.cmake diff --git a/ports/eastl/CONTROL b/ports/eastl/CONTROL new file mode 100644 index 000000000..d43d7203e --- /dev/null +++ b/ports/eastl/CONTROL @@ -0,0 +1,4 @@ +Source: eastl +Version: 3.05.08 +Description: Electronic Arts Standard Template Library. + It is a C++ template library of containers, algorithms, and iterators useful for runtime and tool development across multiple platforms. It is a fairly extensive and robust implementation of such a library and has an emphasis on high performance above all other considerations. diff --git a/ports/eastl/portfile.cmake b/ports/eastl/portfile.cmake new file mode 100644 index 000000000..19fb6e51c --- /dev/null +++ b/ports/eastl/portfile.cmake @@ -0,0 +1,29 @@ +if (VCPKG_LIBRARY_LINKAGE STREQUAL dynamic) + message(STATUS "Warning: Dynamic building not supported by EASTL. Building static.") + set(VCPKG_LIBRARY_LINKAGE static) +endif() + +include(vcpkg_common_functions) +set(SOURCE_PATH ${CURRENT_BUILDTREES_DIR}/src/eastl) +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO electronicarts/EASTL + REF 3.05.08 + SHA512 7b9e87d967252026a660a648688a19e7b88d4eca7f373ba7427b315103a6f8cea555a85b2ef74557cf7e8a486b847589cac4b622b4ab88cab7c0f0a22355ab66 + HEAD_REF master +) + +vcpkg_configure_cmake( + SOURCE_PATH ${SOURCE_PATH} + PREFER_NINJA +) + +vcpkg_install_cmake() + +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include) + +vcpkg_copy_pdbs() + +# Handle copyright +file(INSTALL ${SOURCE_PATH}/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/eastl RENAME copyright) +file(INSTALL ${SOURCE_PATH}/3RDPARTYLICENSES.TXT DESTINATION ${CURRENT_PACKAGES_DIR}/share/eastl) -- cgit v1.2.3