diff --git a/build.py b/build.py index cdab8927..6f828873 100755 --- a/build.py +++ b/build.py @@ -287,7 +287,7 @@ def build_luprex_and_integration(): """ This builds our C++ code, and also UnrealEngine's C++ code. """ - shell(f"{INTEGRATION}/luprex", "make all 2>&1 | sed 's|^cpp/|luprex/cpp/|; s|^ext/|luprex/ext/|'") + shell(INTEGRATION, "make -f luprex/Makefile all") shell(INTEGRATION, f"{UNREALENGINE}/Engine/Build/BatchFiles/{BUILD_BAT} -waitmutex IntegrationEditor {OS} {DEBUG} {INTEGRATION}/Integration.uproject") @@ -295,11 +295,28 @@ def build_luprex_and_integration(): # Make a compile_commands.json file. # -def build_intellisense_database_for_clangd(): +def build_compile_commands_from_luprex(): """ - This builds compile_commands.json, which tells the intellisense system - based on clangd how to compile each source file. - This also installs a .clangd file in the UnrealEngine directory. + Generate compile commands for luprex by parsing make dry-run output. + Returns a list of compile_commands.json entries. + """ + result = subprocess.run( + ["make", "-n", "-B", "-f", "luprex/Makefile", "all"], + capture_output=True, text=True, check=True, cwd=INTEGRATION + ) + entries = [] + for line in result.stdout.splitlines(): + parts = line.split() + if (parts[0] == "g++") and ("-c" in parts): + source = os.path.abspath(os.path.join(INTEGRATION, parts[-1])) + entries.append({ "file": source, "command": line, "directory": INTEGRATION }) + return entries + + +def build_compile_commands_from_integration(): + """ + Generate compile commands for Unreal/Integration by scanning RSP files + generated by UnrealBuildTool. Returns a list of compile_commands.json entries. """ # Find clang compiler. clangs = list(Path(f"{UNREALENGINE}/Engine/Extras/ThirdPartyNotUE/SDKs").rglob("*-linux-gnu/bin/clang++")) @@ -316,14 +333,22 @@ def build_intellisense_database_for_clangd(): for subfile in cpp_files_included_by(cpp): abs = os.path.abspath(os.path.join(f"{UNREALENGINE}/Engine/Source", subfile)) cpp_to_rsp[abs] = rsp - # Read the luprex compile commands database. - ccjson = json.loads(Path(f"{INTEGRATION}/luprex/build/{OS}/compile_commands.json").read_text()) - # Generate the new commands - ccdir = f"{UNREALENGINE}/Engine/Source"; + # Generate compile commands. + entries = [] + ccdir = f"{UNREALENGINE}/Engine/Source" for cpp in sorted(cpp_to_rsp.keys()): rsp = cpp_to_rsp[cpp] args = [clang, "@"+rsp] - ccjson.append({ "file" : cpp, "arguments":args, "directory":ccdir }) + entries.append({ "file": cpp, "arguments": args, "directory": ccdir }) + return entries + + +def build_compile_commands_json(): + """ + Build .vscode/compile_commands.json by combining compile commands + from luprex and from the Unreal/Integration build. + """ + ccjson = build_compile_commands_from_luprex() + build_compile_commands_from_integration() Path(f"{INTEGRATION}/.vscode").mkdir(exist_ok=True) Path(f"{INTEGRATION}/.vscode/compile_commands.json").write_text(json.dumps(ccjson, indent=2)) @@ -385,7 +410,7 @@ store_system_config_in_globals(CONFIG) os.chdir(f"{INTEGRATION}/EnginePatches") if MODE == "ccjson": - build_intellisense_database_for_clangd() + build_compile_commands_json() if MODE == "code-workspace": generate_integration_code_workspace() @@ -401,7 +426,7 @@ if MODE == "all": if MODE in ["all", "c++"]: build_luprex_and_integration() - build_intellisense_database_for_clangd() + build_compile_commands_json() if MODE == "clean": build_clean() diff --git a/luprex/Makefile b/luprex/Makefile index 657331b8..be999dea 100644 --- a/luprex/Makefile +++ b/luprex/Makefile @@ -1,3 +1,14 @@ +####################################################################### +## +## This Makefile must be run from the top-level integration directory: +## make -f luprex/Makefile all +## +####################################################################### + +ifeq (,$(wildcard luprex/Makefile)) + $(error This Makefile must be run from the top-level integration directory: make -f luprex/Makefile all) +endif + ####################################################################### ## ## Auto detect Operating System @@ -33,12 +44,11 @@ ifeq "$(OS)" "Linux" LINKDLL:=g++ -Wall $(OPT) -std=c++20 -export-dynamic -Wl,--no-allow-shlib-undefined -Wl,-z,defs -shared -o LINKEXE:=g++ -Wall $(OPT) -std=c++20 -export-dynamic -o MAKEDEPS:=true - LIBS:=-L./ext/openssl-3.0.1/lib/linux -lssl -lcrypto -ldl - CCJSON:=build/$(OS)/compile_commands.json + LIBS:=-Lluprex/ext/openssl-3.0.1/lib/linux -lssl -lcrypto -ldl - FLAGS_ERIS:=-DLUA_USE_APICHECK -DLUA_USE_POSIX - FLAGS_CORE:=-I./ext/eris-master/src -I./cpp/wrap -I./cpp/core -I./ext - FLAGS_DRV:=-I./ext/openssl-3.1.0/inc -I./src/drv -I./ext + FLAGS_ERIS:=-DLUA_USE_APICHECK -DLUA_USE_POSIX + FLAGS_CORE:=-Iluprex/ext/eris-master/src -Iluprex/cpp/wrap -Iluprex/cpp/core -Iluprex/ext + FLAGS_DRV:=-Iluprex/ext/openssl-3.1.0/inc -Iluprex/cpp/drv -Iluprex/ext endif ####################################################################### @@ -59,12 +69,11 @@ ifeq "$(OS)" "Windows" LINKDLL:=CL $(OPT) /std:c++20 /EHsc /nologo /LDd /Fe: LINKEXE:=CL $(OPT) /std:c++20 /EHsc /nologo /Fe: MAKEDEPS:=g++ -Wall -std=c++20 -MMD -E -o - LIBS:=ext/openssl-3.1.0/lib/visual/libcrypto.lib ext/openssl-3.1.0/lib/visual/libssl.lib ws2_32.lib crypt32.lib cryptui.lib user32.lib advapi32.lib - CCJSON:=build/$(OS)/compile_commands.json + LIBS:=luprex/ext/openssl-3.1.0/lib/visual/libcrypto.lib luprex/ext/openssl-3.1.0/lib/visual/libssl.lib ws2_32.lib crypt32.lib cryptui.lib user32.lib advapi32.lib FLAGS_ERIS:=-DLUA_USE_APICHECK -DLUA_COMPAT_ALL - FLAGS_CORE:=-I./ext/eris-master/src -I./cpp/wrap -I./cpp/core -I./ext - FLAGS_DRV:=-I./ext/openssl-3.1.0/inc -I./src/drv -I./ext + FLAGS_CORE:=-Iluprex/ext/eris-master/src -Iluprex/cpp/wrap -Iluprex/cpp/core -Iluprex/ext + FLAGS_DRV:=-Iluprex/ext/openssl-3.1.0/inc -Iluprex/cpp/drv -Iluprex/ext endif ####################################################################### @@ -94,9 +103,9 @@ BASE_DRV := driver drvutil sslutil readline ## ####################################################################### -OBJ_ERIS := $(patsubst %,build/$(OS)/eris/%.obj,$(BASE_ERIS)) -OBJ_CORE := $(patsubst %,build/$(OS)/core/%.obj,$(BASE_CORE)) -OBJ_DRV := $(patsubst %,build/$(OS)/drv/%.obj,$(BASE_DRV)) +OBJ_ERIS := $(patsubst %,luprex/build/$(OS)/eris/%.obj,$(BASE_ERIS)) +OBJ_CORE := $(patsubst %,luprex/build/$(OS)/core/%.obj,$(BASE_CORE)) +OBJ_DRV := $(patsubst %,luprex/build/$(OS)/drv/%.obj,$(BASE_DRV)) ####################################################################### ## @@ -104,45 +113,40 @@ OBJ_DRV := $(patsubst %,build/$(OS)/drv/%.obj,$(BASE_DRV)) ## ####################################################################### -all: build/$(OS)/$(LUPREX_EXE) build/$(OS)/$(LUPREXSTATIC_EXE) build/$(OS)/$(LUPREXLIB_DLL) $(CCJSON) +all: luprex/build/$(OS)/$(LUPREX_EXE) luprex/build/$(OS)/$(LUPREXSTATIC_EXE) luprex/build/$(OS)/$(LUPREXLIB_DLL) -build/$(OS)/DIRECTORY: - mkdir -p build/$(OS)/core build/$(OS)/eris build/$(OS)/drv - touch build/$(OS)/DIRECTORY +luprex/build/$(OS)/DIRECTORY: + mkdir -p luprex/build/$(OS)/core luprex/build/$(OS)/eris luprex/build/$(OS)/drv + touch luprex/build/$(OS)/DIRECTORY -build/$(OS)/$(LUPREX_EXE): build/$(OS)/$(LUPREXLIB_DLL) $(OBJ_DRV) +luprex/build/$(OS)/$(LUPREX_EXE): luprex/build/$(OS)/$(LUPREXLIB_DLL) $(OBJ_DRV) $(LINKEXE) $@ $(OBJ_DRV) $(LIBS) -build/$(OS)/$(LUPREXSTATIC_EXE): $(OBJ_DRV) $(OBJ_ERIS) $(OBJ_CORE) +luprex/build/$(OS)/$(LUPREXSTATIC_EXE): $(OBJ_DRV) $(OBJ_ERIS) $(OBJ_CORE) $(LINKEXE) $@ $^ $(LIBS) -build/$(OS)/$(LUPREXLIB_DLL): $(OBJ_ERIS) $(OBJ_CORE) +luprex/build/$(OS)/$(LUPREXLIB_DLL): $(OBJ_ERIS) $(OBJ_CORE) $(LINKDLL) $@ $^ -build/$(OS)/eris/%.obj: ext/eris-master/src/%.c build/$(OS)/DIRECTORY +luprex/build/$(OS)/eris/%.obj: luprex/ext/eris-master/src/%.c luprex/build/$(OS)/DIRECTORY $(MAKEDEPS) $@d $(FLAGS_ERIS) $< $(COMPILE) $@ $(FLAGS_ERIS) $< -build/$(OS)/core/%.obj: cpp/core/%.cpp build/$(OS)/DIRECTORY +luprex/build/$(OS)/core/%.obj: luprex/cpp/core/%.cpp luprex/build/$(OS)/DIRECTORY $(MAKEDEPS) $@d $(FLAGS_CORE) $< $(COMPILE) $@ $(FLAGS_CORE) $< -build/$(OS)/drv/%.obj: cpp/drv/%.cpp build/$(OS)/DIRECTORY +luprex/build/$(OS)/drv/%.obj: luprex/cpp/drv/%.cpp luprex/build/$(OS)/DIRECTORY $(MAKEDEPS) $@d $(FLAGS_DRV) $< $(COMPILE) $@ $(FLAGS_DRV) $< -$(CCJSON): Makefile add-compile-commands.py - echo "[]" > $(CCJSON) - python3 ./add-compile-commands.py "$(CCJSON)" "$(COMPILE)" "$(FLAGS_ERIS)" "build/$(OS)/eris/FILE.obj" "ext/eris-master/src/FILE.c" $(BASE_ERIS) - python3 ./add-compile-commands.py "$(CCJSON)" "$(COMPILE)" "$(FLAGS_CORE)" "build/$(OS)/cpp/FILE.obj" "cpp/core/FILE.cpp" $(BASE_CORE) - python3 ./add-compile-commands.py "$(CCJSON)" "$(COMPILE)" "$(FLAGS_DRV)" "build/$(OS)/drv/FILE.obj" "cpp/drv/FILE.cpp" $(BASE_DRV) clean: - rm -f *.pdb - rm -rf build + rm -f luprex/*.pdb + rm -rf luprex/build clean-os: - rm -f *.pdb build/$(OS)/* build/$(OS)/*/* + rm -f luprex/*.pdb luprex/build/$(OS)/* luprex/build/$(OS)/*/* ####################################################################### ## @@ -153,4 +157,3 @@ clean-os: -include $(OBJ_ERIS:%.obj=%.d) -include $(OBJ_CORE:%.obj=%.d) -include $(OBJ_DRV:%.obj=%.d) - diff --git a/luprex/add-compile-commands.py b/luprex/add-compile-commands.py index d52e5d5a..6a6bef70 100644 --- a/luprex/add-compile-commands.py +++ b/luprex/add-compile-commands.py @@ -3,7 +3,7 @@ import sys, os, json from pathlib import Path -LUPREXDIR=os.path.dirname(os.path.abspath(sys.argv[0])) +BASEDIR=os.getcwd() JSONFILE=sys.argv[1] COMPILE=sys.argv[2] @@ -16,11 +16,11 @@ OBJECTS=sys.argv[6:] JSON = json.loads(Path(JSONFILE).read_text()) for base in OBJECTS: - obj = LUPREXDIR + "/" + OBJPAT.replace("FILE", base) - file = LUPREXDIR + "/" + CPAT.replace("FILE", base) - flags = FLAGS.replace("-I./", f"-I{LUPREXDIR}/") + obj = BASEDIR + "/" + OBJPAT.replace("FILE", base) + file = BASEDIR + "/" + CPAT.replace("FILE", base) + flags = FLAGS.replace("-I./", f"-I{BASEDIR}/") command = f"{COMPILE} {obj} {flags} {file}" - JSON.append({"file": file, "command": command, "directory": LUPREXDIR }) + JSON.append({"file": file, "command": command, "directory": BASEDIR }) Path(JSONFILE).write_text(json.dumps(JSON, indent=4))