diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CmakeModule.cpp | 8 | ||||
-rw-r--r-- | src/main.cpp | 56 |
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(); } } |