diff --git a/CMakeLists.txt b/CMakeLists.txt index 2447687a..e8f84a8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,20 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) +# Initialize a variable to hold all the compiler flags -> exported into global config.h(.in) +if(CMAKE_BUILD_TYPE MATCHES Debug) + set(ALL_COMPILER_FLAGS "${CMAKE_CXX_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS}") +elseif(CMAKE_BUILD_TYPE MATCHES Release) + set(ALL_COMPILER_FLAGS "${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS}") +elseif(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) + set(ALL_COMPILER_FLAGS "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${CMAKE_CXX_FLAGS}") +elseif(CMAKE_BUILD_TYPE MATCHES MinSizeRel) + set(ALL_COMPILER_FLAGS "${CMAKE_CXX_FLAGS_MINSIZEREL} ${CMAKE_CXX_FLAGS}") +endif() +# Replace ; with space +string(REPLACE ";" " " ALL_COMPILER_FLAGS "${ALL_COMPILER_FLAGS}") + + # Mainly for FMT set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) @@ -12,6 +26,12 @@ add_library(graph-prototype-options INTERFACE) include(cmake/CompilerWarnings.cmake) set_project_warnings(graph-prototype-options) + +if(CMAKE_CXX_COMPILER MATCHES "/em\\+\\+(-[a-zA-Z0-9.])?$") # if this hasn't been set before via e.g. emcmake + message(" Transpiling to WASM: using: Emscripten (${CMAKE_CXX_COMPILER})") + set(EMSCRIPTEN true) +endif() + if (EMSCRIPTEN) set(CMAKE_EXECUTABLE_SUFFIX ".js") target_compile_options(graph-prototype-options INTERFACE @@ -103,6 +123,10 @@ target_include_directories(fftw INTERFACE ${FFTW_PREFIX}/install/include) target_link_directories(fftw INTERFACE ${FFTW_PREFIX}/install/lib ${FFTW_PREFIX}/install/lib64) add_dependencies(fftw fftw_ext) +# configure a header file to pass the CMake settings to the source code +configure_file("${PROJECT_SOURCE_DIR}/cmake/config.h.in" "${PROJECT_BINARY_DIR}/config.h" @ONLY) +include_directories("${PROJECT_BINARY_DIR}") + add_subdirectory(include) add_subdirectory(src) diff --git a/bench/CMakeLists.txt b/bench/CMakeLists.txt index 0e93dce4..c5a0255e 100644 --- a/bench/CMakeLists.txt +++ b/bench/CMakeLists.txt @@ -1,14 +1,18 @@ -function(add_benchmark BM_NAME) - add_executable(${BM_NAME} ${BM_NAME}.cpp) +function(append_compiler_flags TARGET_NAME) + set(FLAGS_COMMON -Wall) if (EMSCRIPTEN) - target_compile_options(${BM_NAME} PRIVATE -Wall) - target_link_options(${BM_NAME} PRIVATE -Wall) + set(FLAGS_SPECIAL "") else () - target_compile_options(${BM_NAME} PRIVATE -Wall -march=native) - target_link_options(${BM_NAME} PRIVATE -Wall -march=native) + set(FLAGS_SPECIAL -march=native) endif () - # target_compile_options(${BM_NAME} PRIVATE -Wall -march=native -fsanitize=address) - # target_link_options(${BM_NAME} PRIVATE -Wall -march=native -fsanitize=address) + + target_compile_options(${TARGET_NAME} PRIVATE ${FLAGS_COMMON} ${FLAGS_SPECIAL}) + target_link_options(${TARGET_NAME} PRIVATE ${FLAGS_COMMON} ${FLAGS_SPECIAL}) +endfunction() + +function(add_benchmark BM_NAME) + add_executable(${BM_NAME} ${BM_NAME}.cpp) + append_compiler_flags(${BM_NAME}) target_link_libraries(${BM_NAME} PRIVATE graph-prototype-options graph-prototype refl-cpp fmt ut fftw) endfunction() @@ -22,12 +26,6 @@ add_benchmark(bm_profiler) add_benchmark(bm_scheduler) add_executable(bm_case1_nosimd bm_case1.cpp) -if (EMSCRIPTEN) - target_compile_options(bm_case1_nosimd PRIVATE -Wall -DDISABLE_SIMD=1) - target_link_options(bm_case1_nosimd PRIVATE -Wall) - target_link_libraries(bm_case1_nosimd PRIVATE graph-prototype-options graph-prototype refl-cpp fmt ut) -else () - target_compile_options(bm_case1_nosimd PRIVATE -Wall -march=native -DDISABLE_SIMD=1) - target_link_options(bm_case1_nosimd PRIVATE -Wall -march=native) - target_link_libraries(bm_case1_nosimd PRIVATE graph-prototype-options graph-prototype refl-cpp fmt ut) -endif () +append_compiler_flags(bm_case1_nosimd) +target_compile_options(bm_case1_nosimd PRIVATE -DDISABLE_SIMD=1) +target_link_libraries(bm_case1_nosimd PRIVATE graph-prototype-options graph-prototype refl-cpp fmt ut) \ No newline at end of file diff --git a/cmake/CompilerWarnings.cmake b/cmake/CompilerWarnings.cmake index 6ad97996..399cec06 100644 --- a/cmake/CompilerWarnings.cmake +++ b/cmake/CompilerWarnings.cmake @@ -80,6 +80,11 @@ function(set_project_warnings project_name) message(AUTHOR_WARNING "No compiler warnings set for '${CMAKE_CXX_COMPILER_ID}' compiler.") endif() + # Replace semicolons with spaces in PROJECT_WARNINGS + string(REPLACE ";" " " PROJECT_WARNINGS_MOD "${PROJECT_WARNINGS}") + set(${output_var} "${PROJECT_WARNINGS}" PARENT_SCOPE) + set(ALL_COMPILER_FLAGS "${ALL_COMPILER_FLAGS}${PROJECT_WARNINGS_MOD}" PARENT_SCOPE) + target_compile_options(${project_name} INTERFACE ${PROJECT_WARNINGS}) endfunction() diff --git a/cmake/config.h.in b/cmake/config.h.in new file mode 100644 index 00000000..809bc34b --- /dev/null +++ b/cmake/config.h.in @@ -0,0 +1,10 @@ +#ifndef GNURADIO_GRAPH_PROJECT_CONFIG +#define GNURADIO_GRAPH_PROJECT_CONFIG + +#define CXX_COMPILER_PATH "@CMAKE_CXX_COMPILER@" +#define CXX_COMPILER_ARG1 "@CMAKE_CXX_COMPILER_ARG1@" +#define CXX_COMPILER_ID "@CMAKE_CXX_COMPILER_ID@" +#define CXX_COMPILER_VERSION "@CMAKE_CXX_COMPILER_VERSION@" +#define CXX_COMPILER_FLAGS "@ALL_COMPILER_FLAGS@" + +#endif // GNURADIO_GRAPH_PROJECT_CONFIG \ No newline at end of file diff --git a/meson.build b/meson.build index 72c37267..2df3ffb8 100644 --- a/meson.build +++ b/meson.build @@ -30,10 +30,34 @@ pmt_dep = libpmtv.get_variable('pmt_dep') graph_prototype_options = [] if meson.is_cross_build() if meson.get_external_property('EMSCRIPTEN', false) - graph_prototype_options = ['-s','ALLOW_MEMORY_GROWTH=1'] + graph_prototype_options = ['-s','ALLOW_MEMORY_GROWTH=1','-fwasm-exceptions','-pthread','SHELL:-s PTHREAD_POOL_SIZE=30"'] endif endif +# Determine compiler flags based on build type +all_compiler_flags = '' +if get_option('buildtype') == 'debug' + all_compiler_flags = '-g' +elif get_option('buildtype') == 'release' + all_compiler_flags = '-O3' +elif get_option('buildtype') == 'debugoptimized' + all_compiler_flags = '-O2 -g' +elif get_option('buildtype') == 'minsize' + all_compiler_flags = '-Os' +endif + +# Additional compiler flags from the global arguments +all_compiler_flags += ' ' + ' '.join(gcc_warnings) + ' '.join(graph_prototype_options) + +# Configure the header file +config_h_data = configuration_data() +config_h_data.set('CMAKE_CXX_COMPILER', compiler.get_id()) +config_h_data.set('CMAKE_CXX_COMPILER_ARG1', '') +config_h_data.set('CMAKE_CXX_COMPILER_ID', compiler.get_id()) +config_h_data.set('CMAKE_CXX_COMPILER_VERSION', compiler.version()) +config_h_data.set('ALL_COMPILER_FLAGS', all_compiler_flags) +configure_file(input : 'cmake/config.h.in', output : 'config.h', configuration : config_h_data) + subdir('include') subdir('src') if (get_option('enable_testing')) diff --git a/src/main.cpp b/src/main.cpp index c2d086f0..2edd1cd3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,8 @@ #include +#include // contains the project and compiler flags definitions + #include namespace fg = fair::graph; @@ -103,6 +105,10 @@ main() { using fg::merge; using fg::merge_by_index; + fmt::print("Project compiler: '{}' - version '{}'\n", CXX_COMPILER_ID, CXX_COMPILER_VERSION); + fmt::print("Project compiler path: '{}' - arg1 '{}'\n", CXX_COMPILER_PATH, CXX_COMPILER_ARG1); + fmt::print("Project compiler flags: '{}'\n", CXX_COMPILER_FLAGS); + { // declare flow-graph: 2 x in -> adder -> scale-by-2 -> scale-by-minus1 -> output auto merged = merge_by_index<0, 0>(scale(), merge_by_index<0, 0>(scale(), adder())); diff --git a/src/meson.build b/src/meson.build index 51652401..032f202c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,6 +1,7 @@ cpp_args = graph_prototype_options main_exe = executable('main', 'main.cpp', + include_directories: '..', dependencies : [graph_dep, fmt_dep, reflcpp_dep], cpp_args: graph_prototype_options, link_args: graph_prototype_options, diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3ff78c04..dcfb2c01 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -3,28 +3,28 @@ set(TESTS_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) configure_file(build_configure.hpp.in build_configure.hpp @ONLY) +function(setup_test_no_asan TARGET_NAME) + target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_BINARY_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}) + target_link_libraries(${TARGET_NAME} PRIVATE graph-prototype-options graph-prototype fmt refl-cpp ut fftw) + add_test(NAME ${TARGET_NAME} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}) +endfunction() + +function(setup_test TARGET_NAME) + target_compile_options(${TARGET_NAME} PRIVATE "-fsanitize=address") + target_link_options(${TARGET_NAME} PRIVATE "-fsanitize=address") + setup_test_no_asan(${TARGET_NAME}) +endfunction() + function(add_ut_test TEST_NAME) add_executable(${TEST_NAME} ${TEST_NAME}.cpp) - if ((CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")) # needed for clang15 (false positives, fixed in clang16) - target_compile_options(${TEST_NAME} PRIVATE -Wall) - target_link_options(${TEST_NAME} PRIVATE -Wall) - else () - target_compile_options(${TEST_NAME} PRIVATE -fsanitize=address -Wall) - target_link_options(${TEST_NAME} PRIVATE -fsanitize=address -Wall) - endif () - target_include_directories(${TEST_NAME} PRIVATE ${CMAKE_BINARY_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}) - target_link_libraries(${TEST_NAME} PRIVATE graph-prototype-options graph-prototype fmt refl-cpp ut fftw) - add_test(NAME ${TEST_NAME} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}) + setup_test(${TEST_NAME}) endfunction() function(add_app_test TEST_NAME) add_executable(${TEST_NAME} ${TEST_NAME}.cpp) - target_compile_options(${TEST_NAME} PRIVATE -fsanitize=address -Wall) - target_include_directories(${TEST_NAME} PRIVATE ${CMAKE_BINARY_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}) - target_link_options(${TEST_NAME} PRIVATE -fsanitize=address -Wall) - target_link_libraries(${TEST_NAME} PRIVATE graph-prototype-options graph-prototype graph-prototype-plugin fmt refl-cpp fftw) + setup_test(${TEST_NAME}) + target_link_libraries(${TEST_NAME} PRIVATE graph-prototype-plugin) add_dependencies(${TEST_NAME} good_math_plugin good_base_plugin bad_plugin) - add_test(NAME ${TEST_NAME} COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} ${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}) endfunction() add_ut_test(qa_buffer) @@ -43,24 +43,16 @@ add_ut_test(qa_thread_affinity) add_ut_test(qa_thread_pool) add_ut_test(qa_traits) -if (NOT EMSCRIPTEN) +if (NOT (EMSCRIPTEN OR (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang"))) add_subdirectory(plugins) - if (NOT (CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")) - # add add target manually without asan TODO: reenable once it builds on the CI again - # add_ut_test(qa_plugins_test) - add_executable(qa_plugins_test qa_plugins_test.cpp) - target_compile_options(qa_plugins_test PRIVATE -Wall) - target_link_options(qa_plugins_test PRIVATE -Wall) - target_include_directories(qa_plugins_test PRIVATE ${CMAKE_BINARY_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}) - target_link_libraries(qa_plugins_test PRIVATE graph-prototype-options graph-prototype fmt refl-cpp ut fftw) - add_test(NAME qa_plugins_test COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} ${CMAKE_CURRENT_BINARY_DIR}/qa_plugins_test) - target_link_libraries(qa_plugins_test PRIVATE graph-prototype-plugin) - add_dependencies(qa_plugins_test good_math_plugin good_base_plugin bad_plugin) - endif () + add_executable(qa_plugins_test qa_plugins_test.cpp) + setup_test_no_asan(qa_plugins_test) + target_link_libraries(qa_plugins_test PRIVATE graph-prototype-plugin) + add_dependencies(qa_plugins_test good_math_plugin good_base_plugin bad_plugin) add_app_test(app_plugins_test app_plugins_test.cpp) add_app_test(app_grc) target_link_libraries(app_grc PRIVATE yaml-cpp::yaml-cpp) -endif () +endif()