diff --git a/CMake/Util.cmake b/CMake/Util.cmake index 317ba222..84f774c5 100644 --- a/CMake/Util.cmake +++ b/CMake/Util.cmake @@ -39,13 +39,17 @@ function(rift_runtime_module module) # Override output folder with suffix set_target_properties(${target} PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/Bin/Runtimes/${module}/Lib" - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/Bin/Runtimes/${module}/Lib" - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/Bin/Runtimes/${module}/Bin" - INCLUDES_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/Bin/Runtimes/${module}/Include" + ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${module}/Lib" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${module}/Lib" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${module}/Bin" + INCLUDES_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${module}/Include" ) set_target_properties(${target} PROPERTIES OUTPUT_NAME "${module}") + + add_custom_command(TARGET ${target} POST_BUILD COMMAND + ${CMAKE_COMMAND} -E remove_directory "${CMAKE_BINARY_DIR}/Bin/Runtimes/${module}" + ) add_custom_command(TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/${module}" "${CMAKE_BINARY_DIR}/Bin/Runtimes/${module}" ) diff --git a/Libs/Backends/LLVM/Compiler/Src/LLVMBackend/IRGeneration.cpp b/Libs/Backends/LLVM/Compiler/Src/LLVMBackend/IRGeneration.cpp index 092d1c03..d5ecf441 100644 --- a/Libs/Backends/LLVM/Compiler/Src/LLVMBackend/IRGeneration.cpp +++ b/Libs/Backends/LLVM/Compiler/Src/LLVMBackend/IRGeneration.cpp @@ -2,6 +2,7 @@ #include "LLVMBackend/IRGeneration.h" +#include "Components/CDeclCStruct.h" #include "LLVMBackend/Components/CIRFunction.h" #include "LLVMBackend/Components/CIRModule.h" #include "LLVMBackend/Components/CIRType.h" @@ -31,6 +32,8 @@ #include #include #include +#include +#include #include #include #include @@ -371,23 +374,34 @@ namespace rift::compiler::LLVM TArray typeIds; ecs::GetChildren(ast, moduleId, typeIds); ecs::ExcludeIfNot(ast, typeIds); - TArray structIds = ecs::GetIf(ast, typeIds); - TArray classIds = ecs::GetIf(ast, typeIds); - TArray staticIds = ecs::GetIf(ast, typeIds); - DeclareStructs(gen, ast, structIds); - DeclareStructs(gen, ast, classIds); - - TArray functionIds; - p::ecs::GetChildren(ast, classIds, functionIds); - p::ecs::GetChildren(ast, staticIds, functionIds); - ecs::ExcludeIfNot(ast, functionIds); - DeclareFunctions(gen, ast, functionIds); - - DefineStructs(gen, ast, structIds); - DefineStructs(gen, ast, classIds); + { // Native declarations + TArray cStructIds = ecs::GetIf(ast, typeIds); + TArray cStaticIds = ecs::GetIf(ast, typeIds); + TArray cFunctionIds; + p::ecs::GetChildren(ast, cStaticIds, cFunctionIds); + ecs::ExcludeIfNot(ast, cFunctionIds); + DeclareStructs(gen, ast, cStructIds); + DeclareFunctions(gen, ast, cFunctionIds); + } - DefineFunctions(gen, ast, functionIds); + { // Rift declarations & definitions + TArray structIds = ecs::GetIf(ast, typeIds); + TArray classIds = ecs::GetIf(ast, typeIds); + TArray staticIds = ecs::GetIf(ast, typeIds); + TArray functionIds; + p::ecs::GetChildren(ast, classIds, functionIds); + p::ecs::GetChildren(ast, staticIds, functionIds); + ecs::ExcludeIfNot(ast, functionIds); + + DeclareStructs(gen, ast, structIds); + DeclareStructs(gen, ast, classIds); + DeclareFunctions(gen, ast, functionIds); + + DefineStructs(gen, ast, structIds); + DefineStructs(gen, ast, classIds); + DefineFunctions(gen, ast, functionIds); + } if (module.target == AST::RiftModuleTarget::Executable) { diff --git a/Libs/Backends/LLVM/Compiler/Src/LLVMBackend/Linker.cpp b/Libs/Backends/LLVM/Compiler/Src/LLVMBackend/Linker.cpp index af7acff3..13a5173d 100644 --- a/Libs/Backends/LLVM/Compiler/Src/LLVMBackend/Linker.cpp +++ b/Libs/Backends/LLVM/Compiler/Src/LLVMBackend/Linker.cpp @@ -2,6 +2,7 @@ #include "LLVMBackend/Linker.h" +#include "Components/CNativeBinding.h" #include "LLVMBackend/Components/CIRModule.h" #include "Pipe/Core/PlatformProcess.h" #include "Pipe/Core/String.h" @@ -16,14 +17,12 @@ #include - namespace rift::compiler::LLVM { void Link(Compiler& compiler) { - String linkerPath{PlatformProcess::GetExecutablePath()}; - linkerPath.append("/"); - linkerPath.append(RIFT_LLVM_LINKER_PATH); + String linkerPath{ + p::JoinPaths(PlatformProcess::GetExecutablePath(), RIFT_LLVM_LINKER_PATH)}; for (AST::Id moduleId : ecs::ListAll(compiler.ast)) { @@ -33,7 +32,6 @@ namespace rift::compiler::LLVM if (p::files::Exists(irModule.objectFile)) { TArray command; - command.Add(linkerPath.c_str()); const char* extension = nullptr; @@ -52,6 +50,18 @@ namespace rift::compiler::LLVM extension = "lib"; break; } + + p::TArray binaryPaths; + if (auto* cBinding = compiler.ast.TryGet(moduleId)) + { + p::StringView modulePath = AST::GetModulePath(compiler.ast, moduleId); + p::String binaryPath; + for (const auto& nativeBinary : cBinding->binaries) + { + binaryPaths.Add(p::JoinPaths(modulePath, nativeBinary)); + command.Add(binaryPaths.Last().c_str()); + } + } command.Add(irModule.objectFile.data()); p::Path filePath = @@ -60,8 +70,14 @@ namespace rift::compiler::LLVM command.Add(outParam.data()); Log::Info("Linking '{}' from '{}'", p::ToString(filePath), irModule.objectFile); - p::RunProcess(command, - SubprocessOptions::TerminateIfDestroyed | SubprocessOptions::CombinedOutErr); + auto process = p::RunProcess(command, + SubprocessOptions::TerminateIfDestroyed | SubprocessOptions::CombinedOutErr); + i32 returnCode = 0; + p::WaitProcess(process.TryGet(), &returnCode); + if (returnCode != 0) + { + compiler.AddError("Linking failed"); + } } } } diff --git a/Libs/Bindings/Native/Compiler/Include/Components/CNativeBinding.h b/Libs/Bindings/Native/Compiler/Include/Components/CNativeBinding.h index 0dc1d03a..e646822c 100644 --- a/Libs/Bindings/Native/Compiler/Include/Components/CNativeBinding.h +++ b/Libs/Bindings/Native/Compiler/Include/Components/CNativeBinding.h @@ -12,6 +12,9 @@ namespace rift STRUCT(CNativeBinding, p::Struct) PROP(binaries) - p::TArray binaries; + p::TArray binaries; + + PROP(autoGenerateDefinitions) + bool autoGenerateDefinitions = false; }; } // namespace rift diff --git a/Libs/Bindings/Native/Compiler/Src/NativeBindingModule.cpp b/Libs/Bindings/Native/Compiler/Src/NativeBindingModule.cpp index 1c36b8b4..d4fd70b8 100644 --- a/Libs/Bindings/Native/Compiler/Src/NativeBindingModule.cpp +++ b/Libs/Bindings/Native/Compiler/Src/NativeBindingModule.cpp @@ -103,6 +103,11 @@ namespace rift TArray moduleIds; p::ecs::ListAll(ast, moduleIds); + // Only use automatic native bindings on modules marked as such + moduleIds.RemoveIfSwap([ast](auto id) { + return !ast.Get(id).autoGenerateDefinitions; + }); + TArray parsedModules; parsedModules.Reserve(moduleIds.Size()); for (i32 i = 0; i < moduleIds.Size(); ++i) diff --git a/Libs/Pipe b/Libs/Pipe index f79a9b2d..81e184d4 160000 --- a/Libs/Pipe +++ b/Libs/Pipe @@ -1 +1 @@ -Subproject commit f79a9b2d1db9483920f29fa1ec002cc2c38c8127 +Subproject commit 81e184d485b45fdd33184ea0d0c55a2df2528cbf diff --git a/Libs/Runtimes/.gitignore b/Libs/Runtimes/.gitignore new file mode 100644 index 00000000..675789e4 --- /dev/null +++ b/Libs/Runtimes/.gitignore @@ -0,0 +1 @@ +**/Lib/* diff --git a/Libs/Runtimes/IO/__module__.rf b/Libs/Runtimes/IO/__module__.rf index 0fe00890..01d0d9c8 100644 --- a/Libs/Runtimes/IO/__module__.rf +++ b/Libs/Runtimes/IO/__module__.rf @@ -1,5 +1,6 @@ { "CModule": { + "target": "Static", "dependencies": [] }, "CNativeBinding": {