1
0

chore: update build manual and script.

This commit is contained in:
2025-09-29 22:43:28 +08:00
parent 19d0a5bb4d
commit 05a80268ab
8 changed files with 83 additions and 235 deletions

18
.github/linux_build.sh vendored Normal file
View File

@ -0,0 +1,18 @@
#!/bin/bash
# Create build directory and enter it
mkdir bin
cd bin
# Create internal build and install directory, then enter it
mkdir build
mkdir install
cd build
# Build in Release mode
cmake -DCMAKE_BUILD_TYPE=Release ../..
cmake --build .
cmake --install . --prefix=../install
# Back to root directory
cd ..
cd ..

18
.github/windows_build.bat vendored Normal file
View File

@ -0,0 +1,18 @@
@ECHO OFF
:: Create build directory and enter it
MKDIR bin
CD bin
:: Create internal build and install directory, then enter it
MKDIR build
MKDIR install
CD build
:: Build with x64 architecture in Release mode
cmake -A x64 ../..
cmake --build . --config Release
cmake --install . --prefix=../install --config Relese
:: Back to root directory
CD ..
CD ..

View File

@ -12,16 +12,22 @@ It means that it is not stable and work in progress.
* The common compiler supporting C++ 23 (GCC / Clang / MSVC). * The common compiler supporting C++ 23 (GCC / Clang / MSVC).
* Iconv (Optional on Windows. Required on other systems). * Iconv (Optional on Windows. Required on other systems).
* [Google Test](https://github.com/google/googletest) (Required if you build test). * [Google Test](https://github.com/google/googletest) (Required if you build test).
* [Google Benchmark](https://github.com/google/benchmark) (Required if you build benchmark).
* Doxygen (Required if you build documentation). * Doxygen (Required if you build documentation).
* Python and Astral UV (Required if you use "User Build" method)
If you are just want to build this project to make something works, or build other project, rather than code with it,
you commonly do not need build test, benchmark and documentation.
So you actually do not need Google Test, Google Benchmark and Doxygen.
## Preparing
### Compiler
> [!WARNING] > [!WARNING]
> You may face some issues when building on macOS with Clang. That's not your fault. > You may face some issues when building on macOS with Clang. That's not your fault.
> Clang used libc++ library lacks some essential features used by this project. > Clang used libc++ library lacks some essential features used by this project.
> You may try other solutions for compiling this project on macOS or with Clang. > You may try other solutions for compiling this project on macOS or with Clang.
## Preparing
### Google Test ### Google Test
Google Test is required if you need to build test. Google Test is required if you need to build test.
@ -46,6 +52,24 @@ There are the steps instructing you how to compile GoogleTest manually.
1. Use CMake to build Google Test 1. Use CMake to build Google Test
1. Use CMake to install Google Test into previous we created `install` directory. 1. Use CMake to install Google Test into previous we created `install` directory.
### Google Benchmark
Google Benchmark is required if you need to build benchmark.
If you don't need this please skip this chapter.
We use Google Benchmark v1.9.4.
It would be okey use other versions but I have not test on them.
There are the steps instructing you how to compile Google Benchmark manually.
1. Download Google Benchmark source code with given version in GitHub Release page.
1. Extract it into a directory.
1. Enter this directory and create link named `googletest` to previous fetched Google Test root directory. This is instructed by official manual because Google Benchmark rely on Google Test. Link can be create by executing `mklink /D googletest <path-to-googletest-root-dir>` on Windows or `ln -s <path-to-googletest-root-dir> googletest` on POSIX-like OS.
1. Keep stay in this directory and create 2 subdirectory `build` and `install` for CMake build and install respectively.
1. Enter `build` directory and configure CMake with extra `-DCMAKE_CXX_STANDARD=23 -DBENCHMARK_ENABLE_TESTING=OFF` parameters.
1. Use CMake to build Google Benchmark
1. Use CMake to install Google Benchmark into previous we created `install` directory.
### Iconv ### Iconv
Iconv is optional on Windows and disabled in default. Iconv is optional on Windows and disabled in default.
@ -71,33 +95,33 @@ So before compiling, you must make sure `doxygen` are presented in your environm
## Build and Install ## Build and Install
There are 2 different ways to build this project. There are 2 different ways to build this project.
If you are the user of this project (just want this project to make something work), please choose "User Build". If you are the user of this project (just want this project to make something works, or build other projects), please choose "User Build".
If you are a developer (developer of this project, or use this project as dependency to develop your project), please choose "Developer Build". If you are a developer (developer of this project, or use this project as dependency to develop your project), please choose "Developer Build".
### User Build ### User Build
"User Build" is basically how GitHub Action build this project. "User Build" is basically how GitHub Action build this project.
We use Python 3.11 and UV 0.7.17 to manage our build script generator. Execute `.github/windows_build.bat` on Windows or `.github/linux_build.sh` on POSIX-like OS (Linux and macOS) under **the root directory** of this project. The final built artifact is under `bin/install` directory.
It would be okey use other versions but I have not test on them.
TODO...
### Developer Build ### Developer Build
TODO... First, there is a list listing all variables you may configure during compiling.
There is a list listing all variables you may configure during compiling.
* `YYCC_BUILD_TEST`: Set it to `ON` to build test. `OFF` in default. * `YYCC_BUILD_TEST`: Set it to `ON` to build test. `OFF` in default.
It is useful for the developer of this project. It is useful for the developer of this project.
It also suit for the user who has runtime issues on their platforms to check whether this project works as expected. It also suit for the user who has runtime issues on their platforms to check whether this project works as expected.
If you are debugging this project to find bug, I suggest that you build this project under Debug mode and use this test project for debugging.
* `YYCC_BUILD_BENCHMARK`: Set it to `ON` to build benchmark. `OFF` in default.
It is useful for the developer of this project to checking the performace for those homemade functions.
It is highly suggested build this project with Release mode to have real benchmark result.
* `YYCC_BUILD_DOC`: Set it to `ON` to build documentation. `OFF` in default. * `YYCC_BUILD_DOC`: Set it to `ON` to build documentation. `OFF` in default.
It may be useful for the developer who firstly use this project in their own projects. It may be useful for the developer who firstly use this project in their own projects.
Please note that generated documentation is different in different platforms. Please note that generated documentation is different in different platforms.
* `YYCC_ENFORCE_ICONV`: Set it to `ON` to enable Iconv feature forcely. `OFF` in default. * `YYCC_ENFORCE_ICONV`: Set it to `ON` to enable Iconv feature forcely. `OFF` in default.
The usage of this option has been introduced in previous "Iconv" chapter. The usage of this option has been introduced in previous "Iconv" chapter.
* `GTest_ROOT`: TODO * `GTest_ROOT`: TODO
* `benchmark_ROOT`: TODO
* `Iconv_ROOT`: TODO * `Iconv_ROOT`: TODO
* `CMAKE_CXX_STANDARD`: Set C++ standard version of project. * `CMAKE_CXX_STANDARD`: Set C++ standard version of project.
`23` in default and this version can not be lower than C++23. `23` in default and this version can not be lower than C++23.

View File

@ -7,12 +7,12 @@ using namespace std::literals::string_view_literals;
namespace yyccbench::string::op { namespace yyccbench::string::op {
static void StringStrip(benchmark::State& state) { static void BM_StringStrip(benchmark::State& state) {
std::u8string_view strl = u8" \thello\r\n"sv, words = u8" \t\r\n"sv; std::u8string_view strl = u8" \thello\r\n"sv, words = u8" \t\r\n"sv;
for (auto _ : state) { for (auto _ : state) {
auto rv = OP::strip(strl, words); auto rv = OP::strip(strl, words);
} }
} }
BENCHMARK(StringStrip); BENCHMARK(BM_StringStrip)->Name("StringStrip");
} }

4
script/.gitignore vendored
View File

@ -2,10 +2,6 @@
# Exclude VSCode # Exclude VSCode
.vscode/ .vscode/
# Exclude generated files
win_build.bat
linux_build.sh
## ===== Python ===== ## ===== Python =====
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files
__pycache__/ __pycache__/

View File

@ -1,106 +0,0 @@
import argparse
import typing
import re
import shlex
from pathlib import Path
from dataclasses import dataclass
import jinja2
def validate_cpp_ver(ver: str) -> str:
if re.match(r'^[0-9]+$', ver) is not None: return ver
else: raise argparse.ArgumentTypeError('invalid version of C++ standard.')
def write_line(f: typing.TextIO, val: str) -> None:
f.write(val)
f.write('\n')
# Reference: https://stackoverflow.com/questions/29213106/how-to-securely-escape-command-line-arguments-for-the-cmd-exe-shell-on-windows
def escape_for_cmd_exe(arg):
meta_re = re.compile(r'([()%!^"<>&|])')
return meta_re.sub('^\1', arg)
def escape_cmd_argument(arg):
if not arg or re.search(r'(["\s])', arg):
arg = '"' + arg.replace('"', r'\"') + '"'
return escape_for_cmd_exe(arg)
def escape_sh_argument(arg):
return shlex.quote(arg)
@dataclass(frozen=True)
class ScriptSettings:
pic: bool
cpp_version: str
build_doc: bool
build_testbench: bool
class TemplateRender:
loader: jinja2.BaseLoader
environment: jinja2.Environment
win_template: jinja2.Template
linux_template: jinja2.Template
settings: ScriptSettings
def __init__(self, settings: ScriptSettings) -> None:
self.loader = jinja2.FileSystemLoader(self.__get_dir())
self.environment = jinja2.Environment(loader=self.loader)
self.win_template = self.environment.get_template('win_build.bat.jinja')
self.linux_template = self.environment.get_template('linux_build.sh.jinja')
self.settings = settings
def __get_dir(self) -> Path:
return Path(__file__).resolve().parent
def __escape_path(self, val: str, is_win: bool) -> str:
if is_win: return escape_cmd_argument(val)
else: return escape_sh_argument(val)
def __render(self, template: jinja2.Template, dest_file: str, is_win: bool) -> None:
with open(self.__get_dir() / dest_file, 'w', encoding='utf-8') as f:
f.write(template.render(
repo_root_dir = self.__escape_path(str(self.__get_dir().parent), is_win),
cpp_version = self.settings.cpp_version,
build_doc = self.settings.build_doc,
pic = settings.pic
))
def render_win_script(self) -> None:
self.__render(self.win_template, 'win_build.bat', True)
def render_linux_script(self) -> None:
self.__render(self.linux_template, 'linux_build.sh', False)
if __name__ == '__main__':
# parse argument
parser = argparse.ArgumentParser(
prog='YYCC Windows Build Script Generator',
description='YYCC Windows Build Script Generator'
)
parser.add_argument(
'-c', '--cpp',
action='store', default='17', dest='cpp', type=validate_cpp_ver,
help='The version of C++ standard used when building.'
)
parser.add_argument(
'-d', '--build-doc',
action='store_true', dest='build_doc',
help='Build YYCC with documentation.'
)
parser.add_argument(
'-p', '--pic',
action='store_true', dest='pic',
help='Enable Position Independent Code flag on non-Windows platform. This is crucial for compiling dynamic library using this library.'
)
args = parser.parse_args()
# build settings
settings = ScriptSettings(args.cpp, args.build_doc, args.pic)
# build template render and render result
render = TemplateRender(settings)
render.render_win_script()
render.render_linux_script()

View File

@ -1,17 +0,0 @@
#!/bin/bash
# Navigate to project root directory
cd {{ repo_root_dir }}
# Create build and install directory
mkdir build
mkdir install
# Build as release version
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD={{ cpp_version }} {{ '-DCMAKE_POSITION_INDEPENDENT_CODE=True' if pic }} {{ '-DYYCC_BUILD_DOC=ON' if build_doc }} {{ '-DYYCC_BUILD_TESTBENCH=ON' if build_testbench }} ../.. --fresh
cmake --build .
cmake --install . --prefix ../install
# Exit to original path
cd ..
echo "YYCC Linux CMake build done"

View File

@ -1,85 +0,0 @@
@ECHO OFF
:: Navigate to project root directory
CD /d {{ repo_root_dir }}
:: Create build directory and enter it
MKDIR bin
CD bin
MKDIR cpp{{ cpp_version }}
CD cpp{{ cpp_version }}
:: Create internal build directory
MKDIR Win32
MKDIR x64
MKDIR documentation
:: Create internal install directory
MKDIR install
CD install
MKDIR Win32_Debug
MKDIR Win32_Release
MKDIR x64_Debug
MKDIR x64_Release
CD ..
:: Create internal MSVC specific install directory
MKDIR msvc_install
CD msvc_install
MKDIR bin
MKDIR include
MKDIR lib
MKDIR share
CD bin
MKDIR Win32
MKDIR x64
CD ..
CD lib
MKDIR Win32\Debug
MKDIR Win32\Release
MKDIR x64\Debug
MKDIR x64\Release
CD ..
CD ..
:: Build for Win32
CD Win32
cmake -A Win32 -DCMAKE_CXX_STANDARD={{ cpp_version }} -DYYCC_BUILD_TESTBENCH=ON ../../..
cmake --build . --config Debug
cmake --install . --prefix=../install/Win32_Debug --config Debug
cmake --build . --config RelWithDebInfo
cmake --install . --prefix=../install/Win32_Release --config RelWithDebInfo
CD ..
:: Build for x64
CD x64
cmake -A x64 -DCMAKE_CXX_STANDARD={{ cpp_version }} -DYYCC_BUILD_TESTBENCH=ON ../../..
cmake --build . --config Debug
cmake --install . --prefix=../install/x64_Debug --config Debug
cmake --build . --config RelWithDebInfo
cmake --install . --prefix=../install/x64_Release --config RelWithDebInfo
CD ..
{% if build_doc %}
:: Build for documentation
CD documentation
cmake -A x64 -DCMAKE_CXX_STANDARD={{ cpp_version }} -DYYCC_BUILD_DOC=ON ../../..
cmake --build . --config RelWithDebInfo
cmake --build . --target YYCCDocumentation
cmake --install . --prefix=../install/x64_Release --config RelWithDebInfo
CD ..
{% endif %}
:: Copy header files
XCOPY install\x64_Release\include msvc_install\include\ /E /Y
:: Copy binary files
COPY install\Win32_Release\bin\YYCCTestbench.exe msvc_install\bin\Win32\YYCCTestbench.exe /Y
COPY install\x64_Release\bin\YYCCTestbench.exe msvc_install\bin\x64\YYCCTestbench.exe /Y
:: Copy library files
COPY install\Win32_Debug\lib\YYCCommonplace.lib msvc_install\lib\Win32\Debug\YYCCommonplace.lib /Y
COPY install\Win32_Release\lib\YYCCommonplace.lib msvc_install\lib\Win32\Release\YYCCommonplace.lib /Y
COPY install\x64_Debug\lib\YYCCommonplace.lib msvc_install\lib\x64\Debug\YYCCommonplace.lib /Y
COPY install\x64_Release\lib\YYCCommonplace.lib msvc_install\lib\x64\Release\YYCCommonplace.lib /Y
{% if build_doc %}
:: Copy documentation files
XCOPY install\x64_Release\share msvc_install\share\ /E /Y
{% endif %}
:: Leave build directory and report
CD ..\..
ECHO Windows CMake Build Done