mirror of
https://github.com/TokTok/c-toxcore
synced 2026-06-08 02:13:17 +00:00
8a8d02785e
- Add `MpscQueue` for thread-safe task scheduling. - Add `ToxRunner` to execute Tox instances in dedicated threads. - Update `Simulation` to coordinate time steps across multiple runners using a synchronization barrier. - Refactor `FakeMemory` and `FakeClock` to be thread-safe. - Update `tox_network` helpers and tests to utilize the threaded runner infrastructure.
290 lines
9.4 KiB
Python
Executable File
290 lines
9.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import glob
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from dataclasses import dataclass
|
|
from dataclasses import field
|
|
from typing import Any
|
|
from typing import Dict
|
|
from typing import List
|
|
|
|
STD_MODULE = """module std [system] {
|
|
textual header "/usr/include/alloca.h"
|
|
textual header "/usr/include/assert.h"
|
|
textual header "/usr/include/c++/14.2.0/algorithm"
|
|
textual header "/usr/include/c++/14.2.0/array"
|
|
textual header "/usr/include/c++/14.2.0/atomic"
|
|
textual header "/usr/include/c++/14.2.0/cassert"
|
|
textual header "/usr/include/c++/14.2.0/cerrno"
|
|
textual header "/usr/include/c++/14.2.0/chrono"
|
|
textual header "/usr/include/c++/14.2.0/climits"
|
|
textual header "/usr/include/c++/14.2.0/compare"
|
|
textual header "/usr/include/c++/14.2.0/condition_variable"
|
|
textual header "/usr/include/c++/14.2.0/cstddef"
|
|
textual header "/usr/include/c++/14.2.0/cstdint"
|
|
textual header "/usr/include/c++/14.2.0/cstdio"
|
|
textual header "/usr/include/c++/14.2.0/cstdlib"
|
|
textual header "/usr/include/c++/14.2.0/cstring"
|
|
textual header "/usr/include/c++/14.2.0/deque"
|
|
textual header "/usr/include/c++/14.2.0/functional"
|
|
textual header "/usr/include/c++/14.2.0/future"
|
|
textual header "/usr/include/c++/14.2.0/iomanip"
|
|
textual header "/usr/include/c++/14.2.0/iosfwd"
|
|
textual header "/usr/include/c++/14.2.0/iostream"
|
|
textual header "/usr/include/c++/14.2.0/limits"
|
|
textual header "/usr/include/c++/14.2.0/map"
|
|
textual header "/usr/include/c++/14.2.0/memory"
|
|
textual header "/usr/include/c++/14.2.0/mutex"
|
|
textual header "/usr/include/c++/14.2.0/new"
|
|
textual header "/usr/include/c++/14.2.0/optional"
|
|
textual header "/usr/include/c++/14.2.0/ostream"
|
|
textual header "/usr/include/c++/14.2.0/queue"
|
|
textual header "/usr/include/c++/14.2.0/random"
|
|
textual header "/usr/include/c++/14.2.0/stdlib.h"
|
|
textual header "/usr/include/c++/14.2.0/string"
|
|
textual header "/usr/include/c++/14.2.0/thread"
|
|
textual header "/usr/include/c++/14.2.0/type_traits"
|
|
textual header "/usr/include/c++/14.2.0/vector"
|
|
textual header "/usr/include/errno.h"
|
|
textual header "/usr/include/fortify/stdio.h"
|
|
textual header "/usr/include/fortify/string.h"
|
|
textual header "/usr/include/fortify/unistd.h"
|
|
textual header "/usr/include/limits.h"
|
|
textual header "/usr/include/stdarg.h"
|
|
textual header "/usr/include/stdbool.h"
|
|
textual header "/usr/include/stddef.h"
|
|
textual header "/usr/include/stdint.h"
|
|
textual header "/usr/include/sys/time.h"
|
|
textual header "/usr/include/sys/types.h"
|
|
textual header "/usr/include/time.h"
|
|
}
|
|
module "c_toxcore_third_party_cmp" {
|
|
header "third_party/cmp/cmp.h"
|
|
use std
|
|
}
|
|
module "c_toxcore_toxencryptsave_defines" {
|
|
header "toxencryptsave/defines.h"
|
|
}
|
|
module "_benchmark" {
|
|
textual header "/usr/include/benchmark/benchmark.h"
|
|
use std
|
|
}
|
|
module "_com_google_googletest___gtest" {
|
|
textual header "/usr/include/gmock/gmock.h"
|
|
textual header "/usr/include/gtest/gtest.h"
|
|
use std
|
|
}
|
|
module "_com_google_googletest___gtest_main" {
|
|
// Dummy module for gtest_main, assuming it links but headers are in gtest
|
|
use "_com_google_googletest___gtest"
|
|
}
|
|
module "_libsodium" {
|
|
textual header "/usr/include/sodium.h"
|
|
}
|
|
module "_pthread" {
|
|
textual header "/usr/include/pthread.h"
|
|
}
|
|
module "_psocket" {
|
|
textual header "/usr/include/arpa/inet.h"
|
|
textual header "/usr/include/fcntl.h"
|
|
textual header "/usr/include/fortify/sys/socket.h"
|
|
textual header "/usr/include/linux/if.h"
|
|
textual header "/usr/include/netdb.h"
|
|
textual header "/usr/include/netinet/in.h"
|
|
textual header "/usr/include/sys/epoll.h"
|
|
textual header "/usr/include/sys/ioctl.h"
|
|
}
|
|
"""
|
|
|
|
|
|
@dataclass
|
|
class Target:
|
|
name: str
|
|
package: str
|
|
srcs: List[str] = field(default_factory=list)
|
|
hdrs: List[str] = field(default_factory=list)
|
|
deps: List[str] = field(default_factory=list)
|
|
|
|
@property
|
|
def label(self) -> str:
|
|
# Sanitize label for module name
|
|
sanitized = (f"//c-toxcore/{self.package}:{self.name}".replace(
|
|
"/", "_").replace(":",
|
|
"_").replace(".",
|
|
"_").replace("-",
|
|
"_").replace("@", "_"))
|
|
if sanitized.startswith("__"):
|
|
sanitized = sanitized[2:]
|
|
return sanitized
|
|
|
|
|
|
TARGETS: List[Target] = []
|
|
|
|
|
|
class BuildContext:
|
|
|
|
def __init__(self, package: str):
|
|
self.package = package
|
|
|
|
def bzl_load(self, *args: Any, **kwargs: Any) -> None:
|
|
pass
|
|
|
|
def bzl_exports_files(self, *args: Any, **kwargs: Any) -> None:
|
|
pass
|
|
|
|
def bzl_alias(self, *args: Any, **kwargs: Any) -> None:
|
|
pass
|
|
|
|
def bzl_sh_library(self, *args: Any, **kwargs: Any) -> None:
|
|
pass
|
|
|
|
def bzl_cc_fuzz_test(self, *args: Any, **kwargs: Any) -> None:
|
|
pass
|
|
|
|
def bzl_select(self, selector: Dict[str, List[str]]) -> List[str]:
|
|
return selector.get("//tools/config:linux",
|
|
selector.get("//conditions:default", []))
|
|
|
|
def bzl_glob(self, include: List[str]) -> List[str]:
|
|
results = []
|
|
for pattern in include:
|
|
full_pattern = os.path.join(self.package, pattern)
|
|
files = glob.glob(full_pattern)
|
|
results.extend([os.path.relpath(f, self.package) for f in files])
|
|
return results
|
|
|
|
def _add_target(self, name: str, srcs: Any, hdrs: Any, deps: Any) -> None:
|
|
srcs = list(srcs) if srcs else []
|
|
hdrs = list(hdrs) if hdrs else []
|
|
deps = list(deps) if deps else []
|
|
TARGETS.append(Target(name, self.package, srcs, hdrs, deps))
|
|
|
|
def bzl_cc_library(self,
|
|
name: str,
|
|
srcs: Any = (),
|
|
hdrs: Any = (),
|
|
deps: Any = (),
|
|
**kwargs: Any) -> None:
|
|
self._add_target(name, srcs, hdrs, deps)
|
|
|
|
def bzl_cc_binary(self,
|
|
name: str,
|
|
srcs: Any = (),
|
|
hdrs: Any = (),
|
|
deps: Any = (),
|
|
**kwargs: Any) -> None:
|
|
self._add_target(name, srcs, hdrs, deps)
|
|
|
|
def bzl_cc_test(self,
|
|
name: str,
|
|
srcs: Any = (),
|
|
hdrs: Any = (),
|
|
deps: Any = (),
|
|
**kwargs: Any) -> None:
|
|
self._add_target(name, srcs, hdrs, deps)
|
|
|
|
|
|
def resolve_module_name(dep: str, current_pkg: str) -> str:
|
|
# Resolve to canonical label first
|
|
label = dep
|
|
if dep.startswith("@"):
|
|
label = dep
|
|
elif dep.startswith("//"):
|
|
if ":" in dep:
|
|
label = dep
|
|
else:
|
|
pkg_name = os.path.basename(dep)
|
|
label = f"{dep}:{pkg_name}"
|
|
elif dep.startswith(":"):
|
|
label = f"//c-toxcore/{current_pkg}{dep}"
|
|
|
|
# Sanitize
|
|
sanitized = (label.replace("/", "_").replace(":", "_").replace(
|
|
".", "_").replace("-", "_").replace("@", "_"))
|
|
if sanitized.startswith("__"):
|
|
sanitized = sanitized[2:]
|
|
return sanitized
|
|
|
|
|
|
def main() -> None:
|
|
packages = ["toxcore", "testing/support"]
|
|
|
|
for pkg in packages:
|
|
ctx = BuildContext(pkg)
|
|
build_file = os.path.join(pkg, "BUILD.bazel")
|
|
if not os.path.exists(build_file):
|
|
continue
|
|
|
|
with open(build_file, "r") as f:
|
|
exec(
|
|
f.read(),
|
|
{
|
|
"load": ctx.bzl_load,
|
|
"exports_files": ctx.bzl_exports_files,
|
|
"cc_library": ctx.bzl_cc_library,
|
|
"cc_binary": ctx.bzl_cc_binary,
|
|
"cc_test": ctx.bzl_cc_test,
|
|
"cc_fuzz_test": ctx.bzl_cc_fuzz_test,
|
|
"select": ctx.bzl_select,
|
|
"glob": ctx.bzl_glob,
|
|
"alias": ctx.bzl_alias,
|
|
"sh_library": ctx.bzl_sh_library,
|
|
},
|
|
)
|
|
|
|
with open("module.modulemap", "w") as f:
|
|
f.write(STD_MODULE)
|
|
for t in TARGETS:
|
|
f.write(f'module "{t.label}" {{\n')
|
|
for hdr in t.hdrs:
|
|
f.write(f' header "{os.path.join(t.package, hdr)}"\n')
|
|
f.write(" use std\n")
|
|
for dep in t.deps:
|
|
mod_name = resolve_module_name(dep, t.package)
|
|
# Export all dependencies to ensure visibility of types used in headers
|
|
f.write(f" use {mod_name}\n")
|
|
f.write(f" export {mod_name}\n")
|
|
f.write("}\n")
|
|
|
|
# with open("module.modulemap", "r") as f:
|
|
# print(f.read(), file=sys.stderr)
|
|
|
|
src_to_module = {}
|
|
for t in TARGETS:
|
|
for src in t.srcs:
|
|
full_src = os.path.join(t.package, src)
|
|
src_to_module[full_src] = t.label
|
|
|
|
# Sort for deterministic output
|
|
all_srcs = sorted(src_to_module.keys())
|
|
|
|
for src in all_srcs:
|
|
print(f"Validating {src}", file=sys.stderr)
|
|
module_name = src_to_module[src]
|
|
|
|
subprocess.run(
|
|
[
|
|
"clang",
|
|
"-fsyntax-only",
|
|
"-xc++",
|
|
"-Wall",
|
|
"-Werror",
|
|
"-Wno-missing-braces",
|
|
"-DTCP_SERVER_USE_EPOLL",
|
|
"-std=c++23",
|
|
"-fdiagnostics-color=always",
|
|
"-fmodules",
|
|
"-fmodules-strict-decluse",
|
|
"-fmodule-map-file=module.modulemap",
|
|
f"-fmodule-name={module_name}",
|
|
"-I.",
|
|
src,
|
|
],
|
|
check=True,
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|