Skip to content

Commit 9e978cf

Browse files
Merge pull request #14 from Neko-Box-Coder/BuildOption
Adding build option
2 parents ff1e126 + b651390 commit 9e978cf

File tree

6 files changed

+151
-37
lines changed

6 files changed

+151
-37
lines changed

Include/runcpp2/runcpp2.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ namespace runcpp2
2121
SHOW_USER_CONFIG,
2222
SCRIPT_TEMPLATE,
2323
WATCH,
24+
BUILD,
2425
COUNT
2526
};
2627

@@ -60,6 +61,7 @@ namespace runcpp2
6061
const std::vector<std::string>& runArgs,
6162
const Data::ScriptInfo* lastScriptInfo,
6263
Data::ScriptInfo& outScriptInfo,
64+
const std::string& buildOutputDir,
6365
int& returnStatus);
6466
}
6567

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,12 @@ or `Header`
8686
- `Setup`, `Build` and `Cleanup`: List of shell commands for one time setup, building and
8787
cleaning up
8888

89-
To access the source files of the dependencies, you can specify runcpp2 to build locally at
90-
where it script is by passing the `--local` flag. This is useful when you want to
89+
To access the source files of the dependencies, you can specify runcpp2 to build locally in
90+
the current working directory by passing the `--local` flag. This is useful when you want to
9191
look at the headers of the dependencies.
9292

9393
```shell
9494
runcpp2 --local ./script.cpp
9595
```
9696

97-
This will create a `.runcpp2` folder and all the builds and dependencies will be inside it.
97+
This will create a `.runcpp2` folder in the current working directory, and all the builds and dependencies will be inside it.

Src/runcpp2/DependenciesHelper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@ bool runcpp2::CopyDependenciesBinaries( const ghc::filesystem::path& buildDir,
616616
if(!extensionMatched)
617617
continue;
618618

619+
//TODO: Group object files in folders to avoid name collision
619620
ghc::filesystem::path copiedPath = buildDir / it.path().filename();
620621

621622
//Check if we have previously copied the dependencies to the folder

Src/runcpp2/main.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ int main(int argc, char* argv[])
174174
std::unordered_map<runcpp2::CmdOptions, std::string> currentOptions;
175175

176176
{
177-
static_assert(static_cast<int>(runcpp2::CmdOptions::COUNT) == 10, "Update this");
177+
static_assert(static_cast<int>(runcpp2::CmdOptions::COUNT) == 11, "Update this");
178178
std::unordered_map<std::string, runcpp2::OptionInfo> longOptionsMap =
179179
{
180180
{
@@ -212,10 +212,14 @@ int main(int argc, char* argv[])
212212
{
213213
"--watch",
214214
runcpp2::OptionInfo(runcpp2::CmdOptions::WATCH, false)
215+
},
216+
{
217+
"--build",
218+
runcpp2::OptionInfo(runcpp2::CmdOptions::BUILD, false)
215219
}
216220
};
217221

218-
static_assert(static_cast<int>(runcpp2::CmdOptions::COUNT) == 10, "Update this");
222+
static_assert(static_cast<int>(runcpp2::CmdOptions::COUNT) == 11, "Update this");
219223
std::unordered_map<std::string, const runcpp2::OptionInfo&> shortOptionsMap =
220224
{
221225
{"-r", longOptionsMap.at("--reset-cache")},
@@ -226,7 +230,8 @@ int main(int argc, char* argv[])
226230
{"-l", longOptionsMap.at("--local")},
227231
{"-s", longOptionsMap.at("--show-config-path")},
228232
{"-t", longOptionsMap.at("--create-script-template")},
229-
{"-w", longOptionsMap.at("--watch")}
233+
{"-w", longOptionsMap.at("--watch")},
234+
{"-b", longOptionsMap.at("--build")}
230235
};
231236

232237
currentArgIndex = ParseArgs(longOptionsMap, shortOptionsMap, currentOptions, argc, argv);
@@ -243,18 +248,19 @@ int main(int argc, char* argv[])
243248
//Help message
244249
if(currentOptions.count(runcpp2::CmdOptions::HELP))
245250
{
246-
static_assert(static_cast<int>(runcpp2::CmdOptions::COUNT) == 10, "Update this");
251+
static_assert(static_cast<int>(runcpp2::CmdOptions::COUNT) == 11, "Update this");
247252
ssLOG_BASE("Usage: runcpp2 [options] [input_file]");
248253
ssLOG_BASE("Options:");
249254
ssLOG_BASE(" -r, --[r]eset-cache Deletes all cache and build everything from scratch");
250255
ssLOG_BASE(" -c, --reset-user-[c]onfig Replace current user config with the default one");
251256
ssLOG_BASE(" -e, --[e]xecutable Runs as executable instead of shared library");
252257
ssLOG_BASE(" -h, --[h]elp Show this help message");
253258
ssLOG_BASE(" -d, --remove-[d]ependencies Remove dependencies listed in the script");
254-
ssLOG_BASE(" -l, --[l]ocal Build the script and dependencies locally");
259+
ssLOG_BASE(" -l, --[l]ocal Build in the current working directory under .runcpp2 directory");
255260
ssLOG_BASE(" -s, --[s]how-config-path Show where runcpp2 is reading the config from");
256261
ssLOG_BASE(" -t, --create-script-[t]emplate <file> Creates/prepend runcpp2 script info template");
257262
ssLOG_BASE(" -w, --[w]atch Watch script changes and output any compiling errors");
263+
ssLOG_BASE(" -b, --[b]uild Build the script and copy output files to the working directory");
258264

259265
return 0;
260266
}
@@ -321,6 +327,13 @@ int main(int argc, char* argv[])
321327
}
322328
}
323329

330+
if( currentOptions.count(runcpp2::CmdOptions::BUILD) > 0 &&
331+
currentOptions.count(runcpp2::CmdOptions::WATCH) > 0)
332+
{
333+
ssLOG_ERROR("--build option is not compatible with --watch option");
334+
return -1;
335+
}
336+
324337
runcpp2::Data::ScriptInfo parsedScriptInfo;
325338

326339
if(currentOptions.count(runcpp2::CmdOptions::WATCH))
@@ -341,8 +354,6 @@ int main(int argc, char* argv[])
341354
{
342355
int result = 0;
343356

344-
345-
346357
runcpp2::PipelineResult pipelineResult =
347358
runcpp2::StartPipeline( script,
348359
profiles,
@@ -351,6 +362,7 @@ int main(int argc, char* argv[])
351362
scriptArgs,
352363
lastParsedScriptInfo,
353364
parsedScriptInfo,
365+
"",
354366
result);
355367

356368
static_assert(static_cast<int>(runcpp2::PipelineResult::COUNT) == 12, "Update this");
@@ -384,13 +396,18 @@ int main(int argc, char* argv[])
384396

385397
int result = 0;
386398

399+
std::string outputDir;
400+
if(currentOptions.count(runcpp2::CmdOptions::BUILD) > 0)
401+
outputDir = ghc::filesystem::path(script).parent_path().string();
402+
387403
if(runcpp2::StartPipeline( script,
388404
profiles,
389405
preferredProfile,
390406
currentOptions,
391407
scriptArgs,
392408
nullptr,
393409
parsedScriptInfo,
410+
outputDir,
394411
result) != runcpp2::PipelineResult::SUCCESS)
395412
{
396413
return -1;

Src/runcpp2/runcpp2.cpp

Lines changed: 120 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,18 @@ namespace
2323
bool CreateLocalBuildDirectory( const std::string& scriptPath,
2424
ghc::filesystem::path& outBuildPath)
2525
{
26-
std::string scriptDirectory = ghc::filesystem::path(scriptPath).parent_path().string();
26+
// Get the current working directory
27+
std::string currentWorkingDir = ghc::filesystem::current_path().string();
2728

28-
//Create the runcpp2 directory
29-
std::string runcpp2Dir = scriptDirectory + "/.runcpp2";
29+
// Create the .runcpp2 directory in the current working directory
30+
std::string runcpp2Dir = currentWorkingDir + "/.runcpp2";
3031

3132
std::error_code e;
3233
if(!ghc::filesystem::exists(runcpp2Dir, e))
3334
{
3435
if(!ghc::filesystem::create_directory(runcpp2Dir, e))
3536
{
36-
ssLOG_ERROR("Failed to create runcpp2 directory");
37+
ssLOG_ERROR("Failed to create .runcpp2 directory in the current working directory");
3738
return false;
3839
}
3940
}
@@ -481,6 +482,7 @@ runcpp2::StartPipeline( const std::string& scriptPath,
481482
const std::vector<std::string>& runArgs,
482483
const Data::ScriptInfo* lastScriptInfo,
483484
Data::ScriptInfo& outScriptInfo,
485+
const std::string& buildOutputDir,
484486
int& returnStatus)
485487
{
486488
INTERNAL_RUNCPP2_SAFE_START();
@@ -559,6 +561,7 @@ runcpp2::StartPipeline( const std::string& scriptPath,
559561
#endif
560562

561563
//Parsing the script, setting up dependencies, compiling and linking
564+
std::vector<std::string> filesToCopyPaths;
562565
{
563566
//Check if there's script info as yaml file instead
564567
std::error_code e;
@@ -611,9 +614,8 @@ runcpp2::StartPipeline( const std::string& scriptPath,
611614

612615
//Create build directory
613616
{
614-
const bool localBuildDir = currentOptions.count(CmdOptions::LOCAL) > 0;
615617
bool createdBuildDir = false;
616-
if(localBuildDir)
618+
if(currentOptions.count(CmdOptions::LOCAL) > 0)
617619
{
618620
if(CreateLocalBuildDirectory(absoluteScriptPath, buildDir))
619621
createdBuildDir = true;
@@ -796,18 +798,70 @@ runcpp2::StartPipeline( const std::string& scriptPath,
796798
return PipelineResult::UNEXPECTED_FAILURE;
797799
}
798800

799-
//Update finalObjectWriteTime
801+
std::vector<std::string> linkFilesPaths;
802+
std::unordered_set<std::string> linkExtensions;
803+
const Data::FilesTypesInfo& currentFileTypes = profiles.at(profileIndex).FilesTypes;
804+
805+
//Populate the set of link extensions
806+
if(runcpp2::HasValueFromPlatformMap(currentFileTypes.StaticLinkFile.Extension))
807+
{
808+
linkExtensions.insert(*runcpp2::GetValueFromPlatformMap(currentFileTypes.StaticLinkFile
809+
.Extension));
810+
}
811+
if(runcpp2::HasValueFromPlatformMap(currentFileTypes.SharedLinkFile.Extension))
812+
{
813+
linkExtensions.insert(*runcpp2::GetValueFromPlatformMap(currentFileTypes.SharedLinkFile
814+
.Extension));
815+
}
816+
if(runcpp2::HasValueFromPlatformMap(currentFileTypes.ObjectLinkFile.Extension))
817+
{
818+
linkExtensions.insert(*runcpp2::GetValueFromPlatformMap(currentFileTypes.ObjectLinkFile
819+
.Extension));
820+
}
821+
822+
//Separate the copied files from dependencies into files to link and files to copy
800823
for(int i = 0; i < copiedBinariesPaths.size(); ++i)
801824
{
802-
if(!ghc::filesystem::exists(copiedBinariesPaths.at(i), e))
825+
ghc::filesystem::path filePath(copiedBinariesPaths.at(i));
826+
std::string extension = filePath.extension().string();
827+
828+
//Check if the file is a link file based on its extension
829+
if(linkExtensions.find(extension) != linkExtensions.end())
803830
{
804-
ssLOG_ERROR(copiedBinariesPaths.at(i) << " reported as cached but doesn't exist");
831+
linkFilesPaths.push_back(copiedBinariesPaths.at(i));
832+
833+
//Special case when SharedLinkFile and SharedLibraryFile share the same extension
834+
if( runcpp2::HasValueFromPlatformMap(currentFileTypes.SharedLibraryFile.Extension) &&
835+
*runcpp2::GetValueFromPlatformMap(currentFileTypes .SharedLibraryFile
836+
.Extension) == extension)
837+
{
838+
filesToCopyPaths.push_back(copiedBinariesPaths.at(i));
839+
}
840+
}
841+
else
842+
filesToCopyPaths.push_back(copiedBinariesPaths.at(i));
843+
}
844+
845+
ssLOG_DEBUG("Files to link:");
846+
for(int i = 0; i < linkFilesPaths.size(); ++i)
847+
ssLOG_DEBUG(" " << linkFilesPaths[i]);
848+
849+
ssLOG_INFO("Files to copy:");
850+
for(int i = 0; i < filesToCopyPaths.size(); ++i)
851+
ssLOG_INFO(" " << filesToCopyPaths[i]);
852+
853+
// Update finalObjectWriteTime
854+
for(int i = 0; i < linkFilesPaths.size(); ++i)
855+
{
856+
if(!ghc::filesystem::exists(linkFilesPaths.at(i), e))
857+
{
858+
ssLOG_ERROR(linkFilesPaths.at(i) << " reported as cached but doesn't exist");
805859
return PipelineResult::UNEXPECTED_FAILURE;
806860
}
807861

808862
ghc::filesystem::file_time_type lastWriteTime =
809-
ghc::filesystem::last_write_time(copiedBinariesPaths.at(i), e);
810-
863+
ghc::filesystem::last_write_time(linkFilesPaths.at(i), e);
864+
811865
if(lastWriteTime > finalObjectWriteTime)
812866
finalObjectWriteTime = lastWriteTime;
813867
}
@@ -819,11 +873,11 @@ runcpp2::StartPipeline( const std::string& scriptPath,
819873
currentOptions.count(CmdOptions::EXECUTABLE) > 0,
820874
scriptName,
821875
exeExt,
822-
copiedBinariesPaths,
876+
linkFilesPaths,
823877
finalObjectWriteTime))
824878
{
825879
for(int i = 0; i < cachedObjectsFiles.size(); ++i)
826-
copiedBinariesPaths.push_back(cachedObjectsFiles.at(i));
880+
linkFilesPaths.push_back(cachedObjectsFiles.at(i));
827881

828882
if(currentOptions.count(CmdOptions::WATCH) > 0)
829883
{
@@ -845,7 +899,7 @@ runcpp2::StartPipeline( const std::string& scriptPath,
845899
scriptInfo,
846900
availableDependencies,
847901
profiles.at(profileIndex),
848-
copiedBinariesPaths,
902+
linkFilesPaths,
849903
currentOptions.count(CmdOptions::EXECUTABLE) > 0,
850904
exeExt))
851905
{
@@ -896,26 +950,66 @@ runcpp2::StartPipeline( const std::string& scriptPath,
896950
return PipelineResult::COMPILE_LINK_FAILED;
897951
}
898952

899-
if(currentOptions.count(CmdOptions::EXECUTABLE) > 0)
953+
if(currentOptions.count(CmdOptions::BUILD) == 0)
900954
{
901-
//Running the script
902-
if(!RunCompiledScript(target, absoluteScriptPath, runArgs, returnStatus))
955+
if(currentOptions.count(CmdOptions::EXECUTABLE) > 0)
956+
{
957+
//Running the script
958+
if(!RunCompiledScript(target, absoluteScriptPath, runArgs, returnStatus))
959+
{
960+
ssLOG_ERROR("Failed to run script");
961+
return PipelineResult::RUN_SCRIPT_FAILED;
962+
}
963+
964+
return PipelineResult::SUCCESS;
965+
}
966+
//Load the shared library and run it
967+
else
903968
{
904-
ssLOG_ERROR("Failed to run script");
905-
return PipelineResult::RUN_SCRIPT_FAILED;
969+
if(!RunCompiledSharedLib(absoluteScriptPath, target, runArgs, returnStatus))
970+
{
971+
ssLOG_ERROR("Failed to run script");
972+
return PipelineResult::RUN_SCRIPT_FAILED;
973+
}
974+
975+
return PipelineResult::SUCCESS;
906976
}
907-
908-
return PipelineResult::SUCCESS;
909977
}
910-
//Load the shared library and run it
911978
else
912979
{
913-
if(!RunCompiledSharedLib(absoluteScriptPath, target, runArgs, returnStatus))
980+
std::error_code e;
981+
982+
// Copy the output file
914983
{
915-
ssLOG_ERROR("Failed to run script");
916-
return PipelineResult::RUN_SCRIPT_FAILED;
984+
ghc::filesystem::path destFile =
985+
ghc::filesystem::path(buildOutputDir) / target.filename();
986+
987+
ghc::filesystem::copy( target, destFile,
988+
ghc::filesystem::copy_options::overwrite_existing, e);
989+
if(e)
990+
{
991+
ssLOG_ERROR("Failed to copy output file: " << e.message());
992+
return PipelineResult::UNEXPECTED_FAILURE;
993+
}
917994
}
918-
995+
996+
// Copy the files that need to be copied
997+
for(int i = 0; i < filesToCopyPaths.size(); ++i)
998+
{
999+
ghc::filesystem::path srcFile(filesToCopyPaths.at(i));
1000+
ghc::filesystem::path destFile =
1001+
ghc::filesystem::path(buildOutputDir) / srcFile.filename();
1002+
ghc::filesystem::copy( srcFile, destFile,
1003+
ghc::filesystem::copy_options::overwrite_existing, e);
1004+
if(e)
1005+
{
1006+
ssLOG_ERROR("Failed to copy file " << filesToCopyPaths.at(i) << ": " <<
1007+
e.message());
1008+
return PipelineResult::UNEXPECTED_FAILURE;
1009+
}
1010+
}
1011+
1012+
ssLOG_INFO("Build completed. Files copied to " << buildOutputDir);
9191013
return PipelineResult::SUCCESS;
9201014
}
9211015
}

TODO.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
TODO:
22
- Group object files in folders to avoid name collision
3-
- Option for build only
3+
- Allow to specify files to copy for dependencies
44
- Allow runcpp2 to be library
55
- Add ability to add defines for cross-compiler
66
- Ability to compile runcpp2 as single cpp

0 commit comments

Comments
 (0)