diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml index b0582318..df172828 100644 --- a/.github/workflows/cmake-multi-platform.yml +++ b/.github/workflows/cmake-multi-platform.yml @@ -90,6 +90,9 @@ jobs: -DFORTE_MODULE_RT_Events=ON -DFORTE_MODULE_SIGNALPROCESSING=ON -DFORTE_MODULE_UTILS=ON + -DFORTE_BUILD_STATIC_LIBRARY=ON + -DFORTE_BUILD_SHARED_LIBRARY=ON + -DFORTE_C_INTERFACE=ON -DFORTE_TESTS=ON -DFORTE_TEST_SANITIZE=ON ${{ matrix.os == 'windows-latest' && format('-DFORTE_TESTS_INC_DIRS={0}/boost.1.84.0/lib/native/include', github.workspace) || '' }} diff --git a/CMakeLists.txt b/CMakeLists.txt index d7d25f4e..bebe4e72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,7 @@ # Copyright (c) 2010 - 2015 Profactor GmbH, AIT, fortiss GmbH # 2010-2015, 2020 TU Wien/ACIN # 2022 Martin Erich Jobst +# 2024 Jose Cabral # # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at @@ -62,6 +63,9 @@ mark_as_advanced(FORTE_BUILD_STATIC_LIBRARY) set(FORTE_BUILD_SHARED_LIBRARY OFF CACHE BOOL "Build FORTE as shared library") mark_as_advanced(FORTE_BUILD_SHARED_LIBRARY) +SET(FORTE_C_INTERFACE OFF CACHE BOOL "Build C interface to Forte") +mark_as_advanced(FORTE_C_INTERFACE) + ####################################################################################### # Determine the loglevel ####################################################################################### diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ddfc2e58..6059cd0b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -33,47 +33,6 @@ forte_add_sourcefile_with_path_hcpp(${FORTE_BINARY_DIR}/stringlist) set_source_files_properties(${FORTE_BINARY_DIR}/stringlist.h PROPERTIES GENERATED TRUE) set_source_files_properties(${FORTE_BINARY_DIR}/stringlist.cpp PROPERTIES GENERATED TRUE) -####################################################################################### -# Define global Include-directorys -####################################################################################### - -forte_add_include_directories(./) -forte_add_include_directories(${FORTE_BINARY_DIR}) -forte_add_include_directories(${FORTE_BINARY_DIR}/src_gen) - -GET_PROPERTY(INCLUDE_DIRECTORIES GLOBAL PROPERTY FORTE_INCLUDE_DIRECTORIES) - -LIST(LENGTH INCLUDE_DIRECTORIES len) -IF(len GREATER 0) - LIST(REMOVE_DUPLICATES INCLUDE_DIRECTORIES) - LIST(REVERSE INCLUDE_DIRECTORIES) # bugfix, for replaced include files -ENDIF(len GREATER 0) - -GET_PROPERTY(INCLUDE_SYSTEM_DIRECTORIES GLOBAL PROPERTY FORTE_INCLUDE_SYSTEM_DIRECTORIES) -LIST(LENGTH INCLUDE_SYSTEM_DIRECTORIES len) -IF(len GREATER 0) - LIST(REMOVE_DUPLICATES INCLUDE_SYSTEM_DIRECTORIES) - LIST(REVERSE INCLUDE_SYSTEM_DIRECTORIES) # bugfix, for replaced include files -ENDIF(len GREATER 0) - -INCLUDE_DIRECTORIES(${INCLUDE_DIRECTORIES}) -INCLUDE_DIRECTORIES(SYSTEM ${INCLUDE_SYSTEM_DIRECTORIES}) -####################################################################################### -# Define directories for Libraries -####################################################################################### -GET_PROPERTY(LINK_DIRECTORIES GLOBAL PROPERTY FORTE_LINK_DIRECTORIES) -LIST(LENGTH LINK_DIRECTORIES len) -IF(len GREATER 0) - LIST(REMOVE_DUPLICATES LINK_DIRECTORIES) -ENDIF(len GREATER 0) -LINK_DIRECTORIES(${LINK_DIRECTORIES}) - -####################################################################################### -# Define directories for Libraries -####################################################################################### -GET_PROPERTY(DEFINITION GLOBAL PROPERTY FORTE_DEFINITION) -ADD_DEFINITIONS (${DEFINITION}) - ####################################################################################### # Exclude FBs ####################################################################################### @@ -95,40 +54,6 @@ FOREACH(FB ${PLATFORM_REMOVES}) forte_remove_sourcefile_cpp(${FB}.cpp) ENDFOREACH(FB) -####################################################################################### -# Setup Forte with all Functionblocks -####################################################################################### - -#forte init is needed for the temporary forte library, which then is linked to the main.cpp - -forte_add_sourcefile_with_path_hcpp(${FORTE_BINARY_DIR}/forteinit) -set_source_files_properties(${FORTE_BINARY_DIR}/forteinit.h PROPERTIES GENERATED TRUE) -set_source_files_properties(${FORTE_BINARY_DIR}/forteinit.cpp PROPERTIES GENERATED TRUE) - -GET_PROPERTY(SOURCE_TIMER_CPP GLOBAL PROPERTY FORTE_TIMER_CPP) -GET_PROPERTY(SOURCE_TIMER_H GLOBAL PROPERTY FORTE_TIMER_H) - -forte_add_sourcefile_with_path_h(${SOURCE_TIMER_H}) -forte_add_sourcefile_with_path_cpp(${SOURCE_TIMER_CPP}) - -GET_PROPERTY(SOURCE_H GLOBAL PROPERTY FORTE_SOURCE_H) -GET_PROPERTY(SOURCE_H_GROUP GLOBAL PROPERTY FORTE_SOURCE_H_GROUP) -LIST(APPEND SOURCE_FILES ${SOURCE_H}) -LIST(APPEND SOURCE_FILES_GROUP ${SOURCE_H_GROUP}) - -GET_PROPERTY(SOURCE_CPP GLOBAL PROPERTY FORTE_SOURCE_CPP) -GET_PROPERTY(SOURCE_CPP_GROUP_STRUCT GLOBAL PROPERTY FORTE_SOURCE_CPP_GROUP) -LIST(APPEND SOURCE_FILES ${SOURCE_CPP}) -LIST(APPEND SOURCE_FILES_GROUP ${SOURCE_CPP_GROUP_STRUCT}) - -GET_PROPERTY(SOURCE_C GLOBAL PROPERTY FORTE_SOURCE_C) -GET_PROPERTY(SOURCE_C_GROUP_STRUCT GLOBAL PROPERTY FORTE_SOURCE_C_GROUP) -LIST(APPEND SOURCE_FILES ${SOURCE_C}) -LIST(APPEND SOURCE_FILES_GROUP ${SOURCE_C_GROUP_STRUCT}) - -GET_PROPERTY(SOURCE_EXECUTABLE_CPP GLOBAL PROPERTY FORTE_EXECUTABLE_CPP) -GET_PROPERTY(SOURCE_EXECUTABLE_H GLOBAL PROPERTY FORTE_EXECUTABLE_H) - ############################################################################# # Configure Network Layers ############################################################################# @@ -213,6 +138,7 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/arch/startuphook.cpp.in ${CMAKE_BINAR forte_replacefile_if_changed(${CMAKE_BINARY_DIR}/src_gen/startuphook_new.cpp ${CMAKE_BINARY_DIR}/src_gen/startuphook.cpp) file(REMOVE ${CMAKE_BINARY_DIR}/src_gen/startuphook_new.cpp) + ############################################################################# # Load FORTE Extension Files ############################################################################# @@ -226,6 +152,40 @@ IF(len GREATER 0) ENDFOREACH(FILE) ENDIF(len GREATER 0) +####################################################################################### +# Setup Forte with all Functionblocks +####################################################################################### + +#forte init is needed for the temporary forte library, which then is linked to the main.cpp + +forte_add_sourcefile_with_path_hcpp(${FORTE_BINARY_DIR}/forteinit) +set_source_files_properties(${FORTE_BINARY_DIR}/forteinit.h PROPERTIES GENERATED TRUE) +set_source_files_properties(${FORTE_BINARY_DIR}/forteinit.cpp PROPERTIES GENERATED TRUE) + +GET_PROPERTY(SOURCE_TIMER_CPP GLOBAL PROPERTY FORTE_TIMER_CPP) +GET_PROPERTY(SOURCE_TIMER_H GLOBAL PROPERTY FORTE_TIMER_H) + +forte_add_sourcefile_with_path_h(${SOURCE_TIMER_H}) +forte_add_sourcefile_with_path_cpp(${SOURCE_TIMER_CPP}) + +GET_PROPERTY(SOURCE_H GLOBAL PROPERTY FORTE_SOURCE_H) +GET_PROPERTY(SOURCE_H_GROUP GLOBAL PROPERTY FORTE_SOURCE_H_GROUP) +LIST(APPEND SOURCE_FILES ${SOURCE_H}) +LIST(APPEND SOURCE_FILES_GROUP ${SOURCE_H_GROUP}) + +GET_PROPERTY(SOURCE_CPP GLOBAL PROPERTY FORTE_SOURCE_CPP) +GET_PROPERTY(SOURCE_CPP_GROUP_STRUCT GLOBAL PROPERTY FORTE_SOURCE_CPP_GROUP) +LIST(APPEND SOURCE_FILES ${SOURCE_CPP}) +LIST(APPEND SOURCE_FILES_GROUP ${SOURCE_CPP_GROUP_STRUCT}) + +GET_PROPERTY(SOURCE_C GLOBAL PROPERTY FORTE_SOURCE_C) +GET_PROPERTY(SOURCE_C_GROUP_STRUCT GLOBAL PROPERTY FORTE_SOURCE_C_GROUP) +LIST(APPEND SOURCE_FILES ${SOURCE_C}) +LIST(APPEND SOURCE_FILES_GROUP ${SOURCE_C_GROUP_STRUCT}) + +GET_PROPERTY(SOURCE_EXECUTABLE_CPP GLOBAL PROPERTY FORTE_EXECUTABLE_CPP) +GET_PROPERTY(SOURCE_EXECUTABLE_H GLOBAL PROPERTY FORTE_EXECUTABLE_H) + ############################################################################# # Add Files to source-group ############################################################################# @@ -270,17 +230,10 @@ set_property(CACHE FORTE_DEVICE PROPERTY STRINGS None ${devices}) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/forte_device_config.h.in ${CMAKE_BINARY_DIR}/forte_device_config.h) -####################################################################################### -# Link Libraries to the Executable -####################################################################################### -# get Linker-Directories from Modules -get_property(LINK_LIBRARY GLOBAL PROPERTY FORTE_LINK_LIBRARY) - ####################################################################################### # Create Files ####################################################################################### - # setting the C++ version has to be done directly before defining the targets only then modules can override this setting if(NOT DEFINED CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 17) @@ -291,6 +244,25 @@ if(NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED) set(CMAKE_CXX_STANDARD_REQUIRED ON) endif() +####################################################################################### +# Create an object library with all configurations needed which +# is then used by the others targets +####################################################################################### +set(FORTE_BASE_TARGET_NAME FORTE_LITE) +add_library(${FORTE_BASE_TARGET_NAME} OBJECT ${SOURCE_FILES}) #no executables. +target_compile_features(${FORTE_BASE_TARGET_NAME} PUBLIC cxx_std_17) + +####################################################################################### +# Link Libraries to the Executable +####################################################################################### +# get Linker-Directories from Modules +get_property(LINK_LIBRARY GLOBAL PROPERTY FORTE_LINK_LIBRARY) +target_link_libraries(${FORTE_BASE_TARGET_NAME} INTERFACE ${LINK_LIBRARY}) + +####################################################################################### +# Define global link flags +####################################################################################### + get_property(existing_link_flags GLOBAL PROPERTY LINK_FLAGS) if(existing_link_flags) set_property(GLOBAL APPEND PROPERTY FORTE_LINK_FLAGS ${existing_link_flags}) @@ -298,48 +270,143 @@ endif() GET_PROPERTY(link_flags GLOBAL PROPERTY FORTE_LINK_FLAGS) -add_library(FORTE_LITE OBJECT ${SOURCE_FILES}) #no executables. -TARGET_LINK_LIBRARIES (FORTE_LITE ${LINK_LIBRARY}) +target_link_options(${FORTE_BASE_TARGET_NAME} INTERFACE ${link_flags}) + +####################################################################################### +# Define global Include-directorys +####################################################################################### + +forte_add_include_directories(./) +forte_add_include_directories(${FORTE_BINARY_DIR}) +forte_add_include_directories(${FORTE_BINARY_DIR}/src_gen) + +GET_PROPERTY(INCLUDE_DIRECTORIES GLOBAL PROPERTY FORTE_INCLUDE_DIRECTORIES) + +LIST(LENGTH INCLUDE_DIRECTORIES len) +IF(len GREATER 0) + LIST(REMOVE_DUPLICATES INCLUDE_DIRECTORIES) + LIST(REVERSE INCLUDE_DIRECTORIES) # bugfix, for replaced include files +ENDIF(len GREATER 0) + +GET_PROPERTY(INCLUDE_SYSTEM_DIRECTORIES GLOBAL PROPERTY FORTE_INCLUDE_SYSTEM_DIRECTORIES) +LIST(LENGTH INCLUDE_SYSTEM_DIRECTORIES len) +IF(len GREATER 0) + LIST(REMOVE_DUPLICATES INCLUDE_SYSTEM_DIRECTORIES) + LIST(REVERSE INCLUDE_SYSTEM_DIRECTORIES) # bugfix, for replaced include files +ENDIF(len GREATER 0) + +target_include_directories(${FORTE_BASE_TARGET_NAME} PUBLIC ${INCLUDE_DIRECTORIES}) +target_include_directories(${FORTE_BASE_TARGET_NAME} SYSTEM PUBLIC ${INCLUDE_SYSTEM_DIRECTORIES}) + +####################################################################################### +# Define directories for Libraries +####################################################################################### +GET_PROPERTY(LINK_DIRECTORIES GLOBAL PROPERTY FORTE_LINK_DIRECTORIES) +LIST(LENGTH LINK_DIRECTORIES len) +IF(len GREATER 0) + LIST(REMOVE_DUPLICATES LINK_DIRECTORIES) +ENDIF(len GREATER 0) + +target_link_directories(${FORTE_BASE_TARGET_NAME} INTERFACE ${LINK_DIRECTORIES}) -list(JOIN link_flags " " link_flags_string) +####################################################################################### +# Define compile definitions +####################################################################################### +GET_PROPERTY(DEFINITIONS GLOBAL PROPERTY FORTE_DEFINITION) +# the following should be added to the ${FORTE_BASE_TARGET_NAME} target, but it +# was not working in windows for some reason +ADD_DEFINITIONS(${DEFINITIONS}) set(FORTE_LINK_STATIC OFF CACHE BOOL "Force static linking of forte binary") if(FORTE_BUILD_EXECUTABLE) - ADD_EXECUTABLE (forte $ ${SOURCE_EXECUTABLE_CPP} ${FORTE_EXECUTABLE_H}) - set_target_properties(forte PROPERTIES LINK_FLAGS "${link_flags_string}") + SET(FORTE_EXECUTABLE_NAME forte) + ADD_EXECUTABLE (${FORTE_EXECUTABLE_NAME} ${SOURCE_EXECUTABLE_CPP} ${FORTE_EXECUTABLE_H}) if (FORTE_LINK_STATIC) - set_target_properties(forte PROPERTIES LINK_SEARCH_START_STATIC ON) - set_target_properties(forte PROPERTIES LINK_SEARCH_END_STATIC ON) - target_link_options(forte PRIVATE -static-libgcc -static-libstdc++ -static) + set_target_properties(${FORTE_EXECUTABLE_NAME} PROPERTIES LINK_SEARCH_START_STATIC ON) + set_target_properties(${FORTE_EXECUTABLE_NAME} PROPERTIES LINK_SEARCH_END_STATIC ON) + target_link_options(${FORTE_EXECUTABLE_NAME} PRIVATE -static-libgcc -static-libstdc++ -static) endif() - target_compile_features(forte PUBLIC cxx_std_17) - TARGET_LINK_LIBRARIES (forte ${LINK_LIBRARY}) - ADD_DEPENDENCIES (forte FORTE_LITE) + TARGET_LINK_LIBRARIES (forte PUBLIC ${FORTE_BASE_TARGET_NAME}) install(TARGETS forte RUNTIME DESTINATION bin) message("Building executable") endif(FORTE_BUILD_EXECUTABLE) if(FORTE_BUILD_STATIC_LIBRARY) - ADD_LIBRARY (forte-static STATIC $) - set_target_properties(forte-static PROPERTIES LINK_FLAGS "${link_flags_string}") - target_compile_features(forte-static PUBLIC cxx_std_17) - TARGET_LINK_LIBRARIES (forte-static ${LINK_LIBRARY}) - ADD_DEPENDENCIES (forte-static FORTE_LITE) - install(TARGETS forte-static ARCHIVE DESTINATION bin) + SET(FORTE_STATIC_LIBRARY_NAME forte-static) + ADD_LIBRARY (${FORTE_STATIC_LIBRARY_NAME} STATIC) + TARGET_LINK_LIBRARIES (${FORTE_STATIC_LIBRARY_NAME} PUBLIC ${FORTE_BASE_TARGET_NAME}) + install(TARGETS ${FORTE_STATIC_LIBRARY_NAME} ARCHIVE DESTINATION bin) message("Building static library") endif(FORTE_BUILD_STATIC_LIBRARY) if(FORTE_BUILD_SHARED_LIBRARY) - ADD_LIBRARY (forte-shared SHARED $) - set_target_properties(forte-shared PROPERTIES LINK_FLAGS "${link_flags_string}") - target_compile_features(forte-shared PUBLIC cxx_std_17) - TARGET_LINK_LIBRARIES (forte-shared ${LINK_LIBRARY}) - ADD_DEPENDENCIES (forte-shared FORTE_LITE) - install(TARGETS forte-shared ARCHIVE DESTINATION bin LIBRARY DESTINATION bin) + if(WIN32) + message(WARNING "Shared library in windows might not be linkable.") + endif(WIN32) + + SET(FORTE_SHARED_LIBRARY_NAME forte-shared) + + ADD_LIBRARY (${FORTE_SHARED_LIBRARY_NAME} SHARED) + TARGET_LINK_LIBRARIES (${FORTE_SHARED_LIBRARY_NAME} PUBLIC ${FORTE_BASE_TARGET_NAME}) + install(TARGETS ${FORTE_SHARED_LIBRARY_NAME} ARCHIVE DESTINATION bin) + set_property(TARGET ${FORTE_BASE_TARGET_NAME} PROPERTY POSITION_INDEPENDENT_CODE ON) + + set_target_properties(${WINDOWS_EXPORT_ALL_SYMBOLS} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) + message("Building shared library") endif(FORTE_BUILD_SHARED_LIBRARY) +if(FORTE_C_INTERFACE) + # function for configuring common things in both static and shared c libraries + FUNCTION(commonCLibraryConfiguration TARGET_NAME) + set_target_properties(${TARGET_NAME} + PROPERTIES PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/arch/c_interface/forte_c.h) + + TARGET_LINK_LIBRARIES (${TARGET_NAME} PUBLIC ${FORTE_BASE_TARGET_NAME}) + install(TARGETS ${TARGET_NAME} + LIBRARY DESTINATION bin + PUBLIC_HEADER DESTINATION include) + ENDFUNCTION() + + SET(FORTE_C_LIBRARY_NAME "forte-c") + + if(FORTE_BUILD_STATIC_LIBRARY) + SET(FORTE_C_LIBRARY_STATIC_NAME ${FORTE_C_LIBRARY_NAME}-static) + ADD_LIBRARY (${FORTE_C_LIBRARY_STATIC_NAME} STATIC ${CMAKE_CURRENT_SOURCE_DIR}/arch/c_interface/forte_c.cpp) + commonCLibraryConfiguration(${FORTE_C_LIBRARY_STATIC_NAME}) + message("Building C interface static library") + endif(FORTE_BUILD_STATIC_LIBRARY) + + if(FORTE_BUILD_SHARED_LIBRARY) + SET(FORTE_C_LIBRARY_SHARED_NAME ${FORTE_C_LIBRARY_NAME}-shared) + ADD_LIBRARY (${FORTE_C_LIBRARY_SHARED_NAME} SHARED ${CMAKE_CURRENT_SOURCE_DIR}/arch/c_interface/forte_c.cpp) + + # hide all symbols except the ones from the C interface + # NOTE: This is still not working. The dynamic symbols are still being exported + # --exclude-libs is an option for gcc but it does not work with OBJECT libraries + # Exporting the dynamic symbols makes the loading time of the library longer + # but it still can be used as usual + set_target_properties(${FORTE_C_LIBRARY_SHARED_NAME} PROPERTIES + CXX_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN ON) + set_target_properties(${FORTE_C_LIBRARY_SHARED_NAME} PROPERTIES + C_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN ON) + + IF (WIN32 OR CYGWIN) + SET(FORTE_SHARED_PREFIX "__declspec(dllexport)") + else() + SET(FORTE_SHARED_PREFIX "__attribute__((visibility(\"default\")))") + endif() + target_compile_definitions(${FORTE_C_LIBRARY_SHARED_NAME} PRIVATE FORTE_SHARED_PREFIX=${FORTE_SHARED_PREFIX}) + + commonCLibraryConfiguration(${FORTE_C_LIBRARY_SHARED_NAME}) + message("Building C interface shared library") + endif(FORTE_BUILD_SHARED_LIBRARY) + +endif(FORTE_C_INTERFACE) + ####################################################################################### # Generate stringlist and modules ####################################################################################### @@ -347,14 +414,14 @@ endif(FORTE_BUILD_SHARED_LIBRARY) #forte init is needed for the temporary forte library, which then is linked to the main.cpp ADD_CUSTOM_TARGET(forte_init_generator COMMAND ${CMAKE_COMMAND} -DFORTE_BINARY_DIR:STRING="${CMAKE_BINARY_DIR}" -DFORTE_SOURCE_DIR:STRING="${CMAKE_SOURCE_DIR}" -DFORTE_LITTLE_ENDIAN:STRING=${FORTE_LITTLE_ENDIAN} -DFORTE_BIG_ENDIAN:STRING=${FORTE_BIG_ENDIAN} -DFORTE_LOGLEVEL:STRING="${FORTE_LOGLEVEL}" -P ${FORTE_BUILDSUPPORT_DIRECTORY}/generate_init.cmake) # ADD_DEPENDENCIES (forte_init_generator forte_generate_modules_cmake_files) -ADD_DEPENDENCIES (FORTE_LITE forte_init_generator) +ADD_DEPENDENCIES (${FORTE_BASE_TARGET_NAME} forte_init_generator) ADD_CUSTOM_TARGET(forte_generate_modules_cmake_files COMMAND ${CMAKE_COMMAND} -DFORTE_MODULE_LIST:LISTS="${FORTE_MODULE_LIST}" -P ${FORTE_BUILDSUPPORT_DIRECTORY}/generate_modules_cmake_file.cmake) ADD_CUSTOM_TARGET(forte_stringlist_generator COMMAND ${CMAKE_COMMAND} -DFORTE_LINKED_STRINGDICT:STRING="${FORTE_LINKED_STRINGDICT}" -DFORTE_BINARY_DIR:STRING="${CMAKE_BINARY_DIR}" -DFORTE_SOURCE_DIR:STRING="${CMAKE_CURRENT_SOURCE_DIR}" -P ${FORTE_BUILDSUPPORT_DIRECTORY}/generate_stringlist.cmake) -ADD_DEPENDENCIES (FORTE_LITE forte_stringlist_generator) +ADD_DEPENDENCIES (${FORTE_BASE_TARGET_NAME} forte_stringlist_generator) ADD_DEPENDENCIES (forte_stringlist_generator forte_generate_modules_cmake_files) ####################################################################################### @@ -362,7 +429,7 @@ ADD_DEPENDENCIES (forte_stringlist_generator forte_generate_modules_cmake_files) ####################################################################################### if(FORTE_LINKED_STRINGDICT) set(ENABLE_GENERATED_SOURCE_CPP ON) - ADD_DEPENDENCIES (FORTE_LITE forte_stringlist_externals) + ADD_DEPENDENCIES (${FORTE_BASE_TARGET_NAME} forte_stringlist_externals) endif(FORTE_LINKED_STRINGDICT) ####################################################################################### @@ -384,9 +451,15 @@ if(NOT LEN_POST_BUILD_COM EQUAL 0) if(FORTE_BUILD_STATIC_LIBRARY) ADD_CUSTOM_COMMAND(TARGET forte-static POST_BUILD ${POST_BUILD_COM}) + if(FORTE_C_INTERFACE) + ADD_CUSTOM_COMMAND(TARGET forte-c-static POST_BUILD ${POST_BUILD_COM}) + endif(FORTE_C_INTERFACE) endif(FORTE_BUILD_STATIC_LIBRARY) if(FORTE_BUILD_SHARED_LIBRARY) ADD_CUSTOM_COMMAND(TARGET forte-shared POST_BUILD ${POST_BUILD_COM}) + if(FORTE_C_INTERFACE) + ADD_CUSTOM_COMMAND(TARGET forte-c-shared POST_BUILD ${POST_BUILD_COM}) + endif(FORTE_C_INTERFACE) endif(FORTE_BUILD_SHARED_LIBRARY) endif(NOT LEN_POST_BUILD_COM EQUAL 0) diff --git a/src/arch/CMakeLists.txt b/src/arch/CMakeLists.txt index f23c0f5a..3c25c593 100644 --- a/src/arch/CMakeLists.txt +++ b/src/arch/CMakeLists.txt @@ -1,5 +1,5 @@ #******************************************************************************* -# Copyright (c) 2010 - 2018 ACIN +# Copyright (c) 2010 - 2024 ACIN, Jose Cabral # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at # http://www.eclipse.org/legal/epl-2.0. @@ -30,7 +30,7 @@ add_subdirectory(zephyr) add_subdirectory(utils) -forte_add_sourcefile_hcpp(timerha devlog) +forte_add_sourcefile_hcpp(timerha devlog forte_architecture) SET(FORTE_LOGGER_BUFFER_SIZE "300" CACHE STRING "Buffer's length of the logger") mark_as_advanced(FORTE_LOGGER_BUFFER_SIZE) @@ -64,6 +64,4 @@ if (FORTE_STACKTRACE) endif () endif () -forte_add_sourcefile_with_path_cpp(${CMAKE_BINARY_DIR}/src_gen/startuphook.cpp) # created file - - +forte_add_sourcefile_with_path_cpp(${CMAKE_BINARY_DIR}/src_gen/startuphook.cpp) diff --git a/src/arch/ecos/forte_instance.cpp b/src/arch/c_interface/forte_c.cpp similarity index 52% rename from src/arch/ecos/forte_instance.cpp rename to src/arch/c_interface/forte_c.cpp index 9cdd5fe2..9c379ecc 100644 --- a/src/arch/ecos/forte_instance.cpp +++ b/src/arch/c_interface/forte_c.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 fortiss GmbH + * Copyright (c) 2018 - 2024 fortiss GmbH, Jose Cabral * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. @@ -11,42 +11,40 @@ * Tarik Terzimehic - make OPC UA server port setable from the command line *******************************************************************************/ -#include "forte_instance.h" -#include "forteinstance.h" -#include - -#include "fortenew.h" -#include "forte_architecture.h" -#include -#include -#include "../../stdfblib/ita/RMT_DEV.h" +#include "forte_c.h" #include "../utils/mainparam_utils.h" +#include "forte_architecture.h" +#include "forte_printer.h" +#include "forteinstance.h" -unsigned const int cgForteDefaultPort = 61499; +namespace { + const unsigned int defaultPort = 61499; + const unsigned int maxPortValue = 65535; +} -/*!\brief Check if the correct endianess has been configured. - * - * If the right endianess is not set this function will end FORTE. - */ +/** +* @brief Check if the correct endianess has been configured. +*/ bool checkEndianess(); -void forteGlobalInitialize(){ - CForteArchitecture::initialize(); +int forteGlobalInitialize(int argc, char *argv[]){ + return CForteArchitecture::initialize(argc, argv); } -void forteGlobalDeinitialize(){ - CForteArchitecture::deinitialize(); +int forteGlobalDeinitialize(){ + return CForteArchitecture::deinitialize(); } -int forteStartInstance(unsigned int paPort, TForteInstance* paResultInstance){ +FORTE_STATUS forteStartInstance(unsigned int paPort, TForteInstance* paResultInstance){ - if(65535 < paPort){ + if(maxPortValue < paPort){ + DEVLOG_ERROR("Provided port %d is not valid\n", paPort); return FORTE_WRONG_PARAMETERS; } if(0 == paPort){ - paPort = cgForteDefaultPort; + paPort = defaultPort; } char progName[] = "forte"; @@ -60,50 +58,59 @@ int forteStartInstance(unsigned int paPort, TForteInstance* paResultInstance){ return forteStartInstanceGeneric(3, arguments, paResultInstance); } -int forteStartInstanceGeneric(int argc, char *arg[], TForteInstance* paResultInstance){ +FORTE_STATUS forteStartInstanceGeneric(int argc, char *argv[], TForteInstance* paResultInstance){ - if(!CForteArchitecture::isInitialized()){ - return FORTE_ARCHITECTURE_NOT_READY; - } - - if(0 == paResultDevice){ + if(nullptr == paResultInstance){ + DEVLOG_ERROR("Provided result instance parameter is not valid\n"); return FORTE_WRONG_PARAMETERS; } - if(0 != *paResultDevice){ + if(nullptr != *paResultInstance){ + DEVLOG_ERROR("Provided result instance already started\n"); return FORTE_DEVICE_ALREADY_STARTED; } if(!checkEndianess()){ + // logged already in the function return FORTE_WRONG_ENDIANESS; } - const char *pIpPort = parseCommandLineArguments(argc, arg); - if((0 != strlen(pIpPort)) && (nullptr != strchr(pIpPort, ':'))){ - C4diacFORTEInstance *instance = new C4diacFORTEInstance(); - if(!instance->startupNewDevice(ipPort)) { - delete instance; - return FORTE_COULD_NOT_CREATE_DEVICE; - } - *paResultInstance = instance; - DEVLOG_INFO("FORTE is up and running\n"); + if(!CForteArchitecture::isInitialized()){ + DEVLOG_ERROR("The low level platform should be initialized before starting a forte instance\n"); + return FORTE_ARCHITECTURE_NOT_READY; } - else{ //! If needed call listHelp() to list the help for FORTE + + const auto ipPort = parseCommandLineArguments(argc, argv); + if((0 == strlen(ipPort)) || (nullptr == strchr(ipPort, ':'))){ + listHelp(); return FORTE_WRONG_PARAMETERS; } + + C4diacFORTEInstance *instance = new C4diacFORTEInstance(); + if(!instance->startupNewDevice(ipPort)) { + delete instance; + return FORTE_COULD_NOT_CREATE_DEVICE; + } + *paResultInstance = instance; return FORTE_OK; } -void forteStopInstance(int, TForteInstance paInstance){ - if(!CForteArchitecture::isInitialized() || paResultInstance == nullptr){ +void forteRequestStopInstance(TForteInstance paInstance){ + if(!CForteArchitecture::isInitialized() || paInstance == nullptr){ return; } - C4diacFORTEInstance *instance = static_cast(paResultInstance); + auto *instance = static_cast(paInstance); instance->triggerDeviceShutdown(); +} + +void forteWaitForInstanceToStop(TForteInstance paInstance) { + if(!CForteArchitecture::isInitialized() || paInstance == nullptr){ + return; + } + auto *instance = static_cast(paInstance); instance->awaitDeviceShutdown(); delete instance; - DEVLOG_INFO("FORTE finished\n"); } bool checkEndianess(){ diff --git a/src/arch/c_interface/forte_c.h b/src/arch/c_interface/forte_c.h new file mode 100644 index 00000000..6663274a --- /dev/null +++ b/src/arch/c_interface/forte_c.h @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2018 - 2024 fortiss GmbH, Jose Cabral + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Jose Cabral - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#ifndef SRC_ARCH_FORTE_C_H_ +#define SRC_ARCH_FORTE_C_H_ + +#ifndef FORTE_SHARED_PREFIX + #define FORTE_SHARED_PREFIX +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + typedef enum FORTE_STATUS{ + FORTE_OK = 0, + FORTE_DEVICE_ALREADY_STARTED, + FORTE_WRONG_ENDIANESS, + FORTE_WRONG_PARAMETERS, + FORTE_ARCHITECTURE_NOT_READY, + FORTE_COULD_NOT_CREATE_DEVICE, + } FORTE_STATUS; + + typedef void* TForteInstance; + + /** + * \brief Start forte instance + * @param paPort The port on which forte will listen. Use 0 for default 61499 + * @param paResultInstance Address to store the created forte instance + * @return FORTE_OK if no error occurred, other values otherwise + */ + FORTE_SHARED_PREFIX FORTE_STATUS forteStartInstance(unsigned int paPort, TForteInstance* paResultInstance); + + /** + * \brief Start forte instance with posibilities of more arguments + * @param argc Number of arguments in arg + * @param argv Arguments + * @param paResultInstance Address to store the created forte instance + * @return FORTE_OK if no error occurred, other values otherwise + */ + FORTE_SHARED_PREFIX FORTE_STATUS forteStartInstanceGeneric(int argc, char *argv[], TForteInstance* paResultInstance); + + /** + * \brief Request termination of a Forte instance + * @param paInstance Instance to request for termination + */ + FORTE_SHARED_PREFIX void forteRequestStopInstance(TForteInstance paInstance); + + /** + * \brief Waits indefinitely for the intance to stop and deletes it + * @param paInstance Instance to terminate + */ + FORTE_SHARED_PREFIX void forteWaitForInstanceToStop(TForteInstance paInstance); + + /** + * \brief Initializes the architecture. Prepare all resources needed by the Forte's instances. Must be called once before the first Forte instance is started + * @param argc Number of arguments in arg + * @param argv Arguments + * @return 0 if no error occurred, other values otherwise. Any error value is provided by the architecture and not by forte + */ + FORTE_SHARED_PREFIX int forteGlobalInitialize(int argc, char *argv[]); + + /** + * \brief Deinitializes the architecture. Frees all resources used by Forte's instances. Must be called after the last instance is ended + * @return 0 if no error occurred, other values otherwise. Any error value is provided by the architecture and not by forte + */ + FORTE_SHARED_PREFIX int forteGlobalDeinitialize(); + +#ifdef __cplusplus +} +#endif + +#endif /* SRC_ARCH_FORTE_C_H_ */ diff --git a/src/arch/win32/forte_instance.h b/src/arch/common/forte_specific_architecture.cpp similarity index 58% rename from src/arch/win32/forte_instance.h rename to src/arch/common/forte_specific_architecture.cpp index 08a422d3..e6a71707 100644 --- a/src/arch/win32/forte_instance.h +++ b/src/arch/common/forte_specific_architecture.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 fortiss GmbH + * Copyright (c) 2024 Jose Cabral * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. @@ -7,21 +7,15 @@ * SPDX-License-Identifier: EPL-2.0 * * Contributors: - * Jose Cabral, Alois Zoitl - initial API and implementation and/or initial documentation + * Jose Cabral - initial API and implementation and/or initial documentation *******************************************************************************/ -#ifndef FORTE_INSTANCE_H_ -#define FORTE_INSTANCE_H_ +#include "arch/forte_specific_architecture.h" -#ifdef __cplusplus -extern "C" { -#endif - -void startupFORTE(); -void shutdownFORTE(); - -#ifdef __cplusplus +int CForteSpecificArchitecture::initialize(int , char** ){ + return 0; } -#endif -#endif +int CForteSpecificArchitecture::deinitialize() { + return 0; +} diff --git a/src/arch/ecos/ecoscppinit.cpp b/src/arch/ecos/ecoscppinit.cpp index 80d21797..2a2e92ed 100644 --- a/src/arch/ecos/ecoscppinit.cpp +++ b/src/arch/ecos/ecoscppinit.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 - 2011 ACIN + * Copyright (c) 2010 - 2024 ACIN, Jose Cabral * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. @@ -11,11 +11,18 @@ *******************************************************************************/ #include -//current tests have shown that this works only if it is in the main.cpp file -//I don't know why. The best is to copy or include it into your specific main file - //Workaround for an ecos problem extern "C" void __cxa_pure_virtual(void) { //TODO maybe add some exception handling reporting here } + +extern "C" void abort(int ) { while(1) ; } + +void *__dso_handle = 0; + +extern "C" int _getpid(void) { + return 1; +} + +extern "C" void _kill(int ) { while(1) ; } \ No newline at end of file diff --git a/src/arch/ecos/forte_architecture.cpp b/src/arch/ecos/forte_architecture.cpp deleted file mode 100644 index 47d1b5c8..00000000 --- a/src/arch/ecos/forte_architecture.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2018 fortiss GmbH - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Jose Cabral - initial API and implementation and/or initial documentation - *******************************************************************************/ - -#include "../forte_architecture.h" -#include "forteinit.h" - - -extern "C" void abort(int ) { while(1) ; } - -void *__dso_handle = 0; - -extern "C" int _getpid(void) { - return 1; -} - -extern "C" void _kill(int ) { while(1) ; } - -bool CForteArchitecture::mInitialized = false; - -bool CForteArchitecture::initialize(){ - if (!mInitialized){ - initForte(); - mInitialized = true; - } - return true; -} - -void CForteArchitecture::deinitialize(){ - if(mInitialized){ - mInitialized = false; - } -} diff --git a/src/arch/ecos/forte_instance.h b/src/arch/ecos/forte_instance.h deleted file mode 100644 index 79483c61..00000000 --- a/src/arch/ecos/forte_instance.h +++ /dev/null @@ -1,84 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2018 fortiss GmbH - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Jose Cabral - initial API and implementation and/or initial documentation - *******************************************************************************/ - -#ifndef FORTE_INSTANCE_H_ -#define FORTE_INSTANCE_H_ - -/* When moving this file to the outside of the architecture, - * the corresponding defines for exporting in windows or other platform - * must be added here - * - */ -#ifndef FORTE_SHARED_PREFIX - #define FORTE_SHARED_PREFIX -#endif - -#ifndef FORTE_SHARED_CALL - #define FORTE_SHARED_CALL -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - - enum FORTE_STATUS{ - FORTE_OK, - FORTE_DEVICE_ALREADY_STARTED, - FORTE_WRONG_ENDIANESS, - FORTE_WRONG_PARAMETERS, - FORTE_ARCHITECTURE_NOT_READY, - FORTE_COULD_NOT_CREATE_DEVICE, - }; - - typedef void* TForteInstance; - - /** - * \brief Start forte instance - * @param pa_port The port on which to forte will listen. Use 0 for default (normally 61499) - * @param pa_resultDevice Address of an instance of forte - * @return FORTE_OK if no error occurred, other values otherwise - */ - FORTE_SHARED_PREFIX int FORTE_SHARED_CALL forteStartInstance(unsigned int pa_port, TForteInstance* paResultInstance); - - /** - * \brief Start forte instance with posibilities of more arguments - * @param argc Number of arguments in arg - * @param arg Arguments - * @param pa_resultDevice Address of an instance of forte - * @return FORTE_OK if no error occurred, other values otherwise - */ - FORTE_SHARED_PREFIX int FORTE_SHARED_CALL forteStartInstanceGeneric(int argc, char *arg[], TForteInstance* paResultInstance); - - /** - * \brief Terminates a Forte instance - * @param signal Signal value to terminate instance - * @param pa_resultDevice Instance to terminate - */ - FORTE_SHARED_PREFIX void FORTE_SHARED_CALL forteStopInstance(int signal, TForteInstance paInstance); - - /** - * \brief Initializes the architecture. Prepare all resources needed by the Forte's instances. Must be called once before the first Forte instance is started - */ - FORTE_SHARED_PREFIX void FORTE_SHARED_CALL forteGlobalInitialize(); - - /** - * \brief Deinitializes the architecture. Frees all resources used by Forte's instances. Must be called after the last instance is ended - */ - FORTE_SHARED_PREFIX void FORTE_SHARED_CALL forteGlobalDeinitialize(); - - -#ifdef __cplusplus -} -#endif - -#endif /* FORTE_INSTANCE_H_ */ diff --git a/src/arch/ecos/nios2/CMakeLists.txt b/src/arch/ecos/nios2/CMakeLists.txt index 967b39d8..9a06c409 100644 --- a/src/arch/ecos/nios2/CMakeLists.txt +++ b/src/arch/ecos/nios2/CMakeLists.txt @@ -1,5 +1,5 @@ #******************************************************************************* -# Copyright (c) 2018 fortiss GmbH +# Copyright (c) 2018 - 2024 fortiss GmbH, Jose Cabral # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at # http://www.eclipse.org/legal/epl-2.0. @@ -34,7 +34,7 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "Nios2") endif(FORTE_FAKE_TIME) forte_add_sourcefile_cpp(../../posix/forte_architecture_time.cpp ../../forte_standard_time.cpp) - forte_add_sourcefile_cpp(../ecoscppinit.cpp ../../genforte_printer.cpp ../forte_architecture.cpp) + forte_add_sourcefile_cpp(../ecoscppinit.cpp ../../genforte_printer.cpp ../../common/forte_specific_architecture.cpp) forte_add_sourcefile_h(../../forte_architecture_time.h) forte_add_sourcefile_cpp(../../genforte_realFunctions.cpp) diff --git a/src/arch/ecos/phycoreat91/CMakeLists.txt b/src/arch/ecos/phycoreat91/CMakeLists.txt index 08666ee1..244eca66 100644 --- a/src/arch/ecos/phycoreat91/CMakeLists.txt +++ b/src/arch/ecos/phycoreat91/CMakeLists.txt @@ -1,5 +1,5 @@ #******************************************************************************* -# Copyright (c) 2010 -2105 ACIN, fortiss GmbH +# Copyright (c) 2010 - 2024 ACIN, fortiss GmbH, Jose Cabral # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at # http://www.eclipse.org/legal/epl-2.0. @@ -25,7 +25,7 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "Phycore AT91") else(FORTE_FAKE_TIME) forte_add_sourcefile_hcpp(../ecostiha) endif(FORTE_FAKE_TIME) - forte_add_sourcefile_cpp(../../posix/forte_architecture_time.cpp ../../forte_standard_time.cpp) + forte_add_sourcefile_cpp(../ecoscppinit.cpp ../../posix/forte_architecture_time.cpp ../../forte_standard_time.cpp ../../common/forte_specific_architecture.cpp) forte_add_sourcefile_cpp(../../genforte_printer.cpp) forte_add_sourcefile_h(../../forte_architecture_time.h) diff --git a/src/arch/fdselecthand.cpp b/src/arch/fdselecthand.cpp index b2ef1c66..b590dba3 100644 --- a/src/arch/fdselecthand.cpp +++ b/src/arch/fdselecthand.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 - 2014 ACIN, Profactor GmbH, fortiss GmbH + * Copyright (c) 2010 - 2024 ACIN, Profactor GmbH, fortiss GmbH, Jose Cabral * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. @@ -21,23 +21,10 @@ DEFINE_HANDLER(CFDSelectHandler) CFDSelectHandler::CFDSelectHandler(CDeviceExecution& paDeviceExecution) : CExternalEventHandler(paDeviceExecution) { mConnectionListChanged = false; -#ifdef WIN32 - // Windows Socket Startupcode - WORD wVersionRequested; - WSADATA wsaData; - - /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ - wVersionRequested = MAKEWORD(2, 2); - - WSAStartup(wVersionRequested, &wsaData); -#endif } CFDSelectHandler::~CFDSelectHandler(){ this->end(); -#ifdef WIN32 - WSACleanup(); -#endif } // single-threaded-network-code diff --git a/src/arch/forte_architecture.cpp b/src/arch/forte_architecture.cpp new file mode 100644 index 00000000..7a5f2bca --- /dev/null +++ b/src/arch/forte_architecture.cpp @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2017, 2024 fortiss GmbH, Jose Cabral + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Jose Cabral - initial API and implementation and/or initial documentation + * Alois Zoitl - moved archictecture class to common arch folder and adapted + * it for generic use + *******************************************************************************/ + +#include "forte_architecture.h" + +#include "forte_specific_architecture.h" + +#include "forteinit.h" +#include "startuphook.h" + +bool CForteGeneralArchitecture::mInitialized = false; + +int CForteGeneralArchitecture::initialize(int argc, char *argv[]){ + if(mInitialized) { + return 0; + } + if(auto result = CForteSpecificArchitecture::initialize(argc, argv); result != 0){ + return result; + } + initForte(); + startupHook(argc, argv); + CForteGeneralArchitecture::mInitialized = true; + return 0; +} + +int CForteGeneralArchitecture::deinitialize() { + if(!mInitialized) { + return 0; + } + + if(auto result = CForteSpecificArchitecture::deinitialize(); result != 0){ + return result; + } + CForteGeneralArchitecture::mInitialized = false; + return 0; +} + +bool CForteGeneralArchitecture::isInitialized(){ + return mInitialized; +} diff --git a/src/arch/forte_architecture.h b/src/arch/forte_architecture.h index 868c708b..068adc7c 100644 --- a/src/arch/forte_architecture.h +++ b/src/arch/forte_architecture.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 fortiss GmbH + * Copyright (c) 2017, 2024 fortiss GmbH, Jose Cabral * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. @@ -15,20 +15,39 @@ #ifndef SRC_ARCH_FORTE_ARCHITECTURE_H_ #define SRC_ARCH_FORTE_ARCHITECTURE_H_ -class CForteArchitecture{ +class CForteGeneralArchitecture{ public: - static bool initialize(); + + /** + * @brief Initalize everything needed for forte once and calls the specific initialization of each architecture. + * This is called only once before any forte instances is started. + * + * @param argc Number of arguments passed, same as in the main function + * @param argv Arguments passed, same as in the main function + * @return 0 if no error happenned, another value specificied by the specific architecture otherwise + */ + static int initialize(int argc, char *argv[]); + + /** + * @brief Uninitialize everything that was done in `initialize` and calls the specific uninitialization of each architecture + * This is called only once after all forte instances were used. + * + * @return 0 if no error happenned, another value specificied by the specific architecture otherwise + */ + static int deinitialize(); + + /** + * @brief Checks if the lower layers were already initialized + * + * @return true if the lower layers were already initialized, false otherwise. + */ + static bool isInitialized(); - static void deinitialize(); - - static bool isInitialized(){ - return mInitialized; - } private: - - static bool mInitialized; //in some architectures this might be used to avoid double initialization if this would produce an error - + static bool mInitialized; }; +using CForteArchitecture = CForteGeneralArchitecture; + #endif /* SRC_ARCH_FORTE_ARCHITECTURE_H_ */ diff --git a/src/arch/forte_specific_architecture.h b/src/arch/forte_specific_architecture.h new file mode 100644 index 00000000..9eb61822 --- /dev/null +++ b/src/arch/forte_specific_architecture.h @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2024 + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Jose Cabral - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#ifndef SRC_ARCH_COMMON_FORTE_SPECIFIC_ARCHITECTURE_H_ +#define SRC_ARCH_COMMON_FORTE_SPECIFIC_ARCHITECTURE_H_ + +class CForteSpecificArchitecture{ + public: + + /** + * @brief Initalize everything needed in the lower layers that is needed for forte to run + * This is called only once before any forte instances is started + * + * @param argc Number of arguments passed, same as in the main function + * @param argv Arguments passed, same as in the main function + * @return 0 if no error happenned, another value specificied by the specific architecture otherwise + */ + static int initialize(int argc , char* argv[]); + + /** + * @brief Uninitialize everything needed in the lower layers. This is called only once after all forte instances were used + * + * @return 0 if no error happenned, another value specificied by the specific architecture otherwise + */ + static int deinitialize(); +}; + +#endif /* SRC_ARCH_COMMON_FORTE_SPECIFIC_ARCHITECTURE_H_ */ diff --git a/src/arch/freeRTOS/CMakeLists.txt b/src/arch/freeRTOS/CMakeLists.txt index d79593ff..55c6d2b1 100644 --- a/src/arch/freeRTOS/CMakeLists.txt +++ b/src/arch/freeRTOS/CMakeLists.txt @@ -1,5 +1,5 @@ #/************************************************************************************ -# Copyright (c) 2016, 2023 fortiss GmbH, HR Agrartechnik GmbH +# Copyright (c) 2016, 2024 fortiss GmbH, HR Agrartechnik GmbH, Jose Cabral # # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at @@ -63,7 +63,7 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "FreeRTOSLwIP") SET(FORTE_FreeRTOSLwIP_LIB_DIR "" CACHE PATH "Only for executable: ABSOLUTE path to FreeRTOSLwIP folder with object library FORTE_FreeRTOSLwIP_LIB") SET(FORTE_FreeRTOSLwIP_LIB "" CACHE STRING "Only for executable: FreeRTOSLwIP Library file in FORTE_FreeRTOSLwIP_DIR to be linked to forte") - forte_add_sourcefile_hcpp(forte_thread forte_sync forte_sem forte_Init) + forte_add_sourcefile_hcpp(forte_thread forte_sync forte_sem) if(FORTE_FAKE_TIME) forte_set_timer(../fake_time/faketimerha) @@ -72,7 +72,8 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "FreeRTOSLwIP") endif(FORTE_FAKE_TIME) forte_add_sourcefile_cpp(./forte_architecture_time.cpp) - forte_add_sourcefile_cpp(forte_architecture.cpp ../genforte_printer.cpp) + forte_add_sourcefile_cpp(../common/forte_specific_architecture.cpp) + forte_add_sourcefile_cpp(../genforte_printer.cpp) forte_add_sourcefile_cpp(../genforte_fileio.cpp) forte_add_sourcefile_cpp(../genforte_realFunctions.cpp) diff --git a/src/arch/freeRTOS/forte_Init.cpp b/src/arch/freeRTOS/forte_Init.cpp deleted file mode 100644 index 68ab97d1..00000000 --- a/src/arch/freeRTOS/forte_Init.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/************************************************************************************ - * Copyright (c) 2017-2018 fortiss GmbH - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Milan Vathoopan - initial API and implementation and/or initial documentation - * Tarik Terzimehic - make OPC UA server port setable from the command line - ************************************************************************************/ - -#include "forte_Init.h" - -#include "fortenew.h" -#include "forte_architecture.h" -#include "forte_printer.h" -#include -#include -#include "forteinstance.h" - -#include "../utils/mainparam_utils.h" - -unsigned int forte_default_port = 61499; - -/*!\brief Check if the correct endianess has been configured. - * - * If the right endianess is not set this function will end FORTE. - */ - -bool checkEndianess(); - -void forteGlobalInitialize() { - CForteArchitecture::initialize(); -} - -void forteGlobalDeinitialize() { - CForteArchitecture::deinitialize(); -} - -int forteStartInstance(unsigned int paPort, TForteInstance* paResultInstance) { - - if(65535 < paPort) { - return FORTE_WRONG_PARAMETERS; - } - - if(0 == paPort) { - paPort = forte_default_port; - } - - char progName[] = "forte"; - char flag[] = "-c"; - char address[17] = "localhost:"; - char port[6]; - forte_snprintf(port, 6, "%u", paPort); - strcat(address, port); - - char* arguments[] = { progName, flag, address }; - return forteStartInstanceGeneric(3, arguments, paResultInstance); -} - -int forteStartInstanceGeneric(int paArgc, char *paArgv[], TForteInstance* paResultInstance) { - - if(!CForteArchitecture::isInitialized()) { - return FORTE_ARCHITECTURE_NOT_READY; - } - - if(0 == paResultInstance) { - return FORTE_WRONG_PARAMETERS; - } - - if(0 != *paResultInstance) { - return FORTE_DEVICE_ALREADY_STARTED; - } - - if(!checkEndianess()) { - return FORTE_WRONG_ENDIANESS; - } - - const char *pIpPort = parseCommandLineArguments(paArgc, paArgv); - if((0 != strlen(pIpPort)) && (nullptr != strchr(pIpPort, ':'))) { - C4diacFORTEInstance *instance = new C4diacFORTEInstance(); - if(!instance->startupNewDevice(ipPort)) { - delete instance; - return FORTE_COULD_NOT_CREATE_DEVICE; - } - *paResultInstance = instance; - DEVLOG_INFO("FORTE is up and running\n"); - } else { //! If needed call listHelp() to list the help for FORTE - return FORTE_WRONG_PARAMETERS; - } - - return FORTE_OK; -} - -void forteJoinInstance(TForteInstance paInstance) { - C4diacFORTEInstance *instance = static_cast(paInstance); - if(instance != nullptr){ - instance->awaitDeviceShutdown(); - } -} - -void forteStopInstance(int, TForteInstance paInstance) { - if(!CForteArchitecture::isInitialized() || paInstance != nullptr) { - return; - } - C4diacFORTEInstance *instance = static_cast(paInstance); - instance->triggerDeviceShutdown(); - instance->awaitDeviceShutdown(); - delete instance; - DEVLOG_INFO("FORTE finished\n"); -} - -bool checkEndianess() { - int i = 1; - char *p = (char *) &i; - if(p[0] == 1) { - //we are on a little endian platform -#ifdef FORTE_BIG_ENDIAN - DEVLOG_ERROR("Wrong endianess configured! You are on a little endian platform and have configured big endian!\n"); - return false; -#endif - } else { - //we are on a big endian platform -#ifdef FORTE_LITTLE_ENDIAN - DEVLOG_ERROR("Wrong endianess configured! You are on a big endian platform and have configured little endian!\n"); - return false; -#endif - } - - return true; -} diff --git a/src/arch/freeRTOS/forte_Init.h b/src/arch/freeRTOS/forte_Init.h deleted file mode 100644 index b8589483..00000000 --- a/src/arch/freeRTOS/forte_Init.h +++ /dev/null @@ -1,87 +0,0 @@ -/************************************************************************************ - * Copyright (c) 2017 fortiss GmbH - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Milan Vathoopan - initial API and implementation and/or initial documentation - ************************************************************************************/ - -#ifndef SRC_ARCH_FREERTOS_FORTE_INIT_H_ -#define SRC_ARCH_FREERTOS_FORTE_INIT_H_ - -/* When moving this file to the outside of the architecture, - * the corresponding defines for exporting in windows or other platform - * must be added here - * - */ -#ifndef FORTE_SHARED_PREFIX -# define FORTE_SHARED_PREFIX -#endif - -#ifndef FORTE_SHARED_CALL -# define FORTE_SHARED_CALL -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - enum FORTE_STATUS { - FORTE_OK, - FORTE_DEVICE_ALREADY_STARTED, - FORTE_WRONG_ENDIANESS, - FORTE_WRONG_PARAMETERS, - FORTE_ARCHITECTURE_NOT_READY, - FORTE_COULD_NOT_CREATE_DEVICE - }; - - typedef void* TForteInstance; - /** - * \brief Start forte instance - * @param paPort The port on which to forte will listen. Use 0 for default (normally 61499) - * @param paResultInstance Address of an instance of forte where the new instance is stored - * @return FORTE_OK if no error occurred, other values otherwise - */ - FORTE_SHARED_PREFIX int FORTE_SHARED_CALL forteStartInstance(unsigned int paPort, TForteInstance* paResultInstance); - - /** - * \brief Start forte instance with possibilities of more arguments - * @param paArgc Number of arguments in arg - * @param paArgv Arguments - * @param paResultInstance Address of an instance of forte where the new instance is stored - * @return FORTE_OK if no error occurred, other values otherwise - */ - FORTE_SHARED_PREFIX int FORTE_SHARED_CALL forteStartInstanceGeneric(int paArgc, char *paArgv[], TForteInstance pInstance); - - /** - * \brief Terminates a Forte instance - * @param paSignal Signal value to terminate instance - * @param paInstance Instance to terminate - */ - FORTE_SHARED_PREFIX void FORTE_SHARED_CALL forteStopInstance(int paSignal, TForteInstance paInstance); - - /** - * \brief Terminates a Forte instance - * @param paInstance Instance to terminate - */ - FORTE_SHARED_PREFIX void FORTE_SHARED_CALL forteJoinInstance(TForteInstance paInstance); - - /** - * \brief Initializes the architecture. Prepare all resources needed by the Forte's instances. Must be called once before the first Forte instance is started - */ - FORTE_SHARED_PREFIX void FORTE_SHARED_CALL forteGlobalInitialize(); - - /** - * \brief Deinitializes the architecture. Frees all resources used by Forte's instances. Must be called after the last instance is ended - */ - FORTE_SHARED_PREFIX void FORTE_SHARED_CALL forteGlobalDeinitialize(); - -#ifdef __cplusplus -} -#endif - -#endif /* SRC_ARCH_FREERTOS_FORTE_INIT_H_ */ diff --git a/src/arch/freeRTOS/forte_architecture.cpp b/src/arch/freeRTOS/forte_architecture.cpp deleted file mode 100644 index d4a1d255..00000000 --- a/src/arch/freeRTOS/forte_architecture.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************************ - * Copyright (c) 2017 fortiss GmbH - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Milan Vathoopan - initial API and implementation and/or initial documentation - ************************************************************************************/ - -#include "../forte_architecture.h" -#include "forteinit.h" -bool CForteArchitecture::mInitialized = false; - -bool CForteArchitecture::initialize() { - if(!mInitialized) { - initForte(); - mInitialized = true; - } - return true; -} - -void CForteArchitecture::deinitialize() { - if(mInitialized) { - mInitialized = false; - } -} - diff --git a/src/arch/freeRTOS/main.cpp b/src/arch/freeRTOS/main.cpp index c5f649db..0458bea5 100644 --- a/src/arch/freeRTOS/main.cpp +++ b/src/arch/freeRTOS/main.cpp @@ -1,5 +1,5 @@ /************************************************************************************ - * Copyright (c) 2016 fortiss GmbH + * Copyright (c) 2016, 2024 fortiss GmbH, Jose Cabral * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. @@ -13,31 +13,38 @@ #include "FreeRTOS.h" #include "task.h" -#include "../forte_architecture.h" -#include "../devlog.h" -#include "forteinstance.h" +#include "../c_interface/forte_c.h" + +namespace { + const unsigned forteTaskPriority = tskIDLE_PRIORITY + 1; + const unsigned int desiredFortePort = 61499; + const configSTACK_DEPTH_TYPE stackDepth = 2000; +} -const static unsigned mainFORTE_TASK_PRIORITY = tskIDLE_PRIORITY + 1; void vForteTask(void* ) { - C4diacFORTEInstance instance; + TForteInstance forteInstance; - if(instance.startupNewDevice (pIpPort)) { - DEVLOG_INFO("FORTE is up and running\n"); - instance.awaitDeviceShutdown(); - DEVLOG_INFO("FORTE finished\n"); + if(auto result = CForteArchitecture::initialize(0, NULL); result != 0){ + vTaskDelete(nullptr); } - vTaskDelete(nullptr); -} -void vStartForteServerTask(UBaseType_t uxPriority) { - /* Spawn the task. */ - xTaskCreate(vForteTask, "forte", 2000, nullptr, uxPriority, nullptr); + if(auto result = forteStartInstance(desiredFortePort, &forteInstance); result != FORTE_OK){ + vTaskDelete(nullptr); + } + + forteWaitForInstanceToStop(forteInstance); + + vTaskDelete(nullptr); } int main() { - vStartForteServerTask(mainFORTE_TASK_PRIORITY); + if(auto result = forteGlobalInitialize(0, nullptr); result != FORTE_OK){ + return result; + } + + xTaskCreate(vForteTask, "forte", stackDepth, nullptr, forteTaskPriority, nullptr); vTaskStartScheduler(); diff --git a/src/arch/macos/CMakeLists.txt b/src/arch/macos/CMakeLists.txt index 1fb5b7ce..02ba99b0 100644 --- a/src/arch/macos/CMakeLists.txt +++ b/src/arch/macos/CMakeLists.txt @@ -1,5 +1,5 @@ #******************************************************************************* -# Copyright (c) 2016 fortiss GmbH +# Copyright (c) 2016, 2024 fortiss GmbH, Jose Cabral # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at # http://www.eclipse.org/legal/epl-2.0. @@ -28,13 +28,14 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "MacOs") endif(FORTE_FAKE_TIME) forte_add_sourcefile_cpp(../posix/forte_architecture_time.cpp ../forte_standard_time.cpp) + forte_add_sourcefile_cpp(../common/forte_specific_architecture.cpp) forte_add_sourcefile_hcpp(../posix/forte_thread forte_sync forte_sem) forte_add_sourcefile_cpp(../genforte_printer.cpp) forte_add_sourcefile_cpp(../genforte_fileio.cpp) forte_add_sourcefile_h(../forte_architecture_time.h) forte_add_sourcefile_cpp(../genforte_realFunctions.cpp ../utils/timespec_utils.cpp) - forte_add_to_executable_cpp(../posix/main) + forte_add_to_executable_cpp(../main) if(FORTE_COM_ETH) forte_add_handler(CFDSelectHandler sockhand) diff --git a/src/arch/posix/main.cpp b/src/arch/main.cpp similarity index 67% rename from src/arch/posix/main.cpp rename to src/arch/main.cpp index b28d99db..4b1bdeef 100644 --- a/src/arch/posix/main.cpp +++ b/src/arch/main.cpp @@ -12,18 +12,14 @@ * Martin Melik Merkumians, Ingo Hegny, Filip Andren - initial API and implementation and/or initial documentation * Tarik Terzimehic - make OPC UA server port setable from the command line *******************************************************************************/ -#include + #include #include -#include "../startuphook.h" -#include "forteinstance.h" +#include "../core/forteinstance.h" +#include "forte_architecture.h" #include "../utils/mainparam_utils.h" -#ifdef FORTE_IO_PLCNEXT -#include "../../modules/PLCnext/plcNextDeviceStatus.h" -#endif - /*!\brief Check if the correct endianess has been configured. * * If the right endianess is not set this function will end FORTE. @@ -34,45 +30,42 @@ void hookSignals(); C4diacFORTEInstance g4diacForteInstance; -//this keeps away a lot of rtti and exception handling stuff -#ifndef __cpp_exceptions -extern "C" void __cxa_pure_virtual(void){ - //TODO maybe add some reporting here - //Although we should never get here - //if we are here something very very bad has happened e.g., stack overflow or other memory corruption - -} -#endif - void endForte(int ){ g4diacForteInstance.triggerDeviceShutdown(); } +void callOnExit(){ + CForteArchitecture::deinitialize(); +} + int main(int argc, char *arg[]){ checkEndianess(); - startupHook(argc, arg); + if(auto result = CForteArchitecture::initialize(argc, arg); result != 0){ + return result; + } -#ifdef FORTE_IO_PLCNEXT - sleep(3); - DeviceStatus::startup(); -#endif + std::atexit(callOnExit); hookSignals(); - const char *pIpPort = parseCommandLineArguments(argc, arg); - if((0 != strlen(pIpPort)) && (nullptr != strchr(pIpPort, ':'))) { - if(g4diacForteInstance.startupNewDevice(pIpPort)) { - DEVLOG_INFO("FORTE is up and running\n"); - g4diacForteInstance.awaitDeviceShutdown(); - DEVLOG_INFO("FORTE finished\n"); - } - } - else{ //! Lists the help for FORTE + const char *ipPort = parseCommandLineArguments(argc, arg); + if((0 == strlen(ipPort)) || (nullptr == strchr(ipPort, ':'))) { + //! Lists the help for FORTE listHelp(); + return -1; + } + + if(!g4diacForteInstance.startupNewDevice(ipPort)) { + DEVLOG_INFO("Could not start a new device\n"); + return -1; } + DEVLOG_INFO("FORTE is up and running\n"); + g4diacForteInstance.awaitDeviceShutdown(); + DEVLOG_INFO("FORTE finished\n"); + return 0; } @@ -98,6 +91,7 @@ void checkEndianess(){ void hookSignals() { signal(SIGINT, endForte); signal(SIGTERM, endForte); +#ifndef WIN32 signal(SIGHUP, endForte); -} - +#endif +} \ No newline at end of file diff --git a/src/arch/netos/netos74/CMakeLists.txt b/src/arch/netos/netos74/CMakeLists.txt index 713fb7b5..0826eb4f 100644 --- a/src/arch/netos/netos74/CMakeLists.txt +++ b/src/arch/netos/netos74/CMakeLists.txt @@ -1,5 +1,5 @@ #******************************************************************************* -# Copyright (c) 2011, 2014 ACIN, fortiss GmbH +# Copyright (c) 2011, 2014, 2024 ACIN, fortiss GmbH, Jose Cabral # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at # http://www.eclipse.org/legal/epl-2.0. @@ -59,6 +59,7 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "NetOs 7.4") endif(FORTE_FAKE_TIME) forte_add_sourcefile_cpp(../forte_architecture_time.cpp) + forte_add_sourcefile_cpp(../../common/forte_specific_architecture.cpp) forte_add_sourcefile_hcpp(../forte_thread ../forte_sync ../forte_sem) forte_add_sourcefile_cpp(appconf_api.c ../root.cpp ../../genforte_printer.cpp) forte_add_sourcefile_h(../../forte_architecture_time.h) diff --git a/src/arch/pikeos_posix/CMakeLists.txt b/src/arch/pikeos_posix/CMakeLists.txt index 553c4895..233fd0cb 100644 --- a/src/arch/pikeos_posix/CMakeLists.txt +++ b/src/arch/pikeos_posix/CMakeLists.txt @@ -1,5 +1,5 @@ #******************************************************************************* -# Copyright (c) 2018, 2021 SYSGO GmbH +# Copyright (c) 2018, 2021, 2024 SYSGO GmbH, Jose Cabral # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at # http://www.eclipse.org/legal/epl-2.0. @@ -40,10 +40,10 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "PikeOS_Posix") forte_add_include_directories(${CMAKE_CURRENT_SOURCE_DIR}) forte_add_sourcefile_hcpp(../posix/forte_sync ../utils/timespec_utils) - forte_add_sourcefile_cpp(main.cpp forte_thread.cpp pctimeha.cpp forte_sem.cpp forte_architecture_time.cpp + forte_add_sourcefile_cpp(forte_thread.cpp pctimeha.cpp forte_sem.cpp forte_architecture_time.cpp ../genforte_printer.cpp ../genforte_realFunctions.cpp) forte_add_sourcefile_h(../forte_architecture_time.h forte_thread.h pctimeha.h) - + forte_add_sourcefile_cpp(./forte_specific_architecture.cpp) if(FORTE_COM_ETH) forte_add_handler(CFDSelectHandler sockhand) @@ -92,7 +92,7 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "PikeOS_Posix") mark_as_advanced(FORTE_RTTI_AND_EXCEPTIONS) if("$ENV{POSIX_DEBUG}" STREQUAL "true") - forte_add_definition("-DBOOST_TEST_DYN_LINK -g -O0 --coverage -fno-inline -fno-elide-constructors -fexceptions -fsanitize=address") + forte_add_definition("-g -O0 --coverage -fno-inline -fno-elide-constructors -fexceptions -fsanitize=address") forte_add_link_library("-fsanitize=address") forte_add_link_library("--coverage") else() diff --git a/src/arch/pikeos_posix/forte_specific_architecture.cpp b/src/arch/pikeos_posix/forte_specific_architecture.cpp new file mode 100644 index 00000000..b5344be4 --- /dev/null +++ b/src/arch/pikeos_posix/forte_specific_architecture.cpp @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2024 Jose Cabral + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Jose Cabral - initial API and implementation and/or initial documentation + *******************************************************************************/ + +#include "arch/forte_specific_architecture.h" + +/* CG: testing */ +#include + +#ifdef POSIX_LWIP +#include +#endif + +int CForteSpecificArchitecture::initialize(int , char** ){ +#ifdef POSIX_LWIP + /* Initialize the lwIP stack. */ + if (auto result = _lwip_init(); result != 0) { + DEVLOG_ERROR("Initialization of lwIP stack failed.\n"); + return result; + } +#endif // POSIX_LWIP + + return 0; +} + +int CForteSpecificArchitecture::deinitialize() { + return 0; +} diff --git a/src/arch/pikeos_posix/main.cpp b/src/arch/pikeos_posix/main.cpp deleted file mode 100644 index fee4d591..00000000 --- a/src/arch/pikeos_posix/main.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006 - 2018 ACIN, Profactor GmbH, AIT, fortiss GmbH, SYSGO AG - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Alois Zoitl, Gerhard Ebenhofer, Thomas Strasser, Rene Smodic - * Martin Melik Merkumians, Ingo Hegny, Filip Andren - initial API and implementation and/or initial documentation - * Agostino Mascitti - Adaption to PikeOS 4.2 - *******************************************************************************/ -#include -#include -#include -#include "forteinstance.h" - -#include "../utils/mainparam_utils.h" - - -/* CG: testing */ -#include - -#ifdef POSIX_LWIP -#include -#endif - -/*!\brief Check if the correct endianess has been configured. - * - * If the right endianess is not set this function will end FORTE. - */ -void checkEndianess(); - -C4diacFORTEInstance g4diacForteInstance; - -//this keeps away a lot of rtti and exception handling stuff -#ifndef __cpp_exceptions -extern "C" void __cxa_pure_virtual(void){ - //TODO maybe add some reporting here - //Although we should never get here - //if we are here something very very bad has happened e.g., stack overflow or other memory corruption - -} -#endif - -void endForte(int ){ - g4diacForteInstance.triggerDeviceShutdown(); -} - -int main(int argc, char *arg[]){ - - checkEndianess(); - DEVLOG_INFO("FORTE starting\n"); - -#ifdef POSIX_LWIP - /* Initialize the lwIP stack. */ - if (_lwip_init() != 0) { - DEVLOG_ERROR("Initialization of lwIP stack failed.\n"); - exit(-1); - } -#endif - - signal(SIGINT, endForte); - signal(SIGTERM, endForte); - signal(SIGHUP, endForte); - - const char *pIpPort = parseCommandLineArguments(argc, arg); - if((0 != strlen(pIpPort)) && (nullptr != strchr(pIpPort, ':'))){ - if(g4diacForteInstance.startupNewDevice(pIpPort)) { - DEVLOG_INFO("FORTE is up and running\n"); - g4diacForteInstance.awaitDeviceShutdown(); - DEVLOG_INFO("FORTE finished\n"); - } - } - else{ //! Lists the help for FORTE - listHelp(); - } - - return 0; -} - -void checkEndianess(){ - int i = 1; - char *p = (char *) &i; - if(p[0] == 1){ - //we are on a little endian platform -#ifdef FORTE_BIG_ENDIAN - DEVLOG_ERROR("Wrong endianess configured! You are on a little endian platform and have configured big endian!\n"); - exit(-1); -#endif - } - else{ - //we are on a big endian platform -#ifdef FORTE_LITTLE_ENDIAN - DEVLOG_ERROR("Wrong endianess configured! You are on a big endian platform and have configured little endian!\n"); - exit(-1); -#endif - } -} - diff --git a/src/arch/plcnext/CMakeLists.txt b/src/arch/plcnext/CMakeLists.txt index 56ab7b44..00d8bb07 100644 --- a/src/arch/plcnext/CMakeLists.txt +++ b/src/arch/plcnext/CMakeLists.txt @@ -1,5 +1,5 @@ #******************************************************************************* -# Copyright (c) 2018 Johannes Kepler University +# Copyright (c) 2018, 2024 Johannes Kepler University, Jose Cabral # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at # http://www.eclipse.org/legal/epl-2.0. @@ -25,6 +25,7 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "PLCnext") endif(FORTE_FAKE_TIME) forte_add_sourcefile_cpp(../posix/forte_architecture_time.cpp ../forte_standard_time.cpp) + forte_add_sourcefile_cpp(../common/forte_specific_architecture.cpp) forte_add_sourcefile_hcpp(../posix/forte_thread ../posix/forte_sync ../posix/forte_sem) forte_add_sourcefile_cpp(../genforte_printer.cpp) forte_add_sourcefile_cpp(../genforte_fileio.cpp) diff --git a/src/arch/posix/CMakeLists.txt b/src/arch/posix/CMakeLists.txt index 80821e5d..599ec2fc 100644 --- a/src/arch/posix/CMakeLists.txt +++ b/src/arch/posix/CMakeLists.txt @@ -1,5 +1,5 @@ #******************************************************************************* -# Copyright (c) 2010 - 2015 ACIN, Profactor GmbH, fortiss GmbH +# Copyright (c) 2010 - 2024 ACIN, Profactor GmbH, fortiss GmbH, Jose Cabral # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at # http://www.eclipse.org/legal/epl-2.0. @@ -30,11 +30,10 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "Posix") forte_add_sourcefile_cpp(../genforte_printer.cpp) forte_add_sourcefile_cpp(../genforte_fileio.cpp) forte_add_sourcefile_h(../forte_architecture_time.h) - forte_add_sourcefile_cpp(forte_architecture.cpp) forte_add_sourcefile_hcpp(../utils/timespec_utils) forte_add_sourcefile_cpp(../genforte_realFunctions.cpp) - - forte_add_to_executable_cpp(main) + forte_add_sourcefile_cpp(../common/forte_specific_architecture.cpp) + forte_add_to_executable_cpp(../main) if(FORTE_COM_ETH) forte_add_handler(CFDSelectHandler sockhand) @@ -65,10 +64,10 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "Posix") if(FORTE_TESTS AND FORTE_USE_TEST_CONFIG_IN_FORTE) if(FORTE_TEST_CODE_COVERAGE_ANALYSIS) - forte_add_definition("-DBOOST_TEST_DYN_LINK -g -O0 --coverage -fno-inline") + forte_add_definition("-g -O0 --coverage -fno-inline") forte_add_link_library("--coverage") else() - forte_add_definition("-DBOOST_TEST_DYN_LINK -g -O0 -fno-inline") + forte_add_definition("-g -O0 -fno-inline") endif() if(FORTE_TEST_SANITIZE) forte_add_definition("-fsanitize=address") diff --git a/src/arch/posix/forte_architecture.cpp b/src/arch/posix/forte_architecture.cpp deleted file mode 100644 index d4a1d255..00000000 --- a/src/arch/posix/forte_architecture.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/************************************************************************************ - * Copyright (c) 2017 fortiss GmbH - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Milan Vathoopan - initial API and implementation and/or initial documentation - ************************************************************************************/ - -#include "../forte_architecture.h" -#include "forteinit.h" -bool CForteArchitecture::mInitialized = false; - -bool CForteArchitecture::initialize() { - if(!mInitialized) { - initForte(); - mInitialized = true; - } - return true; -} - -void CForteArchitecture::deinitialize() { - if(mInitialized) { - mInitialized = false; - } -} - diff --git a/src/arch/rcX/CMakeLists.txt b/src/arch/rcX/CMakeLists.txt index c1c0b47a..1d7f7ed3 100644 --- a/src/arch/rcX/CMakeLists.txt +++ b/src/arch/rcX/CMakeLists.txt @@ -1,5 +1,5 @@ #/******************************************************************************* -# Copyright (c) 2016 fortiss GmbH +# Copyright (c) 2016, 2024 fortiss GmbH, Jose Cabral # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at # http://www.eclipse.org/legal/epl-2.0. @@ -48,7 +48,7 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "rcX") forte_add_sourcefile_hcpp(forte_thread rcXUtilities forte_sync forte_sem forte_instance) forte_add_sourcefile_h(fortealloc.h ../forte_architecture_time.h) - forte_add_sourcefile_cpp(forte_architecture.cpp ../genforte_printer.cpp) + forte_add_sourcefile_cpp(forte_specific_architecture.cpp ../genforte_printer.cpp) forte_add_sourcefile_cpp(../genforte_fileio.cpp) forte_add_sourcefile_cpp(../genforte_realFunctions.cpp) diff --git a/src/arch/rcX/forte_instance.cpp b/src/arch/rcX/forte_instance.cpp deleted file mode 100644 index 4708f304..00000000 --- a/src/arch/rcX/forte_instance.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017-2018 fortiss GmbH - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Jose Cabral - initial API and implementation and/or initial documentation - *******************************************************************************/ - -#include "forte_instance.h" - -#include "fortenew.h" -#include "forte_architecture.h" -#include "forte_printer.h" -#include -#include -#include "device.h" - -#include "../utils/mainparam_utils.h" - -unsigned int forte_default_port = 61499; - -/*!\brief Check if the correct endianess has been configured. - * - * If the right endianess is not set this function will end FORTE. - */ -bool checkEndianess(); - -void forteGlobalInitialize(){ - CForteArchitecture::initialize(); -} - -void forteGlobalDeinitialize(){ - CForteArchitecture::deinitialize(); -} - -int forteStartInstance(unsigned int pa_port, TForteInstance* paResultDevice){ - - if (65535 < pa_port){ - return FORTE_WRONG_PARAMETERS; - } - - if (0 == pa_port){ - pa_port = forte_default_port; - } - - char progName[] = "forte"; - char flag[] = "-c"; - char address[17] = "localhost:"; - char port[6]; - forte_snprintf(port, 6, "%u", paPort); - strcat(address, port); - - char* arguments[] = { progName, flag, address }; - return forteStartInstanceGeneric(3, arguments, paResultDevice); -} - - -int forteStartInstanceGeneric(int argc, char *arg[], TForteInstance* paResultDevice){ - - if(!CForteArchitecture::isInitialized()){ - return FORTE_ARCHITECTURE_NOT_READY; - } - - if(0 == pa_resultDevice){ - return FORTE_WRONG_PARAMETERS; - } - - if (0 != *pa_resultDevice){ - return FORTE_DEVICE_ALREADY_STARTED; - } - - if (!checkEndianess()){ - return FORTE_WRONG_ENDIANESS; - } - - const char *pIpPort = parseCommandLineArguments(argc, arg); - if((0 != strlen(pIpPort)) && (nullptr != strchr(pIpPort, ':'))){ - C4diacFORTEInstance *instance = new C4diacFORTEInstance(); - if(!instance->startupNewDevice(ipPort)) { - delete instance; - return FORTE_COULD_NOT_CREATE_DEVICE; - } - *paResultDevice = instance; - DEVLOG_INFO("FORTE is up and running\n"); - } - else{ //! If needed call listHelp() to list the help for FORTE - return FORTE_WRONG_PARAMETERS; - } - - return FORTE_OK; -} - -void forteStopInstance(int, TForteInstance paInstance){ - if(!CForteArchitecture::isInitialized()|| paInstance != nullptr){ - return; - } - C4diacFORTEInstance *instance = static_cast(paInstance); - instance->triggerDeviceShutdown(); - instance->awaitDeviceShutdown(); - delete instance; - DEVLOG_INFO("FORTE finished\n"); -} - - -bool checkEndianess(){ - int i = 1; - char *p = (char *) &i; - if(p[0] == 1){ - //we are on a little endian platform -#ifdef FORTE_BIG_ENDIAN - DEVLOG_ERROR("Wrong endianess configured! You are on a little endian platform and have configured big endian!\n"); - return false; -#endif - } - else{ - //we are on a big endian platform -#ifdef FORTE_LITTLE_ENDIAN - DEVLOG_ERROR("Wrong endianess configured! You are on a big endian platform and have configured little endian!\n"); - return false; -#endif - } - - return true; -} diff --git a/src/arch/rcX/forte_instance.h b/src/arch/rcX/forte_instance.h deleted file mode 100644 index 4cc3efd7..00000000 --- a/src/arch/rcX/forte_instance.h +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 fortiss GmbH - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Jose Cabral - initial API and implementation and/or initial documentation - *******************************************************************************/ - -#ifndef FORTE_INSTANCE_H_ -#define FORTE_INSTANCE_H_ - -/* When moving this file to the outside of the architecture, - * the corresponding defines for exporting in windows or other platform - * must be added here - * - */ -#ifndef FORTE_SHARED_PREFIX - #define FORTE_SHARED_PREFIX -#endif - -#ifndef FORTE_SHARED_CALL - #define FORTE_SHARED_CALL -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - - enum FORTE_STATUS{ - FORTE_OK, - FORTE_DEVICE_ALREADY_STARTED, - FORTE_WRONG_ENDIANESS, - FORTE_WRONG_PARAMETERS, - FORTE_ARCHITECTURE_NOT_READY, - FORTE_COULD_NOT_CREATE_DEVICE - }; - - typedef void* TForteInstance; - /** - * \brief Start forte instance - * @param pa_port The port on which to forte will listen. Use 0 for default (normally 61499) - * @param pa_resultDevice Address of an instance of forte - * @return FORTE_OK if no error occurred, other values otherwise - */ - FORTE_SHARED_PREFIX int FORTE_SHARED_CALL forteStartInstance(unsigned int pa_port, TForteInstance* paResultInstance); - - /** - * \brief Start forte instance with posibilities of more arguments - * @param argc Number of arguments in arg - * @param arg Arguments - * @param pa_resultDevice Address of an instance of forte - * @return FORTE_OK if no error occurred, other values otherwise - */ - FORTE_SHARED_PREFIX int FORTE_SHARED_CALL forteStartInstanceGeneric(int argc, char *arg[], TForteInstance* paResultInstance); - - /** - * \brief Terminates a Forte instance - * @param signal Signal value to terminate instance - * @param pa_resultDevice Instance to terminate - */ - FORTE_SHARED_PREFIX void FORTE_SHARED_CALL forteStopInstance(int signal, TForteInstance paInstance); - - /** - * \brief Initializes the architecture. Prepare all resources needed by the Forte's instances. Must be called once before the first Forte instance is started - */ - FORTE_SHARED_PREFIX void FORTE_SHARED_CALL forteGlobalInitialize(); - - /** - * \brief Deinitializes the architecture. Frees all resources used by Forte's instances. Must be called after the last instance is ended - */ - FORTE_SHARED_PREFIX void FORTE_SHARED_CALL forteGlobalDeinitialize(); - - -#ifdef __cplusplus -} -#endif - -#endif /* FORTE_INSTANCE_H_ */ diff --git a/src/arch/rcX/forte_architecture.cpp b/src/arch/rcX/forte_specific_architecture.cpp similarity index 81% rename from src/arch/rcX/forte_architecture.cpp rename to src/arch/rcX/forte_specific_architecture.cpp index 90812c78..8081c4cc 100644 --- a/src/arch/rcX/forte_architecture.cpp +++ b/src/arch/rcX/forte_specific_architecture.cpp @@ -60,19 +60,13 @@ void initialize_destructors(void) /*func_ptr _init_array_start_forte[0] __attribute__ ((used, section(".init_array"), aligned(sizeof(func_ptr)))) = { }; func_ptr _fini_array_star_fortet[0] __attribute__ ((used, section(".fini_array"), aligned(sizeof(func_ptr)))) = { };*/ -bool CForteArchitecture::initialize(){ - if (!mInitialized){ - initialize_constructors(); - initForte(); - CrcXSocketInterface::getInstance(); - mInitialized = true; - } - return true; +int CForteSpecificArchitecture::initialize(){ + initialize_constructors(); + CrcXSocketInterface::getInstance(); + return 0; } -void CForteArchitecture::deinitialize(){ - if(mInitialized){ - initialize_destructors(); //TODO: is it really necessary? When called, _fini_array_start_forte == _fini_array_end_forte, so no function is actually called - mInitialized = false; - } +int CForteSpecificArchitecture::deinitialize(){ + initialize_destructors(); //TODO: is it really necessary? When called, _fini_array_start_forte == _fini_array_end_forte, so no function is actually called + return 0; } diff --git a/src/arch/vxworks/CMakeLists.txt b/src/arch/vxworks/CMakeLists.txt index 47d657a9..3aabae74 100644 --- a/src/arch/vxworks/CMakeLists.txt +++ b/src/arch/vxworks/CMakeLists.txt @@ -1,5 +1,5 @@ #/******************************************************************************* -# Copyright (c) 2016 fortiss GmbH +# Copyright (c) 2016, 2024 fortiss GmbH, Jose Cabral # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at # http://www.eclipse.org/legal/epl-2.0. @@ -25,7 +25,8 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "VxWorks") endif(FORTE_FAKE_TIME) forte_add_sourcefile_cpp(forte_architecture_time.cpp) - forte_add_to_executable_cpp(main) + forte_add_sourcefile_cpp(../common/forte_specific_architecture.cpp) + forte_add_to_executable_cpp(../main) forte_add_sourcefile_hcpp(forte_thread forte_sync forte_sem) forte_add_sourcefile_cpp(../genforte_printer.cpp) diff --git a/src/arch/vxworks/main.cpp b/src/arch/vxworks/main.cpp deleted file mode 100644 index b1f9bd12..00000000 --- a/src/arch/vxworks/main.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 fortiss GmbH - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Jose Cabral - initial API and implementation and/or initial documentation - *******************************************************************************/ -#include -#include -#include -#include "forteinstance.h" - -/*!\brief Check if the correct endianess has been configured. - * - * If the right endianess is not set this function will end FORTE. - */ -void checkEndianess(); - -C4diacFORTEInstance g4diacForteInstance; - -//this keeps away a lot of rtti and exception handling stuff -#ifndef __cpp_exceptions -extern "C" void __cxa_pure_virtual(void){ - //TODO maybe add some reporting here - //Although we should never get here - //if we are here something very very bad has happened e.g., stack overflow or other memory corruption - -} -#endif - -void endForte(int ){ - g4diacForteInstance.triggerDeviceShutdown(); -} - -int startForte(){ - - checkEndianess(); - - signal(SIGINT, endForte); - signal(SIGTERM, endForte); - signal(SIGHUP, endForte); - - if(g4diacForteInstance.startupNewDevice("")) { - DEVLOG_INFO("FORTE is up and running\n"); - g4diacForteInstance.awaitDeviceShutdown(); - DEVLOG_INFO("FORTE finished\n"); - } - return 0; -} - -void checkEndianess(){ - int i = 1; - char *p = (char *) &i; - if(p[0] == 1){ - //we are on a little endian platform -#ifdef FORTE_BIG_ENDIAN - DEVLOG_ERROR("Wrong endianess configured! You are on a little endian platform and have configured big endian!\n"); - exit(-1); -#endif - } - else{ - //we are on a big endian platform -#ifdef FORTE_LITTLE_ENDIAN - DEVLOG_ERROR("Wrong endianess configured! You are on a big endian platform and have configured little endian!\n"); - exit(-1); -#endif - } -} - diff --git a/src/arch/win32/CMakeLists.txt b/src/arch/win32/CMakeLists.txt index 3707fa59..60ed4989 100644 --- a/src/arch/win32/CMakeLists.txt +++ b/src/arch/win32/CMakeLists.txt @@ -1,5 +1,5 @@ #******************************************************************************* -# Copyright (c) 2010 - 2015 ACIN, Profactor GmbH, fortiss GmbH +# Copyright (c) 2010 - 2024 ACIN, Profactor GmbH, fortiss GmbH, Jose Cabral # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at # http://www.eclipse.org/legal/epl-2.0. @@ -28,12 +28,11 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "Win32") else() forte_add_sourcefile_cpp(forte_sync.cpp) endif() - forte_add_sourcefile_cpp(forte_architecture.cpp winforte_printer.cpp forte_architecture_time.cpp ../forte_standard_time.cpp) + forte_add_sourcefile_cpp(forte_specific_architecture.cpp winforte_printer.cpp forte_architecture_time.cpp ../forte_standard_time.cpp) forte_add_sourcefile_cpp(../genforte_fileio.cpp) forte_add_sourcefile_cpp(../genforte_realFunctions.cpp) - forte_add_sourcefile_hcpp(forte_instance) - forte_add_to_executable_cpp(main) + forte_add_to_executable_cpp(../main) if(FORTE_BUILD_SHARED_LIBRARY) set(FORTE_EXTERNAL_TIMEHA OFF CACHE BOOL "Use External Time Handler") @@ -71,7 +70,7 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "Win32") if(MINGW) #force MINGW to statically link libc and lib stdc++ so that no mingw dlls are needed for forte.exe - forte_add_link_flags("-static-libgcc -static-libstdc++") + forte_add_link_flags("-static-libgcc" "-static-libstdc++") forte_add_definition("-W -Wall -Wextra -Woverloaded-virtual -Wconversion -Wshadow") elseif(MSVC) forte_add_definition("-wd4595") #warning 4595: 'operator delete/delete[]': non-member operator new or delete functions may not be declared inline diff --git a/src/arch/win32/forte_instance.cpp b/src/arch/win32/forte_instance.cpp deleted file mode 100644 index ceacbedb..00000000 --- a/src/arch/win32/forte_instance.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 fortiss GmbH - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Jose Cabral, Alois Zoitl - initial API and implementation and/or initial documentation - *******************************************************************************/ -#include "forte_instance.h" -#include "fortenew.h" -#include "forte_architecture.h" -#include "forteinstance.h" - -#include - -C4diacFORTEInstance g4diacForteLibInstance; - -extern "C" -void startupFORTE(){ - CForteArchitecture::initialize(); - initForte(); - g4diacForteLibInstance.startupNewDevice(""); -} - -extern "C" -void shutdownFORTE(){ - g4diacForteLibInstance.triggerDeviceShutdown(); - g4diacForteLibInstance.awaitDeviceShutdown(); -} - diff --git a/src/arch/win32/forte_architecture.cpp b/src/arch/win32/forte_specific_architecture.cpp similarity index 50% rename from src/arch/win32/forte_architecture.cpp rename to src/arch/win32/forte_specific_architecture.cpp index 879d0ddc..b710fe57 100644 --- a/src/arch/win32/forte_architecture.cpp +++ b/src/arch/win32/forte_specific_architecture.cpp @@ -10,29 +10,20 @@ * Alois Zoitl - initial API and implementation and/or initial documentation *******************************************************************************/ -#include "../forte_architecture.h" +#include "arch/forte_specific_architecture.h" #include -bool CForteArchitecture::mInitialized = false; +int CForteSpecificArchitecture::initialize(int, char**) { + // Windows Socket Startupcode + WORD wVersionRequested; + WSADATA wsaData; -bool CForteArchitecture::initialize() { - if (!mInitialized) { - // Windows Socket Startupcode - WORD wVersionRequested; - WSADATA wsaData; + /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ + wVersionRequested = MAKEWORD(2, 2); - /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ - wVersionRequested = MAKEWORD(2, 2); - - WSAStartup(wVersionRequested, &wsaData); - mInitialized = true; - } - return true; + return WSAStartup(wVersionRequested, &wsaData); } -void CForteArchitecture::deinitialize() { - if (mInitialized) { - WSACleanup(); - mInitialized = false; - } +int CForteSpecificArchitecture::deinitialize() { + return WSACleanup(); } diff --git a/src/arch/win32/main.cpp b/src/arch/win32/main.cpp deleted file mode 100644 index 89f7f675..00000000 --- a/src/arch/win32/main.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2010 - 2018 ACIN, Profactor GmbH, fortiss GmbH - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Alois Zoitl, Ingo Hegny, Gerhard Ebenhofer - initial API and implementation and/or initial documentation - * Alois Zoitl - cleaned up main, inserted new architecture initilasation api - *******************************************************************************/ -#include "../forte_architecture.h" -#include "../devlog.h" -#include "../startuphook.h" -#include "forteinstance.h" -#include "../utils/mainparam_utils.h" - -#include -#include - -void hookSignals(); - -C4diacFORTEInstance g4diacForteInstance; - -//this keeps away a lot of rtti and exception handling stuff -#ifndef __cpp_exceptions -extern "C" void __cxa_pure_virtual(void){ - //TODO maybe add some reporting here - //Although we should never get here - //if we are here something very very bad has happened e.g., stack overflow or other memory corruption - -} -#endif - -void endForte(int ){ - g4diacForteInstance.triggerDeviceShutdown(); -} - -int main(int argc, char *arg[]){ - - if(CForteArchitecture::initialize()){ - - startupHook(argc, arg); - - hookSignals(); - - const char *pIpPort = parseCommandLineArguments(argc, arg); - if((0 != strlen(pIpPort)) && (nullptr != strchr(pIpPort, ':'))){ - if(g4diacForteInstance.startupNewDevice(pIpPort)) { - DEVLOG_INFO("FORTE is up and running\n"); - g4diacForteInstance.awaitDeviceShutdown(); - DEVLOG_INFO("FORTE finished\n"); - } - } - else{ //! Lists the help for FORTE - listHelp(); - } - - CForteArchitecture::deinitialize(); - - } - else{ - DEVLOG_ERROR("Architecture could not be initialized\n"); - } - return 0; -} - -void hookSignals() { - signal(SIGINT, endForte); - signal(SIGTERM, endForte); -} diff --git a/src/arch/zephyr/CMakeLists.txt b/src/arch/zephyr/CMakeLists.txt index c9e43596..d16fc379 100644 --- a/src/arch/zephyr/CMakeLists.txt +++ b/src/arch/zephyr/CMakeLists.txt @@ -1,5 +1,5 @@ #/************************************************************************************ -# Copyright (c) 2023 KT Elektronik GmbH +# Copyright (c) 2023 - 2024 KT Elektronik GmbH, Jose Cabral # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at # http://www.eclipse.org/legal/epl-2.0. @@ -21,7 +21,7 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "Zephyr") set(FORTE_LOGLEVEL "NOLOG" CACHE STRING "Loglevel to use" FORCE) SET(FORTE_ZEPHYR_INCLUDES "" CACHE STRING "Folders to include from the Zephyr OS") - forte_add_sourcefile_hcpp(forte_thread forte_sync forte_sem forte_Init) + forte_add_sourcefile_hcpp(forte_thread forte_sync forte_sem) if(FORTE_FAKE_TIME) forte_set_timer(../fake_time/faketimerha) @@ -30,7 +30,8 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "Zephyr") endif(FORTE_FAKE_TIME) forte_add_sourcefile_cpp(./forte_architecture_time.cpp) - forte_add_sourcefile_cpp(forte_architecture.cpp ../genforte_printer.cpp) + forte_add_sourcefile_cpp(../common/forte_specific_architecture.cpp) + forte_add_sourcefile_cpp(../genforte_printer.cpp) forte_add_sourcefile_cpp(zephyrforte_fileio.cpp) forte_add_sourcefile_cpp(../genforte_realFunctions.cpp) diff --git a/src/arch/zephyr/forte_Init.cpp b/src/arch/zephyr/forte_Init.cpp deleted file mode 100644 index ad8054b1..00000000 --- a/src/arch/zephyr/forte_Init.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/************************************************************************************ - Copyright (c) 2023 KT Elektronik GmbH - This program and the accompanying materials are made available under the - terms of the Eclipse Public License 2.0 which is available at - http://www.eclipse.org/legal/epl-2.0. - - SPDX-License-Identifier: EPL-2.0 - - Contributors: - Dirk Kaar - initial API and implementation and/or initial documentation - ************************************************************************************/ - -#include "forte_Init.h" - -#include "fortenew.h" -#include "forte_architecture.h" -#include "forte_printer.h" -#include -#include -#include "forteinstance.h" - -#include "../utils/mainparam_utils.h" - -#include - -constexpr unsigned int forte_default_port = 61499; - -/*!\brief Check if the correct endianess has been configured. - * - * If the right endianess is not set this function will end FORTE. - */ - -bool checkEndianess(); - -void forteGlobalInitialize() { - CForteArchitecture::initialize(); -} - -void forteGlobalDeinitialize() { - CForteArchitecture::deinitialize(); -} - -int forteStartInstance(unsigned int paPort, TForteInstance* paResultInstance) { - - if(65535 < paPort) { - return FORTE_WRONG_PARAMETERS; - } - - if(0 == paPort) { - paPort = forte_default_port; - } - - char progName[] = "forte"; - char flag[] = "-c"; - char address[17] = "localhost:"; - char port[6]; - forte_snprintf(port, 6, "%u", paPort); - strcat(address, port); - char* arguments[] = { progName, flag, address }; - return forteStartInstanceGeneric(3, arguments, paResultInstance); -} - -int forteStartInstanceGeneric(int paArgc, char *paArgv[], TForteInstance* paResultInstance) { - - if(!CForteArchitecture::isInitialized()) { - return FORTE_ARCHITECTURE_NOT_READY; - } - - if(0 == paResultInstance) { - return FORTE_WRONG_PARAMETERS; - } - - if(0 != *paResultInstance) { - return FORTE_DEVICE_ALREADY_STARTED; - } - - if(!checkEndianess()) { - return FORTE_WRONG_ENDIANESS; - } - - const char *ipPort = parseCommandLineArguments(paArgc, paArgv); - if((0 != strlen(ipPort)) && (NULL != strchr(ipPort, ':'))) { - C4diacFORTEInstance *instance = new C4diacFORTEInstance(); - if(!instance->startupNewDevice(ipPort)) { - delete instance; - return FORTE_COULD_NOT_CREATE_DEVICE; - } - *paResultInstance = instance; - DEVLOG_INFO("FORTE is up and running\n"); - } else { //! If needed call listHelp() to list the help for FORTE - return FORTE_WRONG_PARAMETERS; - } - - return FORTE_OK; -} - -void forteJoinInstance(TForteInstance paInstance) { - C4diacFORTEInstance *instance = static_cast(paInstance); - if(instance != nullptr){ - instance->awaitDeviceShutdown(); - } -} - -void forteStopInstance(int, TForteInstance paInstance) { - if(!CForteArchitecture::isInitialized() || paInstance != nullptr) { - return; - } - C4diacFORTEInstance *instance = static_cast(paInstance); - instance->triggerDeviceShutdown(); - instance->awaitDeviceShutdown(); - delete instance; - DEVLOG_INFO("FORTE finished\n"); -} - -bool checkEndianess() { - int i = 1; - char *p = (char *) &i; - if(p[0] == 1) { - //we are on a little endian platform -#ifdef FORTE_BIG_ENDIAN - DEVLOG_ERROR("Wrong endianess configured! You are on a little endian platform and have configured big endian!\n"); - return false; -#endif - } else { - //we are on a big endian platform -#ifdef FORTE_LITTLE_ENDIAN - DEVLOG_ERROR("Wrong endianess configured! You are on a big endian platform and have configured little endian!\n"); - return false; -#endif - } - - return true; -} diff --git a/src/arch/zephyr/forte_Init.h b/src/arch/zephyr/forte_Init.h deleted file mode 100644 index f26c6059..00000000 --- a/src/arch/zephyr/forte_Init.h +++ /dev/null @@ -1,88 +0,0 @@ -/************************************************************************************ - Copyright (c) 2023 KT Elektronik GmbH - This program and the accompanying materials are made available under the - terms of the Eclipse Public License 2.0 which is available at - http://www.eclipse.org/legal/epl-2.0. - - SPDX-License-Identifier: EPL-2.0 - - Contributors: - Dirk Kaar - initial API and implementation and/or initial documentation - ************************************************************************************/ - -#ifndef SRC_ARCH_ZEPHYR_FORTE_INIT_H_ -#define SRC_ARCH_ZEPHYR_FORTE_INIT_H_ - -/* When moving this file to the outside of the architecture, - * the corresponding defines for exporting in windows or other platform - * must be added here - * - */ -#ifndef FORTE_SHARED_PREFIX -# define FORTE_SHARED_PREFIX -#endif - -#ifndef FORTE_SHARED_CALL -# define FORTE_SHARED_CALL -#endif - -#ifdef __cplusplus -extern "C" { -#endif - - enum FORTE_STATUS { - FORTE_OK, - FORTE_DEVICE_ALREADY_STARTED, - FORTE_WRONG_ENDIANESS, - FORTE_WRONG_PARAMETERS, - FORTE_ARCHITECTURE_NOT_READY, - FORTE_COULD_NOT_CREATE_DEVICE - }; - - typedef void* TForteInstance; - - /** - * \brief Start forte instance - * @param paPort The port on which to forte will listen. Use 0 for default (normally 61499) - * @param paResultInstance Address of an instance of forte where the new instance is stored - * @return FORTE_OK if no error occurred, other values otherwise - */ - FORTE_SHARED_PREFIX int FORTE_SHARED_CALL forteStartInstance(unsigned int paPort, TForteInstance* paResultInstance); - - /** - * \brief Start forte instance with possibilities of more arguments - * @param paArgc Number of arguments in arg - * @param paArgv Arguments - * @param paResultInstance Address of an instance of forte where the new instance is stored - * @return FORTE_OK if no error occurred, other values otherwise - */ - FORTE_SHARED_PREFIX int FORTE_SHARED_CALL forteStartInstanceGeneric(int paArgc, char *paArgv[], TForteInstance* paResultInstance); - - /** - * \brief Terminates a Forte instance - * @param paSignal Signal value to terminate instance - * @param paInstance Instance to terminate - */ - FORTE_SHARED_PREFIX void FORTE_SHARED_CALL forteStopInstance(int paSignal, TForteInstance paInstance); - - /** - * \brief Terminates a Forte instance - * @param paInstance Instance to terminate - */ - FORTE_SHARED_PREFIX void FORTE_SHARED_CALL forteJoinInstance(TForteInstance paInstance); - - /** - * \brief Initializes the architecture. Prepare all resources needed by the Forte's instances. Must be called once before the first Forte instance is started - */ - FORTE_SHARED_PREFIX void FORTE_SHARED_CALL forteGlobalInitialize(); - - /** - * \brief Deinitializes the architecture. Frees all resources used by Forte's instances. Must be called after the last instance is ended - */ - FORTE_SHARED_PREFIX void FORTE_SHARED_CALL forteGlobalDeinitialize(); - -#ifdef __cplusplus -} -#endif - -#endif /* SRC_ARCH_ZEPHYR_FORTE_INIT_H_ */ diff --git a/src/arch/zephyr/forte_architecture.cpp b/src/arch/zephyr/forte_architecture.cpp deleted file mode 100644 index 0435db8e..00000000 --- a/src/arch/zephyr/forte_architecture.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/************************************************************************************ - * Copyright (c) 2017 fortiss GmbH - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors: - * Milan Vathoopan - initial API and implementation and/or initial documentation - ************************************************************************************/ - -#include "../forte_architecture.h" -#include "forteinit.h" - -bool CForteArchitecture::mInitialized = false; - -bool CForteArchitecture::initialize() { - if(!mInitialized) { - initForte(); - mInitialized = true; - } - return true; -} - -void CForteArchitecture::deinitialize() { - if(mInitialized) { - mInitialized = false; - } -} - diff --git a/src/modules/PLCnext/CMakeLists.txt b/src/modules/PLCnext/CMakeLists.txt index 74bf25a0..9ab63a00 100644 --- a/src/modules/PLCnext/CMakeLists.txt +++ b/src/modules/PLCnext/CMakeLists.txt @@ -1,5 +1,5 @@ #******************************************************************************* -# * Copyright (c) 2022 Peirlberger Juergen +# * Copyright (c) 2022, 2024 Peirlberger Juergen, Jose Cabral # * This program and the accompanying materials are made available under the # * terms of the Eclipse Public License 2.0 which is available at # * http://www.eclipse.org/legal/epl-2.0. @@ -44,6 +44,8 @@ forte_add_link_library_beginning(Arp.Plc.AnsiC) forte_add_link_flags("-Wno-undef") +forte_add_startup_hook(DeviceStatus::startup) + else("${FORTE_ARCHITECTURE}" STREQUAL "Posix") MESSAGE(FATAL_ERROR "PLCnext IO system is only supported for FORTE on Linux (Posix) platforms!") endif("${FORTE_ARCHITECTURE}" STREQUAL "Posix") diff --git a/src/modules/PLCnext/plcNextDeviceStatus.cpp b/src/modules/PLCnext/plcNextDeviceStatus.cpp index 0c1031d2..69074875 100644 --- a/src/modules/PLCnext/plcNextDeviceStatus.cpp +++ b/src/modules/PLCnext/plcNextDeviceStatus.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Peirlberger Juergen + * Copyright (c) 2022, 2024 Peirlberger Juergen, Jose Cabral * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. @@ -23,6 +23,8 @@ #include #include "plcNextDeviceStatus.h" +#include + using namespace Arp; using namespace Arp::System::Rsc; using namespace Arp::Device::Interface::Services; @@ -35,7 +37,10 @@ bool DeviceStatus::isReady() { return DeviceStatus::started && DeviceStatus::ready; } -bool DeviceStatus::startup() { +bool DeviceStatus::startup(int, char*) { + + // this sleep came from the main. Check again if it's actually needed + sleep(3); // register callback function to get information when plc is ready ArpPlcDomain_SetHandler(DeviceStatus::plcCallbackOperationHandler); diff --git a/src/modules/PLCnext/plcNextDeviceStatus.h b/src/modules/PLCnext/plcNextDeviceStatus.h index 3add845b..4e9ad16e 100644 --- a/src/modules/PLCnext/plcNextDeviceStatus.h +++ b/src/modules/PLCnext/plcNextDeviceStatus.h @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2022 Peirlberger Juergen + * Copyright (c) 2022, 2024 Peirlberger Juergen, Jose Cabral * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. @@ -40,7 +40,7 @@ class DeviceStatus { static volatile bool started; static volatile bool ready; - static bool startup(); + static bool startup(int, char*); static bool isReady(); static void plcCallbackOperationHandler(enum PlcOperation operation); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 880e895c..897f35e7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,5 +1,5 @@ #******************************************************************************* -# Copyright (c) 2011 - 2018 ACIN, nxtControl, Profactor GmbH, fortiss GmbH +# Copyright (c) 2011 - 2024 ACIN, nxtControl, Profactor GmbH, fortiss GmbH, Jose Cabral # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at # http://www.eclipse.org/legal/epl-2.0. @@ -55,6 +55,12 @@ FUNCTION(forte_test_add_inc_system_directories) ENDFOREACH(ARG) ENDFUNCTION(forte_test_add_inc_system_directories) +FUNCTION(forte_test_add_link_library) + FOREACH(ARG ${ARGV}) + SET_PROPERTY(GLOBAL APPEND PROPERTY FORTE_TEST_LIBRARIES ${ARG}) + ENDFOREACH(ARG) +ENDFUNCTION(forte_test_add_link_library) + ####################################################################################### # add subdirectories ####################################################################################### @@ -105,8 +111,8 @@ FILE(WRITE ${CMAKE_BINARY_DIR}/file_test_list.txt "${WRITE_FILE}") # Create Exe File ####################################################################################### -ADD_EXECUTABLE(forte_test $ ${SOURCE_H} ${SOURCE_CPP}) -target_compile_features(forte_test PRIVATE cxx_std_17) +ADD_EXECUTABLE(forte_test ${SOURCE_H} ${SOURCE_CPP}) +target_link_libraries(forte_test FORTE_LITE) ####################################################################################### # Add definitions @@ -116,7 +122,6 @@ GET_PROPERTY(DEFINITION GLOBAL PROPERTY FORTE_DEFINITION) add_definitions(${DEFINITION}) #using target_compile_definitions put the definitions at the beginning giving problems sometimes because cmake adds -O3. if("${FORTE_ARCHITECTURE}" STREQUAL "Posix") - ADD_DEFINITIONS (-DBOOST_TEST_DYN_LINK) if(FORTE_LINK_STATIC) set_target_properties(forte_test PROPERTIES LINK_SEARCH_START_STATIC ON) set_target_properties(forte_test PROPERTIES LINK_SEARCH_END_STATIC ON) @@ -132,18 +137,10 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "Win32") endif() endif("${FORTE_ARCHITECTURE}" STREQUAL "Win32") -add_dependencies(forte_test FORTE_LITE) add_dependencies(forte_test forte_stringlist_generator) SET_TARGET_PROPERTIES(forte_test PROPERTIES LINKER_LANGUAGE CXX) -get_target_property(existing_link_flags_test forte_test LINK_FLAGS) -if(existing_link_flags_test) - set_property(GLOBAL APPEND PROPERTY FORTE_TEST_LINK_FLAGS ${existing_link_flags_test}) -endif() - -GET_PROPERTY(link_flags_test GLOBAL PROPERTY FORTE_TEST_LINK_FLAGS) - #add forte_test to the list of test to be executed by ctest add_test(forte_test ${EXECUTABLE_OUTPUT_PATH}/forte_test) @@ -175,16 +172,8 @@ endif(ENABLE_GENERATED_SOURCE_CPP) forte_test_add_inc_system_directories(${FORTE_TESTS_INC_DIRS}) forte_test_add_inc_system_directories(./) -GET_PROPERTY(INCLUDE_DIRECTORIES GLOBAL PROPERTY FORTE_INCLUDE_DIRECTORIES) GET_PROPERTY(FORTE_TEST_INC GLOBAL PROPERTY FORTE_TEST_INC_DIRECTORIES) - -LIST(APPEND INCLUDE_DIRECTORIES ${FORTE_TEST_INC}) - -LIST(LENGTH INCLUDE_DIRECTORIES len) -IF(len GREATER 0) - LIST(REMOVE_DUPLICATES INCLUDE_DIRECTORIES) - LIST(REVERSE INCLUDE_DIRECTORIES) # bugfix, for replaced include files -ENDIF(len GREATER 0) +target_include_directories(forte_test PUBLIC ${FORTE_TEST_INC}) GET_PROPERTY(INCLUDE_SYSTEM_DIRECTORIES GLOBAL PROPERTY FORTE_INCLUDE_SYSTEM_DIRECTORIES) GET_PROPERTY(INCLUDE_TEST_SYSTEM_DIRECTORIES GLOBAL PROPERTY FORTE_TEST_INC_SYSTEM_DIRECTORIES) @@ -196,19 +185,67 @@ IF(len GREATER 0) LIST(REVERSE INCLUDE_TEST_SYSTEM_DIRECTORIES) # bugfix, for replaced include files ENDIF(len GREATER 0) -target_include_directories(forte_test PUBLIC ${INCLUDE_DIRECTORIES}) INCLUDE_DIRECTORIES(SYSTEM ${INCLUDE_TEST_SYSTEM_DIRECTORIES}) ####################################################################################### -# Link Libraries to the Executeable +# Link Libraries to the Executable ####################################################################################### #Link flags -get_property(LINK_TEST_LIBRARY GLOBAL PROPERTY FORTE_LINK_LIBRARY) +get_property(LINK_TEST_LIBRARY GLOBAL PROPERTY FORTE_TEST_LIBRARIES) +TARGET_LINK_LIBRARIES(forte_test ${LINK_TEST_LIBRARY}) -if("${FORTE_ARCHITECTURE}" STREQUAL "Posix") - SET_PROPERTY(GLOBAL APPEND PROPERTY LINK_TEST_LIBRARY "-lboost_unit_test_framework -lboost_prg_exec_monitor -lboost_test_exec_monitor") -endif("${FORTE_ARCHITECTURE}" STREQUAL "Posix") +####################################################################################### +# Link Libraries to the C Interface Executable +####################################################################################### -TARGET_LINK_LIBRARIES(forte_test ${LINK_TEST_LIBRARY}) +if(FORTE_C_INTERFACE) + if(FORTE_BUILD_STATIC_LIBRARY) + SET(FORTE_C_STATIC_TEST_NAME "forte_c_static_test") + + ADD_EXECUTABLE(${FORTE_C_STATIC_TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/arch/forte_c_test.cpp) + TARGET_LINK_LIBRARIES(${FORTE_C_STATIC_TEST_NAME} forte-c-static ${LINK_TEST_LIBRARY}) + target_include_directories(${FORTE_C_STATIC_TEST_NAME} PRIVATE ${FORTE_TEST_INC}) + SET_TARGET_PROPERTIES(${FORTE_C_STATIC_TEST_NAME} PROPERTIES LINKER_LANGUAGE CXX) + + add_test(${FORTE_C_STATIC_TEST_NAME} ${EXECUTABLE_OUTPUT_PATH}/${FORTE_C_STATIC_TEST_NAME}) + endif(FORTE_BUILD_STATIC_LIBRARY) + + # Currently not working in windows + if(FORTE_BUILD_SHARED_LIBRARY AND NOT WIN32) + SET(FORTE_C_SHARED_TEST_NAME "forte_c_shared_test") + + ADD_EXECUTABLE(${FORTE_C_SHARED_TEST_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/arch/forte_c_test.cpp) + TARGET_LINK_LIBRARIES(${FORTE_C_SHARED_TEST_NAME} forte-c-shared ${LINK_TEST_LIBRARY}) + target_include_directories(${FORTE_C_SHARED_TEST_NAME} PRIVATE ${FORTE_TEST_INC}) + SET_TARGET_PROPERTIES(${FORTE_C_STATIC_TEST_NAME} PROPERTIES LINKER_LANGUAGE CXX) + + add_test(${FORTE_C_SHARED_TEST_NAME} ${EXECUTABLE_OUTPUT_PATH}/${FORTE_C_SHARED_TEST_NAME}) + endif(FORTE_BUILD_SHARED_LIBRARY AND NOT WIN32) +endif(FORTE_C_INTERFACE) + +####################################################################################### +# Test if main can link to forte-static +####################################################################################### +if(FORTE_BUILD_STATIC_LIBRARY) + SET(TEST_FORTE_STATIC "forte_test_static") + GET_PROPERTY(SOURCE_EXECUTABLE_CPP GLOBAL PROPERTY FORTE_EXECUTABLE_CPP) + add_executable (${TEST_FORTE_STATIC} ${SOURCE_EXECUTABLE_CPP}) + target_include_directories(${TEST_FORTE_STATIC} PRIVATE ${INCLUDE_DIRECTORIES}) + target_link_libraries (${TEST_FORTE_STATIC} forte-static) + add_dependencies (${TEST_FORTE_STATIC} forte-static) +endif(FORTE_BUILD_STATIC_LIBRARY) + +####################################################################################### +# Test if main can link to forte-shared +####################################################################################### +# Currently not working in windows +if(FORTE_BUILD_SHARED_LIBRARY AND NOT WIN32) + SET(TEST_FORTE_SHARED "forte_test_shared") + GET_PROPERTY(SOURCE_EXECUTABLE_CPP GLOBAL PROPERTY FORTE_EXECUTABLE_CPP) + add_executable (${TEST_FORTE_SHARED} ${SOURCE_EXECUTABLE_CPP}) + target_include_directories(${TEST_FORTE_SHARED} PRIVATE ${INCLUDE_DIRECTORIES}) + target_link_libraries (${TEST_FORTE_SHARED} forte-shared) + add_dependencies (${TEST_FORTE_SHARED} forte-shared) +endif(FORTE_BUILD_SHARED_LIBRARY AND NOT WIN32) \ No newline at end of file diff --git a/tests/arch/forte_c_test.cpp b/tests/arch/forte_c_test.cpp new file mode 100644 index 00000000..79a7a956 --- /dev/null +++ b/tests/arch/forte_c_test.cpp @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2024 Jose Cabral + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Jose Cabral - initial API and implementation and/or initial documentation + *******************************************************************************/ +#define BOOST_TEST_MODULE FORTE_C_TEST +#include + +#include "../../src/arch/c_interface/forte_c.h" + +#include +#include + +BOOST_AUTO_TEST_CASE(forte_c_interface) +{ + TForteInstance instance{nullptr}; + + // forteStartInstance + // invalid instance result + BOOST_TEST(forteStartInstance(61499, nullptr) == FORTE_WRONG_PARAMETERS); + + // invalid port number, greater than maximum 65535 + BOOST_TEST(forteStartInstance(65536, &instance) == FORTE_WRONG_PARAMETERS); + + char executable[] = "forte"; + char ipPortFlag[] = "-c"; + + int validArgc = 1; + char* validArgV[] = {executable}; + + // invalid ipPort address and parameter + { + int argc = 3; + char invalidAddress[] = "localhost"; + char* argv[] = {executable, ipPortFlag, invalidAddress}; + BOOST_TEST(forteStartInstanceGeneric(argc, argv, nullptr) == FORTE_WRONG_PARAMETERS); + + char nonExistingParameter[] = "--unknown"; + char* argv2[] = {executable, nonExistingParameter}; + BOOST_TEST(forteStartInstanceGeneric(argc, argv2, nullptr) == FORTE_WRONG_PARAMETERS); + } + + // architecture not initialized + { + BOOST_TEST(forteStartInstanceGeneric(validArgc, validArgV, &instance) == FORTE_ARCHITECTURE_NOT_READY); + } + + // valid case and invalid case based on an existing running device + { + BOOST_TEST(forteGlobalInitialize(validArgc, validArgV) == 0); + + // double initialization of the architecture should not fail + BOOST_TEST(forteGlobalInitialize(validArgc, validArgV) == 0); + + BOOST_TEST(forteStartInstanceGeneric(validArgc, validArgV, &instance) == FORTE_OK); + + // try starting on already started device + BOOST_TEST(forteStartInstanceGeneric(validArgc, validArgV, &instance) == FORTE_DEVICE_ALREADY_STARTED); + + // another instance on same port + TForteInstance instance2{nullptr}; + + // stopping non runnning instance should no crash + forteRequestStopInstance(instance2); + forteWaitForInstanceToStop(instance2); + + // let it sleep for some time to since if too fast, the stopping signal + // comes too early + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + // stop running instance + forteRequestStopInstance(instance); + forteWaitForInstanceToStop(instance); + + BOOST_TEST(forteGlobalDeinitialize() == 0); + + // double de-initialization of the architecture should not fail + BOOST_TEST(forteGlobalDeinitialize() == 0); + } +} + diff --git a/tests/core/trace/CMakeLists.txt b/tests/core/trace/CMakeLists.txt index 26b86bcb..3f741132 100644 --- a/tests/core/trace/CMakeLists.txt +++ b/tests/core/trace/CMakeLists.txt @@ -1,5 +1,5 @@ #******************************************************************************* -# Copyright (c) 2024 +# Copyright (c) 2024 Jose Cabral # This program and the accompanying materials are made available under the # terms of the Eclipse Public License 2.0 which is available at # http://www.eclipse.org/legal/epl-2.0. @@ -24,7 +24,7 @@ if(FORTE_TRACE_CTF_TEST) forte_test_add_sourcefile_cpp(TraceReaderSink.cpp) forte_test_add_sourcefile_cpp(EventMessage.cpp) - forte_add_link_library(babeltrace2) + forte_test_add_link_library(babeltrace2) SET(CTF_OUTPUT_DIR ${CMAKE_BINARY_DIR}/ctfOutput) SET(METADATA_FILE ${CMAKE_BINARY_DIR}/src/core/trace/metadata) diff --git a/tests/core/trace/ctfTracerTest.cpp b/tests/core/trace/ctfTracerTest.cpp index a1c5918b..68056680 100644 --- a/tests/core/trace/ctfTracerTest.cpp +++ b/tests/core/trace/ctfTracerTest.cpp @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019 fotiss GmbH + * Copyright (c) 2024 Jose Cabral * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. @@ -16,6 +16,7 @@ #include #include +#include "forte_boost_output_support.h" #include "../stdfblib/ita/EMB_RES.h" #include "config.h" #include "ctfTracerTest_gen.cpp" @@ -77,8 +78,7 @@ BOOST_AUTO_TEST_CASE(sequential_events_test) { command.mFirstParam.pushBack(g_nStringIdCOLD); command.mSecondParam.pushBack(counterInstanceName); command.mSecondParam.pushBack(g_nStringIdCU); - - BOOST_CHECK(EMGMResponse::Ready == resource.executeMGMCommand(command)); + BOOST_TEST(EMGMResponse::Ready == resource.executeMGMCommand(command)); BOOST_TEST_INFO("Event connection: Counter.CUO -> Switch.EI"); command.mFirstParam.clear(); @@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(sequential_events_test) { command.mSecondParam.clear(); command.mSecondParam.pushBack(switchInstanceName); command.mSecondParam.pushBack(g_nStringIdEI); - BOOST_CHECK(EMGMResponse::Ready == resource.executeMGMCommand(command)); + BOOST_TEST(EMGMResponse::Ready == resource.executeMGMCommand(command)); BOOST_TEST_INFO("Data connection: Counter.Q -> Switch.G "); command.mFirstParam.clear(); @@ -96,13 +96,13 @@ BOOST_AUTO_TEST_CASE(sequential_events_test) { command.mSecondParam.clear(); command.mSecondParam.pushBack(switchInstanceName); command.mSecondParam.pushBack(g_nStringIdG); - BOOST_CHECK(EMGMResponse::Ready == resource.executeMGMCommand(command)); + BOOST_TEST(EMGMResponse::Ready == resource.executeMGMCommand(command)); BOOST_TEST_INFO(" Data constant value: Counter.PV = 1"); command.mFirstParam.clear(); command.mFirstParam.pushBack(counterInstanceName); command.mFirstParam.pushBack(g_nStringIdPV); - BOOST_CHECK(EMGMResponse::Ready == resource.writeValue(command.mFirstParam, "1", false)); + BOOST_TEST(EMGMResponse::Ready == resource.writeValue(command.mFirstParam, "1", false)); BOOST_TEST_INFO("Event connection: Switch.EO1 -> Counter.R "); command.mFirstParam.clear(); @@ -111,7 +111,7 @@ BOOST_AUTO_TEST_CASE(sequential_events_test) { command.mSecondParam.clear(); command.mSecondParam.pushBack(counterInstanceName); command.mSecondParam.pushBack(g_nStringIdR); - BOOST_CHECK(EMGMResponse::Ready == resource.executeMGMCommand(command)); + BOOST_TEST(EMGMResponse::Ready == resource.executeMGMCommand(command)); device.startDevice(); // wait for all events to be triggered @@ -150,7 +150,7 @@ BOOST_AUTO_TEST_CASE(sequential_events_test) { auto ctfMessages = getEventMessages(CTF_OUTPUT_DIR); BOOST_TEST_INFO("Expected vs traced: Same size "); - BOOST_CHECK_EQUAL(ctfMessages.size(), expectedMessages.size()); + BOOST_TEST(ctfMessages.size() == expectedMessages.size()); // although vectors can be check directly, this granularity helps debugging in case some message is different for(size_t i = 0; i < expectedMessages.size(); i++ ){ @@ -160,7 +160,7 @@ BOOST_AUTO_TEST_CASE(sequential_events_test) { // add extra event to check that the comparison fails expectedMessages.emplace_back("sendOutputEvent", std::make_unique("E_RESTART", "START", 2),0); - BOOST_CHECK(ctfMessages != expectedMessages); + BOOST_TEST(ctfMessages != expectedMessages); } BOOST_AUTO_TEST_SUITE_END()