refactor: store compil artifacts under a single dir

This commit is contained in:
youben11
2022-04-29 14:26:11 +01:00
committed by Ayoub Benaissa
parent f223f02ab7
commit 211241fcb2
14 changed files with 121 additions and 100 deletions

View File

@@ -22,13 +22,13 @@ public:
~DynamicModule();
static outcome::checked<std::shared_ptr<DynamicModule>, StringError>
open(std::string libraryPath);
open(std::string outputPath);
private:
outcome::checked<void, StringError>
loadClientParametersJSON(std::string path);
loadClientParametersJSON(std::string outputPath);
outcome::checked<void, StringError> loadSharedLibrary(std::string path);
outcome::checked<void, StringError> loadSharedLibrary(std::string outputPath);
private:
std::vector<ClientParameters> clientParametersList;

View File

@@ -28,10 +28,10 @@ using concretelang::clientlib::TensorData;
class ServerLambda {
public:
/// Load the symbol `funcName` of the compilation result located at the path
/// `outputLib`.
/// Load the symbol `funcName` from the shared lib in the artifacts folder
/// located in `outputPath`
static outcome::checked<ServerLambda, concretelang::error::StringError>
load(std::string funcName, std::string outputLib);
load(std::string funcName, std::string outputPath);
/// Load the symbol `funcName` of the dynamic loaded library
static outcome::checked<ServerLambda, concretelang::error::StringError>

View File

@@ -82,7 +82,7 @@ public:
};
class Library {
std::string libraryPath;
std::string outputDirPath;
std::vector<std::string> objectsPath;
std::vector<mlir::concretelang::ClientParameters> clientParametersList;
/** Path to the runtime library. Will be linked to the output library if set
@@ -94,9 +94,9 @@ public:
/** Create a library instance on which you can add compilation results.
* Then you can emit a library file with the given path.
* cleanUp at false keeps intermediate .obj files for later use. */
Library(std::string libraryPath, std::string runtimeLibraryPath = "",
Library(std::string outputDirPath, std::string runtimeLibraryPath = "",
bool cleanUp = true)
: libraryPath(libraryPath), runtimeLibraryPath(runtimeLibraryPath),
: outputDirPath(outputDirPath), runtimeLibraryPath(runtimeLibraryPath),
cleanUp(cleanUp) {}
/** Add a compilation result to the library */
llvm::Expected<std::string> addCompilation(CompilationResult &compilation);
@@ -110,21 +110,20 @@ public:
std::string staticLibraryPath;
/** Returns the path of the shared library */
static std::string getSharedLibraryPath(std::string path);
static std::string getSharedLibraryPath(std::string outputDirPath);
/** Returns the path of the static library */
static std::string getStaticLibraryPath(std::string path);
static std::string getStaticLibraryPath(std::string outputDirPath);
/** Returns the path of the static library */
static std::string getClientParametersPath(std::string path);
static std::string getClientParametersPath(std::string outputDirPath);
// For advanced use
const static std::string OBJECT_EXT, CLIENT_PARAMETERS_EXT, LINKER,
LINKER_SHARED_OPT, AR, AR_STATIC_OPT, DOT_STATIC_LIB_EXT,
DOT_SHARED_LIB_EXT;
const static std::string OBJECT_EXT, LINKER, LINKER_SHARED_OPT, AR,
AR_STATIC_OPT, DOT_STATIC_LIB_EXT, DOT_SHARED_LIB_EXT;
void addExtraObjectFilePath(std::string objectFilePath);
llvm::Expected<std::string>
emit(std::string dotExt, std::string linker,
emit(std::string path, std::string dotExt, std::string linker,
llvm::Optional<std::vector<std::string>> extraArgs = {});
~Library();
@@ -202,15 +201,15 @@ public:
llvm::Optional<std::shared_ptr<Library>> lib = {});
llvm::Expected<CompilerEngine::Library>
compile(std::vector<std::string> inputs, std::string libraryPath,
compile(std::vector<std::string> inputs, std::string outputDirPath,
std::string runtimeLibraryPath = "", bool generateSharedLib = true,
bool generateStaticLib = true, bool generateClientParameters = true,
bool generateCppHeader = true);
/// Compile and emit artifact to the given libraryPath from an LLVM source
/// Compile and emit artifact to the given outputDirPath from an LLVM source
/// manager.
llvm::Expected<CompilerEngine::Library>
compile(llvm::SourceMgr &sm, std::string libraryPath,
compile(llvm::SourceMgr &sm, std::string outputDirPath,
std::string runtimeLibraryPath = "", bool generateSharedLib = true,
bool generateStaticLib = true, bool generateClientParameters = true,
bool generateCppHeader = true);

View File

@@ -24,8 +24,9 @@ namespace serverlib = ::concretelang::serverlib;
/// LibraryCompilationResult is the result of a compilation to a library.
struct LibraryCompilationResult {
/// The output path where the compilation artifact has been generated.
std::string libraryPath;
/// The output directory path where the compilation artifacts have been
/// generated.
std::string outputDirPath;
std::string funcName;
};
@@ -63,7 +64,7 @@ public:
}
auto result = std::make_unique<LibraryCompilationResult>();
result->libraryPath = outputPath;
result->outputDirPath = outputPath;
result->funcName = *options.clientParametersFuncName;
return std::move(result);
}
@@ -73,7 +74,7 @@ public:
llvm::Expected<serverlib::ServerLambda>
loadServerLambda(LibraryCompilationResult &result) override {
auto lambda =
serverlib::ServerLambda::load(result.funcName, result.libraryPath);
serverlib::ServerLambda::load(result.funcName, result.outputDirPath);
if (lambda.has_error()) {
return StreamStringError(lambda.error().mesg);
}
@@ -83,7 +84,8 @@ public:
/// Load the client parameters from the compilation result.
llvm::Expected<clientlib::ClientParameters>
loadClientParameters(LibraryCompilationResult &result) override {
auto path = ClientParameters::getClientParametersPath(result.libraryPath);
auto path =
CompilerEngine::Library::getClientParametersPath(result.outputDirPath);
auto params = ClientParameters::load(path);
if (params.has_error()) {
return StreamStringError(params.error().mesg);

View File

@@ -43,7 +43,9 @@ public:
load(std::string funcName, std::string outputLib, uint64_t seed_msb = 0,
uint64_t seed_lsb = 0,
std::shared_ptr<KeySetCache> unsecure_cache = nullptr) {
std::string jsonPath = ClientParameters::getClientParametersPath(outputLib);
std::string jsonPath =
mlir::concretelang::CompilerEngine::Library::getClientParametersPath(
outputLib);
OUTCOME_TRY(auto cLambda, ClientLambda::load(funcName, jsonPath));
OUTCOME_TRY(auto sLambda, ServerLambda::load(funcName, outputLib));
OUTCOME_TRY(std::shared_ptr<KeySet> keySet,

View File

@@ -96,9 +96,9 @@ void mlir::concretelang::python::populateCompilerAPISubmodule(
pybind11::class_<mlir::concretelang::LibraryCompilationResult>(
m, "LibraryCompilationResult")
.def(pybind11::init([](std::string libraryPath, std::string funcname) {
.def(pybind11::init([](std::string outputDirPath, std::string funcname) {
return mlir::concretelang::LibraryCompilationResult{
libraryPath,
outputDirPath,
funcname,
};
}));

View File

@@ -33,28 +33,28 @@ class LibraryCompilationResult(WrapperCpp):
@staticmethod
# pylint: disable=arguments-differ
def new(library_path: str, func_name: str) -> "LibraryCompilationResult":
"""Build a LibraryCompilationResult at library_path, with func_name as entrypoint.
def new(output_dir_path: str, func_name: str) -> "LibraryCompilationResult":
"""Build a LibraryCompilationResult at output_dir_path, with func_name as entrypoint.
Args:
library_path (str): path to the library
output_dir_path (str): path to the compilation artifacts
func_name (str): entrypoint function name
Raises:
TypeError: if library_path is not of type str
TypeError: if output_dir_path is not of type str
TypeError: if func_name is not of type str
Returns:
LibraryCompilationResult
"""
if not isinstance(library_path, str):
if not isinstance(output_dir_path, str):
raise TypeError(
f"library_path must be of type str, not {type(library_path)}"
f"output_dir_path must be of type str, not {type(output_dir_path)}"
)
if not isinstance(func_name, str):
raise TypeError(f"func_name must be of type str, not {type(func_name)}")
return LibraryCompilationResult.wrap(
_LibraryCompilationResult(library_path, func_name)
_LibraryCompilationResult(output_dir_path, func_name)
)
# pylint: enable=arguments-differ

View File

@@ -25,9 +25,9 @@ from .wrapper import WrapperCpp
from .utils import lookup_runtime_lib
# Default output path for compiled libraries
# Default output path for compilation artifacts
DEFAULT_OUTPUT_PATH = os.path.abspath(
os.path.join(os.path.curdir, "concrete-compiler_output_lib")
os.path.join(os.path.curdir, "concrete-compiler_compilation_artifacts")
)
@@ -49,18 +49,18 @@ class LibrarySupport(WrapperCpp):
f"{type(library_support)}"
)
super().__init__(library_support)
self.library_path = DEFAULT_OUTPUT_PATH
self.output_dir_path = DEFAULT_OUTPUT_PATH
@property
def library_path(self) -> str:
"""Path where to store compiled libraries."""
return self._library_path
def output_dir_path(self) -> str:
"""Path where to store compilation artifacts."""
return self._output_dir_path
@library_path.setter
def library_path(self, path: str):
@output_dir_path.setter
def output_dir_path(self, path: str):
if not isinstance(path, str):
raise TypeError(f"path must be of type str, not {type(path)}")
self._library_path = path
self._output_dir_path = path
@staticmethod
# pylint: disable=arguments-differ
@@ -75,7 +75,7 @@ class LibrarySupport(WrapperCpp):
"""Build a LibrarySupport.
Args:
output_path (str, optional): path where to store compiled libraries.
output_path (str, optional): path where to store compilation artifacts.
Defaults to DEFAULT_OUTPUT_PATH.
runtime_library_path (Optional[str], optional): path to the runtime library. Defaults to None.
generateSharedLib (bool): whether to emit shared library or not. Default to True.
@@ -117,7 +117,7 @@ class LibrarySupport(WrapperCpp):
generateCppHeader,
)
)
library_support.library_path = output_path
library_support.output_dir_path = output_path
return library_support
def compile(
@@ -151,7 +151,7 @@ class LibrarySupport(WrapperCpp):
)
def reload(self, func_name: str = "main") -> LibraryCompilationResult:
"""Reload the library compilation result from the library_path.
"""Reload the library compilation result from the output_dir_path.
Args:
func_name: entrypoint function name
@@ -161,7 +161,7 @@ class LibrarySupport(WrapperCpp):
"""
if not isinstance(func_name, str):
raise TypeError(f"func_name must be of type str, not {type(func_name)}")
return LibraryCompilationResult.new(self.library_path, func_name)
return LibraryCompilationResult.new(self.output_dir_path, func_name)
def load_client_parameters(
self, library_compilation_result: LibraryCompilationResult

View File

@@ -7,10 +7,10 @@
#include <fstream>
#include "boost/outcome.h"
#include "concretelang/ServerLib/DynamicModule.h"
#include "concretelang/Support/CompilerEngine.h"
#include "concretelang/Support/Error.h"
#include <llvm/Support/Path.h>
namespace concretelang {
namespace serverlib {
@@ -25,17 +25,18 @@ DynamicModule::~DynamicModule() {
}
outcome::checked<std::shared_ptr<DynamicModule>, StringError>
DynamicModule::open(std::string libPath) {
DynamicModule::open(std::string outputPath) {
std::shared_ptr<DynamicModule> module = std::make_shared<DynamicModule>();
OUTCOME_TRYV(module->loadClientParametersJSON(libPath));
OUTCOME_TRYV(module->loadSharedLibrary(libPath));
OUTCOME_TRYV(module->loadClientParametersJSON(outputPath));
OUTCOME_TRYV(module->loadSharedLibrary(outputPath));
return module;
}
outcome::checked<void, StringError>
DynamicModule::loadSharedLibrary(std::string path) {
libraryHandle = dlopen(
CompilerEngine::Library::getSharedLibraryPath(path).c_str(), RTLD_LAZY);
DynamicModule::loadSharedLibrary(std::string outputPath) {
libraryHandle =
dlopen(CompilerEngine::Library::getSharedLibraryPath(outputPath).c_str(),
RTLD_LAZY);
if (!libraryHandle) {
return StringError("Cannot open shared library ") << dlerror();
}
@@ -43,8 +44,8 @@ DynamicModule::loadSharedLibrary(std::string path) {
}
outcome::checked<void, StringError>
DynamicModule::loadClientParametersJSON(std::string libPath) {
auto jsonPath = CompilerEngine::Library::getClientParametersPath(libPath);
DynamicModule::loadClientParametersJSON(std::string outputPath) {
auto jsonPath = CompilerEngine::Library::getClientParametersPath(outputPath);
OUTCOME_TRY(auto clientParams, ClientParameters::load(jsonPath));
this->clientParametersList = clientParams;
return outcome::success();

View File

@@ -62,8 +62,8 @@ ServerLambda::loadFromModule(std::shared_ptr<DynamicModule> module,
}
outcome::checked<ServerLambda, StringError>
ServerLambda::load(std::string funcName, std::string outputLib) {
OUTCOME_TRY(auto module, DynamicModule::open(outputLib));
ServerLambda::load(std::string funcName, std::string outputPath) {
OUTCOME_TRY(auto module, DynamicModule::open(outputPath));
return ServerLambda::loadFromModule(module, funcName);
}

View File

@@ -5,7 +5,6 @@
#include <fstream>
#include <iostream>
#include <regex>
#include <stdio.h>
#include <string>
@@ -372,11 +371,12 @@ CompilerEngine::compile(std::unique_ptr<llvm::MemoryBuffer> buffer,
llvm::Expected<CompilerEngine::Library>
CompilerEngine::compile(std::vector<std::string> inputs,
std::string libraryPath, std::string runtimeLibraryPath,
bool generateSharedLib, bool generateStaticLib,
bool generateClientParameters, bool generateCppHeader) {
std::string outputDirPath,
std::string runtimeLibraryPath, bool generateSharedLib,
bool generateStaticLib, bool generateClientParameters,
bool generateCppHeader) {
using Library = mlir::concretelang::CompilerEngine::Library;
auto outputLib = std::make_shared<Library>(libraryPath, runtimeLibraryPath);
auto outputLib = std::make_shared<Library>(outputDirPath, runtimeLibraryPath);
auto target = CompilerEngine::Target::LIBRARY;
for (auto input : inputs) {
auto compilation = compile(input, target, outputLib);
@@ -395,12 +395,12 @@ CompilerEngine::compile(std::vector<std::string> inputs,
}
llvm::Expected<CompilerEngine::Library>
CompilerEngine::compile(llvm::SourceMgr &sm, std::string libraryPath,
CompilerEngine::compile(llvm::SourceMgr &sm, std::string outputDirPath,
std::string runtimeLibraryPath, bool generateSharedLib,
bool generateStaticLib, bool generateClientParameters,
bool generateCppHeader) {
using Library = mlir::concretelang::CompilerEngine::Library;
auto outputLib = std::make_shared<Library>(libraryPath, runtimeLibraryPath);
auto outputLib = std::make_shared<Library>(outputDirPath, runtimeLibraryPath);
auto target = CompilerEngine::Target::LIBRARY;
auto compilation = compile(sm, target, outputLib);
@@ -419,23 +419,32 @@ CompilerEngine::compile(llvm::SourceMgr &sm, std::string libraryPath,
}
/** Returns the path of the shared library */
std::string CompilerEngine::Library::getSharedLibraryPath(std::string path) {
return path + DOT_SHARED_LIB_EXT;
std::string
CompilerEngine::Library::getSharedLibraryPath(std::string outputDirPath) {
llvm::SmallString<0> sharedLibraryPath(outputDirPath);
llvm::sys::path::append(sharedLibraryPath, "sharedlib" + DOT_SHARED_LIB_EXT);
return sharedLibraryPath.str().str();
}
/** Returns the path of the static library */
std::string CompilerEngine::Library::getStaticLibraryPath(std::string path) {
return path + DOT_STATIC_LIB_EXT;
std::string
CompilerEngine::Library::getStaticLibraryPath(std::string outputDirPath) {
llvm::SmallString<0> staticLibraryPath(outputDirPath);
llvm::sys::path::append(staticLibraryPath, "staticlib" + DOT_STATIC_LIB_EXT);
return staticLibraryPath.str().str();
}
/** Returns the path of the static library */
std::string CompilerEngine::Library::getClientParametersPath(std::string path) {
return ClientParameters::getClientParametersPath(path);
std::string
CompilerEngine::Library::getClientParametersPath(std::string outputDirPath) {
llvm::SmallString<0> clientParametersPath(outputDirPath);
llvm::sys::path::append(
clientParametersPath,
ClientParameters::getClientParametersPath("client_parameters"));
return clientParametersPath.str().str();
}
const std::string CompilerEngine::Library::OBJECT_EXT = ".o";
const std::string CompilerEngine::Library::CLIENT_PARAMETERS_EXT =
".concrete.params.json";
const std::string CompilerEngine::Library::LINKER = "ld";
#ifdef __APPLE__
// We need to tell the linker that some symbols will be missing during linking,
@@ -459,7 +468,7 @@ void CompilerEngine::Library::addExtraObjectFilePath(std::string path) {
llvm::Expected<std::string>
CompilerEngine::Library::emitClientParametersJSON() {
auto clientParamsPath = getClientParametersPath(libraryPath);
auto clientParamsPath = getClientParametersPath(outputDirPath);
llvm::json::Value value(clientParametersList);
std::error_code error;
llvm::raw_fd_ostream out(clientParamsPath, error);
@@ -502,10 +511,10 @@ static std::string cppArgsType(std::vector<CircuitGate> inputs) {
}
llvm::Expected<std::string> CompilerEngine::Library::emitCppHeader() {
auto libraryName = llvm::sys::path::filename(libraryPath).str();
std::string libraryName = "fhecircuit";
auto headerName = libraryName + "-client.h";
auto headerPath = std::regex_replace(
libraryPath, std::regex(libraryName + "$"), headerName);
llvm::SmallString<0> headerPath(outputDirPath);
llvm::sys::path::append(headerPath, headerName);
std::error_code error;
llvm::raw_fd_ostream out(headerPath, error);
@@ -559,7 +568,7 @@ llvm::Expected<std::string> CompilerEngine::Library::emitCppHeader() {
out.close();
return headerPath;
return headerPath.str().str();
}
llvm::Expected<std::string>
@@ -567,7 +576,7 @@ CompilerEngine::Library::addCompilation(CompilationResult &compilation) {
llvm::Module *module = compilation.llvmModule.get();
auto sourceName = module->getSourceFileName();
if (sourceName == "" || sourceName == "LLVMDialectModule") {
sourceName = this->libraryPath + ".module-" +
sourceName = this->outputDirPath + ".module-" +
std::to_string(objectsPath.size()) + ".mlir";
}
auto objectPath = sourceName + OBJECT_EXT;
@@ -599,9 +608,9 @@ std::string ensureLibDotExt(std::string path, std::string dotExt) {
}
llvm::Expected<std::string> CompilerEngine::Library::emit(
std::string dotExt, std::string linker,
std::string path, std::string dotExt, std::string linker,
llvm::Optional<std::vector<std::string>> extraArgs) {
auto pathDotExt = ensureLibDotExt(libraryPath, dotExt);
auto pathDotExt = ensureLibDotExt(path, dotExt);
auto error = mlir::concretelang::emitLibrary(objectsPath, pathDotExt, linker,
extraArgs);
if (error) {
@@ -651,7 +660,8 @@ llvm::Expected<std::string> CompilerEngine::Library::emitShared() {
}
#endif
}
auto path = emit(DOT_SHARED_LIB_EXT, LINKER + LINKER_SHARED_OPT, extraArgs);
auto path = emit(getSharedLibraryPath(outputDirPath), DOT_SHARED_LIB_EXT,
LINKER + LINKER_SHARED_OPT, extraArgs);
if (path) {
sharedLibraryPath = path.get();
#ifdef __APPLE__
@@ -680,7 +690,8 @@ llvm::Expected<std::string> CompilerEngine::Library::emitShared() {
}
llvm::Expected<std::string> CompilerEngine::Library::emitStatic() {
auto path = emit(DOT_STATIC_LIB_EXT, AR + AR_STATIC_OPT);
auto path = emit(getStaticLibraryPath(outputDirPath), DOT_STATIC_LIB_EXT,
AR + AR_STATIC_OPT);
if (path) {
staticLibraryPath = path.get();
}
@@ -691,6 +702,8 @@ llvm::Error CompilerEngine::Library::emitArtifacts(bool sharedLib,
bool staticLib,
bool clientParameters,
bool cppHeader) {
// Create output directory if doesn't exist
llvm::sys::fs::create_directory(outputDirPath);
if (sharedLib) {
if (auto err = emitShared().takeError()) {
return err;

View File

@@ -4,7 +4,7 @@
#include "concretelang/ClientLib/Types.h"
#include "concretelang/Common/Error.h"
namespace call_2t_1s_with_header {
namespace fhecircuit {
namespace client {
namespace extract {
@@ -19,4 +19,4 @@ namespace extract {
} // namespace extract
} // namespace client
} // namespace call_2t_1s_with_header
} // namespace fhecircuit

View File

@@ -70,7 +70,7 @@ func @main(%arg0: !FHE.eint<7>) -> !FHE.eint<7> {
using MyLambda = clientlib::TypedClientLambda<scalar_out, scalar_in>;
std::string outputLib = outputLibFromThis(this->test_info_);
auto compiled = compile(outputLib, source);
std::string jsonPath = ClientParameters::getClientParametersPath(outputLib);
std::string jsonPath = compiled.getClientParametersPath(outputLib);
auto maybeLambda = MyLambda::load("main", jsonPath);
ASSERT_TRUE(maybeLambda.has_value());
auto lambda = maybeLambda.value();
@@ -344,9 +344,9 @@ func @extract(%arg0: tensor<3x!FHE.eint<7>>, %arg1: tensor<3x!FHE.eint<7>>) -> !
}
)";
std::string outputLib = outputLibFromThis(this->test_info_);
namespace extract = call_2t_1s_with_header::client::extract;
namespace extract = fhecircuit::client::extract;
auto compiled = compile(outputLib, source, extract::name);
std::string jsonPath = ClientParameters::getClientParametersPath(outputLib);
std::string jsonPath = compiled.getClientParametersPath(outputLib);
auto cLambda_ = extract::load(jsonPath);
ASSERT_TRUE(cLambda_);
tensor1_in ta{1, 2, 3};
@@ -366,7 +366,8 @@ func @extract(%arg0: tensor<3x!FHE.eint<7>>, %arg1: tensor<3x!FHE.eint<7>>) -> !
EXPECT_EQ(fileContent(THIS_TEST_DIRECTORY +
"/call_2t_1s_with_header-client.h.generated"),
fileContent(OUT_DIRECTORY + "/call_2t_1s_with_header-client.h"));
fileContent(OUT_DIRECTORY +
"/call_2t_1s_with_header/fhecircuit-client.h"));
}
TEST(DISABLED_CompiledModule, call_2s_1s_lookup_table) {

View File

@@ -16,11 +16,14 @@ SOURCE_2 = f"{TEST_PATH}/return_0.ir"
SOURCE_C_1 = f"{TEST_PATH}/main_return_13.c"
SOURCE_C_2 = f"{TEST_PATH}/main_return_0.c"
OUTPUT = f"{TEST_PATH}/output.mlir"
LIB = f"{TEST_PATH}/outlib"
LIB_STATIC = LIB + ".a"
DYNAMIC_LIB_EXT = ".dylib" if sys.platform == "darwin" else ".so"
LIB_DYNAMIC = LIB + DYNAMIC_LIB_EXT
ARTIFACTS_DIR = f"{TEST_PATH}/outlib"
LIB_STATIC = ARTIFACTS_DIR + "/staticlib.a"
DYNAMIC_LIB_NAME = "/sharedlib.dylib" if sys.platform == "darwin" else "/sharedlib.so"
LIB_DYNAMIC = ARTIFACTS_DIR + DYNAMIC_LIB_NAME
LIBS = (LIB_STATIC, LIB_DYNAMIC)
HEADER_FILE = ARTIFACTS_DIR + "/fhecircuit-client.h"
CLIENT_PARAMS_FILE = ARTIFACTS_DIR + "/client_parameters.concrete.params.json"
ALL_ARTIFACTS = LIBS + (HEADER_FILE, CLIENT_PARAMS_FILE)
assert_exists(SOURCE_1, SOURCE_2, SOURCE_C_1, SOURCE_C_2)
@@ -48,11 +51,11 @@ def test_roundtrip_many():
def test_compile_library():
remove(LIBS)
remove(ALL_ARTIFACTS)
run(CONCRETECOMPILER, SOURCE_1, "--action=compile", "-o", LIB)
run(CONCRETECOMPILER, SOURCE_1, "--action=compile", "-o", ARTIFACTS_DIR)
assert_exists(LIBS)
assert_exists(ALL_ARTIFACTS)
EXE = "./main.exe"
remove(EXE)
@@ -67,13 +70,13 @@ def test_compile_library():
result = subprocess.run([EXE], capture_output=True)
assert 13 == result.returncode
remove(LIBS, EXE)
remove(ALL_ARTIFACTS, EXE)
def test_compile_many_library():
remove(LIBS)
remove(ALL_ARTIFACTS)
run(CONCRETECOMPILER, SOURCE_1, SOURCE_2, "--action=compile", "-o", LIB)
run(CONCRETECOMPILER, SOURCE_1, SOURCE_2, "--action=compile", "-o", ARTIFACTS_DIR)
assert_exists(LIBS)
@@ -84,4 +87,4 @@ def test_compile_many_library():
result = subprocess.run([EXE], capture_output=True)
assert 0 == result.returncode
remove(LIBS, EXE)
remove(ALL_ARTIFACTS, EXE)