cmake_minimum_required(VERSION 3.11) project(sgpemv2 VERSION 1.2) if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) message(FATAL_ERROR [=[ ** This seems to be the pkg root directory. ** Compiling here your sources is considered ** as unpolite as exploring your nose with ** your pinky whilst attending a wedding party. ** ** Please create a separate build dir and then ** run CMake into it. ]=]) endif() include(FindPkgConfig) include(GNUInstallDirs) set(CMAKE_CXX_STANDARD 17) # ------------------------------------------- function(pkg_config_to_tgt tgt) # ARGN: modules + REQUIRED if(NOT ${tgt}_FOUND) pkg_check_modules(${tgt} ${ARGN}) endif() if(${tgt}_FOUND) add_library(${tgt} INTERFACE IMPORTED) set_target_properties(${tgt} PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${${tgt}_INCLUDE_DIRS}" INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${${tgt}_INCLUDE_DIRS}" INTERFACE_LINK_LIBRARIES "${${tgt}_LIBRARY_DIRS};${${tgt}_LIBRARIES}" INTERFACE_COMPILE_OPTIONS "${${tgt}_CFLAGS_OTHER}") endif() endfunction(pkg_config_to_tgt) function(target_sources_add_headers tgt basedir) # ARGN: [ ...] set(visibilities PUBLIC PRIVATE INTERFACE) cmake_parse_arguments("" "" "" "${visibilities}" ${ARGN}) list(APPEND _PUBLIC ${_UNPARSED_ARGUMENTS}) unset(target_sources_headers) foreach(visibility IN LISTS visibilities) list(APPEND target_sources_headers ${visibility}) foreach(header IN LISTS "_${visibility}") if(IS_ABSOLUTE "${header}") string(REGEX REPLACE ".*/${basedir}/(.*)$" "\\1" rel_header "${header}") list(APPEND target_sources_headers "$" "$") else() list(APPEND target_sources_headers "$" "$") endif() endforeach() endforeach() target_sources(${tgt} ${type} ${target_sources_headers}) endfunction(target_sources_add_headers) # ------------------------------------------- find_package(Gettext REQUIRED) find_package(Intl REQUIRED) find_package(Doxygen COMPONENTS dot) add_compile_options(-Wall -pedantic -Wextra) add_definitions(-DGTK_DISABLE_DEPRECATED -DGSEAL_ENABLE) set(CMAKE_CXX_VISIBILITY_PRESET "hidden") set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) pkg_config_to_tgt(sgpemv2-backend-deps "gthread-2.0 >= 2.32.0" "sigc++-2.0 >= 2.2.9" "glibmm-2.4 >= 2.32.0") pkg_config_to_tgt(sgpemv2-frontend-deps "cairomm-1.0 >= 1.10.0" "gtkmm-3.0 >= 3.4.0") # ------------------------------------------- # TODO: no translations yet, so leave commented and untested. # foreach(lang IN ITEMS ... languages ...) # gettext_create_translations(${CMAKE_CURRENT_BINARY_DIR}/po/${lang}.mo ALL # ${CMAKE_CURRENT_BINARY_DIR}/po/${lang}.po) # gettext_process_po_files(${lang} ALL # INSTALL_DESTINATION ${CMAKE_INSTALL_LOCALEDIR} # PO_FILES ${CMAKE_CURRENT_SOURCE_DIR}/po/${lang}.po) # endforeach() gettext_process_pot_file(${CMAKE_CURRENT_SOURCE_DIR}/po/sgpemv2.pot ALL INSTALL_DESTINATION ${CMAKE_INSTALL_LOCALEDIR} LANGUAGES ${languages}) add_custom_target(doc COMMENT "Build all the documentation") if(NOT DOXYGEN_FOUND) message(STATUS "Cannot find doxygen with dot. Skipping API documentation.") else() set(DOXYGEN_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/api) doxygen_add_docs(api-doc ${CMAKE_CURRENT_SOURCE_DIR}/src/backend/sgpemv2 ${CMAKE_CURRENT_BINARY_DIR}/src/backend/sgpemv2 COMMENT "Building documentation via Doxygen") add_dependencies(doc api-doc) install(DIRECTORY ${DOXYGEN_OUTPUT_DIRECTORY}/html DESTINATION ${CMAKE_INSTALL_DOCDIR} OPTIONAL) endif() # TODO: eventually migrate to sphinx. find_program(MAKEINFO makeinfo) find_program(CONVERT convert) if(NOT (MAKEINFO AND CONVERT)) message(STATUS "Cannot find makeinfo or convert. Skipping Info documentation.") else() set(output ${CMAKE_CURRENT_BINARY_DIR}/doc/sgpemv2.info) set(inputs doc/fdl.texi doc/gpl.texi doc/sgpem2uman.texi doc/sgpem2dman.texi) set(images doc/holt_circle.gif doc/main-window.gif doc/simulation_widget.gif) set(text_image doc/main-window.txt) set(img_deps) foreach(img IN LISTS images) get_filename_component(img_we ${img} NAME_WE) set(img_eps ${CMAKE_CURRENT_BINARY_DIR}/doc/${img_we}.eps) set(img_pdf ${CMAKE_CURRENT_BINARY_DIR}/doc/${img_we}.pdf) add_custom_command(OUTPUT ${img_eps} COMMAND ${CONVERT} ${img} ${img_eps}) add_custom_command(OUTPUT ${img_pdf} COMMAND ${CONVERT} ${img} ${img_pdf}) list(APPEND img_deps ${img_eps} ${img_pdf}) install(FILES ${img_eps} ${img_pdf} ${CMAKE_CURRENT_SOURCE_DIR}/doc/main-window.txt DESTINATION ${CMAKE_INSTALL_INFODIR}/sgpemv2-figures) endforeach() add_custom_command(OUTPUT ${output} COMMAND ${MAKEINFO_EXECUTABLE} -o ${output} ${inputs} DEPENDS ${inputs} ${img_deps} COMMENT "Creating Info file documentation" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc VERBATIM) install(FILES ${output} DESTINATION ${CMAKE_INSTALL_INFODIR}) add_custom_target(info-doc ALL DEPENDS ${outputs}) add_dependencies(doc info-doc) endif() # ------------------------------------------- set(localedir ${CMAKE_INSTALL_FULL_LOCALEDIR}) set(uidir ${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/ui) set(policiesdir ${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/policies) set(plugindir ${CMAKE_INSTALL_FULL_LIBDIR}/${PROJECT_NAME}/plugins) configure_file(src/backend/sgpemv2/config.h.in src/backend/sgpemv2/config.h @ONLY) add_library(sgpemv2-backend SHARED) set_target_properties(sgpemv2-backend PROPERTIES POSITION_INDEPENDENT_CODE ON VERSION 1.2 SOVERSION 1.2.0) target_include_directories(sgpemv2-backend PUBLIC $ $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/backend ${Intl_INCLUDE_DIRS}) target_link_libraries(sgpemv2-backend PRIVATE sgpemv2-backend-deps ${Intl_LIBRARIES}) target_sources_add_headers(sgpemv2-backend src/backend/ PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/src/backend/sgpemv2/config.h sgpemv2/cpu_policies_gatekeeper.hh sgpemv2/cpu_policy.hh sgpemv2/cpu_policy_exception.hh sgpemv2/cpu_policy_manager.hh sgpemv2/environment.hh sgpemv2/global_preferences.hh sgpemv2/history.hh sgpemv2/history_observer.hh sgpemv2/invalid_plugin_exception.hh sgpemv2/key_file.hh sgpemv2/malformed_policy_exception.hh sgpemv2/module.hh sgpemv2/null_policy_exception.hh sgpemv2/policy_parameters.hh sgpemv2/plugin.hh sgpemv2/plugin_manager.hh sgpemv2/process_statistics.hh sgpemv2/ready_queue.hh sgpemv2/request.hh sgpemv2/resource.hh sgpemv2/resource_policies_gatekeeper.hh sgpemv2/resource_policy.hh sgpemv2/resource_policy_manager.hh sgpemv2/process.hh sgpemv2/schedulable.hh sgpemv2/schedulable_statistics.hh sgpemv2/scheduler.hh sgpemv2/serialize_visitor.hh sgpemv2/serializer.hh sgpemv2/serializer_error.hh sgpemv2/serializers_gatekeeper.hh sgpemv2/sgpemv2-visibility.hh sgpemv2/simulation.hh sgpemv2/simulation_observer.hh sgpemv2/simulation_statistics.hh sgpemv2/statistics.hh sgpemv2/string_utils.hh sgpemv2/sub_request.hh sgpemv2/thread.hh sgpemv2/thread_statistics.hh sgpemv2/user_interrupt_exception.hh sgpemv2/templates/down_cast.tcc sgpemv2/templates/parameter.tcc sgpemv2/templates/sequences.tcc sgpemv2/templates/singleton.hh sgpemv2/templates/singleton.tcc PRIVATE sgpemv2/config.h.in # not distributed concrete_environment.cc concrete_environment.hh concrete_history.cc concrete_history.hh concrete_process_statistics.cc concrete_process_statistics.hh concrete_simulation.cc concrete_simulation.hh concrete_simulation_statistics.cc concrete_simulation_statistics.hh concrete_statistics.cc concrete_statistics.hh concrete_thread_statistics.cc concrete_thread_statistics.hh cpp_resource_policy_manager.cc cpp_resource_policy_manager.hh cpu_policies_gatekeeper.cc cpu_policy.cc cpu_policy_exception.cc cpu_policy_manager.cc dynamic_process.cc dynamic_process.hh dynamic_request.cc dynamic_request.hh dynamic_resource.cc dynamic_resource.hh dynamic_schedulable.cc dynamic_schedulable.hh dynamic_sub_request.cc dynamic_sub_request.hh dynamic_thread.cc dynamic_thread.hh environment.cc gettext.h global_preferences.cc history.cc history_observer.cc invalid_plugin_exception.cc key_file.cc malformed_policy_exception.cc module.cc null_policy_exception.cc plugin_manager.cc policy_parameters.cc process.cc process_statistics.cc ready_queue.cc request.cc resource.cc resource_policies_gatekeeper.cc resource_policy.cc resource_policy_fifo.cc resource_policy_fifo.hh resource_policy_lifo.cc resource_policy_lifo.hh resource_policy_manager.cc resource_policy_priority.cc resource_policy_priority.hh resource_policy_priority_inheritance.hh resource_policy_priority_inheritance.cc schedulable.cc schedulable_statistics.cc scheduler.cc serialize_visitor.cc serializer.cc serializer_error.cc serializers_gatekeeper.cc simulation.cc simulation_observer.cc simulation_statistics.cc static_process.cc static_process.hh static_request.cc static_request.hh static_resource.cc static_resource.hh static_schedulable.cc static_schedulable.hh static_sub_request.cc static_sub_request.hh static_thread.cc static_thread.hh statistics.cc string_utils.cc sub_request.cc thread.cc thread_statistics.cc user_interrupt_exception.cc) # TODO: plugins! # add_subdirectory(plugins/pyloader) # add_subdirectory(plugins/xmlsave) # ------------------------------------------- add_executable(sgpemv2) target_include_directories(sgpemv2 PRIVATE ${Intl_INCLUDE_DIRS}) target_link_libraries(sgpemv2 PRIVATE sgpemv2-backend sgpemv2-frontend-deps ${Intl_LIBRARIES}) target_sources(sgpemv2 PRIVATE src/add_request_dialog.cc src/add_request_dialog.hh src/cairo_elements.cc src/cairo_elements.hh src/cairo_widget.cc src/cairo_widget.hh src/configure_policy_dialog.cc src/configure_policy_dialog.hh src/graphical_preferences_editor.cc src/graphical_preferences_editor.hh src/gui_builder.cc src/gui_builder.hh src/holt_container_window.cc src/holt_container_window.hh src/holt_widget.cc src/holt_widget.hh src/jump_to_dialog.cc src/jump_to_dialog.hh src/main.cc src/main.hh src/parse_opts.cc src/parse_opts.hh src/ready_queue_widget.cc src/ready_queue_widget.hh src/resources_widget.cc src/resources_widget.hh src/schedulables_statistics_widget.cc src/schedulables_statistics_widget.hh src/schedulables_statistics_widget.hh src/schedulables_tree_widget.cc src/schedulables_tree_widget.hh src/simulation_controller.cc src/simulation_controller.hh src/simulation_statistics_widget.cc src/simulation_statistics_widget.hh src/simulation_widget.cc src/simulation_widget.hh src/statistics_container_window.cc src/statistics_container_window.hh src/text_simulation.cc src/text_simulation.hh) # ------------------------------------------- # TODO: port the tests! # # ############################################################ # # # # check : testsuite # # # # ############################################################ # if COND_TESTS # # DEJATOOL = src/testsuite/example-test.exp # noinst_PROGRAMS = \ # src/testsuite/test-cairo_widget \ # src/testsuite/test-history \ # src/testsuite/test-holt_widget \ # src/testsuite/test-key_file \ # src/testsuite/test-simulation_widget \ # src/testsuite/test-statistics # # disable : # # src/testsuite/test-global_preferences_serialization # # src/testsuite/test-parse_command # # src/testsuite/test-stepforward # src_testsuite_test_history_CPPFLAGS = \ # -I@top_srcdir@/src/backend \ # $(GLIBMM_CFLAGS) # src_testsuite_test_history_LDFLAGS = \ # -Wl,-rpath -Wl,"$(pkglibdir)" \ # src/backend/libbackend.la \ # $(GLIBMM_LIBS) # src_testsuite_test_history_SOURCES = \ # src/backend/concrete_environment.cc \ # src/backend/concrete_history.cc \ # src/backend/dynamic_process.cc \ # src/backend/dynamic_request.cc \ # src/backend/dynamic_resource.cc \ # src/backend/dynamic_schedulable.cc \ # src/backend/dynamic_sub_request.cc \ # src/backend/dynamic_thread.cc \ # src/backend/static_process.cc \ # src/backend/static_request.cc \ # src/backend/static_resource.cc \ # src/backend/static_schedulable.cc \ # src/backend/static_sub_request.cc \ # src/backend/static_thread.cc \ # src/testsuite/test-history.cc # src_testsuite_test_statistics_CPPFLAGS = \ # -I@top_srcdir@/src/backend \ # $(GLIBMM_CFLAGS) $(GTHREAD_CFLAGS) # src_testsuite_test_statistics_LDFLAGS = \ # -Wl,-rpath -Wl,"$(pkglibdir)" \ # src/backend/libbackend.la \ # $(GLIBMM_LIBS) $(GTHREAD_LIBS) # src_testsuite_test_statistics_SOURCES = \ # src/backend/statistics.cc \ # src/backend/concrete_process_statistics.cc \ # src/backend/concrete_thread_statistics.cc \ # src/backend/concrete_simulation_statistics.cc \ # src/backend/concrete_statistics.cc \ # src/testsuite/test-statistics.cc # #src_testsuite_test_global_preferences_serialization_CPPFLAGS = \ # # -I@top_srcdir@/src/backend \ # # $(GLIBMM_CFLAGS) # #src_testsuite_test_global_preferences_serialization_LDFLAGS = \ # # src/backend/libbackend.la \ # # -Wl,-rpath -Wl,"$(pkglibdir)" \ # # $(GLIBMM_LIBS) # #src_testsuite_test_global_preferences_serialization_SOURCES = \ # # src/testsuite/test-global_preferences_serialization.cc # src_testsuite_test_key_file_CPPFLAGS = \ # -I@top_srcdir@/src/backend \ # $(GLIBMM_CFLAGS) # src_testsuite_test_key_file_LDFLAGS = \ # -Wl,-rpath -Wl,"$(pkglibdir)" \ # src/backend/libbackend.la \ # $(GLIBMM_LIBS) # src_testsuite_test_key_file_SOURCES = \ # src/testsuite/test-key_file.cc # src_testsuite_test_cairo_widget_CPPFLAGS = \ # -I@top_srcdir@/src \ # -I@top_srcdir@/src/backend \ # $(CAIROMM_CFLAGS) \ # $(GTKMM_CFLAGS) \ # $(GLIBMM_CFLAGS) # src_testsuite_test_cairo_widget_LDFLAGS = \ # $(CAIROMM_LIBS) \ # $(GTKMM_LIBS) \ # $(GLIBMM_LIBS) # src_testsuite_test_cairo_widget_SOURCES = \ # src/cairo_elements.cc \ # src/cairo_widget.cc \ # src/testsuite/test-cairo_widget.cc # src_testsuite_test_simulation_widget_CPPFLAGS = \ # -I@top_srcdir@/src \ # -I@top_srcdir@/src/backend \ # $(CAIROMM_CFLAGS) \ # $(GTKMM_CFLAGS) \ # $(GLIBMM_CFLAGS) \ # $(GTHREAD_CFLAGS) # src_testsuite_test_simulation_widget_LDFLAGS = \ # src/backend/libbackend.la \ # -Wl,-rpath -Wl,"$(pkglibdir)" \ # $(CAIROMM_LIBS) \ # $(GTKMM_LIBS) \ # $(GLIBMM_LIBS) \ # $(GTHREAD_LIBS) # src_testsuite_test_simulation_widget_SOURCES = \ # src/cairo_elements.cc \ # src/cairo_widget.cc \ # src/simulation_widget.cc \ # src/testsuite/test-simulation_widget.cc # src_testsuite_test_holt_widget_CPPFLAGS = \ # -I@top_srcdir@/src \ # -I@top_srcdir@/src/backend \ # $(CAIROMM_CFLAGS) \ # $(GTKMM_CFLAGS) \ # $(GLIBMM_CFLAGS) \ # $(GTHREAD_CFLAGS) # src_testsuite_test_holt_widget_LDFLAGS = \ # src/backend/libbackend.la \ # -Wl,-rpath -Wl,"$(pkglibdir)" \ # $(CAIROMM_LIBS) \ # $(GTKMM_LIBS) \ # $(GLIBMM_LIBS) \ # $(GTHREAD_LIBS) # src_testsuite_test_holt_widget_SOURCES = \ # src/cairo_elements.cc \ # src/cairo_widget.cc \ # src/simulation_widget.cc \ # src/holt_container_window.cc \ # src/holt_widget.cc \ # src/testsuite/test-holt_widget.cc # #src_testsuite_test_parse_command_CPPFLAGS = \ # # -I@top_srcdir@/src \ # # -I@top_srcdir@/src/templates \ # # $(GLIBMM_CFLAGS) # #src_testsuite_test_parse_command_LDFLAGS = \ # # src/backend/libbackend.la \ # # -Wl,-rpath -Wl,"$(pkglibdir)" \ # # $(GLIBMM_LIBS) # #src_testsuite_test_parse_command_SOURCES = \ # # src/testsuite/test-parse_command.cc # # advice: get dummy_policy from the somewhere in the repository, and compile it in. # #src_testsuite_test_stepforward_CPPFLAGS = \ # # -I@top_srcdir@/src \ # # -I@top_srcdir@/src/templates \ # # $(GLIBMM_CFLAGS) # #src_testsuite_test_stepforward_LDFLAGS = \ # # src/backend/libbackend.la \ # # -Wl,-rpath -Wl,"$(pkglibdir)" \ # # $(GLIBMM_LIBS) # #src_testsuite_test_stepforward_SOURCES = \ # # src/testsuite/stubs/history.cc \ # # src/testsuite/stubs/prrpolicy.cc \ # # src/testsuite/stubs/policy_manager.cc \ # # src/backend/scheduler.cc \ # # src/testsuite/test-stepforward.cc # # Workaround an automake bug that leaves behind some files # # while it's finishing the distcheck target # CLEANFILES += \ # src/testsuite/.libs/test-cairo_widget \ # src/testsuite/.libs/test-history \ # src/testsuite/.libs/test-holt_widget \ # src/testsuite/.libs/test-key_file \ # src/testsuite/.libs/test-simulation_widget \ # src/testsuite/.libs/test-statistics # # disabled: # # src/testsuite/.libs/test-global_preferences_serialization # endif #~ if COND_TESTS # # ############################################################ # # # # extra files to distribute # # # # ############################################################ # noinst_DATA += \ # src/testsuite/scheduling-wizards/wizard-deadlock-test \ # src/testsuite/scheduling-wizards/wizard-gap-fail \ # src/testsuite/scheduling-wizards/wizard-assert-fail \ # src/testsuite/scheduling-wizards/wizard-unblock-test \ # src/testsuite/scheduling-wizards/wizard-complex-test \ # src/testsuite/scheduling-wizards/wizard-priority-inversion-porno \ # src/testsuite/scheduling-wizards/wizard-priority-preemption-fail \ # src/testsuite/scheduling-wizards/wizard-block-fail # examples_DATA = \ # src/testsuite/scheduling-wizards/environments/Colori_rr_prio_1_2.xgp \ # src/testsuite/scheduling-wizards/environments/DiscWorld_unblock.xgp \ # src/testsuite/scheduling-wizards/environments/Ducks_rr_2.xgp \ # src/testsuite/scheduling-wizards/environments/FruitsBasket_complex.xgp \ # src/testsuite/scheduling-wizards/environments/Fantozzi_lifo_requests.xgp \ # src/testsuite/scheduling-wizards/environments/Matteo_deadlock.xgp \ # src/testsuite/scheduling-wizards/environments/Matteo_preemption_fail.xgp \ # src/testsuite/scheduling-wizards/environments/Modernita_gap_terminated.xgp \ # src/testsuite/scheduling-wizards/environments/MyAutoDeadlock.xgp \ # src/testsuite/scheduling-wizards/environments/Pensieri_fcfs.xgp \ # src/testsuite/scheduling-wizards/environments/Porno_priority_inversion.xgp \ # src/testsuite/scheduling-wizards/environments/ScuolaDiMileto_block_fail.xgp \ # src/testsuite/scheduling-wizards/environments/ScuolaDiMileto_gap_blocked.xgp \ # src/testsuite/scheduling-wizards/environments/ScuolaDiMileto_assert_fail.xgp \ # src/testsuite/scheduling-wizards/environments/ScuolaDiMileto_gap_fail.xgp \ # src/testsuite/scheduling-wizards/environments/TheSecretOfMonkeyIsland.xgp # EXTRA_DIST += $(noinst_DATA) $(examples_DATA) # ------------------------------------------- install(FILES data/logo.png ui/add-process-dialog.ui ui/add-request-dialog.ui ui/add-resource-dialog.ui ui/add-thread-dialog.ui ui/configure-dialog.ui ui/jump-to-dialog.ui ui/main-window.ui ui/statistics-window.ui DESTINATION ${uidir}) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/sgpemv2.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/data/sgpemv2.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons) # TODO: create the export set