aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CmakeModule.cpp8
-rw-r--r--src/main.cpp56
2 files changed, 55 insertions, 9 deletions
diff --git a/src/CmakeModule.cpp b/src/CmakeModule.cpp
index 15597cb..27047ba 100644
--- a/src/CmakeModule.cpp
+++ b/src/CmakeModule.cpp
@@ -121,6 +121,14 @@ namespace sibs
return createBuildDirResult;
FileString cmd = TINYDIR_STRING("cmake ");
+ if(config.getCompiler() == Compiler::GCC)
+ {
+ if(config.getSanitize())
+ {
+ cmd += TINYDIR_STRING(" \"-CMAKE_C_FLAGS=-fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined -lasan -lubsan\" "
+ "\"-CMAKE_CXX_FLAGS=-fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined -lasan -lubsan\"");
+ }
+ }
switch(config.getPackageType())
{
case PackageType::EXECUTABLE:
diff --git a/src/main.cpp b/src/main.cpp
index db57648..134d2c6 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -108,16 +108,18 @@ void usage()
void usageBuild()
{
- printf("Usage: sibs build [project_path] [--debug|--release]\n\n");
+ printf("Usage: sibs build [project_path] [--debug|--release] [--sanitize]\n\n");
printf("Build a sibs project\n\n");
printf("Options:\n");
- printf(" project_path\t\t The directory containing a project.conf file - Optional (default: current working directory)\n");
+ printf(" project_path\t\tThe directory containing a project.conf file - Optional (default: current working directory)\n");
printf(" --debug|--release\t\tOptimization level to build project and dependencies with (if not a system package) - Optional (default: --debug)\n");
+ printf(" --sanitize\t\tAdd runtime address/undefined behavior sanitization. Program can be up to 3 times slower and use 3 times as much RAM. Ignored if compiler doesn't support sanitization - Optional (default: disabled)\n");
printf("Examples:\n");
printf(" sibs build\n");
printf(" sibs build dirA/dirB\n");
printf(" sibs build --release\n");
printf(" sibs build dirA --release\n");
+ printf(" sibs build --sanitize\n");
exit(1);
}
@@ -137,10 +139,11 @@ void usageNew()
void usageTest()
{
- printf("Usage: sibs test [project_path]\n\n");
+ printf("Usage: sibs test [project_path] [--no-sanitize]\n\n");
printf("Build and run tests for a sibs project\n\n");
printf("Options:\n");
- printf(" project_path\t\t The directory containing a project.conf file - Optional (default: current working directory)\n");
+ printf(" project_path\t\tThe directory containing a project.conf file - Optional (default: current working directory)\n");
+ printf(" --no-sanitize\t\tDisable runtime address/undefined behavior - Optional\n");
printf("Examples:\n");
printf(" sibs test\n");
printf(" sibs test dirA/dirB\n");
@@ -213,6 +216,7 @@ int buildProject(const FileString &projectPath, const FileString &projectConfFil
// It's ok if `define` fails. It could fail if `main` has already been replaced by other tests somehow.
sibsConfig.define("main", "sibs_lib_ignore_main");
sibsConfig.define("wmain", "sibs_lib_ignore_wmain");
+ sibsConfig.define("WinMain", "sibs_lib_ignore_WinMain");
sibsConfig.setPackageType(PackageType::DYNAMIC);
}
@@ -279,11 +283,12 @@ int buildProject(const FileString &projectPath, const FileString &projectConfFil
int buildProject(int argc, const _tinydir_char_t **argv)
{
- if(argc > 2)
+ if(argc > 3)
usageBuild();
OptimizationLevel optimizationLevel = OPT_LEV_NONE;
FileString projectPath;
+ bool sanitize = false;
for(int i = 0; i < argc; ++i)
{
@@ -306,6 +311,15 @@ int buildProject(int argc, const _tinydir_char_t **argv)
}
optimizationLevel = OPT_LEV_RELEASE;
}
+ else if(_tinydir_strcmp(arg, TINYDIR_STRING("--sanitize")) == 0)
+ {
+ sanitize = true;
+ }
+ else if(_tinydir_strncmp(arg, TINYDIR_STRING("--"), 2) == 0)
+ {
+ ferr << "Error: Invalid argument " << arg << endl;
+ usageBuild();
+ }
else
{
if(!projectPath.empty())
@@ -349,6 +363,7 @@ int buildProject(int argc, const _tinydir_char_t **argv)
#endif
SibsConfig sibsConfig(compiler, projectPath, optimizationLevel, false);
+ sibsConfig.setSanitize(sanitize);
return buildProject(projectPath, projectConfFilePath, sibsConfig);
}
@@ -356,10 +371,32 @@ int testProject(int argc, const _tinydir_char_t **argv)
{
if(argc > 1)
usageTest();
-
+
FileString projectPath;
- if(argc == 1)
- projectPath = argv[0];
+ bool sanitize = true;
+
+ for(int i = 0; i < argc; ++i)
+ {
+ const _tinydir_char_t *arg = argv[i];
+ if(_tinydir_strcmp(arg, TINYDIR_STRING("--no-sanitize")) == 0)
+ {
+ sanitize = false;
+ }
+ else if(_tinydir_strncmp(arg, TINYDIR_STRING("--"), 2) == 0)
+ {
+ ferr << "Error: Invalid argument " << arg << endl;
+ usageTest();
+ }
+ else
+ {
+ if(!projectPath.empty())
+ {
+ ferr << "Error: Project path was defined more than once. First defined as " << projectPath << " then as " << arg << endl;
+ usageTest();
+ }
+ projectPath = arg;
+ }
+ }
// TODO: If projectPath is not defined and working directory does not contain project.conf, then search every parent directory until one is found
if(projectPath.empty())
@@ -390,6 +427,7 @@ int testProject(int argc, const _tinydir_char_t **argv)
#endif
SibsConfig sibsConfig(compiler, projectPath, OPT_LEV_DEBUG, true);
+ sibsConfig.setSanitize(sanitize);
return buildProject(projectPath, projectConfFilePath, sibsConfig);
}
@@ -543,7 +581,7 @@ int wmain(int argc, const _tinydir_char_t **argv)
}
else
{
- ferr << "Expected command to be either 'build' or 'new', was: " << arg << endl << endl;
+ ferr << "Expected command to be either 'build', 'new' or 'test', was: " << arg << endl << endl;
usage();
}
}