Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5b79b3dae | ||
|
|
5180d13fb0 | ||
|
|
4065b8b4c4 | ||
|
|
a28070713e | ||
|
|
83cf96d254 | ||
|
|
56b3eb60d5 | ||
|
|
c30e09a6eb | ||
|
|
be96cbb57d | ||
|
|
d26b818939 |
No files matched your search
+6
-2
@@ -20,16 +20,21 @@ set(SPARK_LIB "${EXTERNALS_ROOT}/lib/$<CONFIG>")
|
||||
set(BUILD_API_SERVER OFF CACHE BOOL "Build the api server")
|
||||
set(BUILD_DOCS OFF CACHE BOOL "Build documentation")
|
||||
set(BUILD_SDK OFF CACHE BOOL "Build the sdk")
|
||||
set(BUILD_ADMIN_WEB_APP ON CACHE BOOL "Build the Admin WebApp")
|
||||
if (WIN32)
|
||||
set(BUILD_SPARKD OFF CACHE BOOL "Build sparkd")
|
||||
set(BUILD_ADMIN_WEB_APP OFF CACHE BOOL "Build the Admin WebApp")
|
||||
else()
|
||||
set(BUILD_SPARKD ON CACHE BOOL "Build sparkd")
|
||||
set(BUILD_ADMIN_WEB_APP ON CACHE BOOL "Build the Admin WebApp")
|
||||
endif()
|
||||
|
||||
include_directories(BEFORE SYSTEM ${SPARK_INCLUDE} ${EXTERNALS_ROOT}/include/zlib)
|
||||
link_directories(${SPARK_LIB})
|
||||
|
||||
if(BUILD_API_SERVER)
|
||||
add_compile_definitions(SPARK_ENABLE_API_SERVER)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# flags
|
||||
set(
|
||||
@@ -66,7 +71,6 @@ else()
|
||||
set(SPARK_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/$<CONFIG>")
|
||||
|
||||
if(BUILD_API_SERVER)
|
||||
add_compile_definitions(SPARK_ENABLE_API_SERVER)
|
||||
add_compile_definitions(APP_DATA_DIR="\$\{HOME\}/spark_api/")
|
||||
add_compile_definitions(SHARED_MEMORY_PREFIX="spark_api")
|
||||
elseif(BUILD_SPARKD)
|
||||
|
||||
+25
-26
@@ -154,7 +154,9 @@
|
||||
"BUILD_API_SERVER": {
|
||||
"type": "bool",
|
||||
"value": "ON"
|
||||
}
|
||||
},
|
||||
"DOTNET_BINARY_DIR": "${sourceDir}/build/$<CONFIG>/bin/net7.0",
|
||||
"DOTNET_WINDOWS_BINARY_DIR": "${sourceDir}/build/$<CONFIG>/bin/net7.0-windows"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -215,8 +217,7 @@
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Windows"
|
||||
},
|
||||
"hidden": true,
|
||||
"jobs": 4
|
||||
"hidden": true
|
||||
},
|
||||
|
||||
{
|
||||
@@ -243,7 +244,6 @@
|
||||
"rhs": "Linux"
|
||||
},
|
||||
"hidden": true,
|
||||
"jobs": 8,
|
||||
"targets": [
|
||||
"data_files_dir",
|
||||
"admin_web_app_bundle",
|
||||
@@ -284,53 +284,52 @@
|
||||
},
|
||||
|
||||
{
|
||||
"name": "spark-api-server-debug-windows",
|
||||
"name": "spark-api-server-windows",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Windows"
|
||||
},
|
||||
"configurePreset": "spark-api-server-windows",
|
||||
"hidden": true,
|
||||
"configurePreset": "spark-api-server-windows"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "spark-api-server-windows-debug",
|
||||
"displayName": "Spark Api Server (Debug)",
|
||||
"inherits": "spark",
|
||||
"inherits": "spark-api-server-windows",
|
||||
"configuration": "Debug"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "spark-api-server-release-windows",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Windows"
|
||||
},
|
||||
"configurePreset": "spark-api-server-windows",
|
||||
"name": "spark-api-server-windows-release",
|
||||
"displayName": "Spark Api Server (Debug)",
|
||||
"inherits": "spark",
|
||||
"inherits": "spark-api-server-windows",
|
||||
"configuration": "Release"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "spark-api-server-debug-linux",
|
||||
"name": "spark-api-server-linux",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Linux"
|
||||
},
|
||||
"configurePreset": "spark-api-server-linux",
|
||||
"hidden": true,
|
||||
"configurePreset": "spark-api-server-linux"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "spark-api-server-linux-debug",
|
||||
"inherits": "spark-api-server-linux",
|
||||
"displayName": "Spark Api Server (Debug)",
|
||||
"inherits": "spark",
|
||||
"configuration": "Debug"
|
||||
},
|
||||
|
||||
{
|
||||
"name": "spark-api-server-release-linux",
|
||||
"condition": {
|
||||
"type": "equals",
|
||||
"lhs": "${hostSystemName}",
|
||||
"rhs": "Windows"
|
||||
},
|
||||
"configurePreset": "spark-api-server-linux",
|
||||
"displayName": "Spark Api Server (Debug)",
|
||||
"name": "spark-api-server-linux-release",
|
||||
"inherits": "spark-api-server-linux",
|
||||
"displayName": "Spark Api Server (Release)",
|
||||
"configuration": "Release"
|
||||
},
|
||||
|
||||
|
||||
+188
-41
@@ -1,8 +1,15 @@
|
||||
[cmake]: https://cmake.org/
|
||||
[cmake ext]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools
|
||||
[cmake presets]: https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html
|
||||
[cpp ext]: https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools
|
||||
[clangd ext]: https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd
|
||||
[dotnet]: https://dotnet.microsoft.com/en-us/download/dotnet
|
||||
[ninja build]: https://ninja-build.org/
|
||||
[ninja multi-config generator]: https://cmake.org/cmake/help/latest/generator/Ninja%20Multi-Config.html
|
||||
[python]: https://www.python.org/
|
||||
[py venv]: https://docs.python.org/3/library/venv.html
|
||||
[visual studio]: https://visualstudio.microsoft.com/
|
||||
[visual studio generator]: https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2017%202022.html
|
||||
|
||||
# C++ Intellisense for Spark on Windows (VS Code)
|
||||
**Steps**
|
||||
@@ -30,47 +37,187 @@
|
||||
* *The **Clang** presets may work best with the **Clangd** extension*
|
||||
* *Intellisense won't work for generated files/types until you build libspark*
|
||||
|
||||
# Build Sparkd on Linux
|
||||
# Build Spark on Windows
|
||||
### Dependencies
|
||||
* **[CMake][cmake]** (version >= 3.23)
|
||||
* **[Python][python]** (version >= 3.9)
|
||||
* **[Visual Studio][visual studio]** (2022)
|
||||
* **[Dotnet][dotnet]** (sdk version >= 7.0.0)
|
||||
|
||||
**Notes**
|
||||
* Sparkd is built using **[CMakePresets][cmake presets]**
|
||||
### References
|
||||
* **[CMakePresets][cmake presets]**
|
||||
* **[Visual Studio 17 2022 (CMake generator)][visual studio generator]**
|
||||
* **[Python Virtual Environment][py venv]**
|
||||
|
||||
### Notes
|
||||
* *Run commands from the repo root dir unless otherwise noted*
|
||||
|
||||
**Steps**
|
||||
1. Set up the **[Python virtual environment][py venv]**<br>
|
||||
* *Run commands from the repo root dir unless otherwise noted*
|
||||
1. Create the virtual environment
|
||||
```
|
||||
python3 -m venv .venv
|
||||
```
|
||||
2. Activate the virtual environment
|
||||
```
|
||||
. .venv/bin/activate
|
||||
```
|
||||
3. Verify `python` in the venv is first in the path<br>
|
||||
* ***Expected:** output shows the absolute path to `.venv/bin/python`*
|
||||
```
|
||||
which python
|
||||
```
|
||||
4. Update `pip`<br>
|
||||
* *The venv module initializes virtual environments with its own version
|
||||
of pip, rather than the system's version. Even if the latter is up-to-date, the
|
||||
former may not be.*
|
||||
```
|
||||
python -m pip install --upgrade pip
|
||||
```
|
||||
5. Install the packages listed `requirements.txt`
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
2. Build **Sparkd**<br>
|
||||
* From the terminal
|
||||
```
|
||||
tools/build_sparkd.sh
|
||||
```
|
||||
* *Run with `--help` to see available options*
|
||||
* From VS Code
|
||||
1. Install the **[CMake extension][cmake ext]**
|
||||
2. In the VS Code Command Palette, run **CMake: Select Configure
|
||||
Preset**, then select the **[preset][cmake presets]** you wish to
|
||||
build from the dropdown
|
||||
3. Run **CMake: Build** in the command palette.
|
||||
```
|
||||
# Create the virtual environment
|
||||
python3 -m venv .venv
|
||||
|
||||
# Activate the virtual environment
|
||||
.venv\bin\activate.bat
|
||||
|
||||
# Update pip
|
||||
python -m pip install --upgrade pip
|
||||
|
||||
# Install packages
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
2. Build
|
||||
* *Run commands in python virtual environment*
|
||||
```
|
||||
# Configure
|
||||
cmake --preset spark
|
||||
|
||||
# Build Debug
|
||||
cmake --build --preset spark-debug
|
||||
dotnet build spark_client.sln --configuration Debug
|
||||
|
||||
# Build Release
|
||||
cmake --build --preset spark-release
|
||||
dotnet build spark_client.sln --configuration Release
|
||||
```
|
||||
|
||||
# Build Sparkd on Linux
|
||||
### **Dependencies**
|
||||
* **[CMake][cmake]** (version >= 3.23)
|
||||
* **[Ninja Build][ninja build]**
|
||||
* **[Python][python]** (version >= 3.9)
|
||||
* **[Docker][docker]**
|
||||
|
||||
### **References**
|
||||
* **[CMakePresets][cmake presets]**
|
||||
* **[Ninja (CMake generator)][ninja generator]**
|
||||
* **[Python Virtual Environment][py venv]**
|
||||
* **[Devcontainer](devcontainer)**
|
||||
|
||||
### Prerequisites
|
||||
* Open repository in a VS Code [Devcontainer](../docker/sparkd/dev/README.md), or
|
||||
create your own [docker container](../docker/sparkd/dev/README.md) in which to build
|
||||
|
||||
### Notes
|
||||
* *Run commands from the repo root dir unless otherwise noted*<br>
|
||||
|
||||
1. Set up the **[Python virtual environment][py venv]**
|
||||
```
|
||||
# Create the virtual environment
|
||||
python3 -m venv .venv
|
||||
|
||||
# Activate the virtual environment
|
||||
. .venv/bin/activate
|
||||
|
||||
# Update pip
|
||||
python -m pip install --upgrade pip
|
||||
|
||||
# Install packages
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
2. Build
|
||||
* *Run commands in python virtual environment*
|
||||
```
|
||||
# Configure clang debug
|
||||
cmake --preset sparkd-clang-debug
|
||||
|
||||
# Build clang debug
|
||||
cmake --build --preset spark-clang-debug
|
||||
|
||||
# Configure gcc release
|
||||
cmake --build --preset sparkd-gcc-release
|
||||
|
||||
# Build gcc release
|
||||
cmake --build --preset sparkd-gcc-release
|
||||
```
|
||||
|
||||
# Build Spark Api Server on Windows
|
||||
### **Dependencies**
|
||||
* **[CMake][cmake]** (version >= 3.23)
|
||||
* **[Python][python]** (version >= 3.9)
|
||||
* **[Visual Studio][visual studio]** (version)
|
||||
* **[Dotnet][dotnet]** (sdk version >= 7.0.0)
|
||||
|
||||
### **References**
|
||||
* **[CMakePresets][cmake presets]**
|
||||
* **[Visual Studio 17 2022 (CMake generator)][visual studio generator]**
|
||||
* **[Python Virtual Environment][py venv]**
|
||||
|
||||
### Notes
|
||||
* *Run commands from the repo root dir unless otherwise noted*
|
||||
|
||||
1. Set up the **[Python Virtual Environment][py venv]**
|
||||
```
|
||||
# Create the virtual environment
|
||||
python3 -m venv .venv
|
||||
|
||||
# Activate the virtual environment
|
||||
.venv\bin\activate.bat
|
||||
|
||||
# Update pip
|
||||
python -m pip install --upgrade pip
|
||||
|
||||
# Install packages
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
2. Build
|
||||
* *Run in python virtual environment*
|
||||
```
|
||||
# Configure
|
||||
cmake --preset spark-api-server-windows
|
||||
|
||||
# Build debug
|
||||
cmake --build --preset spark-api-server-windows-debug
|
||||
dotnet build Spark.Api.Server.sln --configuration Debug
|
||||
|
||||
# Build release
|
||||
cmake --build --preset spark-api-server-windows-release
|
||||
dotnet build Spark.Api.Server.sln --configuration Release
|
||||
```
|
||||
|
||||
# Build Spark Api Server on Linux
|
||||
### **Dependencies**
|
||||
* **[CMake][cmake]** (version >= 3.23)
|
||||
* **[Python][python]** (version >= 3.9)
|
||||
* **[Dotnet][dotnet]** (sdk version >= 7.0.0)
|
||||
|
||||
### **References**
|
||||
* **[CMakePresets][cmake presets]**
|
||||
* **[Ninja Multi-Config (CMake generator)][ninja multi-config generator]**
|
||||
* **[Python Virtual Environment][py venv]**
|
||||
|
||||
### Prerequisites
|
||||
* Open repository in a VS Code [Devcontainer](../docker/sparkd/dev/README.md), or
|
||||
create your own [docker container](../docker/sparkd/dev/README.md) in which to build
|
||||
|
||||
### Notes
|
||||
* *Run commands from the repo root dir unless otherwise noted*
|
||||
|
||||
1. Set up the **[Python Virtual Environment][py venv]**
|
||||
```
|
||||
# Create the virtual environment
|
||||
python3 -m venv .venv
|
||||
|
||||
# Activate the virtual environment
|
||||
. .venv/bin/activate
|
||||
|
||||
# Update pip
|
||||
python -m pip install --upgrade pip
|
||||
|
||||
# Install packages
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
2. Build
|
||||
* *Run in python virtual environment*
|
||||
```
|
||||
# Configure
|
||||
cmake --preset spark-api-server-linux
|
||||
|
||||
# Build debug
|
||||
cmake --build --preset spark-api-server-linux-debug
|
||||
dotnet build Spark.Api.Server.sln --configuration Debug
|
||||
|
||||
# Build release
|
||||
cmake --build --preset spark-api-server-linux-release
|
||||
dotnet build Spark.Api.Server.sln --configuration Release
|
||||
```
|
||||
@@ -1,13 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace bts.websocket_core {
|
||||
// Represents a unique client, a little redundant
|
||||
public interface IUniqueID {
|
||||
public string ID { get; }
|
||||
public int GetHashCode();
|
||||
public string ToString();
|
||||
public bool Equals(object? obj);
|
||||
public interface IUniqueID : IEquatable<object?> {
|
||||
string ID { get; }
|
||||
|
||||
public int GetHashCode() =>
|
||||
ID.GetHashCode();
|
||||
|
||||
public string? ToString() =>
|
||||
ID;
|
||||
|
||||
bool IEquatable<object?>.Equals(object? obj) =>
|
||||
obj is IUniqueID other && ID == other.ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,6 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace bts.websocket_core {
|
||||
// Represents a unique client, a little redundant
|
||||
public class UniqueID : IUniqueID {
|
||||
|
||||
public string ID { get; }
|
||||
public UniqueID(string id) {
|
||||
ID = id;
|
||||
}
|
||||
public override int GetHashCode() {
|
||||
return this.ID.GetHashCode();
|
||||
}
|
||||
public override string ToString() {
|
||||
return this.ID.ToString() ?? "";
|
||||
}
|
||||
public override bool Equals(object? obj) {
|
||||
var other = obj == null ? null : obj as IUniqueID;
|
||||
return other != null && (string)other.ID == ID;
|
||||
}
|
||||
public class UniqueID(string id) : IUniqueID {
|
||||
public string ID { get; } = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,10 @@ include(${CMAKE_SOURCE_DIR}/cmake/Protobuf.cmake)
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GenerateDefaultConfig.cmake)
|
||||
include(${CMAKE_SOURCE_DIR}/cmake/PrintList.cmake)
|
||||
|
||||
if (DEFINED DOTNET_BINARY_DIR OR DEFINED DOTNET_WINDOWS_BINARY_DIR)
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/AddCopyBinariesTarget.cmake)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
if(BUILD_SPARKD)
|
||||
message(FATAL_ERROR "Cannot build sparkd on Windows (Please set BUILD_SPARKD to False)")
|
||||
@@ -53,6 +57,20 @@ get_link_libraries(_link_libs)
|
||||
print_list(_link_libs VERBOSE)
|
||||
target_link_libraries(${PROJECT_NAME} ${_link_libs})
|
||||
|
||||
# Copy binaries to Dotnet build dirs (for csprojs that depend on libspark)
|
||||
if (DEFINED DOTNET_BINARY_DIR)
|
||||
add_copy_binaries_target(
|
||||
copy_to_dotnet_binary_dir
|
||||
${DOTNET_BINARY_DIR}
|
||||
"Copy ${PROJECT_NAME} bins to Dotnet build dir")
|
||||
endif()
|
||||
if (DEFINED DOTNET_WINDOWS_BINARY_DIR)
|
||||
add_copy_binaries_target(
|
||||
copy_to_dotnet_windows_binary_dir
|
||||
${DOTNET_WINDOWS_BINARY_DIR}
|
||||
"Copy ${PROJECT_NAME} bins to Dotnet Windows build dir")
|
||||
endif()
|
||||
|
||||
if(BUILD_SPARKD)
|
||||
install(TARGETS ${PROJECT_NAME} DESTINATION "${SPARK_INSTALL_PREFIX}/bin")
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
function(add_copy_binaries_target tgt_name dest_dir)
|
||||
set(_output
|
||||
"${dest_dir}/${PROJECT_NAME}.dll"
|
||||
"$<$<CONFIG:Debug>:${dest_dir}/${PROJECT_NAME}.pdb>")
|
||||
add_custom_command(
|
||||
OUTPUT ${_output}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS -E copy
|
||||
$<$<CONFIG:Debug>:${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${PROJECT_NAME}.pdb>
|
||||
${dest_dir}/${PROJECT_NAME}.pdb
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS -E copy
|
||||
${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${PROJECT_NAME}.dll
|
||||
${dest_dir}/${PROJECT_NAME}.dll)
|
||||
add_custom_target(${tgt_name} ALL DEPENDS ${_output} COMMENT ${ARGN})
|
||||
endfunction()
|
||||
@@ -1,245 +0,0 @@
|
||||
import argparse
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
from typing import Optional
|
||||
from cmake.cmake_utils import CMakeCompilerPair, CMakeConfigureCommand
|
||||
from core.argparse_utils import add_toggle_opt, get_arg
|
||||
from core.file_utils import CWD, SparkPaths, as_path, create_dir, link_file
|
||||
from core.iter_utils import flatten, is_none_or_empty
|
||||
from core.logging import exit_msg
|
||||
|
||||
|
||||
def _parse_compiler(arg: str or None):
|
||||
'''Parses compiler input (from cli) and returns a tuple of c, cxx compilers respectively'''
|
||||
known_compilers = {
|
||||
'gcc': CMakeCompilerPair('gcc', 'gcc-11', 'g++-11'),
|
||||
'clang': CMakeCompilerPair('clang', 'clang', 'clang++'),
|
||||
'clang-13': CMakeCompilerPair('clang', 'clang-13', 'clang++-13'),
|
||||
}
|
||||
if arg in known_compilers:
|
||||
return known_compilers[arg]
|
||||
raise ValueError(
|
||||
f"Unexpected compiler '{arg}'. Please use one of [{' '.join(known_compilers)}]"
|
||||
)
|
||||
|
||||
|
||||
def _parse_build_dir(build_dir, build_type: Optional[str] = None):
|
||||
if build_dir is not None:
|
||||
return as_path(build_dir).value()
|
||||
rv = SparkPaths.root().joinpath('build')
|
||||
if build_type is not None:
|
||||
rv = rv.joinpath(build_type)
|
||||
return rv
|
||||
|
||||
|
||||
class BuildApiServerArgs:
|
||||
def __init__(self, args):
|
||||
args_dict = vars(args)
|
||||
self.compiler = _parse_compiler(get_arg(args_dict, 'compiler', 'gcc'))
|
||||
# Forcibly correct case (so user doesn't have to worry abt it)
|
||||
self.build_type = args.build_type.title()
|
||||
if self.build_type not in ['Debug', 'Release']:
|
||||
raise ValueError(f"Unexpected build_type '{args.build_type}'")
|
||||
self.cmake_build_dir = _parse_build_dir(
|
||||
args_dict.get('cmake_output_dir')).absolute()
|
||||
self.clean = args.clean
|
||||
self.jobs = args.jobs
|
||||
self.targets = None if args.target is None else flatten(args.target)
|
||||
self.dotnet_verbosity = args.verbosity
|
||||
# Translate dotnet verbosity level to binary '--verbose' flag for cmake
|
||||
self.cmake_verbose = args.verbosity in [
|
||||
'd', 'detailed', 'diag', 'diagnostic'
|
||||
]
|
||||
|
||||
|
||||
def _get_arg_parser():
|
||||
parser = argparse.ArgumentParser(description='Build spark_client.sln')
|
||||
|
||||
parser.add_argument(
|
||||
'--build-type',
|
||||
metavar='debug|release',
|
||||
type=str,
|
||||
nargs='?',
|
||||
help='The build type')
|
||||
|
||||
parser.add_argument(
|
||||
'--compiler',
|
||||
metavar='gcc|clang',
|
||||
type=str,
|
||||
nargs='?',
|
||||
help='The compiler')
|
||||
|
||||
parser.add_argument(
|
||||
'-o',
|
||||
'--cmake-output-dir',
|
||||
metavar='path',
|
||||
type=str,
|
||||
nargs='?',
|
||||
help=
|
||||
'The directory in which to build libspark (defaults to [repo_root]/build)'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'-t',
|
||||
'--target',
|
||||
type=str,
|
||||
action='append',
|
||||
nargs='+',
|
||||
help='The target(s) to build')
|
||||
|
||||
parser.add_argument(
|
||||
'-j',
|
||||
'--jobs',
|
||||
type=int,
|
||||
help='[CMake] The number of parallel jobs to run')
|
||||
|
||||
add_toggle_opt(
|
||||
parser, 'clean', help='Whether or not to perform a clean build')
|
||||
|
||||
parser.add_argument(
|
||||
'--verbosity',
|
||||
metavar='[q(uiet)|m(inimal)|n(ormal)|d(etailed)|diag(nostic)]',
|
||||
choices=[
|
||||
'q', 'quiet', 'm', 'minimal', 'n', 'normal', 'd', 'detailed',
|
||||
'diag', 'diagnostic'
|
||||
],
|
||||
type=str,
|
||||
help='The output verbosity level')
|
||||
|
||||
parser.set_defaults(
|
||||
build_type='Debug', compiler='gcc', verbosity='minimal')
|
||||
return parser
|
||||
|
||||
|
||||
def _configure(src_dir, build_dir, compiler: CMakeCompilerPair):
|
||||
'''Configures sparkd (server) build'''
|
||||
|
||||
cmd = CMakeConfigureCommand(
|
||||
src_dir=src_dir,
|
||||
build_dir=build_dir,
|
||||
generator='"Ninja Multi-Config"',
|
||||
compiler=compiler)
|
||||
cmd.add_opt('BUILD_API_SERVER', True)
|
||||
cmd.add_opt('BUILD_SPARKD', False)
|
||||
cmd.add_opt('BUILD_WEB', False)
|
||||
cmd.add_opt('CMAKE_EXPORT_COMPILE_COMMANDS', True)
|
||||
return _run_cmd(str(cmd))
|
||||
|
||||
|
||||
def _check_results(proc_results):
|
||||
for res in proc_results:
|
||||
if res.returncode != 0:
|
||||
exit_msg(1, f'The following build subprocess failed: {res}')
|
||||
|
||||
|
||||
def _run_cmd(cmd):
|
||||
print(f'run cmd: {cmd}')
|
||||
return subprocess.run(cmd, shell=True)
|
||||
|
||||
|
||||
def _dotnet_build(build_type='Debug', verbosity='minimal'):
|
||||
'''Builds dotnet'''
|
||||
with (CWD(SparkPaths.root())):
|
||||
cmd_parts = [f'dotnet build Spark.Api.Server.sln']
|
||||
if verbosity is not None:
|
||||
cmd_parts.append(f'--verbosity {verbosity}')
|
||||
if build_type is not None:
|
||||
cmd_parts.append(f'--configuration {build_type}')
|
||||
return _run_cmd(' '.join(cmd_parts))
|
||||
|
||||
|
||||
def _dotnet_clean(build_type='Debug', verbosity='minimal'):
|
||||
'''Cleans dotnet'''
|
||||
with (CWD(SparkPaths.root())):
|
||||
cmd_parts = [f'dotnet clean Spark.Api.Server.sln']
|
||||
if verbosity is not None:
|
||||
cmd_parts.append(f'--verbosity {verbosity}')
|
||||
if build_type is not None:
|
||||
cmd_parts.append(f'--configuration {build_type}')
|
||||
return _run_cmd(' '.join(cmd_parts))
|
||||
|
||||
|
||||
def _cmake_build(
|
||||
build_dir, build_type=None, targets=None, jobs=None, verbose=False):
|
||||
'''Builds libspark'''
|
||||
|
||||
build_type = build_type or 'release'
|
||||
build_dir = as_path(build_dir).value()
|
||||
cmd_parts = [f'cmake --build {build_dir} --config {build_type.title()}']
|
||||
if jobs is not None:
|
||||
cmd_parts.append(f'-j {jobs}')
|
||||
if not is_none_or_empty(targets):
|
||||
cmd_parts.append(' '.join([f"--target {t}" for t in targets]))
|
||||
if verbose:
|
||||
cmd_parts.append('--verbose')
|
||||
return _run_cmd(' '.join(cmd_parts))
|
||||
|
||||
|
||||
def _cmake_clean(build_dir, build_type=None, jobs=None, verbose=False):
|
||||
'''Cleans libspark'''
|
||||
# In cmake, 'clean' is technically a build target
|
||||
_cmake_build(build_dir, build_type, ['clean'], jobs=jobs, verbose=verbose)
|
||||
|
||||
|
||||
def _build(
|
||||
src_dir,
|
||||
cmake_build_dir,
|
||||
build_type: str,
|
||||
compiler=None,
|
||||
targets=None,
|
||||
clean=False,
|
||||
jobs=None,
|
||||
cmake_verbose=False,
|
||||
dotnet_verbosity: Optional[str] = None) -> list:
|
||||
'''Builds libspark'''
|
||||
|
||||
# check if explicit no-op
|
||||
if targets is not None and len(targets) == 0:
|
||||
return []
|
||||
|
||||
compiler = compiler or CMakeCompilerPair('gcc', 'gcc', 'g++')
|
||||
cmake_build_dir = as_path(cmake_build_dir).value()
|
||||
proc_results = []
|
||||
|
||||
try:
|
||||
create_dir(cmake_build_dir)
|
||||
proc_results.append(
|
||||
_configure(
|
||||
src_dir=src_dir, build_dir=cmake_build_dir, compiler=compiler))
|
||||
if proc_results[-1].returncode:
|
||||
# Build is broken (exit early)
|
||||
return proc_results
|
||||
except Exception as e:
|
||||
exit_msg(1, e)
|
||||
|
||||
if clean:
|
||||
# cmake clean
|
||||
proc_results.append(
|
||||
_cmake_clean(cmake_build_dir, build_type, jobs, cmake_verbose))
|
||||
# dotnet clean
|
||||
proc_results.append(_dotnet_clean(build_type, dotnet_verbosity))
|
||||
|
||||
# cmake build
|
||||
proc_results.append(
|
||||
_cmake_build(
|
||||
cmake_build_dir, build_type, targets, jobs, cmake_verbose))
|
||||
return proc_results
|
||||
|
||||
|
||||
def _main():
|
||||
args = BuildApiServerArgs(_get_arg_parser().parse_args())
|
||||
proc_results = _build(
|
||||
src_dir=SparkPaths.root(),
|
||||
cmake_build_dir=args.cmake_build_dir,
|
||||
build_type=args.build_type,
|
||||
compiler=args.compiler,
|
||||
targets=args.targets,
|
||||
jobs=args.jobs,
|
||||
cmake_verbose=args.cmake_verbose,
|
||||
dotnet_verbosity=args.dotnet_verbosity)
|
||||
_check_results(proc_results)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
_main()
|
||||
+7
-236
@@ -1,247 +1,18 @@
|
||||
from abc import ABC, abstractmethod
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
|
||||
from core.argparse_utils import add_toggle_opt, get_arg
|
||||
from core.file_utils import SparkPaths, copy, create_dir
|
||||
from core.table_formatter import fmt_table
|
||||
from core.build_target import BuildTarget
|
||||
from core.cmake_utils import CMakeTarget
|
||||
from core.dotnet_utils import CsprojTarget
|
||||
from core.file_utils import SparkPaths, create_dir
|
||||
from core.logging import exit_msg
|
||||
from core.iter_utils import at_bounded, join_t
|
||||
from core.iter_utils import at_bounded
|
||||
from core.visual_studio_utils import get_preferred_vs_context, VisualStudioContext
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class VisualStudioContext:
|
||||
def __init__(
|
||||
self,
|
||||
version,
|
||||
year,
|
||||
prompt_path: Path,
|
||||
msbuild_path: Path,
|
||||
msbuild_arg_prefix,
|
||||
):
|
||||
self.version = version
|
||||
self.year = year
|
||||
self.prompt_path = prompt_path
|
||||
self.msbuild_path = msbuild_path
|
||||
self._msbuild_arg_prefix = msbuild_arg_prefix
|
||||
|
||||
def prompt_cmd(self):
|
||||
return f'{self.prompt_path} -arch=x64 -host_arch=x64'
|
||||
|
||||
def msbuild_flag(self, flag):
|
||||
return f'{self._msbuild_arg_prefix}{flag}'
|
||||
|
||||
def msbuild_clp(self, key, value=None):
|
||||
rv = f'{self._msbuild_arg_prefix}clp:{key}'
|
||||
if value is not None:
|
||||
rv = f'{rv}={value}'
|
||||
return rv
|
||||
|
||||
def msbuild_target(self, target):
|
||||
return f'{self._msbuild_arg_prefix}t:{target}'
|
||||
|
||||
def msbuild_prop(self, key, value):
|
||||
return f'{self._msbuild_arg_prefix}p:{key}={value}'
|
||||
|
||||
|
||||
def _get_supported_vs_contexts():
|
||||
'''Gets a list of supported Visual Studio contexts (versions)'''
|
||||
# vs 17
|
||||
vs17_path = Path('C:/Program Files/Microsoft Visual Studio/2022/Community')
|
||||
vs17 = VisualStudioContext(
|
||||
17,
|
||||
2022,
|
||||
vs17_path.joinpath('Common7/Tools/VsDevCmd.bat'),
|
||||
vs17_path.joinpath('Msbuild/Current/Bin/amd64/MSBuild.exe'),
|
||||
'-',
|
||||
)
|
||||
|
||||
# vs 16
|
||||
vs16_path = Path(
|
||||
'C:/Program Files (x86)/Microsoft Visual Studio/2019/Community')
|
||||
vs16 = VisualStudioContext(
|
||||
16,
|
||||
2019,
|
||||
vs16_path.joinpath('Common7/Tools/VsDevCmd.bat'),
|
||||
vs16_path.joinpath('MSBuild/Current/Bin/MSBuild.exe'),
|
||||
'/',
|
||||
)
|
||||
return [vs17, vs16]
|
||||
|
||||
|
||||
def _get_preferred_vs_context():
|
||||
'''Gets the most preferred Visual Studio context (version) on this computer'''
|
||||
vs_ctxs = _get_supported_vs_contexts()
|
||||
for vs_context in vs_ctxs:
|
||||
if vs_context.prompt_path.exists():
|
||||
return vs_context
|
||||
supported_versions = ', '.join([str(v.version) for v in vs_ctxs])
|
||||
raise ValueError(
|
||||
f'Failed to find supported Visual Studio version (works with {supported_versions})'
|
||||
)
|
||||
|
||||
|
||||
class BuildTarget(ABC):
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
source_path: Optional[Path],
|
||||
out_path: Optional[Path],
|
||||
aliases=[]):
|
||||
self.name = name
|
||||
self.source_path = source_path
|
||||
self.out_path = out_path
|
||||
self.aliases = aliases
|
||||
|
||||
@abstractmethod
|
||||
def configure(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def build(self):
|
||||
pass
|
||||
|
||||
def is_match(self, targets):
|
||||
return any(
|
||||
t.lower() == self.name.lower() or t in self.aliases
|
||||
for t in targets)
|
||||
|
||||
|
||||
class CMakeTarget(BuildTarget):
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
preset='spark',
|
||||
build_preset='spark-debug',
|
||||
source_path=SparkPaths.root(),
|
||||
out_path=SparkPaths.default_build(),
|
||||
aliases=[],
|
||||
verbosity: Optional[str] = None,
|
||||
):
|
||||
if out_path is None:
|
||||
raise ValueError('out_path is None')
|
||||
if source_path is None:
|
||||
raise ValueError('source_path is None')
|
||||
BuildTarget.__init__(self, name, source_path, out_path, aliases)
|
||||
self.preset = preset
|
||||
self.build_preset = build_preset
|
||||
self.verbosity = verbosity
|
||||
|
||||
def _get_configure_cmd(self):
|
||||
cmd_parts = ['cmake']
|
||||
if self.preset is not None:
|
||||
cmd_parts.append(f'--preset {self.preset}')
|
||||
if self.verbosity is not None:
|
||||
cmd_parts.append(f'-DCMAKE_MESSAGE_LOG_LEVEL={self.verbosity}')
|
||||
if self.source_path is not None:
|
||||
cmd_parts.append(f'-S {self.source_path}')
|
||||
if self.out_path is not None:
|
||||
cmd_parts.append(f'-B {self.out_path}')
|
||||
return ' '.join(cmd_parts)
|
||||
|
||||
def _get_build_cmd(self):
|
||||
cmd_parts = ['cmake --build']
|
||||
# In CMake, the build dir arg (-B) can't be combined w/ --preset
|
||||
if self.build_preset is not None:
|
||||
cmd_parts.append(f'--preset {self.build_preset}')
|
||||
elif self.out_path is not None:
|
||||
cmd_parts.append(f'{self.out_path}')
|
||||
return ' '.join(cmd_parts)
|
||||
|
||||
def configure(self):
|
||||
cmd = self._get_configure_cmd()
|
||||
print(f'configure_cmd: {cmd}')
|
||||
subprocess.run(cmd).check_returncode()
|
||||
if self.out_path is not None:
|
||||
copy(
|
||||
SparkPaths.tools().joinpath('cpp.build.props'),
|
||||
self.out_path.joinpath('Directory.Build.Props'))
|
||||
|
||||
def build(self):
|
||||
cmd = self._get_build_cmd()
|
||||
print(f'build_cmd: {cmd}')
|
||||
subprocess.run(cmd).check_returncode()
|
||||
|
||||
def __str__(self):
|
||||
return fmt_table(
|
||||
{
|
||||
'name': self.name,
|
||||
'configure_cmd': self._get_configure_cmd(),
|
||||
'build_cmd': self._get_build_cmd(),
|
||||
})
|
||||
|
||||
|
||||
class CsprojTarget(BuildTarget):
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
source_path: Path,
|
||||
out_path: Path,
|
||||
aliases=[],
|
||||
configuration: str = 'debug',
|
||||
verbosity: str = 'minimal',
|
||||
vs_context: Optional[VisualStudioContext] = None,
|
||||
restore=True,
|
||||
):
|
||||
BuildTarget.__init__(self, name, source_path, out_path, aliases)
|
||||
self.configuration = configuration
|
||||
self.verbosity = verbosity
|
||||
self.restore = restore
|
||||
self.vs_context = vs_context or _get_preferred_vs_context()
|
||||
|
||||
def _get_build_cmd(self):
|
||||
cfg = self.configuration
|
||||
build_cmd_steps = [self.vs_context.prompt_cmd()]
|
||||
base_output_path_arg = self.vs_context.msbuild_prop(
|
||||
'BaseOutputPath', self.out_path.joinpath(cfg.title()))
|
||||
if self.restore:
|
||||
# Restore build (download nugets)
|
||||
restore_cmd_args = [
|
||||
f'"{self.vs_context.msbuild_path}"',
|
||||
f"{self.vs_context.msbuild_flag('m')}",
|
||||
f"{self.vs_context.msbuild_prop('platform', 'x64')}",
|
||||
f"{self.vs_context.msbuild_prop('configuration', cfg.title())}",
|
||||
f"{self.vs_context.msbuild_target('restore')}",
|
||||
f"{self.vs_context.msbuild_clp('verbosity', self.verbosity)}",
|
||||
f"{self.vs_context.msbuild_clp('summary')}",
|
||||
base_output_path_arg,
|
||||
self.source_path,
|
||||
]
|
||||
restore_cmd = join_t(' ', restore_cmd_args)
|
||||
build_cmd_steps.append(restore_cmd)
|
||||
|
||||
# Main build
|
||||
dbg_type = 'portable' if cfg.lower() == 'debug' else 'none'
|
||||
build_cmd_prefix = ' '.join(
|
||||
[
|
||||
f'"{self.vs_context.msbuild_path}"',
|
||||
f"{self.vs_context.msbuild_flag('m')}",
|
||||
f"{self.vs_context.msbuild_prop('platform', 'x64')}",
|
||||
f"{self.vs_context.msbuild_prop('GenerateFullPaths', 'true')}",
|
||||
f"{self.vs_context.msbuild_prop('configuration', cfg.title())}",
|
||||
f"{self.vs_context.msbuild_prop('debugtype', dbg_type)}",
|
||||
f"{self.vs_context.msbuild_clp('verbosity', self.verbosity)}",
|
||||
f"{self.vs_context.msbuild_clp('summary')}"
|
||||
])
|
||||
build_cmd_steps.append(
|
||||
f'{build_cmd_prefix} {base_output_path_arg} {self.source_path}')
|
||||
return ' && '.join(build_cmd_steps)
|
||||
|
||||
def configure(self):
|
||||
pass
|
||||
|
||||
def build(self):
|
||||
subprocess.run(self._get_build_cmd()).check_returncode()
|
||||
|
||||
def __str__(self):
|
||||
return fmt_table(
|
||||
{
|
||||
'name': self.name,
|
||||
'build_cmd': self._get_build_cmd()
|
||||
})
|
||||
|
||||
|
||||
def _get_arg_parser():
|
||||
parser = argparse.ArgumentParser(description='Build spark_client.sln')
|
||||
parser.add_argument(
|
||||
@@ -397,7 +168,7 @@ def _main():
|
||||
if tgt_names is None or len(tgt_names) == 0:
|
||||
tgt_names = ['libspark', 'spark']
|
||||
|
||||
vs_context = _get_preferred_vs_context()
|
||||
vs_context = get_preferred_vs_context()
|
||||
tgts = _get_targets(
|
||||
build_type=args.configuration,
|
||||
build_dir=build_dir,
|
||||
|
||||
@@ -2,9 +2,8 @@ import argparse
|
||||
from typing import cast
|
||||
import subprocess
|
||||
|
||||
from cmake.cmake_utils import CMakeCompilerPair, CMakeConfigureCommand
|
||||
from core.argparse_utils import add_toggle_opt, get_arg
|
||||
from core.cmake_utils import CMakeCompilerPair, CMakeConfigureCommand
|
||||
from core.argparse_utils import add_toggle_opt, get_arg
|
||||
from core.file_utils import CWD, SparkPaths, as_path, create_dir
|
||||
from core.iter_utils import distinct, flatten
|
||||
from core.logging import exit_msg
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class CMakeCompilerPair:
|
||||
'''Represents a pair of c, cxx compilers'''
|
||||
def __init__(self, name, c, cxx):
|
||||
self.name = name
|
||||
self.c = c
|
||||
self.cxx = cxx
|
||||
|
||||
def to_opts(self):
|
||||
opts = {}
|
||||
if self.c:
|
||||
opts['C_COMPILER'] = self.c
|
||||
if self.cxx:
|
||||
opts['CXX_COMPILER'] = self.cxx
|
||||
return opts
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.name} ({self.c}, {self.cxx})'
|
||||
|
||||
|
||||
class CMakeConfigureCommand:
|
||||
def __init__(
|
||||
self,
|
||||
src_dir,
|
||||
build_dir,
|
||||
generator: Optional[str] = None,
|
||||
build_type: Optional[str] = None,
|
||||
compiler: Optional[CMakeCompilerPair] = None):
|
||||
if src_dir is None:
|
||||
raise ValueError('Source dir cannot be None')
|
||||
self.cmd = 'cmake'
|
||||
self.add_opt('-S', src_dir)
|
||||
self.add_opt('-B', build_dir)
|
||||
if generator is not None:
|
||||
self.add_opt('-G', generator)
|
||||
if build_type is not None:
|
||||
self.add_opt('CMAKE_BUILD_TYPE', build_type)
|
||||
if compiler is not None:
|
||||
self.add_opt('CMAKE_C_COMPILER', compiler.c)
|
||||
self.add_opt('CMAKE_CXX_COMPILER', compiler.cxx)
|
||||
|
||||
def add_opt(self, name: str, value):
|
||||
if name is None:
|
||||
raise ValueError('opt name cannot be None')
|
||||
if value is None:
|
||||
return self
|
||||
if not name.startswith('-'):
|
||||
name = f'-D{name}'
|
||||
self.cmd = f'{self.cmd} {name}={value}'
|
||||
else:
|
||||
self.cmd = f'{self.cmd} {name} {value}'
|
||||
return self
|
||||
|
||||
def __str__(self):
|
||||
return self.cmd
|
||||
@@ -0,0 +1,35 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
|
||||
from core.table_formatter import fmt_table
|
||||
from core.iter_utils import join_t
|
||||
from core.visual_studio_utils import get_preferred_vs_context, VisualStudioContext
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class BuildTarget(ABC):
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
source_path: Optional[Path],
|
||||
out_path: Optional[Path],
|
||||
aliases=[]):
|
||||
self.name = name
|
||||
self.source_path = source_path
|
||||
self.out_path = out_path
|
||||
self.aliases = aliases
|
||||
|
||||
@abstractmethod
|
||||
def configure(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def build(self):
|
||||
pass
|
||||
|
||||
def is_match(self, targets):
|
||||
return any(
|
||||
t.lower() == self.name.lower() or t in self.aliases
|
||||
for t in targets)
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
import subprocess
|
||||
|
||||
from build_target import BuildTarget
|
||||
from os import PathLike
|
||||
from file_utils import copy, SparkPaths
|
||||
from table_formatter import fmt_table
|
||||
from typing import Optional
|
||||
|
||||
|
||||
@@ -63,3 +68,83 @@ class CMakeConfigureCommand:
|
||||
|
||||
def __str__(self):
|
||||
return self.cmd
|
||||
|
||||
|
||||
class CMakeTarget(BuildTarget):
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
preset='spark',
|
||||
build_preset='spark-debug',
|
||||
source_path=SparkPaths.root(),
|
||||
out_path=SparkPaths.default_build(),
|
||||
aliases=[],
|
||||
verbosity: Optional[str] = None,
|
||||
):
|
||||
if out_path is None:
|
||||
raise ValueError('out_path is None')
|
||||
if source_path is None:
|
||||
raise ValueError('source_path is None')
|
||||
BuildTarget.__init__(self, name, source_path, out_path, aliases)
|
||||
self.preset = preset
|
||||
self.build_preset = build_preset
|
||||
self.verbosity = verbosity
|
||||
|
||||
def _get_configure_cmd(self):
|
||||
cmd_parts = ['cmake']
|
||||
if self.preset is not None:
|
||||
cmd_parts.append(f'--preset {self.preset}')
|
||||
if self.verbosity is not None:
|
||||
cmd_parts.append(f'-DCMAKE_MESSAGE_LOG_LEVEL={self.verbosity}')
|
||||
if self.source_path is not None:
|
||||
cmd_parts.append(f'-S {self.source_path}')
|
||||
if self.out_path is not None:
|
||||
cmd_parts.append(f'-B {self.out_path}')
|
||||
return ' '.join(cmd_parts)
|
||||
|
||||
def _get_build_cmd(self):
|
||||
cmd_parts = ['cmake --build']
|
||||
# In CMake, the build dir arg (-B) can't be combined w/ --preset
|
||||
if self.build_preset is not None:
|
||||
cmd_parts.append(f'--preset {self.build_preset}')
|
||||
elif self.out_path is not None:
|
||||
cmd_parts.append(f'{self.out_path}')
|
||||
return ' '.join(cmd_parts)
|
||||
|
||||
def configure(self):
|
||||
cmd = self._get_configure_cmd()
|
||||
print(f'configure_cmd: {cmd}')
|
||||
subprocess.run(cmd).check_returncode()
|
||||
if self.out_path is not None:
|
||||
copy(
|
||||
SparkPaths.tools().joinpath('cpp.build.props'),
|
||||
self.out_path.joinpath('Directory.Build.Props'))
|
||||
|
||||
def build(self):
|
||||
cmd = self._get_build_cmd()
|
||||
print(f'build_cmd: {cmd}')
|
||||
subprocess.run(cmd).check_returncode()
|
||||
|
||||
def __str__(self):
|
||||
return fmt_table(
|
||||
{
|
||||
'name': self.name,
|
||||
'configure_cmd': self._get_configure_cmd(),
|
||||
'build_cmd': self._get_build_cmd(),
|
||||
})
|
||||
|
||||
|
||||
def get_cmake_build_type(build_type: str):
|
||||
'''
|
||||
Converts a case-insensitive build-type str (from cli) to a case-sensitive CMAKE_BUILD_TYPE var
|
||||
'''
|
||||
|
||||
# The 'build_type' arg is case-sensitive because 'CMAKE_BUILD_TYPE' is substitued for a folder
|
||||
# in the externals-libs path. In order to match a real path, it must be 'Debug' or 'Release'.
|
||||
# Keep the orig_build_type around for potential use in err msg.
|
||||
orig_build_type = build_type
|
||||
build_type = build_type or 'debug'
|
||||
build_type = build_type.title()
|
||||
if build_type not in ['Debug', 'Release']:
|
||||
raise ValueError(f"Unexpected build_type '{orig_build_type}'")
|
||||
return build_type
|
||||
@@ -0,0 +1,78 @@
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
|
||||
from core.table_formatter import fmt_table
|
||||
from core.build_target import BuildTarget
|
||||
from core.iter_utils import join_t
|
||||
from core.visual_studio_utils import get_preferred_vs_context, VisualStudioContext
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class CsprojTarget(BuildTarget):
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
source_path: Path,
|
||||
out_path: Path,
|
||||
aliases=[],
|
||||
configuration: str = 'debug',
|
||||
verbosity: str = 'minimal',
|
||||
vs_context: Optional[VisualStudioContext] = None,
|
||||
restore=True,
|
||||
):
|
||||
BuildTarget.__init__(self, name, source_path, out_path, aliases)
|
||||
self.configuration = configuration
|
||||
self.verbosity = verbosity
|
||||
self.restore = restore
|
||||
self.vs_context = vs_context or get_preferred_vs_context()
|
||||
|
||||
def _get_build_cmd(self):
|
||||
cfg = self.configuration
|
||||
build_cmd_steps = [self.vs_context.prompt_cmd()]
|
||||
base_output_path_arg = self.vs_context.msbuild_prop(
|
||||
'BaseOutputPath', self.out_path.joinpath(cfg.title()))
|
||||
if self.restore:
|
||||
# Restore build (download nugets)
|
||||
restore_cmd_args = [
|
||||
f'"{self.vs_context.msbuild_path}"',
|
||||
f"{self.vs_context.msbuild_flag('m')}",
|
||||
f"{self.vs_context.msbuild_prop('platform', 'x64')}",
|
||||
f"{self.vs_context.msbuild_prop('configuration', cfg.title())}",
|
||||
f"{self.vs_context.msbuild_target('restore')}",
|
||||
f"{self.vs_context.msbuild_clp('verbosity', self.verbosity)}",
|
||||
f"{self.vs_context.msbuild_clp('summary')}",
|
||||
base_output_path_arg,
|
||||
self.source_path,
|
||||
]
|
||||
restore_cmd = join_t(' ', restore_cmd_args)
|
||||
build_cmd_steps.append(restore_cmd)
|
||||
|
||||
# Main build
|
||||
dbg_type = 'portable' if cfg.lower() == 'debug' else 'none'
|
||||
build_cmd_prefix = ' '.join(
|
||||
[
|
||||
f'"{self.vs_context.msbuild_path}"',
|
||||
f"{self.vs_context.msbuild_flag('m')}",
|
||||
f"{self.vs_context.msbuild_prop('platform', 'x64')}",
|
||||
f"{self.vs_context.msbuild_prop('GenerateFullPaths', 'true')}",
|
||||
f"{self.vs_context.msbuild_prop('configuration', cfg.title())}",
|
||||
f"{self.vs_context.msbuild_prop('debugtype', dbg_type)}",
|
||||
f"{self.vs_context.msbuild_clp('verbosity', self.verbosity)}",
|
||||
f"{self.vs_context.msbuild_clp('summary')}"
|
||||
])
|
||||
build_cmd_steps.append(
|
||||
f'{build_cmd_prefix} {base_output_path_arg} {self.source_path}')
|
||||
return ' && '.join(build_cmd_steps)
|
||||
|
||||
def configure(self):
|
||||
pass
|
||||
|
||||
def build(self):
|
||||
subprocess.run(self._get_build_cmd()).check_returncode()
|
||||
|
||||
def __str__(self):
|
||||
return fmt_table(
|
||||
{
|
||||
'name': self.name,
|
||||
'build_cmd': self._get_build_cmd()
|
||||
})
|
||||
@@ -0,0 +1,72 @@
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class VisualStudioContext:
|
||||
def __init__(
|
||||
self,
|
||||
version,
|
||||
year,
|
||||
prompt_path: Path,
|
||||
msbuild_path: Path,
|
||||
msbuild_arg_prefix,
|
||||
):
|
||||
self.version = version
|
||||
self.year = year
|
||||
self.prompt_path = prompt_path
|
||||
self.msbuild_path = msbuild_path
|
||||
self._msbuild_arg_prefix = msbuild_arg_prefix
|
||||
|
||||
def prompt_cmd(self):
|
||||
return f'{self.prompt_path} -arch=x64 -host_arch=x64'
|
||||
|
||||
def msbuild_flag(self, flag):
|
||||
return f'{self._msbuild_arg_prefix}{flag}'
|
||||
|
||||
def msbuild_clp(self, key, value=None):
|
||||
rv = f'{self._msbuild_arg_prefix}clp:{key}'
|
||||
if value is not None:
|
||||
rv = f'{rv}={value}'
|
||||
return rv
|
||||
|
||||
def msbuild_target(self, target):
|
||||
return f'{self._msbuild_arg_prefix}t:{target}'
|
||||
|
||||
def msbuild_prop(self, key, value):
|
||||
return f'{self._msbuild_arg_prefix}p:{key}={value}'
|
||||
|
||||
|
||||
def get_supported_vs_contexts():
|
||||
'''Gets a list of supported Visual Studio contexts (versions)'''
|
||||
# vs 17
|
||||
vs17_path = Path('C:/Program Files/Microsoft Visual Studio/2022/Community')
|
||||
vs17 = VisualStudioContext(
|
||||
17,
|
||||
2022,
|
||||
vs17_path.joinpath('Common7/Tools/VsDevCmd.bat'),
|
||||
vs17_path.joinpath('Msbuild/Current/Bin/amd64/MSBuild.exe'),
|
||||
'-',
|
||||
)
|
||||
|
||||
# vs 16
|
||||
vs16_path = Path(
|
||||
'C:/Program Files (x86)/Microsoft Visual Studio/2019/Community')
|
||||
vs16 = VisualStudioContext(
|
||||
16,
|
||||
2019,
|
||||
vs16_path.joinpath('Common7/Tools/VsDevCmd.bat'),
|
||||
vs16_path.joinpath('MSBuild/Current/Bin/MSBuild.exe'),
|
||||
'/',
|
||||
)
|
||||
return [vs17, vs16]
|
||||
|
||||
|
||||
def get_preferred_vs_context():
|
||||
'''Gets the most preferred Visual Studio context (version) on this computer'''
|
||||
vs_ctxs = get_supported_vs_contexts()
|
||||
for vs_context in vs_ctxs:
|
||||
if vs_context.prompt_path.exists():
|
||||
return vs_context
|
||||
supported_versions = ', '.join([str(v.version) for v in vs_ctxs])
|
||||
raise ValueError(
|
||||
f'Failed to find supported Visual Studio version (works with {supported_versions})'
|
||||
)
|
||||
Reference in new issue
Block a user