Browse Source

Support lists of arguments for linking

Linking now works with multiple Cakelisp files.
GeneralDependencyResolver
Macoy Madson 1 month ago
parent
commit
5c127483eb
6 changed files with 37 additions and 55 deletions
  1. +7
    -2
      runtime/HotReloading.cake
  2. +5
    -5
      src/Evaluator.cpp
  3. +2
    -1
      src/Generators.cpp
  4. +6
    -32
      src/ModuleManager.cpp
  5. +16
    -14
      src/RunProcess.cpp
  6. +1
    -1
      src/RunProcess.hpp

+ 7
- 2
runtime/HotReloading.cake View File

@@ -3,13 +3,18 @@
(set-module-option build-time-compiler "/usr/bin/clang++")
;; Include cakelisp source for DynamicLoader.hpp
(set-module-option build-time-compile-arguments
"-std=c++11" "-Wall" "-Wextra" "-Wno-unused-parameter" "-O0"
"-g" "-c" 'source-input "-o" 'object-output "-fPIC" "-Isrc/")
;; TODO: This only makes sense on a per-target basis. Instead, modules should be able to append
;; arguments to the link command only
(set-module-option build-time-linker "/usr/bin/clang++")
;; This needs to link -ldl and such (depending on platform...)
(set-module-option build-time-link-arguments
"-shared" "-o" 'library-output 'object-input)
(set-cakelisp-option build-time-link-arguments
"-shared" "-o" 'executable-output 'object-input
;; TODO: Make this get built by cakelisp too?
"src/DynamicLoader.o"
;; TODO: OS dependent
"-ldl" "-lpthread")

(import &comptime-only "Macros.cake")
(c-import "<unordered_map>" "<vector>")


+ 5
- 5
src/Evaluator.cpp View File

@@ -612,9 +612,9 @@ int BuildExecuteCompileTimeFunctions(EvaluatorEnvironment& environment,
}

ProcessCommandInput compileTimeInputs[] = {
{ProcessCommandArgumentType_SourceInput, sourceOutputName},
{ProcessCommandArgumentType_ObjectOutput, buildObjectName},
{ProcessCommandArgumentType_CakelispHeadersInclude, headerInclude}};
{ProcessCommandArgumentType_SourceInput, {sourceOutputName}},
{ProcessCommandArgumentType_ObjectOutput, {buildObjectName}},
{ProcessCommandArgumentType_CakelispHeadersInclude, {headerInclude}}};
const char** buildArguments = MakeProcessArgumentsFromCommand(
environment.compileTimeBuildCommand, compileTimeInputs, ArraySize(compileTimeInputs));
if (!buildArguments)
@@ -671,8 +671,8 @@ int BuildExecuteCompileTimeFunctions(EvaluatorEnvironment& environment,

ProcessCommandInput linkTimeInputs[] = {
{ProcessCommandArgumentType_DynamicLibraryOutput,
buildObject.dynamicLibraryPath.c_str()},
{ProcessCommandArgumentType_ObjectInput, buildObject.buildObjectName.c_str()}};
{buildObject.dynamicLibraryPath.c_str()}},
{ProcessCommandArgumentType_ObjectInput, {buildObject.buildObjectName.c_str()}}};
const char** linkArgumentList = MakeProcessArgumentsFromCommand(
environment.compileTimeLinkCommand, linkTimeInputs, ArraySize(linkTimeInputs));
if (!linkArgumentList)


+ 2
- 1
src/Generators.cpp View File

@@ -61,8 +61,9 @@ bool SetProcessCommandArguments(EvaluatorEnvironment& environment, const std::ve
{"'source-input", ProcessCommandArgumentType_SourceInput},
{"'object-output", ProcessCommandArgumentType_ObjectOutput},
{"'cakelisp-headers-include", ProcessCommandArgumentType_CakelispHeadersInclude},
{"'object-input", ProcessCommandArgumentType_ObjectInput},
{"'object-input", ProcessCommandArgumentType_ObjectInput},
{"'library-output", ProcessCommandArgumentType_DynamicLibraryOutput},
{"'executable-output", ProcessCommandArgumentType_ExecutableOutput},
};
bool found = false;
for (unsigned int i = 0; i < ArraySize(symbolsToCommandTypes); ++i)


+ 6
- 32
src/ModuleManager.cpp View File

@@ -366,8 +366,8 @@ bool moduleManagerBuild(ModuleManager& manager)
manager.environment.buildTimeBuildCommand;

ProcessCommandInput buildTimeInputs[] = {
{ProcessCommandArgumentType_SourceInput, module->sourceOutputName.c_str()},
{ProcessCommandArgumentType_ObjectOutput, buildObjectName}};
{ProcessCommandArgumentType_SourceInput, {module->sourceOutputName.c_str()}},
{ProcessCommandArgumentType_ObjectOutput, {buildObjectName}}};
const char** buildArguments = MakeProcessArgumentsFromCommand(
buildCommand, buildTimeInputs, ArraySize(buildTimeInputs));
if (!buildArguments)
@@ -426,7 +426,6 @@ bool moduleManagerBuild(ModuleManager& manager)
if (log.buildProcess)
printf("Linking %s\n", object->filename.c_str());

objectNameBufferSize += object->filename.size();
++numObjectsToLink;

// If all our objects are older than our executable, don't even link!
@@ -450,44 +449,21 @@ bool moduleManagerBuild(ModuleManager& manager)

if (numObjectsToLink)
{
// Four objects means we need three spaces and a null terminator
int totalNameBufferSize = objectNameBufferSize + numObjectsToLink;
char* objectNameBuffer = new char[totalNameBufferSize];
char* writeHead = objectNameBuffer;
std::vector<const char*> objectsToLink(numObjectsToLink);
for (int i = 0; i < numObjectsToLink; ++i)
{
BuiltObject* object = builtObjects[i];

if (!writeStringToBuffer(object->filename.c_str(), &writeHead, objectNameBuffer,
totalNameBufferSize))
{
delete[] objectNameBuffer;
builtObjectsFree(builtObjects);
return false;
}

if (i < numObjectsToLink - 1)
{
if (!writeCharToBuffer(' ', &writeHead, objectNameBuffer, totalNameBufferSize))
{
delete[] objectNameBuffer;
builtObjectsFree(builtObjects);
return false;
}
}
objectsToLink[i] = object->filename.c_str();
}

if (log.buildProcess)
printf("Link '%s'\n", objectNameBuffer);

ProcessCommandInput linkTimeInputs[] = {
{ProcessCommandArgumentType_ExecutableOutput, outputExecutableName},
{ProcessCommandArgumentType_ObjectInput, objectNameBuffer}};
{ProcessCommandArgumentType_ExecutableOutput, {outputExecutableName}},
{ProcessCommandArgumentType_ObjectInput, objectsToLink}};
const char** linkArgumentList = MakeProcessArgumentsFromCommand(
manager.environment.buildTimeLinkCommand, linkTimeInputs, ArraySize(linkTimeInputs));
if (!linkArgumentList)
{
delete[] objectNameBuffer;
builtObjectsFree(builtObjects);
return false;
}
@@ -498,13 +474,11 @@ bool moduleManagerBuild(ModuleManager& manager)
int linkStatus = 0;
if (runProcess(linkArguments, &linkStatus) != 0)
{
delete[] objectNameBuffer;
builtObjectsFree(builtObjects);
return false;
}

free(linkArgumentList);
delete[] objectNameBuffer;

waitForAllProcessesClosed(OnCompileProcessOutput);



+ 16
- 14
src/RunProcess.cpp View File

@@ -191,23 +191,14 @@ void PrintProcessArguments(const char** processArguments)
const char** MakeProcessArgumentsFromCommand(ProcessCommand& command,
const ProcessCommandInput* inputs, int numInputs)
{
int numArguments = command.arguments.size();
// +1 for file to execute
int numFinalArguments = numArguments + 1;
// +1 again for the null terminator
const char** newArguments = (const char**)calloc(sizeof(const char*), numFinalArguments + 1);
for (int i = 0; i < numFinalArguments; ++i)
newArguments[i] = nullptr;
newArguments[numFinalArguments] = nullptr;
newArguments[0] = command.fileToExecute.c_str();
std::vector<const char*> argumentsAccumulate;

for (int i = 0; i < numArguments; ++i)
for (unsigned int i = 0; i < command.arguments.size(); ++i)
{
int finalArgumentIndex = i + 1;
ProcessCommandArgument& argument = command.arguments[i];

if (argument.type == ProcessCommandArgumentType_String)
newArguments[finalArgumentIndex] = argument.contents.c_str();
argumentsAccumulate.push_back(argument.contents.c_str());
else
{
bool found = false;
@@ -215,7 +206,8 @@ const char** MakeProcessArgumentsFromCommand(ProcessCommand& command,
{
if (inputs[input].type == argument.type)
{
newArguments[finalArgumentIndex] = inputs[input].value;
for (const char* value : inputs[input].value)
argumentsAccumulate.push_back(value);
found = true;
break;
}
@@ -223,12 +215,22 @@ const char** MakeProcessArgumentsFromCommand(ProcessCommand& command,
if (!found)
{
printf("error: command missing input\n");
free(newArguments);
return nullptr;
}
}
}

int numUserArguments = argumentsAccumulate.size();
// +1 for file to execute
int numFinalArguments = numUserArguments + 1;
// +1 again for the null terminator
const char** newArguments = (const char**)calloc(sizeof(const char*), numFinalArguments + 1);

newArguments[0] = command.fileToExecute.c_str();
for (int i = 1; i < numFinalArguments; ++i)
newArguments[i] = argumentsAccumulate[i - 1];
newArguments[numFinalArguments] = nullptr;

return newArguments;
}



+ 1
- 1
src/RunProcess.hpp View File

@@ -36,7 +36,7 @@ struct ProcessCommand
struct ProcessCommandInput
{
ProcessCommandArgumentType type;
const char* value;
std::vector<const char*> value;
};

void PrintProcessArguments(const char** processArguments);


Loading…
Cancel
Save