diff --git a/CMakeLists.txt b/CMakeLists.txt index 5008074..1acdfba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ endif() option(PLOTLYPP_BUILD_EXAMPLES "Build the examples" ${MAIN_PROJECT}) option(PLOTLYPP_BUILD_MODULES "Build Plotly++ as a C++ module" OFF) +option(PLOTLYPP_SYSTEM_INCLUDE "Include as system headers (skip for clang-tidy)." OFF) if(MAIN_PROJECT) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -46,6 +47,10 @@ else() endif() set(JSON_TARGET nlohmann_json::nlohmann_json) +if (PLOTLYPP_SYSTEM_INCLUDE) + set(PLOTLYPP_INCLUDE_TYPE "SYSTEM") +endif() + if(PLOTLYPP_BUILD_MODULES) # Build as C++20 module add_library(plotlypp STATIC) @@ -68,7 +73,7 @@ else() endif() target_link_libraries(plotlypp ${SCOPE} ${JSON_TARGET}) -target_include_directories(plotlypp ${SCOPE} +target_include_directories(plotlypp ${PLOTLYPP_INCLUDE_TYPE} ${SCOPE} $ $ ) diff --git a/examples/3d_charts.cpp b/examples/3d_charts.cpp index 443071c..8c2847d 100644 --- a/examples/3d_charts.cpp +++ b/examples/3d_charts.cpp @@ -122,8 +122,8 @@ Figure gen3dSurfaceTorus() { Eigen::MatrixXd u(kNumPoints, kNumPoints); Eigen::MatrixXd v(kNumPoints, kNumPoints); - for (int i = 0; i < kNumPoints; ++i) { - for (int j = 0; j < kNumPoints; ++j) { + for (auto i = 0u; i < kNumPoints; ++i) { + for (auto j = 0u; j < kNumPoints; ++j) { u(i, j) = ugrid[i][j]; v(i, j) = vgrid[i][j]; } diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 4acc5ee..c971796 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -24,6 +24,7 @@ add_library(math_utils target_include_directories(math_utils PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_compile_features(math_utils PUBLIC cxx_std_17) +include(Warnings.cmake) add_executable(example example.cpp @@ -42,9 +43,22 @@ target_link_libraries(example Eigen3::Eigen ) +target_include_directories(example SYSTEM PRIVATE + $ +) + if(PLOTLYPP_BUILD_MODULES) add_executable(module_example module_example.cpp) target_link_libraries(module_example PRIVATE plotlypp) # Must use at least C++20 for modules target_compile_features(module_example PRIVATE cxx_std_20) endif() + +set_target_warnings(example) +target_compile_options(example PRIVATE + $<$,$>: + # Clang complains with -Wpedantic. For external users we also have the PLOTLYPP_SYSTEM_INCLUDE CMake option + # to treat all plotlypp headers as system headers. + -Wno-overlength-strings + > +) diff --git a/examples/Warnings.cmake b/examples/Warnings.cmake new file mode 100644 index 0000000..6a5f435 --- /dev/null +++ b/examples/Warnings.cmake @@ -0,0 +1,69 @@ + +set(MSVC_WARNINGS + /W4 # Baseline reasonable warnings + # /Wall # Also warns on files included from the standard library, so it's not very useful and creates too many extra warnings. + /permissive- + /w14062 # enumerator 'identifier' in switch of enum 'enumeration' is not handled, ie -Wswitch equivalent + /w14242 # 'identifier': conversion from 'type1' to 'type1', possible loss of data + /w14254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data + /w14263 # 'function': member function does not override any base class virtual member function + /w14265 # 'classname': class has virtual functions, but destructor is not virtual instances of this class may not be destructed correctly + /w14287 # 'operator': unsigned/negative constant mismatch + /we4289 # nonstandard extension used: 'variable': loop control variable declared in the for-loop is used outside the for-loop scope + /w14296 # 'operator': expression is always 'boolean_value' + /w14311 # 'variable': pointer truncation from 'type1' to 'type2' + /w14545 # expression before comma evaluates to a function which is missing an argument list + /w14546 # function call before comma missing argument list + /w14547 # 'operator': operator before comma has no effect; expected operator with side-effect + /w14549 # 'operator': operator before comma has no effect; did you intend 'operator'? + /w14555 # expression has no effect; expected expression with side- effect + /w14619 # pragma warning: there is no warning number 'number' + /w14640 # Enable warning on thread un-safe static member initialization + /w14826 # Conversion from 'type1' to 'type_2' is sign-extended. This may cause unexpected runtime behavior. + /w14905 # wide string literal cast to 'LPSTR' + /w14906 # string literal cast to 'LPWSTR' + /w14928 # illegal copy-initialization; more than one user-defined conversion has been implicitly applied +) + + +set(GCC_WARNINGS + -Wall + -Wextra # reasonable and standard + -Wpedantic + -Wshadow # warn the user if a variable declaration shadows one from a parent context, may cause warnings in 3rd party libs + -Wnon-virtual-dtor # warn the user if a class with virtual functions has a non-virtual destructor. This helps catch hard to track down memory errors + -Wold-style-cast # warn for c-style casts + -Wcast-align # warn for potential performance problem casts + -Wunused # warn on anything being unused + -Woverloaded-virtual # warn if you overload (not override) a virtual function + -Wconversion # warn on type conversions that may lose data + -Wsign-conversion # warn on sign conversions + -Wnull-dereference # warn if a null dereference is detected + -Wdouble-promotion # warn if float is implicit promoted to double + -Wformat=2 # warn on security issues around functions that format output (ie printf) + # Maybe GCC only + -Wmisleading-indentation # warn if indentation implies blocks where blocks do not exist + -Wduplicated-cond # warn if if / else chain has duplicated conditions + -Wduplicated-branches # warn if if / else branches have duplicated code + -Wlogical-op # warn about logical operations being used where bitwise were probably wanted + -Wuseless-cast # warn if you perform a cast to the same type + -Wpedantic +) + +function(set_target_warnings target_name) + target_compile_options(${target_name} PRIVATE + $<$,$>: + -Werror + -Wno-unknown-warning-option # Silences errors for the flags below + ${GCC_WARNINGS} + > + $<$: + -Werror + ${GCC_WARNINGS} + > + $<$: + /WX + ${MSVC_WARNINGS} + > + ) +endfunction() diff --git a/examples/subplots.cpp b/examples/subplots.cpp index 14bc321..89c1241 100644 --- a/examples/subplots.cpp +++ b/examples/subplots.cpp @@ -70,7 +70,7 @@ Figure gen3dSubplots() { std::vector> z(x_grid.size(), std::vector(x_grid[0].size())); - for (auto i = 0; i < x_grid.size(); ++i) { + for (auto i = 0u; i < x_grid.size(); ++i) { for (size_t j = 0; j < x_grid[0].size(); ++j) { double x_val = x_grid[i][j]; double y_val = y_grid[i][j]; @@ -137,9 +137,9 @@ VolcanoData generate_data(int n) { std::normal_distribution<> elev_dist(1000.0, 5000.0); std::uniform_real_distribution<> lon_dist(-180.0, 180.0); std::uniform_real_distribution<> lat_dist(-70.0, 80.0); - std::uniform_int_distribution<> status_dist(0, 1); - std::uniform_int_distribution<> type_dist(0, 3); - std::uniform_int_distribution<> country_dist(0, 5); + std::uniform_int_distribution status_dist(0, 1); + std::uniform_int_distribution type_dist(0, 3); + std::uniform_int_distribution country_dist(0, 5); std::vector statuses = {"Historical", "Holocene"}; std::vector types = {"Stratovolcano", "Shield volcano", "Submarine volcano", "Caldera"}; diff --git a/include/plotlypp/figure.hpp b/include/plotlypp/figure.hpp index c811691..05d1094 100644 --- a/include/plotlypp/figure.hpp +++ b/include/plotlypp/figure.hpp @@ -51,7 +51,7 @@ class Figure { void toHtml(std::ostream& os) const { // Serialize and sanitize for HTML embedding. // This escapes '<' to '\u003c' so the browser never confuses JSON data for HTML tags. - auto html_safe_serialize = [this](const auto& json) { + auto html_safe_serialize = [](const auto& json) { std::string s = serialize(json); // Escape '<' to '\u003c' so the browser never confuses JSON data for HTML tags. size_t pos = 0;