diff --git a/.appveyor.yml b/.appveyor.yml index 83cb2f5059..2736459328 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,7 +2,7 @@ image: - Visual Studio 2017 environment: HOPSAN_BUILD_SCRIPT_NOPAUSE: 1 - HOPSAN_BUILD_QT_HOME: C:\Qt\5.12.6\mingw73_64 + HOPSAN_BUILD_QT_HOME: C:\Qt\5.13.2\mingw73_64 HOPSAN_BUILD_MINGW_HOME: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64 platform: x64 configuration: Release @@ -16,12 +16,12 @@ build_script: - set PATH=%PATH:C:\Program Files\Git\usr\bin;=% - PATH - cd dependencies - - setupDiscount.bat - - setupFmi4c.bat - - setupXerces.bat - setupZlib.bat - setupLibzip.bat + - setupXerces.bat - setupDCPLib.bat + - setupDiscount.bat + - setupFmi4c.bat # - setupHDF5.bat (takes to long to build) - setupKatex.bat - setupTclap.bat @@ -31,12 +31,15 @@ build_script: - setupSsp4c.bat - call setHopsanBuildPaths.bat - cd .. - - mkdir build - - cd build - - qmake.exe ..\HopsanNG.pro -r -spec win32-g++ CONFIG+=release - - cd .. - - mingw32-make.exe -j6 -C build + - cmake -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install_dir -Bbuild_dir -S. + - cmake --build build_dir --config Release --parallel 6 + - cmake --build build_dir --config Release --parallel 6 --target install + - cd install_dir - dir bin + - cd .. test_script: - - runUnitTests.bat - - runValidationTests.bat + - cd build_dir + - ctest -C Release --output-on-failure --parallel 4 + - cd .. +# - set PATH=%CD%\install\bin;%PATH% +# - runValidationTests.bat TODO Fix this diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index fd86150961..e969a348c1 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -2,9 +2,9 @@ name: ghactions-ci-build on: [pull_request] jobs: - cmake-msvc2019: + cmake-msvc2022: timeout-minutes: 30 - runs-on: windows-2025 + runs-on: windows-2022 env: HOPSAN_BUILD_SCRIPT_NOPAUSE: 1 HOPSAN_BUILD_CMAKE_GENERATOR: '"Visual Studio 17 2022"' @@ -45,13 +45,13 @@ jobs: working-directory: dependencies run: | call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" amd64 - call setupDiscount.bat - call setupTclap.bat - call setupFmi4c.bat call setupZlib.bat call setupLibzip.bat call setupXerces.bat call setupDCPLib.bat + call setupDiscount.bat + call setupFmi4c.bat + call setupTclap.bat call setupQwt.bat call setupSsp4c.bat @@ -101,12 +101,12 @@ jobs: shell: bash working-directory: dependencies run: | - ./setupDiscount.sh - ./setupTclap.sh - ./setupFmi4c.sh ./setupLibzip.sh ./setupXerces.sh ./setupDCPLib.sh + ./setupDiscount.sh + ./setupFmi4c.sh + ./setupTclap.sh ./setupQwt.sh ./setupSsp4c.sh diff --git a/.gitignore b/.gitignore index 347e245f35..29ece2383c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .vs/ bin/ HopsanNG_bd/ +build/ output64/ output/ output_deb/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 5cbe7f9d03..9d13a5bdac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,13 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.10) project(Hopsan) cmake_policy(SET CMP0054 NEW) -cmake_policy(SET CMP0079 NEW) +cmake_policy(SET CMP0057 NEW) +if (POLICY CMP0079) + cmake_policy(SET CMP0079 NEW) +endif() -set(HOPSANCORE_INSTALL_DST "HopsanCore") -message(WARNING "Hopsan CMake support is still experimental, but should be working for for GCC / MinGW and limited MSVC build") +set(HOPSANCORE_INSTALL_DST "HopsanCore" CACHE STRING "") include(CheckCXXCompilerFlag) if (MINGW) @@ -77,7 +79,7 @@ if (WIN32) if (MINGW) file(TO_CMAKE_PATH "$ENV{mingw_path}" mingw_home_bin) - if (EXISTS ${mingw_path}) + if (EXISTS ${mingw_home_bin}) message(STATUS "Installing from MinGW directory: ${mingw_home_bin}") install(FILES ${mingw_home_bin}/libgcc_s_seh-1.dll @@ -87,14 +89,14 @@ if (WIN32) # Qt binaries that are only part of the mingw build if (EXISTS ${qt_home_bin}) - install(FILES ${qt_home_bin}/Qt5WebKit.dll - ${qt_home_bin}/Qt5WebKitWidgets.dll - ${qt_home_bin}/libicuin56.dll - ${qt_home_bin}/libicuuc56.dll - ${qt_home_bin}/libicudt56.dll - ${qt_home_bin}/libeay32.dll - ${qt_home_bin}/ssleay32.dll - DESTINATION bin) + install_files_if_they_exist(bin + ${qt_home_bin}/Qt5WebKit.dll + ${qt_home_bin}/Qt5WebKitWidgets.dll + ${qt_home_bin}/libicuin56.dll + ${qt_home_bin}/libicuuc56.dll + ${qt_home_bin}/libicudt56.dll + ${qt_home_bin}/libeay32.dll + ${qt_home_bin}/ssleay32.dll) endif() else() message(WARNING "Env variable mingw_path not set, not installing mingw binaries") diff --git a/HopsanCLI/CMakeLists.txt b/HopsanCLI/CMakeLists.txt index cf42dc610b..b909df4da4 100644 --- a/HopsanCLI/CMakeLists.txt +++ b/HopsanCLI/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) + project(HopsanCLI) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) @@ -9,6 +9,11 @@ file(GLOB_RECURSE hopsancli_srcfiles *.cpp *.h *.hpp) add_executable(hopsancli ${hopsancli_srcfiles}) +if(MSVC) + # Enable multi-core build with MSVC + target_compile_options(hopsancli PRIVATE "/MP") +endif() + target_include_directories(hopsancli PRIVATE $ $ diff --git a/HopsanCore/CMakeLists.txt b/HopsanCore/CMakeLists.txt index 20f59a3368..6e9eb15bf0 100644 --- a/HopsanCore/CMakeLists.txt +++ b/HopsanCore/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.1) project(HopsanCore) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) @@ -7,7 +6,7 @@ if(WIN32) endif() find_package(Threads) -set(HOPSANCORE_INSTALL_DST "" CACHE STRING "Hopsan source code installation relative CMAKE_INSTALL_PREFIX ") +set(HOPSANCORE_INSTALL_DST "" CACHE STRING "Hopsan source code installation relative CMAKE_INSTALL_PREFIX") # Include dependencies functions include(dependencies/libnumhop.cmake) @@ -26,6 +25,11 @@ add_indexingcsvparser_src(hopsancore) add_rapidxml_src(hopsancore) add_sundials_src(hopsancore) +if(MSVC) + # Enable multi-core build with MSVC + target_compile_options(hopsancore PRIVATE "/MP") +endif() + # Set compiler definitions if(WIN32) target_compile_definitions(hopsancore PRIVATE HOPSANCORE_DLLEXPORT) @@ -38,7 +42,11 @@ if (MSVC) # Undefine odd min and max macros to enable use of std::min, std::max, make it public so all projects get this define target_compile_definitions(hopsancore PUBLIC NOMINMAX) endif() -target_compile_definitions(hopsancore PRIVATE HOPSANCORE_WRITELOG) +if (NOT MSVC) + # Do not enable core logging with msvc + # TODO Investigate why its not working, comment from release script was "so that MSVC dlls do not try to access the log file" + target_compile_definitions(hopsancore PRIVATE HOPSANCORE_WRITELOG) +endif() if(CMAKE_BUILD_TYPE MATCHES Debug) target_compile_definitions(hopsancore PUBLIC HOPSAN_BUILD_TYPE_DEBUG) else() diff --git a/HopsanGUI/CMakeLists.txt b/HopsanGUI/CMakeLists.txt index 7bc5b10cf2..85b5df42c2 100644 --- a/HopsanGUI/CMakeLists.txt +++ b/HopsanGUI/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) + project(HopsanGUI) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) @@ -7,9 +7,12 @@ if(WIN32) endif() if(WIN32) -find_package(Qt5 COMPONENTS Core Gui Widgets Xml Svg Network Test PrintSupport REQUIRED) + find_package(Qt5 COMPONENTS Core Gui Widgets Xml Svg Network Test PrintSupport REQUIRED) + if(MINGW) + find_package(Qt5 OPTIONAL_COMPONENTS WebKitWidgets) + endif() else() -find_package(Qt5 COMPONENTS Core Gui Widgets Xml Svg Network Test PrintSupport WebEngineWidgets REQUIRED) + find_package(Qt5 COMPONENTS Core Gui Widgets Xml Svg Network Test PrintSupport WebEngineWidgets REQUIRED) endif() set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) @@ -18,38 +21,46 @@ include(${CMAKE_CURRENT_LIST_DIR}/../helpers.cmake) include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/qwt.cmake) include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/discount.cmake) include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/katex.cmake) -include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/libzip.cmake) -include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/xerces.cmake) include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/ssp4c.cmake) -set(target_name hopsangui) - file(GLOB_RECURSE srcfiles *.cpp *.h *.hpp *.qrc) -add_executable(${target_name} ${srcfiles}) +add_executable(hopsangui ${srcfiles}) -target_include_directories(${target_name} PRIVATE +if(MSVC) + # Enable multi-core build with MSVC + target_compile_options(hopsangui PRIVATE "/MP") +endif() + +target_include_directories(hopsangui PRIVATE $ - $ - $ - $) + $) -target_compile_definitions(${target_name} PRIVATE _USE_MATH_DEFINES) +target_compile_definitions(hopsangui PRIVATE _USE_MATH_DEFINES) +target_compile_definitions(hopsangui PRIVATE DEVELOPMENT) if(NOT CMAKE_BUILD_TYPE MATCHES Debug) # Silence qDebug() for all non Debug configurations - target_compile_definitions(${target_name} PRIVATE QT_NO_DEBUG_OUTPUT) + target_compile_definitions(hopsangui PRIVATE QT_NO_DEBUG_OUTPUT) endif() -target_link_libraries(${target_name} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Xml Qt5::Svg Qt5::Network Qt5::Test Qt5::PrintSupport - qwt hopsancore hopsangeneratorgui symhop ops hopsandcp xercesc ssp4c ) +target_link_libraries(hopsangui Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Xml Qt5::Svg Qt5::Network Qt5::Test Qt5::PrintSupport + qwt hopsancore hopsangeneratorgui symhop ops hopsandcp ssp4c::ssp4c) if(UNIX) -target_link_libraries(${target_name} Qt5::WebEngineWidgets) + message(STATUS "Linking with Qt5::WebEngineWidgets") + target_link_libraries(hopsangui Qt5::WebEngineWidgets) + target_compile_definitions(hopsangui PRIVATE USEWEBENGINE) +endif() +# If Qt5WebKitWidgets was found, link it +if (Qt5WebKitWidgets_DIR) + message(STATUS "Linking with Qt5::WebKitWidgets") + target_link_libraries(hopsangui Qt5::WebKitWidgets) + target_compile_definitions(hopsangui PRIVATE USEWEBKIT) endif() -target_link_optional_libraries(${target_name} libhopsanremoteclient hopsanhdf5exporter discount katex) +target_link_optional_libraries(hopsangui libhopsanremoteclient hopsanhdf5exporter discount katex) -set_target_properties(${target_name} PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") +set_target_properties(hopsangui PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") -install(TARGETS ${target_name} +install(TARGETS hopsangui RUNTIME DESTINATION bin ) diff --git a/HopsanGUI/PlotArea.cpp b/HopsanGUI/PlotArea.cpp index c54b0a9604..3d034358c5 100644 --- a/HopsanGUI/PlotArea.cpp +++ b/HopsanGUI/PlotArea.cpp @@ -273,12 +273,20 @@ PlotArea::PlotArea(PlotTab *pParentPlotTab) // Legend Stuff mpRightPlotLegend = new PlotLegend(QwtPlot::yRight); mpRightPlotLegend->attach(mpQwtPlot); +#if QWT_VERSION >= 0x060300 mpRightPlotLegend->setAlignmentInCanvas(Qt::AlignRight | Qt::AlignTop); +#else + mpRightPlotLegend->setAlignment(Qt::AlignRight | Qt::AlignTop); +#endif mpRightPlotLegend->setZ(LegendBelowCurveZOrderType); mpLeftPlotLegend = new PlotLegend(QwtPlot::yLeft); mpLeftPlotLegend->attach(mpQwtPlot); +#if QWT_VERSION >= 0x060300 mpLeftPlotLegend->setAlignmentInCanvas(Qt::AlignLeft | Qt::AlignTop); +#else + mpLeftPlotLegend->setAlignment(Qt::AlignLeft | Qt::AlignTop); +#endif mpLeftPlotLegend->setZ(LegendBelowCurveZOrderType); constructLegendSettingsDialog(); @@ -1869,6 +1877,7 @@ void PlotArea::applyLegendSettings() int alignL = mpLegendLPosition->currentIndex(); int alignR = mpLegendRPosition->currentIndex(); +#if QWT_VERSION >= 0x060300 if ( alignL == 0 ) { mpLeftPlotLegend->setAlignmentInCanvas(Qt::AlignTop | Qt::AlignLeft); @@ -1894,6 +1903,33 @@ void PlotArea::applyLegendSettings() { mpRightPlotLegend->setAlignmentInCanvas(Qt::AlignVCenter | Qt::AlignRight); } +#else + if ( alignL == 0 ) + { + mpLeftPlotLegend->setAlignment(Qt::AlignTop | Qt::AlignLeft); + } + else if ( alignL == 1 ) + { + mpLeftPlotLegend->setAlignment(Qt::AlignBottom | Qt::AlignLeft); + } + else + { + mpLeftPlotLegend->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); + } + + if ( alignR == 0 ) + { + mpRightPlotLegend->setAlignment(Qt::AlignTop | Qt::AlignRight); + } + else if ( alignR == 1 ) + { + mpRightPlotLegend->setAlignment(Qt::AlignBottom | Qt::AlignRight); + } + else + { + mpRightPlotLegend->setAlignment(Qt::AlignVCenter | Qt::AlignRight); + } +#endif QColor bgColor(mpLegendBgColor->currentText()); //bgColor.setAlpha(128); @@ -2716,6 +2752,7 @@ void PlotArea::setSmartYAxisLimits(const QwtPlot::Axis axisId, QwtInterval axisL void PlotArea::calculateLegendBufferOffsets(const QwtPlot::Axis axisId, double &rBottomOffset, double &rTopOffset) { double leftLegendHeight=0, rightLegendHeight=0; +#if QWT_VERSION >= 0x060300 if (mpLeftPlotLegend->isVisible()) { leftLegendHeight = mpLeftPlotLegend->geometry(mpQwtPlot->geometry()).height() + mpLeftPlotLegend->offsetInCanvas(Qt::Vertical); @@ -2724,11 +2761,26 @@ void PlotArea::calculateLegendBufferOffsets(const QwtPlot::Axis axisId, double & { rightLegendHeight = mpRightPlotLegend->geometry(mpQwtPlot->geometry()).height() + mpRightPlotLegend->offsetInCanvas(Qt::Vertical); } +#else + if (mpLeftPlotLegend->isVisible()) + { + leftLegendHeight = mpLeftPlotLegend->geometry(mpQwtPlot->geometry()).height() + mpLeftPlotLegend->borderDistance(); + } + if (mpRightPlotLegend->isVisible()) + { + rightLegendHeight = mpRightPlotLegend->geometry(mpQwtPlot->geometry()).height() + mpRightPlotLegend->borderDistance(); + } +#endif //! @todo even if a legend is empty it seems to be visible and the borderDistance will be added, this causes unnecessary space when on top or bottom (and the other legend is not) // Figure out vertical alignment, by bitwise masking +#if QWT_VERSION >= 0x060300 Qt::Alignment lva = mpLeftPlotLegend->alignmentInCanvas() & Qt::AlignVertical_Mask; Qt::Alignment rva = mpRightPlotLegend->alignmentInCanvas() & Qt::AlignVertical_Mask; +#else + Qt::Alignment lva = mpLeftPlotLegend->alignment() & Qt::AlignVertical_Mask; + Qt::Alignment rva = mpRightPlotLegend->alignment() & Qt::AlignVertical_Mask; +#endif rBottomOffset = rTopOffset = 0; if(mpLegendsAutoOffsetCheckBox->isChecked()) diff --git a/HopsanGUI/Widgets/ModelWidget.h b/HopsanGUI/Widgets/ModelWidget.h index 4dc8d2d687..b5ba9fbb0a 100644 --- a/HopsanGUI/Widgets/ModelWidget.h +++ b/HopsanGUI/Widgets/ModelWidget.h @@ -58,7 +58,6 @@ class AnimationWidget; class SimulationThreadHandler; class GUIMessageHandler; class LogDataHandler2; -class ssdHandle; #include "CoreAccess.h" #include "RemoteCoreAccess.h" diff --git a/HopsanGUI/Widgets/SSMEditorWidget.cpp b/HopsanGUI/Widgets/SSMEditorWidget.cpp index acb305f1a7..0bceec0458 100644 --- a/HopsanGUI/Widgets/SSMEditorWidget.cpp +++ b/HopsanGUI/Widgets/SSMEditorWidget.cpp @@ -27,14 +27,13 @@ //! @brief A widget for editing SSM parameter mappings //! @author Robert Braun //! -//$Id$ #include "SSMEditorWidget.h" -#include +#include #include -#include #include -#include +#include +#include #include "ssp4c_ssm_parameter_mapping.h" #include "ssp4c_ssm_mapping_entry.h" diff --git a/HopsanGUI/Widgets/SSMEditorWidget.h b/HopsanGUI/Widgets/SSMEditorWidget.h index b6bae490e5..32fa0e7902 100644 --- a/HopsanGUI/Widgets/SSMEditorWidget.h +++ b/HopsanGUI/Widgets/SSMEditorWidget.h @@ -27,18 +27,16 @@ //! @brief A widget for editing SSM parameter mappings //! @author Robert Braun //! -//$Id$ #ifndef SSMEDITORGWIDGET_H #define SSMEDITORGWIDGET_H -#include +#include #include -#include +#include // Forward declarations -class ssmParameterMappingHandle; -class QPushButton; +struct ssmParameterMappingHandle; class SSMEditorWidget : public QWidget { diff --git a/HopsanGUI/Widgets/SSPWidget.h b/HopsanGUI/Widgets/SSPWidget.h index c1cbf663af..6e406616b5 100644 --- a/HopsanGUI/Widgets/SSPWidget.h +++ b/HopsanGUI/Widgets/SSPWidget.h @@ -1,19 +1,40 @@ -#include -#include -#include - #ifndef SSPWIDGET_H #define SSPWIDGET_H #include +#include +#include +#include //Forward declarations -class sspHandle; -class ssdHandle; -class ssvParameterSetHandle; -class ssmParameterMappingHandle; -class ssdSystemHandle; -class SSPTreeWidget; +struct sspHandle; +struct ssdHandle; +struct ssvParameterSetHandle; +struct ssmParameterMappingHandle; +struct ssdSystemHandle; + +class SSPTreeWidget : public QTreeWidget +{ + Q_OBJECT + +public: + explicit SSPTreeWidget(QWidget *parent = nullptr); + + enum ItemType { + SSPItem, + SSDItem = QTreeWidgetItem::UserType + 1, + SystemItem, + FMUItem, + SSVItem, + SSMItem + }; + +protected: + void startDrag(Qt::DropActions supportedActions) override; + void dragMoveEvent(QDragMoveEvent *event) override; + void dropEvent(QDropEvent *event) override; + void contextMenuEvent(QContextMenuEvent *event) override; +}; class SSPWidget : public QWidget { @@ -42,29 +63,4 @@ protected slots: QMap mSspFileMap; }; -class SSPTreeWidget : public QTreeWidget -{ - Q_OBJECT - -public: - explicit SSPTreeWidget(QWidget *parent = nullptr); - - enum ItemType { - SSPItem, - SSDItem = QTreeWidgetItem::UserType + 1, - SystemItem, - FMUItem, - SSVItem, - SSMItem - }; - -protected: - void startDrag(Qt::DropActions supportedActions) override; - void dragMoveEvent(QDragMoveEvent *event) override; - void dropEvent(QDropEvent *event) override; - void contextMenuEvent(QContextMenuEvent *event) override; -}; - - - #endif // SSPWIDGET_H diff --git a/HopsanGUI/Widgets/SSVEditorWidget.cpp b/HopsanGUI/Widgets/SSVEditorWidget.cpp index 84feedbf22..dc3cc0b0b4 100644 --- a/HopsanGUI/Widgets/SSVEditorWidget.cpp +++ b/HopsanGUI/Widgets/SSVEditorWidget.cpp @@ -27,14 +27,13 @@ //! @brief A widget for editing SSV parameter sets //! @author Robert Braun //! -//$Id$ #include "SSVEditorWidget.h" -#include +#include #include -#include #include -#include +#include +#include #include "ssp4c.h" #include "ssp4c_ssv_parameter_set.h" diff --git a/HopsanGUI/Widgets/SSVEditorWidget.h b/HopsanGUI/Widgets/SSVEditorWidget.h index 6b3b77c8d9..9b6b3e868a 100644 --- a/HopsanGUI/Widgets/SSVEditorWidget.h +++ b/HopsanGUI/Widgets/SSVEditorWidget.h @@ -27,18 +27,16 @@ //! @brief A widget for editing SSV parameter sets //! @author Robert Braun //! -//$Id$ #ifndef SSVEDITORWIDGET_H #define SSVEDITORWIDGET_H -#include +#include #include -#include +#include // Forward declarations -class ssvParameterSetHandle; -class QPushButton; +struct ssvParameterSetHandle; class SSVEditorWidget : public QWidget { diff --git a/HopsanGenerator/CMakeLists.txt b/HopsanGenerator/CMakeLists.txt index 355f16483c..acd987ba33 100644 --- a/HopsanGenerator/CMakeLists.txt +++ b/HopsanGenerator/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) + project(HopsanGenerator) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) @@ -10,31 +10,34 @@ find_package(Qt5 COMPONENTS Core Xml REQUIRED) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(target_name hopsangenerator) - file(GLOB_RECURSE srcfiles src/*.cpp include/*.h include/*.hpp templates.qrc) -add_library(${target_name} SHARED ${srcfiles}) +add_library(hopsangenerator SHARED ${srcfiles}) + +if(MSVC) + # Enable multi-core build with MSVC + target_compile_options(hopsangenerator PRIVATE "/MP") +endif() # Set compiler definitions if(WIN32) - target_compile_definitions(${target_name} PRIVATE HOPSANGENERATOR_DLLEXPORT) - target_compile_definitions(${target_name} INTERFACE HOPSANGENERATOR_DLLIMPORT) + target_compile_definitions(hopsangenerator PRIVATE HOPSANGENERATOR_DLLEXPORT) + target_compile_definitions(hopsangenerator INTERFACE HOPSANGENERATOR_DLLIMPORT) endif() if(NOT CMAKE_BUILD_TYPE MATCHES Debug) # Silence qDebug() for all non Debug configurations - target_compile_definitions(${target_name} PRIVATE QT_NO_DEBUG_OUTPUT) + target_compile_definitions(hopsangenerator PRIVATE QT_NO_DEBUG_OUTPUT) endif() -target_include_directories(${target_name} PUBLIC +target_include_directories(hopsangenerator PUBLIC $ $) -target_link_libraries(${target_name} hopsancore symhop Qt5::Core Qt5::Xml) +target_link_libraries(hopsangenerator hopsancore symhop Qt5::Core Qt5::Xml) -set_target_properties(${target_name} PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") +set_target_properties(hopsangenerator PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") -install(TARGETS ${target_name} +install(TARGETS hopsangenerator RUNTIME DESTINATION bin LIBRARY DESTINATION lib ) diff --git a/Ops/CMakeLists.txt b/Ops/CMakeLists.txt index dcc4e67f61..bfe3bb26bb 100644 --- a/Ops/CMakeLists.txt +++ b/Ops/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(Ops) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) @@ -9,6 +8,12 @@ endif() file(GLOB_RECURSE ops_srcfiles src/*.cpp ) add_library(ops SHARED ${ops_srcfiles}) + +if(MSVC) + # Enable multi-core build with MSVC + target_compile_options(ops PRIVATE "/MP") +endif() + target_include_directories(ops PUBLIC $ $) diff --git a/SymHop/CMakeLists.txt b/SymHop/CMakeLists.txt index 495a328811..b0aaca1504 100644 --- a/SymHop/CMakeLists.txt +++ b/SymHop/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.1) project(SymHop) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) @@ -16,6 +15,11 @@ file(GLOB_RECURSE headerfiles include/*.h include/*.hpp) # Create library target and add source code files add_library(symhop STATIC ${srcfiles} ${headerfiles}) +if(MSVC) + # Enable multi-core build with MSVC + target_compile_options(symhop PRIVATE "/MP") +endif() + # Set include directories target_include_directories(symhop PUBLIC $ diff --git a/UnitTests/DefaultLibraryXMLTest/CMakeLists.txt b/UnitTests/DefaultLibraryXMLTest/CMakeLists.txt index a2892b8e02..a13def6a6c 100644 --- a/UnitTests/DefaultLibraryXMLTest/CMakeLists.txt +++ b/UnitTests/DefaultLibraryXMLTest/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(DefaultLibraryXMLTest) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) diff --git a/UnitTests/GeneratorTest/CMakeLists.txt b/UnitTests/GeneratorTest/CMakeLists.txt index 59b2cb80b0..106f8bc914 100644 --- a/UnitTests/GeneratorTest/CMakeLists.txt +++ b/UnitTests/GeneratorTest/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(HopsanCoreTests) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) diff --git a/UnitTests/HopsanCoreTests/ComponentUtilitiesTest/CMakeLists.txt b/UnitTests/HopsanCoreTests/ComponentUtilitiesTest/CMakeLists.txt index 7f52053267..2017aa544a 100644 --- a/UnitTests/HopsanCoreTests/ComponentUtilitiesTest/CMakeLists.txt +++ b/UnitTests/HopsanCoreTests/ComponentUtilitiesTest/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(HopsanCoreTests) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) diff --git a/UnitTests/HopsanCoreTests/HStringTest/CMakeLists.txt b/UnitTests/HopsanCoreTests/HStringTest/CMakeLists.txt index b715dcd226..b8e9256dab 100644 --- a/UnitTests/HopsanCoreTests/HStringTest/CMakeLists.txt +++ b/UnitTests/HopsanCoreTests/HStringTest/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(HopsanCoreTests) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) diff --git a/UnitTests/HopsanCoreTests/HVectorTest/CMakeLists.txt b/UnitTests/HopsanCoreTests/HVectorTest/CMakeLists.txt index f61a6fef48..da42cd0778 100644 --- a/UnitTests/HopsanCoreTests/HVectorTest/CMakeLists.txt +++ b/UnitTests/HopsanCoreTests/HVectorTest/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(HopsanCoreTests) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) diff --git a/UnitTests/HopsanCoreTests/LookupTableTest/CMakeLists.txt b/UnitTests/HopsanCoreTests/LookupTableTest/CMakeLists.txt index a817cfea28..7b9fee6994 100644 --- a/UnitTests/HopsanCoreTests/LookupTableTest/CMakeLists.txt +++ b/UnitTests/HopsanCoreTests/LookupTableTest/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(HopsanCoreTests) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) diff --git a/UnitTests/HopsanCoreTests/SimulationTest/CMakeLists.txt b/UnitTests/HopsanCoreTests/SimulationTest/CMakeLists.txt index bae0c6c80d..79a04e1a03 100644 --- a/UnitTests/HopsanCoreTests/SimulationTest/CMakeLists.txt +++ b/UnitTests/HopsanCoreTests/SimulationTest/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(HopsanCoreTests) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) diff --git a/UnitTests/HopsanCoreTests/UtilitiesTest/CMakeLists.txt b/UnitTests/HopsanCoreTests/UtilitiesTest/CMakeLists.txt index b96d70898c..84ee4cfdaf 100644 --- a/UnitTests/HopsanCoreTests/UtilitiesTest/CMakeLists.txt +++ b/UnitTests/HopsanCoreTests/UtilitiesTest/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(HopsanCoreTests) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) diff --git a/UnitTests/SymHopTest/CMakeLists.txt b/UnitTests/SymHopTest/CMakeLists.txt index 001d13f021..f3884a9942 100644 --- a/UnitTests/SymHopTest/CMakeLists.txt +++ b/UnitTests/SymHopTest/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(HopsanCoreTests) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) diff --git a/UnitTests/hopsanclitest/CMakeLists.txt b/UnitTests/hopsanclitest/CMakeLists.txt index 7c58e35411..9825dce988 100644 --- a/UnitTests/hopsanclitest/CMakeLists.txt +++ b/UnitTests/hopsanclitest/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(hopsanclitest) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) diff --git a/Utilities/benchmarkClasses/classes.py b/Utilities/benchmarkClasses/classes.py index c9d37f6483..e9fa55f0b7 100644 --- a/Utilities/benchmarkClasses/classes.py +++ b/Utilities/benchmarkClasses/classes.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 __author__ = 'Peter Nordin' __email__ = "peter.nordin@liu.se" diff --git a/Utilities/benchmarkHopsanCLI.py b/Utilities/benchmarkHopsanCLI.py index d45acbfed5..e0eba4c5a8 100644 --- a/Utilities/benchmarkHopsanCLI.py +++ b/Utilities/benchmarkHopsanCLI.py @@ -1,8 +1,5 @@ -#!/usr/bin/python +#!/usr/bin/python3 # Script to benchmark Hopsan Core simulation through the CLI based on different compiler options -# Author: Peter Nordin -# Date: 20150708 -# $Id$ import shutil as sh import sys diff --git a/Utilities/evalBenchmark.py b/Utilities/evalBenchmark.py index 077f1b6300..412ad70996 100644 --- a/Utilities/evalBenchmark.py +++ b/Utilities/evalBenchmark.py @@ -1,8 +1,5 @@ -#!/usr/bin/python +#!/usr/bin/python3 # Script to evaluate benchmark results created by benchmarkHopsanCli.py -# Author: Peter Nordin -# Date: 20150714 -# $Id: evalBenchmark.py 8194 2015-07-08 14:34:05Z petno25 $ import matplotlib.pyplot as plt import sys diff --git a/Utilities/licenseChanger.py b/Utilities/licenseChanger.py index fe345da272..cc4ad99b2b 100755 --- a/Utilities/licenseChanger.py +++ b/Utilities/licenseChanger.py @@ -1,7 +1,5 @@ -#!/usr/bin/python +#!/usr/bin/python3 # Script to change the license header of code files -# Author: Peter Nordin -# $Id$ import os import sys diff --git a/componentLibraries/CMakeLists.txt b/componentLibraries/CMakeLists.txt index 46b0716447..1565ffa5f3 100644 --- a/componentLibraries/CMakeLists.txt +++ b/componentLibraries/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(ComponentLibraries) include(${CMAKE_CURRENT_LIST_DIR}/../helpers.cmake) diff --git a/componentLibraries/ModelicaExampleLib/CMakeLists.txt b/componentLibraries/ModelicaExampleLib/CMakeLists.txt index a9d71f6db6..fc174984b9 100644 --- a/componentLibraries/ModelicaExampleLib/CMakeLists.txt +++ b/componentLibraries/ModelicaExampleLib/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(ModelicaExampleLibrary) install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/ DESTINATION componentLibraries/modelica-example-library diff --git a/componentLibraries/autoLibs/CMakeLists.txt b/componentLibraries/autoLibs/CMakeLists.txt index b42df5179e..d927c44b21 100644 --- a/componentLibraries/autoLibs/CMakeLists.txt +++ b/componentLibraries/autoLibs/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(AutoLibs) install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/ DESTINATION componentLibraries/autoLibs diff --git a/componentLibraries/defaultLibrary/CMakeLists.txt b/componentLibraries/defaultLibrary/CMakeLists.txt index 7a2e9426c2..58169d210a 100644 --- a/componentLibraries/defaultLibrary/CMakeLists.txt +++ b/componentLibraries/defaultLibrary/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(DefaultComponentLibrary) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) @@ -8,17 +7,27 @@ include(${CMAKE_CURRENT_LIST_DIR}/../../dependencies/fmi4c.cmake) file(GLOB_RECURSE component_files *.cpp *.cci *.h *.hpp) add_library(defaultcomponentlibrary SHARED ${component_files}) + +if(MSVC) + # Enable multi-core build with MSVC + target_compile_options(defaultcomponentlibrary PRIVATE "/MP") +endif() + target_include_directories(defaultcomponentlibrary PUBLIC $) target_link_libraries(defaultcomponentlibrary hopsancore) -target_link_optional_libraries(defaultcomponentlibrary fmi4c) +target_link_optional_libraries(defaultcomponentlibrary fmi4c::fmi4c) if(WIN32) set_target_properties(defaultcomponentlibrary PROPERTIES PREFIX "" IMPORT_PREFIX "") endif() +if (MSVC) + target_compile_options(defaultcomponentlibrary PRIVATE "/bigobj") +endif() + install(TARGETS defaultcomponentlibrary RUNTIME DESTINATION componentLibraries/defaultLibrary LIBRARY DESTINATION componentLibraries/defaultLibrary diff --git a/componentLibraries/defaultLibrary/generateLibraryFiles.bat b/componentLibraries/defaultLibrary/generateLibraryFiles.bat index 0ba654b44b..176a2003eb 100644 --- a/componentLibraries/defaultLibrary/generateLibraryFiles.bat +++ b/componentLibraries/defaultLibrary/generateLibraryFiles.bat @@ -1,3 +1,3 @@ @echo off -C:\Python27\python.exe generateLibraryFiles.py . -if "%~1" neq "-nopause" pause \ No newline at end of file +python.exe generateLibraryFiles.py . +if "%~1" neq "-nopause" pause diff --git a/componentLibraries/defaultLibrary/generateLibraryFiles.py b/componentLibraries/defaultLibrary/generateLibraryFiles.py index 7d22479c27..c1252bac2f 100755 --- a/componentLibraries/defaultLibrary/generateLibraryFiles.py +++ b/componentLibraries/defaultLibrary/generateLibraryFiles.py @@ -1,8 +1,5 @@ -#!/usr/bin/python -# Script to generate all library files from teh existing directory structure and component hpp file -# Author: Peter Nordin -# Date: 20150319 -# $Id$ +#!/usr/bin/env python3 +# Script to generate all library files from the existing directory structure and component hpp file import os import sys @@ -212,7 +209,7 @@ def findFiles2(parentDir, suffixes, excludeDirs): def checkTypeName(filepath): typename = '' - file_h = open(filepath, 'r') + file_h = open(filepath, 'r', encoding='utf-8', errors='ignore') if not file_h.closed: found_creator = False # Read until we find the creator function diff --git a/componentLibraries/exampleComponentLib/CMakeLists.txt b/componentLibraries/exampleComponentLib/CMakeLists.txt index 68475ccf3d..31a8a66a44 100644 --- a/componentLibraries/exampleComponentLib/CMakeLists.txt +++ b/componentLibraries/exampleComponentLib/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(ExampleComponentLibrary) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) diff --git a/componentLibraries/exampleComponentLib/generateLibraryFiles.bat b/componentLibraries/exampleComponentLib/generateLibraryFiles.bat index 0ba654b44b..176a2003eb 100644 --- a/componentLibraries/exampleComponentLib/generateLibraryFiles.bat +++ b/componentLibraries/exampleComponentLib/generateLibraryFiles.bat @@ -1,3 +1,3 @@ @echo off -C:\Python27\python.exe generateLibraryFiles.py . -if "%~1" neq "-nopause" pause \ No newline at end of file +python.exe generateLibraryFiles.py . +if "%~1" neq "-nopause" pause diff --git a/componentLibraries/exampleComponentLib/generateLibraryFiles.py b/componentLibraries/exampleComponentLib/generateLibraryFiles.py index 7d22479c27..c1252bac2f 100755 --- a/componentLibraries/exampleComponentLib/generateLibraryFiles.py +++ b/componentLibraries/exampleComponentLib/generateLibraryFiles.py @@ -1,8 +1,5 @@ -#!/usr/bin/python -# Script to generate all library files from teh existing directory structure and component hpp file -# Author: Peter Nordin -# Date: 20150319 -# $Id$ +#!/usr/bin/env python3 +# Script to generate all library files from the existing directory structure and component hpp file import os import sys @@ -212,7 +209,7 @@ def findFiles2(parentDir, suffixes, excludeDirs): def checkTypeName(filepath): typename = '' - file_h = open(filepath, 'r') + file_h = open(filepath, 'r', encoding='utf-8', errors='ignore') if not file_h.closed: found_creator = False # Read until we find the creator function diff --git a/componentLibraries/extensionLibrary/CMakeLists.txt b/componentLibraries/extensionLibrary/CMakeLists.txt index 4387ab3ecc..ff483710e5 100644 --- a/componentLibraries/extensionLibrary/CMakeLists.txt +++ b/componentLibraries/extensionLibrary/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.0) project(ExampleComponentLibrary) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) diff --git a/componentLibraries/extensionLibrary/generateLibraryFiles.bat b/componentLibraries/extensionLibrary/generateLibraryFiles.bat index 0ba654b44b..176a2003eb 100644 --- a/componentLibraries/extensionLibrary/generateLibraryFiles.bat +++ b/componentLibraries/extensionLibrary/generateLibraryFiles.bat @@ -1,3 +1,3 @@ @echo off -C:\Python27\python.exe generateLibraryFiles.py . -if "%~1" neq "-nopause" pause \ No newline at end of file +python.exe generateLibraryFiles.py . +if "%~1" neq "-nopause" pause diff --git a/componentLibraries/extensionLibrary/generateLibraryFiles.py b/componentLibraries/extensionLibrary/generateLibraryFiles.py index 7d22479c27..c1252bac2f 100755 --- a/componentLibraries/extensionLibrary/generateLibraryFiles.py +++ b/componentLibraries/extensionLibrary/generateLibraryFiles.py @@ -1,8 +1,5 @@ -#!/usr/bin/python -# Script to generate all library files from teh existing directory structure and component hpp file -# Author: Peter Nordin -# Date: 20150319 -# $Id$ +#!/usr/bin/env python3 +# Script to generate all library files from the existing directory structure and component hpp file import os import sys @@ -212,7 +209,7 @@ def findFiles2(parentDir, suffixes, excludeDirs): def checkTypeName(filepath): typename = '' - file_h = open(filepath, 'r') + file_h = open(filepath, 'r', encoding='utf-8', errors='ignore') if not file_h.closed: found_creator = False # Read until we find the creator function diff --git a/dependencies/.gitattributes b/dependencies/.gitattributes index 59c6f1ab8e..b5c6f7bd72 100644 --- a/dependencies/.gitattributes +++ b/dependencies/.gitattributes @@ -1 +1,2 @@ discount-attribute.patch eol=lf +qwt-build.patch eol=lf diff --git a/dependencies/.gitignore b/dependencies/.gitignore index 24e7d88cd6..f3e5640306 100644 --- a/dependencies/.gitignore +++ b/dependencies/.gitignore @@ -1,30 +1,22 @@ +*-code/ +*-build/ +*-build*/ fmilibrary/ -fmilibrary-code/ -fmilibrary-build/ fmi4c/ -fmi4c-code/ -fmi4c-build*/ qwt/ -qwt-code/ -qwt-build/ zeromq/ -zeromq-code/ -zeromq-build/ discount/ -discount-code/ -discount-build/ hdf5/ -hdf5-code/ -hdf5-build/ katex/ -katex-code/ tclap/ -tclap-code/ -cppzmq-code/ msgpack-c/ -msgpack-c-code/ -msgpack-c-build/ -*.zip -*.tar.gz -*.tar.bz2 +libzip/ +zlib/ +xerces/ +dcplib/ +ssp4c/ *.7z +*.tar.bz2 +*.tar.gz +*.tar.xz +*.zip diff --git a/dependencies/dcplib.cmake b/dependencies/dcplib.cmake new file mode 100644 index 0000000000..69b721181b --- /dev/null +++ b/dependencies/dcplib.cmake @@ -0,0 +1,70 @@ +set(local_xerces_dir ${CMAKE_CURRENT_LIST_DIR}/xerces) +set(local_zlib_dir ${CMAKE_CURRENT_LIST_DIR}/zlib) +set(local_libzip_dir ${CMAKE_CURRENT_LIST_DIR}/libzip) +set(local_asio_dir ${CMAKE_CURRENT_LIST_DIR}/asio-code) +set(local_dcplib_dir ${CMAKE_CURRENT_LIST_DIR}/dcplib) + + +find_package(Threads) +find_package(ICU MODULE COMPONENTS uc data) +find_package(libzip CONFIG PATHS ${local_libzip_dir}) +find_package(XercesC CONFIG PATHS ${local_xerces_dir}) + +#add_library(ZIP::ZIP ALIAS libzip::zip) +# add alias compatible with older cmake versions +add_library(ZIP::ZIP INTERFACE IMPORTED) +set_target_properties(ZIP::ZIP PROPERTIES INTERFACE_LINK_LIBRARIES libzip::zip) + +# TODO Use proper ASIO lookup and installation +add_library(ASIO::ASIO INTERFACE IMPORTED) +set_target_properties(ASIO::ASIO PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "ASIO_STANDALONE" + INTERFACE_INCLUDE_DIRECTORIES "${local_asio_dir}/include" +) +target_link_libraries(ASIO::ASIO INTERFACE Threads::Threads) + +find_package(DCPLib CONFIG PATHS ${local_dcplib_dir} NO_DEFAULT_PATH) + + +# Add zlib to installation if local variant found +if (EXISTS ${local_zlib_dir}) + # When building with mingw, zlib uses the lib prefix on windows + if (MINGW) + file(GLOB lib_files ${local_zlib_dir}/bin/libzlib${CMAKE_SHARED_LIBRARY_SUFFIX}) + else() + file(GLOB lib_files ${local_zlib_dir}/bin/zlib${CMAKE_SHARED_LIBRARY_SUFFIX}) + endif() + install(FILES ${lib_files} DESTINATION bin) +endif() + +# Add libzip to installation if local variant found +if (EXISTS ${local_libzip_dir}) + # When building with mingw, libzip uses the lib prefix on windows + if (WIN32) + if (MINGW) + file(GLOB lib_files ${local_libzip_dir}/bin/libzip${CMAKE_SHARED_LIBRARY_SUFFIX}) + else() + file(GLOB lib_files ${local_libzip_dir}/bin/zip*${CMAKE_SHARED_LIBRARY_SUFFIX}) + endif() + install(FILES ${lib_files} DESTINATION bin) + else() + file(GLOB lib_files ${local_libzip_dir}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}zip${CMAKE_SHARED_LIBRARY_SUFFIX}*) + install(FILES ${lib_files} DESTINATION lib) + endif() +endif() + +# Add xerces to installation if local variant found +if (EXISTS ${local_xerces_dir}) + # When building with mingw, xerces uses the lib prefix on windows + if (WIN32) + if (MINGW) + file(GLOB lib_files ${local_xerces_dir}/bin/libxerces-c${CMAKE_SHARED_LIBRARY_SUFFIX}) + else() + file(GLOB lib_files ${local_xerces_dir}/bin/xerces-c*${CMAKE_SHARED_LIBRARY_SUFFIX}) + endif() + install(FILES ${lib_files} DESTINATION bin) + else() + file(GLOB lib_files ${local_xerces_dir}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}xerces-c*${CMAKE_SHARED_LIBRARY_SUFFIX}*) + install(FILES ${lib_files} DESTINATION lib) + endif() +endif() diff --git a/dependencies/dependencies.xml b/dependencies/dependencies.xml index 7171049e1b..5fa4667345 100644 --- a/dependencies/dependencies.xml +++ b/dependencies/dependencies.xml @@ -116,14 +116,14 @@ - - https://github.com/robbr48/fmi4c/archive/refs/tags/v1.1.zip + + https://github.com/robbr48/fmi4c/archive/4a77c6a971750be6b70b7d52f7ee492d0f901819.zip - - https://github.com/robbr48/ssp4c/archive/refs/tags/v1.0.zip + + https://github.com/peterNordin/ssp4c/archive/72339ea2955a6c44ab058193723b8fc260bfd56e.zip diff --git a/dependencies/download-dependencies.py b/dependencies/download-dependencies.py index 4d5be61e2b..9205e54ad8 100755 --- a/dependencies/download-dependencies.py +++ b/dependencies/download-dependencies.py @@ -179,6 +179,7 @@ class DependenciesXML: def __init__(self, dependencies_xml_file): tree = ET.parse(dependencies_xml_file) self.root = tree.getroot() + self.cache_dir = str() def __match_choice(self, name, version, choices, allow_missing): found_name = False @@ -204,6 +205,19 @@ def __download_and_check_releasefile(self, dep_name, releasefile_element, force) fname = decide_file_name(dep_name, url) do_download = True + + use_cache = len(self.cache_dir) > 0 + cached_fpath = os.path.join(self.cache_dir, fname) + if use_cache and not os.path.isfile(fname) and os.path.isfile(cached_fpath): + print("Found {} in download cache".format(fname)) + if verify_filehash(cached_fpath, hash_algo, expected_hashsum): + print("Copying {}".format(cached_fpath)) + shutil.copyfile(cached_fpath, fname) + else: + print('Warning: ' + hash_algo + ' missmatch in file ' + cached_fpath) + print('Expected: ' + expected_hashsum) + print('Actual: ' + hashsum_file(cached_fpath, hash_algo)) + if os.path.isfile(fname): print('Info: File already exists '+fname) if verify_filehash(fname, hash_algo, expected_hashsum): @@ -218,6 +232,9 @@ def __download_and_check_releasefile(self, dep_name, releasefile_element, force) if do_download: isok = download(url, fname, hash_algo, expected_hashsum) if isok: + if use_cache: + print("Copying {} to download cache {}".format(fname, cached_fpath)) + shutil.copyfile(fname, cached_fpath) return (fname, True, True) return ("", False, False) @@ -234,6 +251,9 @@ def __get_dependencies_matching_choice(self, chosen_deps, choose_all): allready_added_names.append(dep_name) return matching_dependencies + def set_download_cache_dir(self, dir_path): + self.cache_dir = dir_path + def list_dependencies(self): names = list() for dep in self.root: @@ -339,6 +359,7 @@ def download_and_unpack_chosen_dependencies(self, choices, download_all, include if __name__ == "__main__": argparser = argparse.ArgumentParser() argparser.add_argument('--all', dest='download_all', action='store_true', help='Download all dependencies (excluding toolchain)' ) + argparser.add_argument('--cache', dest='cache_dir', type=str, help='Cache directory for downloads') argparser.add_argument('--include-toolchain', dest='download_toolchain', action='store_true', help='Download toolchain dependencies' ) argparser.add_argument('--list', dest='list', action='store_true', help='List available dependencies' ) argparser.add_argument('--force', dest='force', action='store_true', @@ -352,6 +373,13 @@ def download_and_unpack_chosen_dependencies(self, choices, download_all, include chosen_deps = args.dependency_name[0] deps_xml = DependenciesXML('dependencies.xml') + if args.cache_dir: + print("Using download cache dir: " + args.cache_dir) + if not os.path.isdir(args.cache_dir): + print('Error: {} does not exist or is not a directory'.format(args.cache_dir)) + sys.exit(1) + deps_xml.set_download_cache_dir(args.cache_dir) + if args.output_flatpak: deps = deps_xml.ouput_dependencies_flatpak() output = str() @@ -366,6 +394,6 @@ def download_and_unpack_chosen_dependencies(self, choices, download_all, include deps_xml.check_choices(chosen_deps) all_ok = deps_xml.download_and_unpack_chosen_dependencies(chosen_deps, args.download_all, args.download_toolchain, args.force) if all_ok: - exit(0) + sys.exit(0) else: - exit(1) + sys.exit(1) diff --git a/dependencies/fmi4c.cmake b/dependencies/fmi4c.cmake index bc2eac9a16..e4e3053b6d 100644 --- a/dependencies/fmi4c.cmake +++ b/dependencies/fmi4c.cmake @@ -1,44 +1,14 @@ set(local_fmi4c_dir ${CMAKE_CURRENT_LIST_DIR}/fmi4c) if (EXISTS ${local_fmi4c_dir}) - - set(zlibstatic_name zlibstatic) - if (NOT WIN32) - set(zlibstatic_name z) - endif() - - set(fmi4c_dbg_ext "") - if (WIN32) - set(fmi4c_dbg_ext d) - endif() - - set(static_fmi4c ${local_fmi4c_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}fmi4c${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(static_fmi4c_d ${local_fmi4c_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}fmi4c${fmi4c_dbg_ext}${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(static_zlib ${local_fmi4c_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}${zlibstatic_name}${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(static_zlib_d ${local_fmi4c_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}${zlibstatic_name}${fmi4c_dbg_ext}${CMAKE_STATIC_LIBRARY_SUFFIX}) - - add_library(fmi4c STATIC IMPORTED) - - set_target_properties(fmi4c PROPERTIES - IMPORTED_LOCATION ${static_fmi4c} - IMPORTED_LOCATION_DEBUG ${static_fmi4c_d} - INTERFACE_INCLUDE_DIRECTORIES ${local_fmi4c_dir}/include - INTERFACE_COMPILE_DEFINITIONS "USEFMI4C;FMI4C_STATIC") - - if (EXISTS ${static_zlib}) - message(STATUS "Found static zlib in ${local_fmi4c_dir}") - add_library(fmi4c_zlib STATIC IMPORTED) - set_target_properties(fmi4c_zlib PROPERTIES - IMPORTED_LOCATION ${static_zlib} - IMPORTED_LOCATION_DEBUG ${static_zlib_d}) - target_link_libraries(fmi4c INTERFACE fmi4c_zlib) + find_package(fmi4c CONFIG PATHS ${local_fmi4c_dir} NO_DEFAULT_PATH) + if (fmi4c_FOUND) + message(STATUS "Building with Fmi4c support") + target_compile_definitions(fmi4c::fmi4c INTERFACE USEFMI4C) + install(DIRECTORY ${local_fmi4c_dir} DESTINATION dependencies) else() - find_package(ZLIB MODULE REQUIRED) - target_link_libraries(fmi4c INTERFACE ZLIB::ZLIB) + message(WARNING "Fmi4c configuration packet not found in ${local_fmi4c_dir}") endif() - - install(DIRECTORY ${local_fmi4c_dir} DESTINATION dependencies) - message(STATUS "Building with Fmi4c support") else() message(WARNING "Building without Fmi4c support") endif() diff --git a/dependencies/hdf5.cmake b/dependencies/hdf5.cmake index 1272798796..cf6d541237 100644 --- a/dependencies/hdf5.cmake +++ b/dependencies/hdf5.cmake @@ -14,6 +14,8 @@ if (hdf5_FOUND) message(STATUS "Building with HDF5 support") # TODO: Not sure why cant use hdf5:: namespace here target_compile_definitions(hdf5-shared INTERFACE USEHDF5) + #target_compile_definitions(hdf5::hdf5-shared INTERFACE USEHDF5) + #set_target_properties(hdf5::hdf5-shared PROPERTIES INTERFACE_COMPILE_DEFINITIONS USEHDF5) # Set as target property for compatibility with old CMake elseif(HDF5_FOUND) # Repackage results from FindHDF5 Module as target message(STATUS "Building with HDF5 module support") @@ -23,13 +25,14 @@ elseif(HDF5_FOUND) set_target_properties(module_hdf5-shared PROPERTIES INTERFACE_LINK_LIBRARIES "${HDF5_C_LIBRARIES}" INTERFACE_INCLUDE_DIRECTORIES "${HDF5_C_INCLUDE_DIRS}" - INTERFACE_COMPILE_DEFINITIONS "${HDF5_c_DEFINITIONS}") + INTERFACE_COMPILE_DEFINITIONS "${HDF5_C_DEFINITIONS}") add_library(hdf5::hdf5-shared ALIAS module_hdf5-shared) set_target_properties(module_hdf5_cpp-shared PROPERTIES INTERFACE_LINK_LIBRARIES "${HDF5_CXX_LIBRARIES}" INTERFACE_INCLUDE_DIRECTORIES "${HDF5_CXX_INCLUDE_DIRS}" INTERFACE_COMPILE_DEFINITIONS "${HDF5_CXX_DEFINITIONS}") - target_compile_definitions(module_hdf5_cpp-shared INTERFACE USEHDF5) + #target_compile_definitions(module_hdf5_cpp-shared INTERFACE USEHDF5) + set_target_properties(module_hdf5_cpp-shared PROPERTIES INTERFACE_COMPILE_DEFINITIONS USEHDF5) # Set as target property for compatibility with old CMake add_library(hdf5::hdf5_cpp-shared ALIAS module_hdf5_cpp-shared) endif() else() diff --git a/dependencies/libzip.cmake b/dependencies/libzip.cmake deleted file mode 100644 index 7790eca09e..0000000000 --- a/dependencies/libzip.cmake +++ /dev/null @@ -1,37 +0,0 @@ -set(local_libzip_dir ${CMAKE_CURRENT_LIST_DIR}/libzip) -if(WIN32) - set(CMAKE_FIND_LIBRARY_PREFIXES lib) -endif(WIN32) -find_library(libzip NAMES ${CMAKE_FIND_LIBRARY_PREFIXES}zip - ${CMAKE_FIND_LIBRARY_PREFIXES}zip${CMAKE_SHARED_LIBRARY_SUFFIX} - ${CMAKE_STATIC_LIBRARY_PREFIX}zip${CMAKE_STATIC_LIBRARY_SUFFIX} - ${CMAKE_STATIC_LIBRARY_PREFIX}zip${CMAKE_SHARED_LIBRARY_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} - PATHS ${local_libzip_dir}/lib NO_DEFAULT_PATH) - -if (libzip) - message(STATUS "Found local libzip") - add_library(libzip STATIC IMPORTED) - if (MSVC) - set_target_properties(libzip PROPERTIES - IMPORTED_LOCATION ${local_libzip_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}zip${CMAKE_STATIC_LIBRARY_SUFFIX} - INTERFACE_INCLUDE_DIRECTORIES ${local_libzip_dir}/include) - elseif (MINGW) - set_target_properties(libzip PROPERTIES - IMPORTED_LOCATION ${local_libzip_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}zip${CMAKE_SHARED_LIBRARY_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} - INTERFACE_INCLUDE_DIRECTORIES ${local_libzip_dir}/include) - else() - set_target_properties(libzip PROPERTIES - IMPORTED_LOCATION ${local_libzip_dir}/lib/libzip.so - INTERFACE_INCLUDE_DIRECTORIES ${local_libzip_dir}/include) - endif() - -else() - message(STATUS "Looking for libzip in system") - find_package(libzip CONFIG) # Search in system - if (libzip_FOUND) - message(STATUS "Found libzip") - add_library(libzip STATIC IMPORTED) - else() - message(WARNING "Could not find libzip") - endif() -endif() diff --git a/dependencies/msgpack.cmake b/dependencies/msgpack.cmake index 8e35bd7234..d939c57c2f 100644 --- a/dependencies/msgpack.cmake +++ b/dependencies/msgpack.cmake @@ -4,9 +4,9 @@ if (NOT msgpack_FOUND) message(STATUS "Looking for msgpack in system") find_package(msgpack CONFIG) # Search in system if (msgpack_FOUND) - message(STATUS " Found msgpack") + message(STATUS " Found system msgpack") if (NOT TARGET msgpackc-cxx) - add_library(msgpackc-cxx INTERFACE) + add_library(msgpackc-cxx INTERFACE IMPORTED) target_link_libraries(msgpackc-cxx INTERFACE msgpackc) endif() else() @@ -14,4 +14,8 @@ if (NOT msgpack_FOUND) endif() else() message(STATUS "Found local msgpack") + if (NOT TARGET msgpackc-cxx) + add_library(msgpackc-cxx INTERFACE IMPORTED) + target_link_libraries(msgpackc-cxx INTERFACE msgpackc) + endif() endif() diff --git a/dependencies/qwt-build.patch b/dependencies/qwt-build.patch index ad8423f9e8..b1e1973921 100644 --- a/dependencies/qwt-build.patch +++ b/dependencies/qwt-build.patch @@ -1,16 +1,5 @@ ---- qwtbuild.pri 2019-01-02 16:21:31.556467000 +0000 -+++ qwtbuild.pri 2019-02-07 11:35:07.912813492 +0000 -@@ -50,7 +50,7 @@ - #QMAKE_CXXFLAGS *= -Wsign-conversion - #QMAKE_CXXFLAGS *= -Wlogical-op - #QMAKE_CXXFLAGS *= -Werror=format-security -- #QMAKE_CXXFLAGS *= -std=c++11 -+ QMAKE_CXXFLAGS *= -std=c++11 - - # when using the gold linker ( Qt < 4.8 ) - might be - # necessary on non linux systems too ---- qwtconfig.pri 2019-01-02 16:21:31.556467000 +0000 -+++ qwtconfig.pri 2019-02-07 11:41:33.202068749 +0000 +--- qwtconfig.pri 2024-05-08 09:00:29.929579700 +0200 ++++ qwtconfig.pri 2026-03-20 19:45:37.481705300 +0100 @@ -28,6 +28,8 @@ # QWT_INSTALL_PREFIX = C:/Qwt-$$QWT_VERSION-qt-$$QT_VERSION } @@ -20,7 +9,7 @@ QWT_INSTALL_DOCS = $${QWT_INSTALL_PREFIX}/doc QWT_INSTALL_HEADERS = $${QWT_INSTALL_PREFIX}/include QWT_INSTALL_LIBS = $${QWT_INSTALL_PREFIX}/lib -@@ -118,7 +120,7 @@ +@@ -114,7 +116,7 @@ # Otherwise you have to build it from the designer directory. ###################################################################### @@ -29,7 +18,25 @@ ###################################################################### # Compile all Qwt classes into the designer plugin instead -@@ -161,7 +163,7 @@ +@@ -137,7 +139,7 @@ + # Otherwise you have to build them from the examples directory. + ###################################################################### + +-QWT_CONFIG += QwtExamples ++#QWT_CONFIG += QwtExamples + + ###################################################################### + # The playground is primarily intended for the Qwt development +@@ -148,7 +150,7 @@ + # Otherwise you have to build them from the playground directory. + ###################################################################### + +-QWT_CONFIG += QwtPlayground ++#QWT_CONFIG += QwtPlayground + + ###################################################################### + # If you want to auto build the tests, enable the line below +@@ -164,7 +166,7 @@ macx:!static:CONFIG(qt_framework, qt_framework|qt_no_framework) { diff --git a/dependencies/setupAll.bat b/dependencies/setupAll.bat index dbc78185fd..554b56086a 100644 --- a/dependencies/setupAll.bat +++ b/dependencies/setupAll.bat @@ -1,15 +1,19 @@ set HOPSAN_BUILD_SCRIPT_NOPAUSE=true + +REM First base libraries (order is important, zlib->libzip->xerces) +start /wait cmd /c setupZlib.bat +start /wait cmd /c setupLibzip.bat +start /wait cmd /c setupXerces.bat + +REM DCPLib depends on xerces and libzip +start /wait cmd /c setupDCPLib.bat start /wait cmd /c setupDiscount.bat start /wait cmd /c setupFmi4c.bat +REM HDF5 depends on zlib and libzip start /wait cmd /c setupHDF5.bat start /wait cmd /c setupKatex.bat start /wait cmd /c setupMsgpack.bat start /wait cmd /c setupQwt.bat start /wait cmd /c setupTclap.bat start /wait cmd /c setupZeroMQ.bat -start /wait cmd /c setupZlib.bat -start /wait cmd /c setupLibzip.bat -start /wait cmd /c setupXerces.bat -REM DCPLib must come after xerces and libzip (zlib before libzip) -start /wait cmd /c setupDCPLib.bat start /wait cmd /c setupSsp4c.bat diff --git a/dependencies/setupAll.sh b/dependencies/setupAll.sh index 66cb19dd0e..ea234c313d 100755 --- a/dependencies/setupAll.sh +++ b/dependencies/setupAll.sh @@ -1,15 +1,18 @@ #!/bin/bash + +# First base libraries xerces depends on libzip ./setupAsio.sh +./setupLibzip.sh +./setupXerces.sh + +# DCPLib depends on xerces and libzip +./setupDCPLib.sh ./setupDiscount.sh ./setupFmi4c.sh ./setupHDF5.sh ./setupKatex.sh -./setupLibzip.sh ./setupMsgpack.sh ./setupQwt.sh ./setupTclap.sh -./setupXerces.sh ./setupZeroMQ.sh -# DCPLib must come after xerces and libzip -./setupDCPLib.sh ./setupSsp4c.sh diff --git a/dependencies/setupDCPLib.bat b/dependencies/setupDCPLib.bat index dc777987ae..1833ddf264 100644 --- a/dependencies/setupDCPLib.bat +++ b/dependencies/setupDCPLib.bat @@ -8,19 +8,28 @@ set codedir=%basedir%\%name%-code set builddir=%basedir%\%name%-build set installdir=%basedir%\%name% -set xercesdir=%basedir:\=/%xerces - call setHopsanBuildPaths.bat -"%git_path%\..\usr\bin\patch" dcplib-code/include/core/dcp/model/pdu/IpToStr.hpp dcplib-patch.txt +set asiodir=%basedir%\asio-code +set libzipdir=%basedir%\libzip +set xercesdir=%basedir%\xerces + +set PATH=%PATH_WITH_MSYS% +patch.exe --forward dcplib-code/include/core/dcp/model/pdu/IpToStr.hpp dcplib-patch.txt +set PATH=%PATH_WITHOUT_MSYS% mkdir %builddir% -cd %builddir% -cmake -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DLOGGING=ON -DASIO_ROOT="%basedir%\asio-code" -DXercesC_LIBRARY="%xercesdir%/bin/libxerces-c.dll" -DXercesC_INCLUDE_DIR="%xercesdir%/include" -DXercesC_VERSION="3.2.2" -DZIP_LIBRARY="%basedir%\libzip\bin\libzip.dll" -DZIP_INCLUDE_DIR="%basedir%\libzip\include" -DCMAKE_INSTALL_PREFIX="%installdir%" %codedir% -cmake --build . --parallel 8 -cmake --build . --target install +cmake -B"%builddir%" ^ + -S"%codedir%" ^ + -G %HOPSAN_BUILD_CMAKE_GENERATOR% ^ + -Wno-dev ^ + -DLOGGING=ON ^ + -DASIO_ROOT="%asiodir%" ^ + -DCMAKE_PREFIX_PATH="%xercesdir%;%libzipdir%" ^ + -DCMAKE_INSTALL_PREFIX="%installdir%" +cmake --build %builddir% --parallel 8 +cmake --build %builddir% --target install -cd %basedir% echo. echo setupDCPLib.bat done if "%HOPSAN_BUILD_SCRIPT_NOPAUSE%" == "" ( diff --git a/dependencies/setupDCPLib.sh b/dependencies/setupDCPLib.sh index 2a10a1431f..f9f751fd65 100755 --- a/dependencies/setupDCPLib.sh +++ b/dependencies/setupDCPLib.sh @@ -10,29 +10,26 @@ builddir=${basedir}/${name}-build installdir=${basedir}/${name} xercesdir=${basedir}/xerces libzipdir=${basedir}/libzip +asiodir=${basedir}/asio-code # Download and verify ./download-dependencies.py ${name} #Patch code to fix bug -patch dcplib-code/include/core/dcp/model/pdu/IpToStr.hpp dcplib-patch.txt +patch --forward dcplib-code/include/core/dcp/model/pdu/IpToStr.hpp dcplib-patch.txt # Include general settings source setHopsanBuildPaths.sh -# Create build dir and enter it -mkdir -p $builddir -cd $builddir - -echo ${xercesdir}/lib/cmake/XercesC - -# Generate makefiles -cmake -Wno-dev -DLOGGING=ON -DASIO_ROOT="${basedir}/asio-code" -DCMAKE_PREFIX_PATH="${xercesdir};${libzipdir}" -DXercesC_VERSION="3.2.2" -DCMAKE_INSTALL_PREFIX="${installdir}" "${codedir}" +cmake -B"${builddir}" \ + -S"${codedir}" \ + -Wno-dev \ + -DASIO_ROOT="${asiodir}" \ + -DCMAKE_PREFIX_PATH="${xercesdir};${libzipdir}" \ + -DCMAKE_INSTALL_PREFIX="${installdir}" # Build and install -cmake --build . --parallel 8 -cmake --build . --target install +cmake --build "${builddir}" --parallel 8 +cmake --build "${builddir}" --target install -# Return to basedir -cd $basedir echo "setupDCPLib.sh done!" diff --git a/dependencies/setupDiscount.bat b/dependencies/setupDiscount.bat index 6b79f7afd1..45b6f7e699 100755 --- a/dependencies/setupDiscount.bat +++ b/dependencies/setupDiscount.bat @@ -1,5 +1,4 @@ @ECHO OFF - REM Bat script for building Discount automatically setlocal @@ -12,23 +11,43 @@ set installdir=%basedir%\%name% call setHopsanBuildPaths.bat -REM Apply build patch -set PATH=%PATH_WITH_MSYS% -cd %codedir% - REM Configure with CMake and then build and install if exist %builddir% ( echo Removing existing build directory %builddir% rmdir /S /Q %builddir% ) -mkdir %builddir% -cd %builddir% + +REM Apply build patch +set PATH=%PATH_WITH_MSYS% +REM nothing to patch set PATH=%PATH_WITHOUT_MSYS% -cmake -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DBUILD_SHARED_LIBS=ON -DCMAKE_BUILD_TYPE=Release -DDISCOUNT_ONLY_LIBRARY=ON -DCMAKE_INSTALL_PREFIX=%installdir% %codedir%\cmake -cmake --build . --config Release --parallel 8 -cmake --build . --config Release --target install -cd %basedir% +if "%HOPSAN_BUILD_COMPILER%" == "msvc" ( + REM Since libmarkdown does not export any symbols explicitly, a lib file is never created, so let cmake export all symbols + cmake -S %codedir%\cmake ^ + -B %builddir% ^ + -DCMAKE_POLICY_VERSION_MINIMUM=3.5 ^ + -G %HOPSAN_BUILD_CMAKE_GENERATOR% ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DBUILD_SHARED_LIBS=ON ^ + -DDISCOUNT_ONLY_LIBRARY=ON ^ + -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON ^ + -DCMAKE_INSTALL_PREFIX=%installdir% +) else ( + cmake -S %codedir%\cmake ^ + -B %builddir% ^ + -DCMAKE_POLICY_VERSION_MINIMUM=3.5 ^ + -G %HOPSAN_BUILD_CMAKE_GENERATOR% ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DBUILD_SHARED_LIBS=ON ^ + -DDISCOUNT_ONLY_LIBRARY=ON ^ + -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=OFF ^ + -DCMAKE_INSTALL_PREFIX=%installdir% +) + +cmake --build %builddir% --config Release --parallel 8 +cmake --build %builddir% --config Release --target install + echo. echo setupDiscount.bat done if "%HOPSAN_BUILD_SCRIPT_NOPAUSE%" == "" ( diff --git a/dependencies/setupDiscount.sh b/dependencies/setupDiscount.sh index f1a7c16531..4ce4a11854 100755 --- a/dependencies/setupDiscount.sh +++ b/dependencies/setupDiscount.sh @@ -1,7 +1,5 @@ #!/bin/bash -# $Id$ - -# Shell script building HopsaGUI dependency Discount automatically +# Shell script building Discount automatically basedir=`pwd` name=discount diff --git a/dependencies/setupFmi4c.bat b/dependencies/setupFmi4c.bat index fda9a0ae35..b2ffc0eed7 100644 --- a/dependencies/setupFmi4c.bat +++ b/dependencies/setupFmi4c.bat @@ -20,7 +20,16 @@ if exist %builddir_d% ( ) mkdir %builddir_d% pushd %builddir_d% -cmake -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_DEBUG_POSTFIX="d" -DCMAKE_INSTALL_PREFIX=%installdir% -DFMI4C_BUILD_SHARED=OFF -DFMI4C_USE_SYSTEM_ZIP=OFF -DFMI4C_USE_INCLUDED_ZLIB=ON %codedir% +cmake -Wno-dev ^ + -G %HOPSAN_BUILD_CMAKE_GENERATOR% ^ + -DCMAKE_BUILD_TYPE=Debug ^ + -DCMAKE_DEBUG_POSTFIX="d" ^ + -DCMAKE_INSTALL_LIBDIR=lib ^ + -DFMI4C_BUILD_SHARED=OFF ^ + -DFMI4C_USE_SYSTEM_ZIP=OFF ^ + -DFMI4C_USE_INCLUDED_ZLIB=ON ^ + -DCMAKE_INSTALL_PREFIX=%installdir% ^ + %codedir% cmake --build . --config Debug --parallel 8 cmake --build . --config Debug --target install popd @@ -32,7 +41,16 @@ if exist %builddir_r% ( ) mkdir %builddir_r% pushd %builddir_r% -cmake -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_BUILD_TYPE=Release -DCMAKE_DEBUG_POSTFIX="d" -DCMAKE_INSTALL_PREFIX=%installdir% -DFMI4C_BUILD_SHARED=OFF -DFMI4C_USE_SYSTEM_ZIP=OFF -DFMI4C_USE_INCLUDED_ZLIB=ON %codedir% +cmake -Wno-dev ^ + -G %HOPSAN_BUILD_CMAKE_GENERATOR% ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DCMAKE_DEBUG_POSTFIX="d" ^ + -DCMAKE_INSTALL_LIBDIR=lib ^ + -DFMI4C_BUILD_SHARED=OFF ^ + -DFMI4C_USE_SYSTEM_ZIP=OFF ^ + -DFMI4C_USE_INCLUDED_ZLIB=ON ^ + -DCMAKE_INSTALL_PREFIX=%installdir% ^ + %codedir% cmake --build . --config Release --parallel 8 cmake --build . --config Release --target install popd diff --git a/dependencies/setupFmi4c.sh b/dependencies/setupFmi4c.sh index 7e82681dd1..3719f0a02b 100755 --- a/dependencies/setupFmi4c.sh +++ b/dependencies/setupFmi4c.sh @@ -21,7 +21,12 @@ mkdir -p $builddir cd $builddir # Generate makefiles -cmake -Wno-dev -DCMAKE_INSTALL_PREFIX=${installdir} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_LIBDIR=lib -DFMI4C_BUILD_SHARED=OFF ${codedir} +cmake -Wno-dev \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_LIBDIR=lib \ + -DFMI4C_BUILD_SHARED=OFF \ + -DCMAKE_INSTALL_PREFIX=${installdir} \ + ${codedir} # Build and install cmake --build . --parallel 8 diff --git a/dependencies/setupHDF5.bat b/dependencies/setupHDF5.bat index 18d4fc3030..652b2f30df 100755 --- a/dependencies/setupHDF5.bat +++ b/dependencies/setupHDF5.bat @@ -8,20 +8,23 @@ set codedir=%basedir%\%name%-code set builddir=%basedir%\%name%-build set installdir=%basedir%\%name% +set zlibdir=%basedir%\zlib +set libzipdir=%basedir%\libzip + call setHopsanBuildPaths.bat mkdir %builddir% cd %builddir% if "%HOPSAN_BUILD_COMPILER%" == "msvc" ( - cmake -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_SH="CMAKE_SH-NOTFOUND" -DBUILD_SHARED_LIBS=ON -DHDF5_BUILD_FORTRAN=OFF -DBUILD_TESTING=OFF -DHDF5_BUILD_EXAMPLES=OFF -DHDF5_BUILD_CPP_LIB=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX="%installdir%" %codedir% + cmake -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_PREFIX_PATH="%zlibdir%;%libzipdir%" -DCMAKE_SH="CMAKE_SH-NOTFOUND" -DBUILD_SHARED_LIBS=ON -DHDF5_BUILD_FORTRAN=OFF -DBUILD_TESTING=OFF -DHDF5_BUILD_EXAMPLES=OFF -DHDF5_BUILD_CPP_LIB=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX="%installdir%" %codedir% cmake --build . --config Debug --parallel 8 cmake --build . --config Debug --target install - cmake -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_SH="CMAKE_SH-NOTFOUND" -DBUILD_SHARED_LIBS=ON -DHDF5_BUILD_FORTRAN=OFF -DBUILD_TESTING=OFF -DHDF5_BUILD_EXAMPLES=OFF -DHDF5_BUILD_CPP_LIB=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="%installdir%" %codedir% + cmake -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_PREFIX_PATH="%zlibdir%;%libzipdir%" -DCMAKE_SH="CMAKE_SH-NOTFOUND" -DBUILD_SHARED_LIBS=ON -DHDF5_BUILD_FORTRAN=OFF -DBUILD_TESTING=OFF -DHDF5_BUILD_EXAMPLES=OFF -DHDF5_BUILD_CPP_LIB=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="%installdir%" %codedir% cmake --build . --config Release --parallel 8 cmake --build . --config Release --target install ) else ( - cmake -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_SH="CMAKE_SH-NOTFOUND" -DBUILD_SHARED_LIBS=ON -DHDF5_BUILD_FORTRAN=OFF -DBUILD_TESTING=OFF -DHDF5_BUILD_EXAMPLES=OFF -DHDF5_BUILD_CPP_LIB=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="%installdir%" %codedir% + cmake -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_PREFIX_PATH="%zlibdir%;%libzipdir%" -DCMAKE_SH="CMAKE_SH-NOTFOUND" -DBUILD_SHARED_LIBS=ON -DHDF5_BUILD_FORTRAN=OFF -DBUILD_TESTING=OFF -DHDF5_BUILD_EXAMPLES=OFF -DHDF5_BUILD_CPP_LIB=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="%installdir%" %codedir% cmake --build . --parallel 8 cmake --build . --target install ) diff --git a/dependencies/setupMsgpack.bat b/dependencies/setupMsgpack.bat index 3c17bf60f6..3c80a2dabf 100644 --- a/dependencies/setupMsgpack.bat +++ b/dependencies/setupMsgpack.bat @@ -14,7 +14,7 @@ call setHopsanBuildPaths.bat REM build mkdir %builddir% cd %builddir% -cmake -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_BUILD_TYPE=Release -DCMAKE_SH="CMAKE_SH-NOTFOUND" -DCMAKE_INSTALL_PREFIX=%installdir% %codedir% +cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_BUILD_TYPE=Release -DCMAKE_SH="CMAKE_SH-NOTFOUND" -DCMAKE_INSTALL_PREFIX=%installdir% %codedir% cmake --build . --config Release --parallel 8 cmake --build . --config Release --target install if not "%HOPSAN_BUILD_DEPENDENCIES_TEST%" == "false" ( diff --git a/dependencies/setupMsgpack.sh b/dependencies/setupMsgpack.sh index 12041da482..2143adad54 100755 --- a/dependencies/setupMsgpack.sh +++ b/dependencies/setupMsgpack.sh @@ -21,7 +21,7 @@ mkdir -p $builddir cd $builddir # Generate makefiles -cmake -Wno-dev -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_POLICY_VERSION=3.5 -DCMAKE_INSTALL_PREFIX=${installdir} ${codedir} +cmake -Wno-dev -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_INSTALL_PREFIX=${installdir} ${codedir} # Build and install cmake --build . diff --git a/dependencies/setupSsp4c.bat b/dependencies/setupSsp4c.bat index b287d1fcbc..bde83ca7dc 100644 --- a/dependencies/setupSsp4c.bat +++ b/dependencies/setupSsp4c.bat @@ -20,9 +20,18 @@ if exist %builddir% ( mkdir %builddir% pushd %builddir% -cmake -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%installdir% -DSSP4C_BUILD_SHARED=OFF %codedir% -cmake --build . --config Debug --parallel 8 -cmake --build . --config Debug --target install +if "%HOPSAN_BUILD_COMPILER%" == "msvc" ( + cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=%installdir% -DSSP4C_BUILD_SHARED=OFF %codedir% + cmake --build . --config Debug --parallel 8 + cmake --build . --config Debug --target install + cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%installdir% -DSSP4C_BUILD_SHARED=OFF %codedir% + cmake --build . --config Release --parallel 8 + cmake --build . --config Release --target install +) else ( + cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%installdir% -DSSP4C_BUILD_SHARED=OFF %codedir% + cmake --build . --config Release --parallel 8 + cmake --build . --config Release --target install +) popd echo. diff --git a/dependencies/setupSsp4c.sh b/dependencies/setupSsp4c.sh index 4fbb3fa7d0..f11a7b1fd6 100755 --- a/dependencies/setupSsp4c.sh +++ b/dependencies/setupSsp4c.sh @@ -21,7 +21,12 @@ mkdir -p $builddir cd $builddir # Generate makefiles -cmake -Wno-dev -DCMAKE_INSTALL_PREFIX=${installdir} -DCMAKE_BUILD_TYPE=Release -DSSP4C_BUILD_SHARED=OFF ${codedir} +cmake -Wno-dev \ + -DCMAKE_BUILD_TYPE=Release \ + -DSSP4C_BUILD_SHARED=OFF \ + -DCMAKE_INSTALL_LIBDIR=lib \ + -DCMAKE_INSTALL_PREFIX=${installdir} \ + ${codedir} # Build and install cmake --build . --parallel 8 diff --git a/dependencies/setupXerces.bat b/dependencies/setupXerces.bat index 7759e62c62..2242f974e0 100644 --- a/dependencies/setupXerces.bat +++ b/dependencies/setupXerces.bat @@ -1,5 +1,5 @@ @ECHO OFF -REM Bat script building libzip dependency automatically +REM Bat script building libxerces dependency automatically setlocal set basedir=%~dp0 @@ -15,9 +15,20 @@ call setHopsanBuildPaths.bat mkdir %builddir% cd %builddir% -cmake -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_INSTALL_PREFIX="%installdir%" %codedir% -cmake --build . --parallel 8 -cmake --build . --target install +if "%HOPSAN_BUILD_COMPILER%" == "msvc" ( + cmake -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% ^ + -DCMAKE_BUILD_TYPE=Debug ^ + -DCMAKE_INSTALL_PREFIX="%installdir%" ^ + %codedir% + cmake --build . --config Debug --parallel 8 + cmake --build . --config Debug --target install +) +cmake -Wno-dev -G %HOPSAN_BUILD_CMAKE_GENERATOR% ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DCMAKE_INSTALL_PREFIX="%installdir%" ^ + %codedir% +cmake --build . --config Release --parallel 8 +cmake --build . --config Release --target install cd %basedir% echo. diff --git a/dependencies/setupZeroMQ.bat b/dependencies/setupZeroMQ.bat index dbc9c10a2c..dac00e8644 100755 --- a/dependencies/setupZeroMQ.bat +++ b/dependencies/setupZeroMQ.bat @@ -27,17 +27,17 @@ mkdir %builddir% cd %builddir% if "%HOPSAN_BUILD_COMPILER%" == "msvc" ( - cmake -Wno-dev -DWITH_LIBSODIUM=OFF -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=%installdir% %codedir% + cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -Wno-dev -DWITH_LIBSODIUM=OFF -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=%installdir% %codedir% cmake --build . --config Debug --parallel 8 cmake --build . --config Debug --target install - cmake -Wno-dev -DWITH_LIBSODIUM=OFF -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%installdir% %codedir% + cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -Wno-dev -DWITH_LIBSODIUM=OFF -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%installdir% %codedir% cmake --build . --config Release --parallel 8 cmake --build . --config Release --target install if not "%HOPSAN_BUILD_DEPENDENCIES_TEST%" == "false" ( ctest -C Release --parallel 8 ) ) else ( - cmake -Wno-dev -DWITH_LIBSODIUM=OFF -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%installdir% %codedir% + cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -Wno-dev -DWITH_LIBSODIUM=OFF -G %HOPSAN_BUILD_CMAKE_GENERATOR% -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=%installdir% %codedir% cmake --build . --parallel 8 cmake --build . --target install if not "%HOPSAN_BUILD_DEPENDENCIES_TEST%" == "false" ( diff --git a/dependencies/setupZeroMQ.sh b/dependencies/setupZeroMQ.sh index 932218c9b6..9714966f80 100755 --- a/dependencies/setupZeroMQ.sh +++ b/dependencies/setupZeroMQ.sh @@ -18,7 +18,7 @@ source setHopsanBuildPaths.sh mkdir -p $builddir cd $builddir -zmq_cmake_args="-Wno-dev -DBUILD_STATIC=OFF -DZMQ_HAVE_TIPC=OFF -DCMAKE_INSTALL_LIBDIR=lib" +zmq_cmake_args="-DCMAKE_POLICY_VERSION_MINIMUM=3.5 -Wno-dev -DBUILD_STATIC=OFF -DZMQ_HAVE_TIPC=OFF -DCMAKE_INSTALL_LIBDIR=lib" if [[ ${OSTYPE} == darwin* ]]; then zmq_cmake_args="${zmq_cmake_args} -DZMQ_BUILD_FRAMEWORK=OFF" fi diff --git a/dependencies/ssp4c.cmake b/dependencies/ssp4c.cmake index 80f3b77180..9cc14e47a0 100644 --- a/dependencies/ssp4c.cmake +++ b/dependencies/ssp4c.cmake @@ -1,44 +1,14 @@ set(local_ssp4c_dir ${CMAKE_CURRENT_LIST_DIR}/ssp4c) if (EXISTS ${local_ssp4c_dir}) - - set(zlibstatic_name zlibstatic) - if (NOT WIN32) - set(zlibstatic_name z) - endif() - - set(ssp4c_dbg_ext "") - if (WIN32) - set(ssp4c_dbg_ext d) - endif() - - set(static_ssp4c ${local_ssp4c_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}ssp4c${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(static_ssp4c_d ${local_ssp4c_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}ssp4c${ssp4c_dbg_ext}${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(static_zlib ${local_ssp4c_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}${zlibstatic_name}${CMAKE_STATIC_LIBRARY_SUFFIX}) - set(static_zlib_d ${local_ssp4c_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}${zlibstatic_name}${ssp4c_dbg_ext}${CMAKE_STATIC_LIBRARY_SUFFIX}) - - add_library(ssp4c STATIC IMPORTED) - - set_target_properties(ssp4c PROPERTIES - IMPORTED_LOCATION ${static_ssp4c} - IMPORTED_LOCATION_DEBUG ${static_ssp4c_d} - INTERFACE_INCLUDE_DIRECTORIES ${local_ssp4c_dir}/include - INTERFACE_COMPILE_DEFINITIONS "USESSP4C;SSP4C_STATIC") - - if (EXISTS ${static_zlib}) - message(STATUS "Found static zlib in ${local_ssp4c_dir}") - add_library(ssp4c_zlib STATIC IMPORTED) - set_target_properties(ssp4c_zlib PROPERTIES - IMPORTED_LOCATION ${static_zlib} - IMPORTED_LOCATION_DEBUG ${static_zlib_d}) - target_link_libraries(ssp4c INTERFACE ssp4c_zlib) + find_package(ssp4c CONFIG PATHS ${local_ssp4c_dir} NO_DEFAULT_PATH) + if (ssp4c_FOUND) + message(STATUS "Building with ssp4c support") + target_compile_definitions(ssp4c::ssp4c INTERFACE USESSP4C) + install(DIRECTORY ${local_ssp4c_dir} DESTINATION dependencies) else() - find_package(ZLIB MODULE REQUIRED) - target_link_libraries(ssp4c INTERFACE ZLIB::ZLIB) + message(WARNING "Ssp4c configuration packet not found in ${local_ssp4c_dir}") endif() - - install(DIRECTORY ${local_ssp4c_dir} DESTINATION dependencies) - message(STATUS "Building with ssp4c support") else() message(WARNING "Building without ssp4c support") endif() diff --git a/dependencies/xerces.cmake b/dependencies/xerces.cmake deleted file mode 100644 index e7ca6f384f..0000000000 --- a/dependencies/xerces.cmake +++ /dev/null @@ -1,40 +0,0 @@ -if (NOT TARGET xercesc) - set(local_xerces_dir ${CMAKE_CURRENT_LIST_DIR}/xerces) - set(CMAKE_FIND_LIBRARY_PREFIXES lib) - find_library(xercesc NAMES xerces-c ${CMAKE_STATIC_LIBRARY_PREFIX}xerces-c_3D${CMAKE_STATIC_LIBRARY_SUFFIX} PATHS ${local_xerces_dir}/lib) - - #set(CMAKE_FIND_DEBUG_MODE TRUE) - #find_package(xercesc CONFIG PATHS ${local_xerces_dir} NO_DEFAULT_PATH REQUIRED) # Search for local version - #set(CMAKE_FIND_DEBUG_MODE FALSE) - - if (xercesc) - message(STATUS "Found local xerces") - #add_library(xercesc INTERFACE) - - add_library(xercesc STATIC IMPORTED) - - if (MINGW) - set_target_properties(xercesc PROPERTIES - IMPORTED_LOCATION ${local_xerces_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}xerces-c${CMAKE_SHARED_LIBRARY_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX} - INTERFACE_INCLUDE_DIRECTORIES ${local_xerces_dir}/include) - elseif(MSVC) - set_target_properties(xercesc PROPERTIES - IMPORTED_LOCATION ${local_xerces_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}xerces-c_3D${CMAKE_STATIC_LIBRARY_SUFFIX} - INTERFACE_INCLUDE_DIRECTORIES ${local_xerces_dir}/include) - else() - set_target_properties(xercesc PROPERTIES - IMPORTED_LOCATION ${local_xerces_dir}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}xerces-c${CMAKE_SHARED_LIBRARY_SUFFIX} - INTERFACE_INCLUDE_DIRECTORIES ${local_xerces_dir}/include) - endif() - - else() - message(STATUS "Looking for xerces in system") - find_package(xercesc CONFIG) # Search in system - if (xercesc_FOUND) - message(STATUS " Found xerces") - add_library(xercesc INTERFACE) - else() - message(WARNING "Could not find xerces") - endif() - endif() -endif() diff --git a/dependencies/zeromq.cmake b/dependencies/zeromq.cmake index defc2e2844..48ee999ed8 100644 --- a/dependencies/zeromq.cmake +++ b/dependencies/zeromq.cmake @@ -12,14 +12,17 @@ endif() if (ZeroMQ_FOUND) message(STATUS "Building with ZeroMQ support") - target_compile_definitions(libzmq INTERFACE USEZMQ) + #target_compile_definitions(libzmq INTERFACE USEZMQ) + set_target_properties(libzmq PROPERTIES INTERFACE_COMPILE_DEFINITIONS USEZMQ) # Set as target property for compatibility with old CMake elseif(zmq_FOUND) message(STATUS "Building with ZeroMQ support (found by PkgConfig)") if (NOT TARGET libzmq) add_library(libzmq INTERFACE) endif() - target_link_libraries(libzmq INTERFACE PkgConfig::zmq) - target_compile_definitions(libzmq INTERFACE USEZMQ) + #target_link_libraries(libzmq INTERFACE PkgConfig::zmq) + #target_compile_definitions(libzmq INTERFACE USEZMQ) + set_target_properties(libzmq PROPERTIES INTERFACE_LINK_LIBRARIES PkgConfig::zmq + INTERFACE_COMPILE_DEFINITIONS USEZMQ) # Set as target property for compatibility with old CMake else() message(WARNING "Building without ZeroMQ support") endif() diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 310e1bdcca..4c97d79342 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -30,7 +30,7 @@ if (${BUILD_USER_DOCUMENTATION} OR ${BUILD_DEVELOPER_DOCUMENTATION}) [[htmllinkimage{2}="\htmlonly

\endhtmlonly"]] [[htmlimagerightcaption{2}="\htmlonly
\2
\endhtmlonly"]]) set(DOXYGEN_VERBATIM_VARS DOXYGEN_ALIASES) - + set(DOXYGEN_RECURSIVE YES) set(documentation_directories ${PROJECT_SOURCE_DIR}/HopsanCore/include ${PROJECT_SOURCE_DIR}/HopsanCore/src @@ -66,11 +66,11 @@ if (${BUILD_USER_DOCUMENTATION} OR ${BUILD_DEVELOPER_DOCUMENTATION}) ${PROJECT_SOURCE_DIR}/hopsanremote ${PROJECT_SOURCE_DIR}/doc) endif() - + # Ensure that all images are copied, they are not auto copied since most of them are added through alias commands file(GLOB png_files ${CMAKE_CURRENT_LIST_DIR}/graphics/*.png) set(DOXYGEN_HTML_EXTRA_FILES ${png_files}) - + # On MINGW CMake TO_NATIVE_PATH inside FindDoxygen does not work, and we need to fix the path here if (MINGW) string(REPLACE "\\" "" DOXYGEN_DOT_PATH "${DOXYGEN_DOT_PATH}") diff --git a/helpers.cmake b/helpers.cmake index 3128096028..a06ebc8856 100644 --- a/helpers.cmake +++ b/helpers.cmake @@ -33,3 +33,14 @@ function(target_link_optional_libraries target_name) endif() endforeach() endfunction() + +function(install_files_if_they_exist dest) + foreach(file_path ${ARGN}) + if(EXISTS ${file_path}) + install(FILES ${file_path} + DESTINATION ${dest}) + else() + message(STATUS "Did not find: ${file_path}, will not install!") + endif() + endforeach() +endfunction() diff --git a/hopsanc/CMakeLists.txt b/hopsanc/CMakeLists.txt index 5493c89bbf..b6c6e952e2 100644 --- a/hopsanc/CMakeLists.txt +++ b/hopsanc/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.1) project(hopsanc) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) @@ -13,6 +12,11 @@ file(GLOB_RECURSE headerfiles include/*.h include/*.hpp) # Create library target and add source code files add_library(hopsanc SHARED ${srcfiles} ${headerfiles}) +if(MSVC) + # Enable multi-core build with MSVC + target_compile_options(hopsanc PRIVATE "/MP") +endif() + # Set include directories target_include_directories(hopsanc PUBLIC $ diff --git a/hopsandcp/CMakeLists.txt b/hopsandcp/CMakeLists.txt index 24e0a087a4..8c284effba 100644 --- a/hopsandcp/CMakeLists.txt +++ b/hopsandcp/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.1) project(hopsandcp) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) @@ -6,13 +5,7 @@ if(WIN32) set(CMAKE_SHARED_LIBRARY_PREFIX "") endif() -#set(CMAKE_AUTOMOC ON) - -# include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/xerces.cmake) -# include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/libzip.cmake) -# include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/zlib.cmake) -include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/libzip.cmake) -#include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/zlib.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/dcplib.cmake) # Find source code file(GLOB_RECURSE srcfiles src/*.cpp) @@ -21,26 +14,22 @@ file(GLOB_RECURSE headerfiles include/*.h include/*.hpp) # Create library target and add source code files add_library(hopsandcp STATIC ${srcfiles} ${headerfiles}) +if(MSVC) + # Enable multi-core build with MSVC + target_compile_options(hopsandcp PRIVATE "/MP") +endif() + # Set include directories target_include_directories(hopsandcp PUBLIC $ $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ $) -if(MINGW) - target_link_libraries(hopsandcp hopsancore libzip -lws2_32) -else() - target_link_libraries(hopsandcp hopsancore libzip) +target_link_libraries(hopsandcp hopsancore DCPLib::Master DCPLib::Slave DCPLib::Zip DCPLib::Ethernet) +if(WIN32 AND MINGW) + target_link_libraries(hopsandcp -lws2_32) +elseif(WIN32 AND MSVC) + target_link_libraries(hopsandcp ws2_32) endif() target_compile_definitions(hopsandcp PUBLIC LOGGING=ON) diff --git a/hopsandcp/include/dcpserver.h b/hopsandcp/include/dcpserver.h index 6e4c07146e..a203935f88 100644 --- a/hopsandcp/include/dcpserver.h +++ b/hopsandcp/include/dcpserver.h @@ -3,6 +3,7 @@ #include "hopsandcp_win32dll.h" +#include #include #include #include diff --git a/hopsangeneratorgui/CMakeLists.txt b/hopsangeneratorgui/CMakeLists.txt index c570b67534..ff035985ce 100644 --- a/hopsangeneratorgui/CMakeLists.txt +++ b/hopsangeneratorgui/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.1) project(HopsanGeneratorGUI) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) @@ -9,28 +8,31 @@ endif() find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED) set(CMAKE_AUTOMOC ON) -set(target_name hopsangeneratorgui) - # Find source code file(GLOB_RECURSE srcfiles src/*.cpp) file(GLOB_RECURSE headerfiles include/*.h include/*.hpp) # Create library target and add source code files -add_library(${target_name} STATIC ${srcfiles} ${headerfiles}) +add_library(hopsangeneratorgui STATIC ${srcfiles} ${headerfiles}) + +if(MSVC) + # Enable multi-core build with MSVC + target_compile_options(hopsangeneratorgui PRIVATE "/MP") +endif() # Set include directories -target_include_directories(${target_name} PUBLIC +target_include_directories(hopsangeneratorgui PUBLIC $ $) # Set link dependencies -target_link_libraries(${target_name} Qt5::Core Qt5::Gui Qt5::Widgets) +target_link_libraries(hopsangeneratorgui Qt5::Core Qt5::Gui Qt5::Widgets) # Set compiler definitions # TODO: Should create aseparat target for debug/release flag, right now this is set on hopsancore, but only those who depend on it will get the flag automatically if(CMAKE_BUILD_TYPE MATCHES Debug) - target_compile_definitions(${target_name} PRIVATE HOPSAN_BUILD_TYPE_DEBUG) + target_compile_definitions(hopsangeneratorgui PRIVATE HOPSAN_BUILD_TYPE_DEBUG) else() - target_compile_definitions(${target_name} PRIVATE HOPSAN_BUILD_TYPE_RELEASE) - target_compile_definitions(${target_name} PRIVATE QT_NO_DEBUG_OUTPUT) + target_compile_definitions(hopsangeneratorgui PRIVATE HOPSAN_BUILD_TYPE_RELEASE) + target_compile_definitions(hopsangeneratorgui PRIVATE QT_NO_DEBUG_OUTPUT) endif() diff --git a/hopsanhdf5exporter/CMakeLists.txt b/hopsanhdf5exporter/CMakeLists.txt index d4e4800f51..a09bfb3524 100644 --- a/hopsanhdf5exporter/CMakeLists.txt +++ b/hopsanhdf5exporter/CMakeLists.txt @@ -1,4 +1,3 @@ -cmake_minimum_required(VERSION 3.1) project(HopsanHdf5Exporter) set(CMAKE_CXX_STANDARD 14) set(CMAKE_DEBUG_POSTFIX _d) @@ -9,21 +8,24 @@ endif() include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/hdf5.cmake) if (TARGET module_hdf5-shared) - set(target_name hopsanhdf5exporter) - # Find source code file(GLOB_RECURSE srcfiles ${CMAKE_CURRENT_LIST_DIR}/*.cpp ${CMAKE_CURRENT_LIST_DIR}/*.h ${CMAKE_CURRENT_LIST_DIR}/*.hpp) # Create library target and add source code files - add_library(${target_name} STATIC ${srcfiles}) + add_library(hopsanhdf5exporter STATIC ${srcfiles}) + + if(MSVC) + # Enable multi-core build with MSVC + target_compile_options(hopsanhdf5exporter PRIVATE "/MP") + endif() # Set include directories - target_include_directories(${target_name} PUBLIC + target_include_directories(hopsanhdf5exporter PUBLIC $ $) # Set link dependencies - target_link_libraries(${target_name} hopsancore hdf5::hdf5-shared hdf5::hdf5_cpp-shared) + target_link_libraries(hopsanhdf5exporter hopsancore hdf5::hdf5-shared hdf5::hdf5_cpp-shared) endif() diff --git a/hopsanremote/CMakeLists.txt b/hopsanremote/CMakeLists.txt index 48cfc56c3b..0b214d07a1 100644 --- a/hopsanremote/CMakeLists.txt +++ b/hopsanremote/CMakeLists.txt @@ -1,5 +1,6 @@ -cmake_minimum_required(VERSION 3.0) project(HopsanRemote) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_DEBUG_POSTFIX _d) include(${CMAKE_CURRENT_LIST_DIR}/../helpers.cmake) include(${CMAKE_CURRENT_LIST_DIR}/../dependencies/zeromq.cmake) diff --git a/hopsanremote/hopsanaddressserver/CMakeLists.txt b/hopsanremote/hopsanaddressserver/CMakeLists.txt index fbcc1bbe4d..53ff1659d0 100644 --- a/hopsanremote/hopsanaddressserver/CMakeLists.txt +++ b/hopsanremote/hopsanaddressserver/CMakeLists.txt @@ -1,23 +1,22 @@ -cmake_minimum_required(VERSION 3.0) -project(HopsanAddressServer) -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_DEBUG_POSTFIX _d) find_package(Threads REQUIRED) -set(target_name hopsanaddresserver) - file(GLOB srcfiles *.cpp *.h) -add_executable(${target_name} ${srcfiles}) +add_executable(hopsanaddresserver ${srcfiles}) + +if(MSVC) + # Enable multi-core build with MSVC + target_compile_options(hopsanaddresserver PRIVATE "/MP") +endif() -target_include_directories(${target_name} PRIVATE +target_include_directories(hopsanaddresserver PRIVATE $ $) -target_link_libraries(${target_name} libhopsanremoteclient Threads::Threads) +target_link_libraries(hopsanaddresserver libhopsanremoteclient Threads::Threads) -set_target_properties(${target_name} PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") +set_target_properties(hopsanaddresserver PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") -install(TARGETS ${target_name} +install(TARGETS hopsanaddresserver RUNTIME DESTINATION bin ) diff --git a/hopsanremote/hopsanremoteclient/CMakeLists.txt b/hopsanremote/hopsanremoteclient/CMakeLists.txt index 86b4ed0ab1..ae37c4cc23 100644 --- a/hopsanremote/hopsanremoteclient/CMakeLists.txt +++ b/hopsanremote/hopsanremoteclient/CMakeLists.txt @@ -1,20 +1,13 @@ -cmake_minimum_required(VERSION 3.0) -project(HopsanRemoteClient) -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_DEBUG_POSTFIX _d) +add_executable(hopsanremoteclient main.cpp) -set(target_name hopsanremoteclient) - -add_executable(${target_name} main.cpp) - -target_include_directories(${target_name} PRIVATE +target_include_directories(hopsanremoteclient PRIVATE $ $) -target_link_libraries(${target_name} libhopsanremoteclient) +target_link_libraries(hopsanremoteclient libhopsanremoteclient) -set_target_properties(${target_name} PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") +set_target_properties(hopsanremoteclient PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") -install(TARGETS ${target_name} +install(TARGETS hopsanremoteclient RUNTIME DESTINATION bin ) diff --git a/hopsanremote/hopsanserver/CMakeLists.txt b/hopsanremote/hopsanserver/CMakeLists.txt index 0643342b74..5b3f2f9d4a 100644 --- a/hopsanremote/hopsanserver/CMakeLists.txt +++ b/hopsanremote/hopsanserver/CMakeLists.txt @@ -1,21 +1,15 @@ -cmake_minimum_required(VERSION 3.0) -project(HopsanServer) -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_DEBUG_POSTFIX _d) find_package(Threads REQUIRED) -set(target_name hopsanserver) +add_executable(hopsanserver main.cpp) -add_executable(${target_name} main.cpp) - -target_include_directories(${target_name} PRIVATE +target_include_directories(hopsanserver PRIVATE $ $) -target_link_libraries(${target_name} libhopsanremotecommon Threads::Threads) +target_link_libraries(hopsanserver libhopsanremotecommon Threads::Threads) -set_target_properties(${target_name} PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") +set_target_properties(hopsanserver PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") -install(TARGETS ${target_name} +install(TARGETS hopsanserver RUNTIME DESTINATION bin ) diff --git a/hopsanremote/hopsanservermonitor/CMakeLists.txt b/hopsanremote/hopsanservermonitor/CMakeLists.txt index 7a24d352dc..dd7f741415 100644 --- a/hopsanremote/hopsanservermonitor/CMakeLists.txt +++ b/hopsanremote/hopsanservermonitor/CMakeLists.txt @@ -1,21 +1,15 @@ -cmake_minimum_required(VERSION 3.0) -project(HopsanServerMonitor) -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_DEBUG_POSTFIX _d) find_package(Threads REQUIRED) -set(target_name hopsanservermonitor) +add_executable(hopsanservermonitor main.cpp) -add_executable(${target_name} main.cpp) - -target_include_directories(${target_name} PRIVATE +target_include_directories(hopsanservermonitor PRIVATE $ $) -target_link_libraries(${target_name} libhopsanremoteclient libhopsanremotecommon Threads::Threads) +target_link_libraries(hopsanservermonitor libhopsanremoteclient libhopsanremotecommon Threads::Threads) -set_target_properties(${target_name} PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") +set_target_properties(hopsanservermonitor PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") -install(TARGETS ${target_name} +install(TARGETS hopsanservermonitor RUNTIME DESTINATION bin ) diff --git a/hopsanremote/hopsanserverworker/CMakeLists.txt b/hopsanremote/hopsanserverworker/CMakeLists.txt index 294cb26a17..eccd1d0941 100644 --- a/hopsanremote/hopsanserverworker/CMakeLists.txt +++ b/hopsanremote/hopsanserverworker/CMakeLists.txt @@ -1,22 +1,16 @@ -cmake_minimum_required(VERSION 3.0) -project(HopsanServerWorker) -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_DEBUG_POSTFIX _d) find_package(Threads REQUIRED) -set(target_name hopsanserverworker) +add_executable(hopsanserverworker main.cpp) -add_executable(${target_name} main.cpp) - -target_include_directories(${target_name} PRIVATE +target_include_directories(hopsanserverworker PRIVATE $ $ $) -target_link_libraries(${target_name} libhopsanremotecommon hopsancore Threads::Threads) +target_link_libraries(hopsanserverworker libhopsanremotecommon hopsancore Threads::Threads) -set_target_properties(${target_name} PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") +set_target_properties(hopsanserverworker PROPERTIES INSTALL_RPATH "\$ORIGIN/../lib") -install(TARGETS ${target_name} +install(TARGETS hopsanserverworker RUNTIME DESTINATION bin ) diff --git a/hopsanremote/libhopsanremoteclient/CMakeLists.txt b/hopsanremote/libhopsanremoteclient/CMakeLists.txt index 248653723c..510640c41f 100644 --- a/hopsanremote/libhopsanremoteclient/CMakeLists.txt +++ b/hopsanremote/libhopsanremoteclient/CMakeLists.txt @@ -1,30 +1,22 @@ -cmake_minimum_required(VERSION 3.0) -project(Ops) -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_DEBUG_POSTFIX _d) -if(WIN32) - set(CMAKE_SHARED_LIBRARY_PREFIX "") -endif() find_package(Threads REQUIRED) -set(target_name libhopsanremoteclient) - file(GLOB_RECURSE srcfiles src/*.cpp include/*.h include/*.hpp) -add_library(${target_name} STATIC ${srcfiles}) -set_target_properties(${target_name} PROPERTIES OUTPUT_NAME hopsanremoteclient) +add_library(libhopsanremoteclient STATIC ${srcfiles}) +set_target_properties(libhopsanremoteclient PROPERTIES OUTPUT_NAME hopsanremoteclient) -target_include_directories(${target_name} PUBLIC +target_include_directories(libhopsanremoteclient PUBLIC $ $) -target_link_libraries(${target_name} libhopsanremotecommon Threads::Threads) +target_link_libraries(libhopsanremoteclient libhopsanremotecommon Threads::Threads) -set_target_properties(${target_name} PROPERTIES INSTALL_RPATH "\$ORIGIN") +set_target_properties(libhopsanremoteclient PROPERTIES INSTALL_RPATH "\$ORIGIN") -install(TARGETS ${target_name} +install(TARGETS libhopsanremoteclient RUNTIME DESTINATION bin LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib ) install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include ) diff --git a/hopsanremote/libhopsanremotecommon/CMakeLists.txt b/hopsanremote/libhopsanremotecommon/CMakeLists.txt index b147fe276a..40d3516f7e 100644 --- a/hopsanremote/libhopsanremotecommon/CMakeLists.txt +++ b/hopsanremote/libhopsanremotecommon/CMakeLists.txt @@ -1,30 +1,26 @@ -cmake_minimum_required(VERSION 3.0) -project(Ops) -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_DEBUG_POSTFIX _d) -if(WIN32) - set(CMAKE_SHARED_LIBRARY_PREFIX "") -endif() - -set(target_name libhopsanremotecommon) - include(${CMAKE_CURRENT_LIST_DIR}/../../dependencies/zeromq.cmake) include(${CMAKE_CURRENT_LIST_DIR}/../../dependencies/msgpack.cmake) file(GLOB_RECURSE srcfiles src/*.cpp include/*.h include/*.hpp) -add_library(${target_name} STATIC ${srcfiles}) -set_target_properties(${target_name} PROPERTIES OUTPUT_NAME hopsanremotecommon) +add_library(libhopsanremotecommon STATIC ${srcfiles}) +set_target_properties(libhopsanremotecommon PROPERTIES OUTPUT_NAME hopsanremotecommon) + +if(MSVC) + # Enable multi-core build with MSVC + target_compile_options(libhopsanremotecommon PRIVATE "/MP") +endif() -target_include_directories(${target_name} PUBLIC +target_include_directories(libhopsanremotecommon PUBLIC $ $) -target_link_libraries(${target_name} PUBLIC libzmq msgpackc-cxx) +target_link_libraries(libhopsanremotecommon PUBLIC libzmq msgpackc-cxx) -install(TARGETS ${target_name} +install(TARGETS libhopsanremotecommon RUNTIME DESTINATION bin LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib ) install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION include ) diff --git a/makeDebRelease.sh b/makeDebRelease.sh index 282a8d225d..3ff2d88980 100755 --- a/makeDebRelease.sh +++ b/makeDebRelease.sh @@ -1,8 +1,6 @@ #!/bin/bash -# $Id$ # Shell script for building DEB packages of hopsan for multiple distributions using pbuilder -# Author: Peter Nordin peter.nordin@liu.se set -u #set -e @@ -19,7 +17,7 @@ devversion=2.24.0 debianDistArchArray=( trixie:amd64:trixie bookworm:amd64:bookworm bullseye:amd64:bullseye ) -ubuntuDistArchArray=( plucky:amd64:trixie +ubuntuDistArchArray=( questing:amd64:trixie noble:amd64:trixie jammy:amd64:bookworm focal:amd64:bullseye ) @@ -124,7 +122,7 @@ if [[ ${baseversion_or_tag} =~ ^v ]]; then fi echo "Choose remote to clone from:" -select remote in file://${hopsancode_root} https://github.com/Hopsan/hopsan.git https://github.com/peterNordin/hopsan.git +select remote in https://github.com/Hopsan/hopsan.git https://github.com/robbr48/hopsan.git https://github.com/peterNordin/hopsan.git file://${hopsancode_root} do if [[ -z "$remote" ]]; then echo Invalid choice @@ -139,10 +137,6 @@ if [[ ${hopsancode_url} == file://${hopsancode_root} ]]; then popd > /dev/null fi -echo -boolAskYNQuestion "Do you want the defaultComponentLibrary to be build in?" n -readonly doBuildInComponents=${boolYNQuestionAnswer} - echo distArchArrayDo=() for i in "${debianDistArchArray[@]}"; do @@ -158,7 +152,6 @@ echo echo ------------------------------------------------- echo This is a DEVELOPMENT release: ${doDevRelease} echo Release baseversion number: ${baseversion} -echo Built in components: ${doBuildInComponents} echo URL to clone: ${hopsancode_url} echo Branch to clone: ${branch_or_tag_to_clone} echo @@ -177,24 +170,66 @@ echo # outputDir=${hopsancode_root}/output_deb outputDebDir=${outputDir}/debs +# If a persistent cache dir for hopsan dependencies dowloads exists in the "workspace" then prefer it over loca cache that will be removed by git clean +if [[ -d ${hopsancode_root}/../hopsan-dependencies-cache ]]; then + readonly dependencies_cache=${hopsancode_root}/../hopsan-dependencies-cache +else + readonly dependencies_cache=${outputDir}/dependencies-cache +fi readonly tmp_stage_directory=${outputDir}/hopsan-stage mkdir -p ${outputDebDir} mkdir -p ${pbuilderWorkDir} +mkdir -p ${dependencies_cache} pushd ${outputDir} > /dev/null # ----------------------------------------------------------------------------- # Clone source code to ensure a clean build # -echo Cloning from ${hopsancode_url} into ${tmp_stage_directory} -rm -rf ${tmp_stage_directory} -git clone -b ${branch_or_tag_to_clone} --depth 1 ${hopsancode_url} ${tmp_stage_directory} -if [[ $? -ne 0 ]]; then - echo Error: Failed to clone from ${hopsancode_url} - exit 1 + +# For builds from official upstream, always clean clone to ensure that the correct code is used +if [[ ${hopsancode_url} == https://github.com/Hopsan/hopsan.git ]]; then + rm -rf ${tmp_stage_directory} fi + +echo "Cloning from ${hopsancode_url} into ${tmp_stage_directory}" +if [[ -d ${tmp_stage_directory} ]]; then + echo "Reusing: ${tmp_stage_directory} as it exists, resetting --hard and clean -ffdx" + set -e + pushd ${tmp_stage_directory} > /dev/null + git remote set-url origin ${hopsancode_url} + git fetch --all --prune --tags + if (git show-ref --verify refs/tags/${branch_or_tag_to_clone}) &> /dev/null; then + echo "Checking out tag: ${branch_or_tag_to_clone}" + git checkout -B ${branch_or_tag_to_clone} + git reset --hard refs/tags/${branch_or_tag_to_clone} + else + echo "Checking out branch: ${branch_or_tag_to_clone}" + git checkout ${branch_or_tag_to_clone} + git reset --hard origin/${branch_or_tag_to_clone} + fi + git clean -ffdx + popd > /dev/null + set +e +else + git clone --config advice.detachedHead=false --branch ${branch_or_tag_to_clone} --filter=blob:none ${hopsancode_url} ${tmp_stage_directory} + if [[ $? -ne 0 ]]; then + echo Error: Failed to clone from ${hopsancode_url} + exit 1 + fi + pushd ${tmp_stage_directory} > /dev/null + if (git show-ref --verify refs/tags/${branch_or_tag_to_clone}) &> /dev/null; then + echo "Checking out tag as branch: ${branch_or_tag_to_clone}" + git checkout -b ${branch_or_tag_to_clone} + git reset --hard refs/tags/${branch_or_tag_to_clone} + fi + popd > /dev/null +fi + pushd ${tmp_stage_directory} > /dev/null -git submodule update --init --recommend-shallow +echo "Updaing git submodules" +git submodule sync +git submodule update --init --filter=blob:none --recursive if [[ $? -ne 0 ]]; then echo Error: Failed to clone submodules from git exit 1 @@ -218,7 +253,8 @@ readonly packageorigsrcfile=${outputfile_basename}.orig.tar.gz readonly package_dirname=${name}-${fullversionname} stage_directory=${tmp_stage_directory}-${fullversionname} -mv ${tmp_stage_directory} ${stage_directory} +rm -rf ${stage_directory} # Cleanup unlikely leftovers +cp -r ${tmp_stage_directory} ${stage_directory} # ----------------------------------------------------------------------------- # Prepare source code inside stage directory and package it into original source package @@ -226,11 +262,11 @@ mv ${tmp_stage_directory} ${stage_directory} readonly hopsancode_gitwc=${stage_directory} ${stage_directory}/packaging/prepareSourceCode.sh ${hopsancode_gitwc} ${stage_directory} \ ${baseversion} ${releaserevision} ${fullversionname} \ - ${doDevRelease} ${doBuildInComponents} + ${doDevRelease} # Download dependencies, since that can not be done inside a pbuilder environment # Unfortunately all dependencies must be downloaded since we can not know at this point which of them will be used pushd ${stage_directory}/dependencies > /dev/null -./download-dependencies.py --all +./download-dependencies.py --all --cache ${dependencies_cache} popd > /dev/null set +e # Remove .git directory and submodule files (if present) before packaging source code diff --git a/makeWindowsRelease.py b/makeWindowsRelease.py index 3cbe6ad386..f996704549 100644 --- a/makeWindowsRelease.py +++ b/makeWindowsRelease.py @@ -10,6 +10,8 @@ import zipfile import uuid import time +from pathlib import Path +from enum import IntEnum # -------------------- Setup Start -------------------- # Version numbers @@ -18,12 +20,8 @@ gFullVersion = gBaseVersion gReleaseFileVersionName = gBaseVersion -# Global parameters -gDoDevRelease = False -gIncludeCompiler = False - # Build directory -gTemporaryBuildDir = r'C:\temp_release' +g_temporary_build_root = Path("C:/temp_release") # External programs inkscapeDirList = [r'C:\Program Files\Inkscape\bin', r'C:\Program Files (x86)\Inkscape\bin'] @@ -32,965 +30,796 @@ gsDirList = [r'C:\Program Files\gs\gs9.27\bin', r'C:\Program Files (x86)\gs\gs9.27\bin', r'C:\Program Files\gs\gs9.22\bin', r'C:\Program Files (x86)\gs\gs9.22\bin', r'C:\Program Files\gs\gs9.21\bin', r'C:\Program Files (x86)\gs\gs9.21\bin', r'C:\Program Files\gs\gs9.19\bin', r'C:\Program Files (x86)\gs\gs9.19\bin', r'C:\Program Files\gs\gs9.18\bin', r'C:\Program Files (x86)\gs\gs9.18\bin', r'C:\Program Files (x86)\gs\gs10.04.0\bin', ] # Compilers and build tools -qtcreatorDirList = [r'C:\Qt\qtcreator-3.5.1', r'C:\Qt\qtcreator-3.6.0', r'C:\Qt\Tools\QtCreator'] -msvc2008DirList = [r'C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin', r'C:\Program (x86)\Microsoft SDKs\Windows\v7.0\Bin'] -msvc2010DirList = [r'C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin', r'C:\Program (x86)\Microsoft SDKs\Windows\v7.1\Bin'] +qtcreatorDirList = [r'C:\Qt\Tools\QtCreator'] +msvc2022DirList = [r'C:\Program Files\Microsoft Visual Studio\2022\Community', r'C:\Program (x86)\Microsoft SDKs\Windows\v7.1\Bin'] # Runtime binaries to copy to bin directory (Note! Path to qt/bin and mingw/bin and plugin directories is set by external script) # Note! This list must be adapted to the actual version of Qt/MinGW that you are using when building the release qtRuntimeBins = ['Qt5Core.dll', 'Qt5Gui.dll', 'Qt5Network.dll', 'Qt5OpenGL.dll', 'Qt5Widgets.dll', 'Qt5Sql.dll', 'Qt5Svg.dll', 'Qt5WebKit.dll', 'Qt5Xml.dll', 'Qt5WebKitWidgets.dll', 'Qt5Test.dll', 'libicuin56.dll', 'libicuuc56.dll', 'libicudt56.dll', 'Qt5PrintSupport.dll', 'libeay32.dll', 'ssleay32.dll'] -qtRuntimeBins32 = ['Qt5Core.dll', 'Qt5Gui.dll', 'Qt5Network.dll', 'Qt5OpenGL.dll', 'Qt5Widgets.dll', 'Qt5Sensors.dll', 'Qt5Positioning.dll', 'Qt5Qml.dll', 'Qt5Quick.dll', - 'Qt5Sql.dll', 'Qt5Svg.dll', 'Qt5Xml.dll', 'Qt5WebChannel.dll', 'Qt5Multimedia.dll', 'Qt5MultimediaWidgets.dll', - 'Qt5Test.dll', 'Qt5PrintSupport.dll'] qtPluginBins = [r'iconengines/qsvgicon.dll', r'imageformats/qjpeg.dll', r'imageformats/qsvg.dll', r'platforms/qwindows.dll'] mingwBins = ['libgcc_s_seh-1.dll', 'libstdc++-6.dll', 'libwinpthread-1.dll'] -mingwBins32 = ['libgcc_s_dw2-1.dll', 'libstdc++-6.dll', 'libwinpthread-1.dll'] mingwOptBins = [] -mingwOptBins32 = ['libeay32.dll', 'ssleay32.dll'] -dependencyFiles = ['qwt/lib/qwt.dll', 'zeromq/bin/libzmq.dll', 'hdf5/bin/hdf5_cpp.dll', 'hdf5/bin/hdf5.dll', 'fmilibrary/lib/libfmilib_shared.dll', - 'discount/bin/libmarkdown.dll'] +dependencyFiles = ['qwt/lib/qwt.dll', 'zeromq/bin/libzmq.dll', 'hdf5/bin/libhdf5_cpp.dll', 'hdf5/bin/libhdf5.dll', 'discount/bin/libmarkdown.dll'] # -------------------- Setup End -------------------- -# Internal global help variables -hopsan_bin_backup_dir = '' -hopsanDir = os.getcwd() +# ----- Input / Output help functions ----- - -STD_OUTPUT_HANDLE = -11 - -def quotePath(path): - """Appends quotes around string if quotes are not already present""" - if path[0] != r'"': - path = r'"'+path - if path[-1] != r'"': - path = path+r'"' - return path - -def slashAtEnd(path): - """ Append / at the end of a string (for paths) if not alrady present""" - if len(path) > 0: - if path[-1] != '/': - return path+'/' - return path - - -class bcolors: +class BColors(IntEnum): + """Windows console color codes.""" WHITE = 0x07 - GREEN= 0x0A + GREEN = 0x0A RED = 0x0C YELLOW = 0x0E BLUE = 0x0B -std_out_handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE) - -def setColor(color, handle=std_out_handle): - bool = ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color) - return bool +def set_color(color: BColors, handle=None) -> bool: + """Set console text color (Windows only).""" + if handle is None: + STD_OUTPUT_HANDLE = -11 + handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE) + return ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color) -setColor(bcolors.WHITE) +def print_success(text: str) -> None: + """Print a success message in green.""" + set_color(BColors.GREEN) + print(f"Success: {text}") + set_color(BColors.WHITE) -def printSuccess(text): - setColor(bcolors.GREEN) - print "Success: " + text - setColor(bcolors.WHITE) +def print_warning(text: str) -> None: + """Print a warning message in yellow.""" + set_color(BColors.YELLOW) + print(f"Warning: {text}") + set_color(BColors.WHITE) -def printWarning(text): - setColor(bcolors.YELLOW) - print "Warning: " + text - setColor(bcolors.WHITE) +def print_error(text: str) -> None: + """Print an error message in red.""" + set_color(BColors.RED) + print(f"Error: {text}") + set_color(BColors.WHITE) -def printError(text): - setColor(bcolors.RED) - print('Error: '+text) - setColor(bcolors.WHITE) +def print_debug(text: str) -> None: + """Print a debug message in blue.""" + set_color(BColors.BLUE) + print(f"Debug: {text}") + set_color(BColors.WHITE) -def printDebug(text): - setColor(bcolors.BLUE) - print "Debug: " + text - setColor(bcolors.WHITE) - -def pathExists(path, failMsg="", okMsg=""): - if os.path.isdir(path): - if okMsg!="": - printSuccess(okMsg) - return True - else: - if failMsg!="": - printError(failMsg) - return False - - -def fileExists(fileName): - return os.path.isfile(fileName) +def quote_path(path): + """Appends quotes around string if quotes are not already present.""" + path = str(path) + if not path.startswith('"'): + path = '"' + path + if not path.endswith('"'): + path += '"' + return path -def selectPathFromList(list_of_paths, failMsg, sucessMsg): - selected="" - for item in list_of_paths: - if pathExists(item): - selected = item - break - if selected=="": - printError(failMsg) - else: - printSuccess(sucessMsg) - return selected +def askYesNoQuestion(msg): + """Returns True on yes, False on no.""" + while True: + ans = input(msg).lower() + if ans in ("y", "yes"): + return True + elif ans in ("n", "no"): + return False -def findFileInDirTree(root_dir, file_name): - for dirpath, dirnames, filenames in os.walk(root_dir,topdown=True): - for filename in filenames: - if file_name == filename: - return True - return False +def askForVersion(): + dodevrelease = False + version = input('Enter release version number on the form a.b.c or leave blank for DEV build release: ') + if version == '': + dodevrelease = True + # Get date and time stamp of last commit used instead of "revision number" + revnum = '19700101.0000' + p = subprocess.Popen(['getGitInfo.bat', 'date.time', '.'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) + stdout, stderr = p.communicate() + if p.returncode == 0: + revnum = stdout.strip() -def askYesNoQuestion(msg): - # Returns true on yes - while(True): - ans = raw_input(msg) - if ans=="y": - return True - elif ans=="n": - return False + return version, revnum, dodevrelease -def setReadOnlyForAllFilesInDir(rootDir): - for dirpath, dirnames, filenames in os.walk(rootDir,topdown=True): - print "Setting files read-only in directory: "+ dirpath - for filename in filenames: - #print "Setting files read-only: "+ os.path.join(dirpath, filename) - os.chmod(os.path.join(dirpath, filename), stat.S_IREAD) +# ----- Finding files or directories help functions ----- +def select_path_from_list(list_of_paths: list[str | Path], fail_msg: str, success_msg: str) -> Path | None: + """Select the first existing directory from a list of paths. -def writeDoNotSafeFileHereFileToAllDirectories(rootDir): - for dirpath, dirnames, filenames in os.walk(rootDir,topdown=True): - print "Adding DoNotSaveFile to directory: "+dirpath - open(dirpath+"\---DO_NOT_SAVE_FILES_IN_THIS_DIRECTORY---", 'a+').close() + Args: + list_of_paths: List of paths to check. + fail_msg: Error message if no valid path is found. + success_msg: Success message if a valid path is found. + Returns: + Path object of the first existing directory, or None if no valid path exists. + """ + for path in list_of_paths: + path_obj = Path(path) + if path_obj.is_dir(): + print_success(success_msg) + print(f" {path_obj}") + return path_obj -def replace_pattern(filepath, re_pattern, replacement): - data = None - with open(filepath, 'r+') as f: - data = re.sub(re_pattern, replacement, f.read()) - with open(filepath, 'w+') as f: - f.write(data) + print_error(fail_msg) + return None -def replace_line_with_pattern(filepath, re_pattern, replacement): - data = str() - with open(filepath, 'r+') as f: - for line in f: - if re.search(re_pattern, line) is not None: - if replacement != '': - data += replacement + '\n' - else: - data += line - with open(filepath, 'w+') as f: - f.write(data) - -def prepend_append_line_with_pattern(filepath, re_pattern, prepend_text, append_text): - data = str() - with open(filepath, 'r+') as f: - for line in f: - if re.search(re_pattern, line) is not None: - new_line = line; - new_line = prepend_text + new_line - new_line = new_line[:-1] + append_text - data += new_line + '\n' - else: - data += line - with open(filepath, 'w+') as f: - f.write(data) - -def is_git_repo(dir): - if os.path.isdir(dir): - dotgitfile = os.path.join(dir, '.git') - return os.path.isdir(dotgitfile) +def find_file_in_dir_tree(root_dir: str, file_name: str) -> bool: + root = Path(root_dir) + for file in root.rglob('*'): + if file.is_file() and file.name == file_name: + return True return False -def is_git_submodule(dir): - if os.path.isdir(dir): - dotgitfile = os.path.join(dir, '.git') - return os.path.isfile(dotgitfile) - return False -def find_repo_root(path): - if is_git_repo(path) or is_git_submodule(path): - return path, True - else: - parts = os.path.split(path) - if len(path) > 1: - return find_repo_root(parts[0]) - else: - return parts[0], False - -def git_export(rel_src_dir, dst_dir, repo_dir=None, allow_dirty=True): - if repo_dir is None: - repo_dir = os.getcwd() - - src = rel_src_dir.rstrip('/') - dst = dst_dir - - # Check if src is subdir or file under a submodule of the current repo - # if so, then export from the submodule instead - repo_root, found = find_repo_root(os.path.join(repo_dir,src)) - src_rel_root = os.path.relpath(os.path.abspath(src), repo_root) - # print('rr '+repo_root) - # print('rd '+repo_dir) - # print('srr '+src_rel_root) - if repo_root != repo_dir and src_rel_root != '.': - print('Exporting "'+src+'", a member of submodule '+os.path.relpath(repo_root,repo_dir)) - return git_export(src_rel_root, dst_dir, repo_dir=os.path.abspath(repo_root), allow_dirty=allow_dirty ) - - if is_git_submodule(rel_src_dir): - print('Exporting submodule "'+rel_src_dir+'" to "'+dst_dir+'"') - else: - print('Exporting "'+rel_src_dir+'" to "'+dst_dir+'"') +def check_files_exist_in_dir(root_dir: str | Path, list_of_files: list[str]) -> bool: + """Check if all files exist in the given directory. - temp_dir = tempfile.mkdtemp() - time.sleep(1) - temp_file_name = str(uuid.uuid4()) - temp_file_path = os.path.join(temp_dir, temp_file_name).replace(' ','_')+'.tar' - temp_file_path_bash = temp_file_path.replace('\\','/') - src_bash = src.replace('\\','/') + Args: + root_dir: Root directory path. + list_of_files: List of filenames to check. - src_is_file = os.path.isfile(os.path.join(repo_dir,src)) + Returns: + True if all files exist, False otherwise. + """ + root_path = Path(root_dir) + did_find_all = True - if src_is_file: - wd = repo_dir - elif is_git_submodule(src): - wd = src - else: - wd = repo_dir - - # If a dirty state is allowed, we must first create a stash commit that we then export - commit_hash = 'HEAD' - was_stashed_ok = True - if allow_dirty: - args = ['git', 'stash', 'create', 'dirty_git_export_state'] - p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=wd) - stdout, stderr = p.communicate() - if p.returncode != 0: - print(args) - print('Stash create failed with return code: '+str(p.returncode)) - print(stdout) - print(stderr) - was_stashed_ok = False - else: - if stdout != '': - # Remove newline from stdout containing the commit hash - commit_hash = stdout[:-1] - - if not was_stashed_ok: - # Cleanup - shutil.rmtree(temp_dir) - return False + for filename in list_of_files: + file_path = root_path / filename + if not file_path.exists(): + print_error(f"{file_path} does not exist!") + did_find_all = False + return did_find_all - if src_is_file: - src_dir, src_file = os.path.split(src_bash) - if src_dir != '': - src_dir = ':'+src_dir - args = ['git', 'archive', '--format=tar', commit_hash+src_dir, src_file, '-o', temp_file_path_bash] - else: - # Append dirname to destination path - dirname = lastpathelement(src_bash) - dst = os.path.join(dst_dir, dirname) - if is_git_submodule(src): - #print('"'+rel_src_dir+'" is a submodule') - args = ['git', 'archive', '--format=tar', commit_hash, '-o', temp_file_path_bash] - else: - args = ['git', 'archive', '--format=tar', commit_hash+':'+src_bash, '-o', temp_file_path_bash] - - p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=wd) - stdout, stderr = p.communicate() - was_export_ok = False - if p.returncode != 0: - print(args) - print('Failed with return code: '+str(p.returncode)) - print(stdout) - print(stderr) - else: - tf = tarfile.open(temp_file_path) - tf.extractall(path=dst) - tf.close() - was_export_ok = True - - # Cleanup - shutil.rmtree(temp_dir) - - if was_export_ok: - # Now recurse into subdirectories if they are submodules - for currdir, subdirst, files in os.walk(src): - if currdir != src: - currdirdst = os.path.split(os.path.join(dst_dir, currdir))[0] - if is_git_submodule(currdir): - if not git_export(currdir, currdirdst, repo_dir=None, allow_dirty=allow_dirty): - was_export_ok = False - break - - return was_export_ok +# ----- File system operations help functions ----- def copy_file(src, dst): - if fileExists(src): + if Path(src).is_file(): shutil.copy(src, dst) else: print('Could not copy file: '+src+' it does not exist') -def mkdirs(path): - try: - os.makedirs(path) - except OSError: - if not os.path.isdir(path): - printError('Could not create directory path: '+path) - -def del_rw(action, name, exc): - os.chmod(name, stat.S_IWRITE) - os.remove(name) - -def callRd(tgt): - if pathExists(tgt): - shutil.rmtree(tgt, onerror=del_rw) - - -def callEXE(cmd, args): - #print "callEXE: " + quotePath(cmd)+r' '+args - if fileExists(cmd): - os.system(r'"'+quotePath(cmd)+r' '+args+r'"') - else: - printError(cmd+r' Does not exist!') - +def copy_dir_to(src_dir: str, dst_dir: str) -> bool: + """Copy a source directory into a destination directory. + Creates the destination directory if it doesn't exist. The source + directory name becomes a subdirectory within the destination. -def callDel(tgt): - if fileExists(tgt): - os.remove(tgt) + Args: + src_dir: Path to the source directory to copy. + dst_dir: Path to the destination directory. + Returns: + True if successful, False otherwise. + """ + src_path = Path(src_dir).resolve() + dst_path = Path(dst_dir).resolve() -def zip_directory(dir_path, zip_file_path): - print('Compressing directory: '+dir_path+' into: '+zip_file_path) - file_basepath = os.path.splitext(zip_file_path)[0] - dir_parts = os.path.split(dir_path) - if dir_parts[0] != '': - root = dir_parts[0] - base = dir_parts[1] - shutil.make_archive(file_basepath, 'zip', root_dir=root, base_dir=base) - else: - base = dir_parts[1] - shutil.make_archive(file_basepath, 'zip', base_dir=base) - + if not src_path.is_dir(): + print_error(f"Source directory {src_path} does not exist!") + return False -# Returns the last part of a path (split[1] or split[0] if only one part) -def lastpathelement(path): - parts = os.path.split(path) - if len(parts) == 1: - return parts[0] - elif len(parts) == 2: - return parts[1] - else: - return None - - -def copyFileToDir(srcDir, srcFile, dstDir, keep_relative_path=True): - if not srcDir[-1] == '/': - srcDir = srcDir+'/' - if not dstDir[-1] == '/': - dstDir = dstDir+'/' - src = srcDir+srcFile - #print(src) - if fileExists(src): - if keep_relative_path: - src_dirname = os.path.dirname(srcFile) - if not src_dirname == '': - #print(src_dirname) - dstDir=dstDir+src_dirname - #print(dstDir) - if not os.path.exists(dstDir): - print('Creating dst: '+dstDir) - os.makedirs(dstDir) - shutil.copy2(src, dstDir) - else: - print('Error: Source file '+src+' does not exist!') + # Create destination if it does not exist + dst_path.mkdir(parents=True, exist_ok=True) + tgt_path = dst_path / src_path.name + if tgt_path.exists(): + print_error(f"Target directory {tgt_path} already exists") + return False -def checkFilesExistInDir(root_dir, list_of_files): - did_find_all = True; - for f in list_of_files: - file_path = os.path.join(root_dir, f) - if not fileExists(file_path): - printError(file_path+' does not exist!') - did_find_all = False - return did_find_all + print(f"Copying: {src_path} to: {tgt_path}") + shutil.copytree(src_path, tgt_path) + return True -# Copy srcDir into dstDir, creating dstDir if necessary -def copyDirTo(srcDir, dstDir): - srcDir = os.path.normpath(srcDir) - dstDir = os.path.normpath(dstDir) - if os.path.exists(srcDir): - # Create destination if it does not exist - if not os.path.exists(dstDir): - os.makedirs(dstDir) - tgtDir = os.path.join(dstDir, lastpathelement(srcDir)) - if os.path.exists(tgtDir): - printError('tgtDir '+tgtDir+' already exists') - return False - print('Copying: '+srcDir+' to: '+tgtDir) - shutil.copytree(srcDir, tgtDir) - return True - else: - printError('Src directory '+srcDir+' does not exist!') - return False def move(src, dst): - print 'moving '+quotePath(src)+' to '+quotePath(dst) - if src != dst: - shutil.move(src, dst) - -def move_backup(src, dst): - dst_date=dst+time.strftime('%Y%m%d_%H%M%S') - move(src, dst_date) - return dst_date + print(f"Moving {quote_path(src)} to {quote_path(dst)}") + src_path = Path(src) + dst_path = Path(dst) + if src_path != dst_path: + shutil.move(str(src_path), str(dst_path)) -def makeMSVCOutDirName(version, arch): - return "MSVC"+version+"_"+arch +def mkdirs(path): + try: + os.makedirs(path) + except OSError: + if not os.path.isdir(path): + print_error('Could not create directory path: '+path) -def verifyPaths(): - print "Verifying and selecting path variables..." +def remove_dir(tgt): + def del_rw(action, name, exc): + os.chmod(name, stat.S_IWRITE) + os.remove(name) - global inkscapeDir - global innoDir - global qtDir - global msvc2008Path - global msvc2010Path - global jomDir - global qmakeDir + tgt_path = Path(tgt) + if tgt_path.exists(): + shutil.rmtree(tgt_path, onerror=del_rw) - isOk = True +def remove_file(tgt): + """Delete a file if it exists.""" + tgt_path = Path(tgt) + if tgt_path.is_file(): + tgt_path.unlink() - #Check if Qt path exists - qtDir = selectPathFromList(qmakeDir, "Qt libs could not be found in one of the expected locations.", "Found Qt libs!") - if qtDir == "": - isOk = False +def set_read_only_for_all_files_in_dir(root_dir): + root_path = Path(root_dir) + for dirpath in sorted(root_path.rglob('*')): + if dirpath.is_dir(): + print(f"Setting files read-only in directory: {dirpath}") + for file in dirpath.iterdir(): + if file.is_file(): + file.chmod(stat.S_IREAD) - #Check if qtcreator path exist - creatorDir = selectPathFromList(qtcreatorDirList, "Qt Creator could not be found in one of the expected locations.", "Found Qt Creator!") - if creatorDir == "": - isOk = False - jomDir = creatorDir+r'\bin' - qmakeDir = qmakeDir +def write_do_not_save_file_to_all_directories(root_dir): + root_path = Path(root_dir) + for dirpath in sorted(root_path.rglob('*')): + if dirpath.is_dir(): + marker_file = dirpath / '---DO_NOT_SAVE_FILES_IN_THIS_DIRECTORY---' + print(f"Adding DoNotSaveFile to directory: {dirpath}") + marker_file.touch() - #Make sure Visual Studio 2008 is installed in correct location - msvc2008Path = selectPathFromList(msvc2008DirList, "Microsoft Windows SDK 7.0 (MSVC2008) is not installed in expected place.", "Found location of Microsoft Windows SDK 7.0 (MSVC2008)!") - #if msvc2008Path == "": - # isOk = False - #Make sure Visual Studio 2010 is installed in correct location - msvc2010Path = selectPathFromList(msvc2010DirList, "Microsoft Windows SDK 7.1 (MSVC2010) is not installed in expected place.", "Found location of Microsoft Windows SDK 7.1 (MSVC2010)!") - #if msvc2010Path == "": - # isOk = False +# ----- Various help functions ----- - #Make sure the correct inno dir is used, 32 or 64 bit computers (Inno Setup is 32-bit) - innoDir = selectPathFromList(innoDirList, "Inno Setup 5 is not installed in expected place.", "Found Inno Setup!") - if innoDir == "": - isOk = False +def replace_pattern(filepath, re_pattern, replacement): + data = None + with open(filepath, 'r+') as f: + data = re.sub(re_pattern, replacement, f.read()) + if data: + with open(filepath, 'w+') as f: + f.write(data) - #Make sure the correct incskape dir is used, 32 or 64 bit computers (Inkscape is 32-bit) - inkscapeDir = selectPathFromList(inkscapeDirList, "Inkscape is not installed in expected place.", "Found Inkscape!") - if inkscapeDir == "": - risOk = False - #Make sure that doxygen is present for documentation build, but we dont care about result just print error if missing - selectPathFromList(doxygenDirList, "Doxygen is not installed in expected place.", "Found Doxygen!") +def call_exe(cmd, *args): + """Execute an external command with arguments.""" + cmd_path = Path(cmd) + if cmd_path.is_file(): + print([str(cmd_path), *args]) + subprocess.run([str(cmd_path), *args], check=False) + else: + print_error(f"{cmd} does not exist!") - # Make sure that Ghostscript is present for documentation build, Doxygen seems to require 32-bit version - gs_dir = selectPathFromList(gsDirList, "Ghostscript 32-bit is not installed in expected place.", "Found Ghostscript!") - if not findFileInDirTree(gs_dir, 'gswin32.exe'): - printError('You must install the 32-bit version of Ghostscipt, Doxygen is apparently hard-coded for that version') - if isOk: - printSuccess("Verification of path variables.") +def zip_directory(dir_path: str, zip_file_path: str) -> None: + """Compress a directory into a zip file. - return isOk + Args: + dir_path: Path to the directory to compress. + zip_file_path: Path where the zip file will be created. + """ + dir_path = Path(dir_path) + zip_file_path = Path(zip_file_path) + zip_file_destination = zip_file_path.stem + print(f"Compressing directory: {dir_path} into: {zip_file_path}") -def askForVersion(): - dodevrelease = False - version = raw_input('Enter release version number on the form a.b.c or leave blank for DEV build release: ') - if version == '': - dodevrelease = True + parent = dir_path.parent + name = dir_path.name + shutil.make_archive(str(zip_file_destination), 'zip', root_dir=str(parent), base_dir=name) - # Get date and time stamp of last commit used instead of "revision number" - revnum = '19700101.0000' - p = subprocess.Popen(['getGitInfo.bat', 'date.time', '.'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - if p.returncode == 0: - revnum = stdout[:-1] - return version, revnum, dodevrelease +# ----- Main help functions ----- +class BuildToolPaths: + """Container for all tool paths that the build process needs.""" + inkscape_dir: Path | None = None + gs_dir: Path | None = None + doxygen_dir: Path | None = None + inno_dir: Path | None = None + mingw_dir: Path | None = None + msvc2022_path: Path | None = None + qmake_dir: Path | None = None + qt_dir: Path | None = None + jom_dir: Path | None = None -def msvcCompile(msvcVersion, architecture, msvcpath): - print "Compiling HopsanCore with Microsoft Visual Studio "+msvcVersion+" "+architecture+"..." + def verify_paths(self) -> bool: + print("Verifying and selecting build tool path variables...") + isOk = True - if msvcpath == "": - print(r'Error: msvcpath not set!') - return False + # Check if mingw path exists + self.mingw_dir = select_path_from_list([g_mingw_dir], "Mingw could not be found in the expected location.", "Found MinGW!") + if self.mingw_dir == "": + isOk = False - # Remove previous files - callDel(hopsanDir+r'\bin\hopsancore*.*') - - # Create clean build directory - hopsanBuildDir = hopsanDir+r'\HopsanCore_bd' - callRd(hopsanBuildDir) - mkdirs(hopsanBuildDir) - - # Create compilation script and compile - os.chdir(hopsanDir) - # Generate compile script, setup compiler and compile - mkspec = "win32-msvc"+msvcVersion - jom = quotePath(jomDir+r'\jom.exe') - qmake = quotePath(qmakeDir+r'\qmake.exe') - hopcorepro = quotePath(hopsanDir+r'\HopsanCore\HopsanCore.pro') - f = open('compileWithMSVC.bat', 'w') - f.write(r'echo off'+"\n") - f.write(r'REM This file has been automatically generated by the python build script. Do NOT commit it to svn!'+"\n") - f.write(r'setlocal enabledelayedexpansion'+"\n") - f.write(r'call '+quotePath(msvcpath+r'\SetEnv.cmd')+r' /Release /'+architecture+"\n") - f.write(r'COLOR 07'+"\n") - f.write(r'cd '+quotePath(hopsanBuildDir)+"\n") - f.write(r'call '+jom+r' clean'+"\n") - f.write(r'call '+qmake+r' '+hopcorepro+r' -r -spec '+mkspec+r' "CONFIG+=release" "QMAKE_CXXFLAGS_RELEASE += -wd4251"'+"\n") - f.write(r'call '+jom+"\n") - f.write(r'cd ..'+"\n") - #f.write("pause\n") - f.close() - - # Compile - os.system("compileWithMSVC.bat") - #printDebug(os.environ["PATH"]) - - #Remove build directory - callRd(hopsanBuildDir) - - hopsanDirBin = hopsanDir+r'\bin' - if not fileExists(hopsanDirBin+r'\hopsancore.dll'): - printError("Failed to build HopsanCore with Visual Studio "+msvcVersion+" "+architecture) - return False + # Check if Qt path exists + self.qt_dir = select_path_from_list([g_qmake_dir], "Qt libs could not be found in one of the expected locations.", "Found Qt libs!") + if self.qt_dir == "": + isOk = False + self.qmake_dir = Path(g_qmake_dir) - #Move files to correct MSVC directory - targetDir = hopsanDirBin+"\\"+makeMSVCOutDirName(msvcVersion, architecture) - callRd(targetDir) - mkdirs(targetDir) - move(hopsanDirBin+r'\hopsancore.dll', targetDir) - move(hopsanDirBin+r'\hopsancore.lib', targetDir) - move(hopsanDirBin+r'\hopsancore.exp', targetDir) + # Check if qtcreator path exist + self.creator_dir = select_path_from_list(qtcreatorDirList, "Qt Creator could not be found in one of the expected locations.", "Found Qt Creator!") + if self.creator_dir == "": + isOk = False + self.jom_dir = self.creator_dir / "bin" - return True + # Make sure Visual Studio 2022 is installed in correct location + self.msvc2022_path = select_path_from_list(msvc2022DirList, "Microsoft Windows SDK 7.1 (MSVC2010) is not installed in expected place.", "Found location of Microsoft Windows SDK 7.1 (MSVC2010)!") + #if self.msvc2022_path == "": + # isOk = False + # Make sure the correct inno dir is used, 32 or 64 bit computers (Inno Setup is 32-bit) + self.inno_dir = select_path_from_list(innoDirList, "Inno Setup is not installed in expected place.", "Found Inno Setup!") + if self.inno_dir == "": + isOk = False -def prepareSourceCode(versionnumber, revisionnumber, dodevrelease): - # Regenerate default library - hopsanDefaultLibraryDir = hopsanDir+r'\componentLibraries\defaultLibrary' - os.chdir(hopsanDefaultLibraryDir) - os.system(r'generateLibraryFiles.bat -nopause') - os.chdir(hopsanDir) + # Make sure the correct incskape dir is used, 32 or 64 bit computers (Inkscape is 32-bit) + self.inkscape_dir = select_path_from_list(inkscapeDirList, "Inkscape is not installed in expected place.", "Found Inkscape!") + if self.inkscape_dir == "": + isOk = False - copy_file(r'HopsanGUI\graphics\splash.svg', r'HopsanGUI\graphics\tempdummysplash.svg') + # Make sure that doxygen is present for documentation build, but we dont care about result just print error if missing + self.doxygen_dir = select_path_from_list(doxygenDirList, "Doxygen is not installed in expected place.", "Found Doxygen!") - fullversion = versionnumber+'.'+revisionnumber - if not dodevrelease: - # Set version numbers (by changing .h files) - replace_pattern('HopsanCore/include/HopsanCoreVersion.h', r'#define HOPSANCOREVERSION .*', r'#define HOPSANCOREVERSION "{}"'.format(fullversion)) - replace_pattern(r'HopsanGUI/version_gui.h', r'#define HOPSANGUIVERSION .*', r'#define HOPSANGUIVERSION "{}"'.format(fullversion)) - replace_pattern(r'HopsanCLI/version_cli.h', r'#define HOPSANCLIVERSION .*', r'#define HOPSANCLIVERSION "{}"'.format(fullversion)) + # Make sure that Ghostscript is present for documentation build, Doxygen seems to require 32-bit version + self.gs_dir = select_path_from_list(gsDirList, "Ghostscript 32-bit is not installed in expected place.", "Found Ghostscript!") + if not find_file_in_dir_tree(self.gs_dir, 'gswin32.exe'): + print_error('You must install the 32-bit version of Ghostscipt, Doxygen is apparently hard-coded for that version') - # Hide splash screen development warning - replace_pattern(r'HopsanGUI/graphics/tempdummysplash.svg', r'Development version', '') + if isOk: + print_success("Verification of tool path variables.") - # Make sure development flag is not defined - replace_pattern(r'HopsanGUI/HopsanGUI.pro', r'.*?DEFINES \*= DEVELOPMENT', r'#DEFINES *= DEVELOPMENT') + return isOk - # Set the release version definition - replace_pattern(r'HopsanGUI/version_gui.h', r'#define HOPSANRELEASEVERSION .*', r'#define HOPSANRELEASEVERSION "{}"'.format(fullversion)) - # Set splash screen version and revision number - replace_pattern(r'HopsanGUI/graphics/tempdummysplash.svg', r'0\.00\.0', versionnumber) - replace_pattern(r'HopsanGUI/graphics/tempdummysplash.svg', r'20170000\.0000', revisionnumber) - # Regenerate splash screen - callEXE(inkscapeDir+r'\inkscape.com', r'HopsanGUI\graphics\tempdummysplash.svg --export-background="#ffffff" --export-dpi=90 --export-type=png --export-filename=HopsanGUI/graphics/splash.png') - callDel(r'HopsanGUI\graphics\tempdummysplash.svg') +def extract_hopsan_build_path(arch: str, path_name: str) -> str: + script_path = Path('dependencies') / 'setHopsanBuildPaths.bat' - # Make sure we compile defaultLibrary into core - replace_pattern('Common.prf', r'.*?DEFINES \*= HOPSAN_INTERNALDEFAULTCOMPONENTS', r'DEFINES *= HOPSAN_INTERNALDEFAULTCOMPONENTS') - replace_pattern(r'HopsanCore/HopsanCore.pro', r'#INTERNALCOMPLIB.CPP#', r'../componentLibraries/defaultLibrary/defaultComponentLibraryInternal.cpp \\') - replace_pattern(r'HopsanCore/HopsanCore.pro', r'#INTERNALCOMPLIB_FMI4C_DEPENDENCY#', r'include($${PWD}/../dependencies/fmi4c.pri)') - prepend_append_line_with_pattern('componentLibraries/defaultLibrary/defaultComponentLibrary.xml', '', '\n') - replace_pattern('componentLibraries/componentLibraries.pro', 'defaultLibrary', '') + try: + result = subprocess.run( + [str(script_path), arch], + capture_output=True, + text=True, + check=False + ) + except FileNotFoundError: + return f"Script not found: {script_path}" + + if result.returncode != 0: + return "Failed to run setHopsanBuildPaths.bat script" + + for line in result.stdout.splitlines(): + if line.startswith(path_name): + parts = line.split(':', 1) + if len(parts) == 2: + return parts[1].strip() + + return f"{path_name} path not found!" + + +def create_clean_output_directory(package_output_destination: Path) -> bool: + """Try to remove and recreate the output directory. + Args: + package_output_destination: Path object pointing to the desired output directory. + Returns: + True if successful, False otherwise. + """ + # Clear old output folder + remove_dir(package_output_destination) + if package_output_destination.exists(): + print_warning("Unable to clear old output folder.") + if not ask_yes_no_question("Continue? (y/n): "): + return False + # Create new output folder + package_output_destination.mkdir(parents=True, exist_ok=True) + if not package_output_destination.exists(): + print_error("Failed to create package output folder.") + return False -def buildRelease(): + return True - # Make sure we undefine HOPSANCORE_WRITELOG, so that MSVC dlls do not try to access the log file - replace_pattern('HopsanCore/HopsanCore.pro', r'.*?DEFINES \*= HOPSANCORE_WRITELOG', r'#DEFINES *= HOPSANCORE_WRITELOG') +def prepare_source_code(version_number: str, revision_number: str, dev_release: bool) -> None: + """ + Regenerate the default library, update version macros, and rebuild the splash screen. + + Parameters + ---------- + version_number: str + Human readable version (e.g. ``"2.5"``). + revision_number: str + Numeric revision (e.g. ``"20240406"``). + dev_release: bool + ``True`` for a development build, ``False`` for a production release. + """ + + # ------------------------------------------------------------------ + # Regenerate the default library + # ------------------------------------------------------------------ + default_lib_dir = g_hopsan_src_dir / "componentLibraries" / "defaultLibrary" + os.chdir(default_lib_dir) + call_exe(default_lib_dir / "generateLibraryFiles.bat", "-nopause") + os.chdir(g_hopsan_src_dir) + + # ------------------------------------------------------------------ + # Temporary splash‑screen copy + # ------------------------------------------------------------------ + splash_src = g_hopsan_src_dir / "HopsanGUI" / "graphics" / "splash.svg" + splash_tmp = g_hopsan_src_dir / "HopsanGUI" / "graphics" / "tempdummysplash.svg" + shutil.copyfile(splash_src, splash_tmp) + + # ------------------------------------------------------------------ + # Version strings + # ------------------------------------------------------------------ + full_version = f"{version_number}.{revision_number}" + + if not dev_release: + # Update core / GUI / CLI version macros + replace_pattern( + g_hopsan_src_dir / "HopsanCore" / "include" / "HopsanCoreVersion.h", + r"#define HOPSANCOREVERSION .*", + f'#define HOPSANCOREVERSION "{full_version}"', + ) + replace_pattern( + g_hopsan_src_dir / "HopsanGUI" / "version_gui.h", + r"#define HOPSANGUIVERSION .*", + f'#define HOPSANGUIVERSION "{full_version}"', + ) + replace_pattern( + g_hopsan_src_dir / "HopsanCLI" / "version_cli.h", + r"#define HOPSANCLIVERSION .*", + f'#define HOPSANCLIVERSION "{full_version}"', + ) + + # Hide development warning in the temporary splash file + replace_pattern(splash_tmp, r"Development version", "") + + # Remove the DEVELOPMENT define in the CMakeList file + # TODO: Use as CMake option instead maybe + replace_pattern( + g_hopsan_src_dir / "HopsanGUI" / "CMakeLists.txt", + r"target_compile_definitions(${target_name} PRIVATE DEVELOPMENT)", + r"", + ) + + # Release‑specific macro (always set) + replace_pattern( + g_hopsan_src_dir / "HopsanGUI" / "version_gui.h", + r"#define HOPSANRELEASEVERSION .*", + f'#define HOPSANRELEASEVERSION "{full_version}"', + ) + + # ------------------------------------------------------------------ + # Update splash‑screen placeholders + # ------------------------------------------------------------------ + replace_pattern(splash_tmp, r"0\.00\.0", version_number) + replace_pattern(splash_tmp, r"20170000\.0000", revision_number) + + # ------------------------------------------------------------------ + # Export splash as PNG via Inkscape + # ------------------------------------------------------------------ + inkscape_exe = g_toolpaths.inkscape_dir / r"inkscape.com" + svg_path = splash_tmp.as_posix() + png_path = (g_hopsan_src_dir / "HopsanGUI" / "graphics" / "splash.png").as_posix() + + call_exe( + inkscape_exe, + svg_path, + "--export-background=#ffffff", + "--export-dpi=90", + "--export-type=png", + f"--export-filename={png_path}", + ) + + # ------------------------------------------------------------------ + # Clean up temporary file + # ------------------------------------------------------------------ + splash_tmp.unlink() + + +# def msvcCompile(msvcVersion, architecture, msvcpath): + # print("Compiling HopsanCore with Microsoft Visual Studio "+msvcVersion+" "+architecture+"...") + + # if msvcpath == "": + # print(r'Error: msvcpath not set!') + # return False + + # # Remove previous files + # remove_file(g_hopsan_src_dir+r'\bin\hopsancore*.*') + + # # Create clean build directory + # hopsanBuildDir = g_hopsan_src_dir+r'\HopsanCore_bd' + # remove_dir(hopsanBuildDir) + # mkdirs(hopsanBuildDir) + + # # Create compilation script and compile + # os.chdir(g_hopsan_src_dir) + # # Generate compile script, setup compiler and compile + # mkspec = "win32-msvc"+msvcVersion + # jom = quotePath(jomDir+r'\jom.exe') + # qmake = quotePath(qmake_dir+r'\qmake.exe') + # hopcorepro = quotePath(g_hopsan_src_dir+r'\HopsanCore\HopsanCore.pro') + # f = open('compileWithMSVC.bat', 'w') + # f.write(r'echo off'+"\n") + # f.write(r'REM This file has been automatically generated by the python build script. Do NOT commit it to svn!'+"\n") + # f.write(r'setlocal enabledelayedexpansion'+"\n") + # f.write(r'call '+quotePath(msvcpath+r'\SetEnv.cmd')+r' /Release /'+architecture+"\n") + # f.write(r'COLOR 07'+"\n") + # f.write(r'cd '+quotePath(hopsanBuildDir)+"\n") + # f.write(r'call '+jom+r' clean'+"\n") + # f.write(r'call '+qmake+r' '+hopcorepro+r' -r -spec '+mkspec+r' "CONFIG+=release" "QMAKE_CXXFLAGS_RELEASE += -wd4251"'+"\n") + # f.write(r'call '+jom+"\n") + # f.write(r'cd ..'+"\n") + # #f.write("pause\n") + # f.close() + + # # Compile + # os.system("compileWithMSVC.bat") + # #print_debug(os.environ["PATH"]) + + # #Remove build directory + # remove_dir(hopsanBuildDir) + + # hopsan_src_dirBin = g_hopsan_src_dir+r'\bin' + # if not file_exists(hopsan_src_dirBin+r'\hopsancore.dll'): + # print_error("Failed to build HopsanCore with Visual Studio "+msvcVersion+" "+architecture) + # return False + + # def makeMSVCOutDirName(version, arch): + # return "MSVC"+version+"_"+arch + + # #Move files to correct MSVC directory + # targetDir = hopsan_src_dirBin+"\\"+makeMSVCOutDirName(msvcVersion, architecture) + # remove_dir(targetDir) + # mkdirs(targetDir) + # move(hopsan_src_dirBin+r'\hopsancore.dll', targetDir) + # move(hopsan_src_dirBin+r'\hopsancore.lib', targetDir) + # move(hopsan_src_dirBin+r'\hopsancore.exp', targetDir) + + # return True + + +def build_mingw_release(install_destination: Path) -> bool: # ======================================================== - # Build HOPSANCORE with MSVC, else remove those folders + # Build HOPSANCORE with MSVC # ======================================================== - if buildVCpp: - if msvc2008Path != "": - if not msvcCompile("2008", "x86", msvc2008Path): - return False - if not msvcCompile("2008", "x64", msvc2008Path): - return False - if msvc2010Path != "": - if not msvcCompile("2010", "x86", msvc2010Path): - return False - if not msvcCompile("2010", "x64", msvc2010Path): - return False - else: - hopsanBinDir = hopsanDir+"\\bin\\" - callRd(hopsanBinDir+makeMSVCOutDirName("2008", "x86")) - callRd(hopsanBinDir+makeMSVCOutDirName("2008", "x64")) - callRd(hopsanBinDir+makeMSVCOutDirName("2010", "x86")) - callRd(hopsanBinDir+makeMSVCOutDirName("2010", "x64")) - - # Make sure the MinGW compilation uses the HOPSANCORE_WRITELOG define, so that log file is enabled - replace_pattern('HopsanCore/HopsanCore.pro',r'.*?DEFINES \*= HOPSANCORE_WRITELOG', 'DEFINES *= HOPSANCORE_WRITELOG') + # if buildVCpp: + # if msvc2022Path != "": + # if not msvcCompile("2022", "x64", msvc2022Path): + # return False # ======================================================== - # BUILD WITH MINGW32 + # BUILD WITH MINGW # ======================================================== - print "Compiling with MinGW" - - # Remove previous files - #callDel(hopsanDir+r'\bin\hopsancore*.*') - #callDel(hopsanDir+r'\bin\hopsangui*.*') - #callDel(hopsanDir+r'\bin\hopsancli*.*') - - # Create clean build directory - hopsanBuildDir = hopsanDir+r'\HopsanNG_bd' - callRd(hopsanBuildDir) - mkdirs(hopsanBuildDir) - - # Generate compile script, setup compiler and compile - mkspec = "win32-g++" - f = open('compileWithMinGW.bat', 'w') - f.write(r'echo off'+"\n") - f.write(r'REM This file has been automatically generated by the python build script. Do NOT commit it to svn!'+"\n") - f.write(r'SET PATH='+mingwDir+r';'+qmakeDir+r';%PATH%'+"\n") - f.write(r'mingw32-make.exe clean'+"\n") - f.write(r'qmake.exe '+quotePath(hopsanDir+r'\HopsanNG.pro')+r' -r -spec '+mkspec+r' "CONFIG+=release"'+"\n") - f.write(r'mingw32-make.exe -j8'+"\n") - #f.write("pause\n") - f.close() - - os.chdir(hopsanBuildDir) - os.system(r'..\compileWithMinGW.bat') - - if not fileExists(hopsanDir+r'\bin\hopsancore.dll') or not fileExists(hopsanDir+r'\bin\hopsangui.exe') or not fileExists(hopsanDir+r'\bin\hopsancli.exe'): - printError("Failed to build Hopsan with MinGW.") + print("Building with MinGW") + + build_type='Release' + code_dir=g_hopsan_src_dir + build_dir = g_temporary_build_root / f'hopsan-release-build-{build_type}' + + # Ensure clean build and install directories + remove_dir(build_dir) + remove_dir(install_destination) + + # Generate build script for MinGW + script_content = f"""echo off + REM This file was automatically generated by the makeWindowsrelease.py script! + set PATH={g_mingw_dir};{g_qmake_dir};%PATH% + set "mingw_path={g_mingw_dir}" + set "qmake_path={g_qmake_dir}" + + cmake -G"MinGW Makefiles" -DCMAKE_COLOR_MAKEFILE=OFF -DCMAKE_BUILD_TYPE={build_type} -DCMAKE_INSTALL_PREFIX={install_destination} -B{build_dir} -S{code_dir} --fresh + cmake --build {build_dir} --config {build_type} --parallel 16 + cmake --build {build_dir} --config {build_type} --parallel 16 --target install + REM ctest -C {build_dir} --output-on-failure --parallel 8 + """ + + build_script = Path('compile-with-MinGW.bat') + build_script.write_text(script_content) + try: + subprocess.run( + str(build_script), + shell=True, + check=True, + ) + except subprocess.CalledProcessError as e: + print_error(f"Build failed with exit code {e.returncode}") + + required_files = [ + install_destination / 'bin' / 'hopsancore.dll', + install_destination / 'bin' / 'hopsangui.exe', + install_destination / 'bin' / 'hopsancli.exe', + ] + if not all(file.exists() for file in required_files): + print_error("Failed to build Hopsan with MinGW.") return False - printSuccess("Compilation using MinGW") + print_success("Building with MinGW") return True -def runValidation(): - print "Running validation tests" - os.chdir(hopsanDir) - return subprocess.call("runValidationTests.bat nopause") == 0 +def finalize_install_dir(hopsan_installation_destination): + # Write the do not save files here file + write_do_not_save_file_to_all_directories(hopsan_installation_destination) + # Set all files to read-only + set_read_only_for_all_files_in_dir(hopsan_installation_destination) + return True -def copyFiles(): +def create_zip_package(hopsan_installation_destination: str, zip_file: str, output_dir: str) -> bool: + """Create a zip package and move it to the output directory. - # Make sure we are in the hopsan root - os.chdir(hopsanDir) + Args: + zip_file: Name of the zip file to create. + output_dir: Directory where the zip file will be moved. - # Create a temporary release directory - mkdirs(gTemporaryBuildDir) - if not pathExists(gTemporaryBuildDir): - printError("Failed to create temporary directory") - return False + Returns: + True if successful, False otherwise. + """ + print(f"Creating zip package: {zip_file}...") + zip_directory(hopsan_installation_destination, zip_file) + move(zip_file, output_dir) - # Create directories - mkdirs(gTemporaryBuildDir+'/Models') - mkdirs(gTemporaryBuildDir+'/componentLibraries') - mkdirs(gTemporaryBuildDir+'/doc') - mkdirs(gTemporaryBuildDir+'/dependencies/tools') - mkdirs(gTemporaryBuildDir+'/hopsanc') - - # Copy "bin" folder to temporary directory - copyDirTo(r'bin', gTemporaryBuildDir) - - # Build user documentation - os.system("buildUserDocumentation") - if not fileExists(hopsanDir+r'\doc\html\index.html'): - printError("Failed to build user documentation") - - # Export HopsanCore including all source code, then cleanup unneeded file - git_export('HopsanCore', gTemporaryBuildDir) - callRd(gTemporaryBuildDir+r'/HopsanCore/dependencies/sundials/config') - callRd(gTemporaryBuildDir+r'/HopsanCore/dependencies/sundials/doc') - callRd(gTemporaryBuildDir+r'/HopsanCore/dependencies/sundials/examples') - callRd(gTemporaryBuildDir+r'/HopsanCore/dependencies/sundials/test') - callDel(gTemporaryBuildDir+r'/HopsanCore/dependencies/sundials/INSTALL_GUIDE.pdf') - callDel(gTemporaryBuildDir+r'/HopsanCore/dependencies/sundials/CMakeLists.txt') - - # Export HopsanC include directory - git_export('hopsanc/include', gTemporaryBuildDir+r'/hopsanc') - - # Export needed core code dependencies - copyDirTo(r'dependencies/katex', gTemporaryBuildDir+r'/dependencies') - - # Copy 3pdependency installations - if not copyDirTo(r'dependencies/fmilibrary', gTemporaryBuildDir+r'/dependencies'): + output_path = Path(output_dir) / zip_file + if not output_path.exists(): + print_error(f"Failed to create zip package: {zip_file}") return False - if not copyDirTo(r'dependencies/fmi4c', gTemporaryBuildDir+r'/dependencies'): - return False - - # Copy 7zip to temporary directory - git_export(r'dependencies/tools/7z', gTemporaryBuildDir+'/dependencies/tools') - # Export "Example Models" SVN directory to temporary directory - git_export(r'Models\Example Models', gTemporaryBuildDir+r'\Models') - - # Export "Test Models" SVN directory to temporary directory - git_export(r'Models\Component Test', gTemporaryBuildDir+r'\Models') - - # Export "Benchmark Models" SVN directory to temporary directory - git_export(r'Models\Benchmark Models', gTemporaryBuildDir+r'\Models') - - # Export defaultLibrary" SVN directory to temporary directory - git_export(r'componentLibraries\defaultLibrary', gTemporaryBuildDir+r'\componentLibraries') - - # Export "exampleComponentLib" SVN directory to temporary directory - git_export(r'componentLibraries\exampleComponentLib', gTemporaryBuildDir+r'\componentLibraries') - copyFileToDir('componentLibraries/exampleComponentLib', 'exampleComponentLib.dll', gTemporaryBuildDir+r'\componentLibraries\exampleComponentLib') - - # Export ModelicaExmpleLibrary - git_export(r'componentLibraries\ModelicaExampleLib', gTemporaryBuildDir+r'\componentLibraries') - - # Export "extensionLibrary" Git directory to temporary directory - git_export(r'componentLibraries\extensionLibrary', gTemporaryBuildDir+r'\componentLibraries') - copyFileToDir('componentLibraries/extensionLibrary', 'extensionLibrary.dll', gTemporaryBuildDir+r'\componentLibraries\extensionLibrary') - - # Export "autoLibs" SVN directory to temporary directory - git_export(r'componentLibraries\autoLibs', gTemporaryBuildDir+r'\componentLibraries') - - # Export "Scripts" folder to temporary directory - git_export(r'Scripts', gTemporaryBuildDir) - - # Copy "hopsan-default-configuration.xml" file to temporary directory - git_export("hopsan-default-configuration.xml", gTemporaryBuildDir) + print_success(f"Created zip package: {zip_file} successfully!") + return True - # Copy "release notes" file to temporary directory - git_export("Hopsan-release-notes.txt", gTemporaryBuildDir) - # Copy "README.md" file to temporary directory - git_export("README.md", gTemporaryBuildDir) +def create_inno_installer(hopsan_installation_destination: str, exe_file_name: str, inno_arch: str, output_dir: str) -> bool: + """Generate an Inno Setup installer executable. - # Copy documentation to temporary directory - copyDirTo(r'doc\html', gTemporaryBuildDir+r'\doc') - copyDirTo(r'doc\graphics', gTemporaryBuildDir+r'\doc') + Args: + exe_file_name: Name of the executable file (without .exe extension). + inno_arch: Target architecture (e.g., "x64", "x86"). + output_dir: Directory where the installer will be created. - # Write the do not save files here file - writeDoNotSafeFileHereFileToAllDirectories(gTemporaryBuildDir) + Returns: + True if successful, False otherwise. + """ + exe_file = f"{exe_file_name}.exe" + print(f"Generating install executable: {exe_file}...") - # Set all files to read-only - setReadOnlyForAllFilesInDir(gTemporaryBuildDir) + inno_args = [ + f'/o{output_dir}', + f'/f{exe_file_name}', + f'/dMyAppVersion={gFullVersion}', + f'/dMyArchitecture={inno_arch}', + f'/dMyFilesSource={hopsan_installation_destination}', + str(g_hopsan_src_dir / "packaging/windows/HopsanReleaseInnoSetupScript.iss") + ] - return True + call_exe(g_toolpaths.inno_dir / "iscc.exe", *inno_args) -def createZipInstaller(zipFile, outputDir): - print('Creating zip package: '+zipFile+'...') - zip_directory(gTemporaryBuildDir, zipFile) - move(zipFile, outputDir) - if not fileExists(os.path.join(outputDir, zipFile)): - printError('Failed to create zip package: '+zipFile) + output_path = Path(output_dir) / exe_file + if not output_path.exists(): + print_error(f"Failed to create installer executable: {exe_file}") return False - printSuccess('Created zip package: '+zipFile+' successfully!') - return True -def createInnoInstaller(exeFileName, innoArch, outputDir): - exeFile=exeFileName+'.exe' - print 'Generating install executable: '+exeFile+'...' - innocmd=r' /o"'+outputDir+r'" /f"'+exeFileName+r'" /dMyAppVersion="'+gFullVersion+r'" /dMyArchitecture="'+innoArch+r'" /dMyFilesSource="'+gTemporaryBuildDir+r'" packaging/windows/HopsanReleaseInnoSetupScript.iss' - #print innocmd - callEXE(innoDir+r'\iscc.exe', innocmd) - if not fileExists(outputDir+'/'+exeFile): - printError('Failed to create installer executable: '+exeFile) - return False - printSuccess('Generated install executable: '+exeFile) + print_success(f"Generated install executable: {exe_file}") return True -def createInstallFiles(): +def create_installation_packages(hopsan_installation_destination: Path, package_output_destination: Path): # Make sure we are in the hopsan root - os.chdir(hopsanDir) - - if gDo64BitRelease: - zipFile=r'Hopsan-'+gReleaseFileVersionName+r'-win64-zip.zip' - zipWithCompilerFile=r'Hopsan-'+gReleaseFileVersionName+r'-win64-with_compiler-zip.zip' - exeFileName=r'Hopsan-'+gReleaseFileVersionName+r'-win64-installer' - exeWithCompilerFileName=r'Hopsan-'+gReleaseFileVersionName+r'-win64-with_compiler-installer' - innoArch=r'x64' - else: - zipFile=r'Hopsan-'+gReleaseFileVersionName+r'-win32-zip.zip' - zipWithCompilerFile=r'Hopsan-'+gReleaseFileVersionName+r'-win32-with_compiler-zip.zip' - exeFileName=r'Hopsan-'+gReleaseFileVersionName+r'-win32-installer' - exeWithCompilerFileName=r'Hopsan-'+gReleaseFileVersionName+r'-win32-with_compiler-installer' - innoArch=r'' #Should be empty for 32-bit + os.chdir(g_hopsan_src_dir) + + zip_file = f"Hopsan-{gReleaseFileVersionName}-win64-zip.zip" + zip_with_compiler_file = f"Hopsan-{gReleaseFileVersionName}-win64-with_compiler-zip.zip" + exe_file_name = f"Hopsan-{gReleaseFileVersionName}-win64-installer" + exe_with_compiler_file_name = f"Hopsan-{gReleaseFileVersionName}-win64-with_compiler-installer" + inno_arch = "x64" # Create zip package - if not createZipInstaller(zipFile, hopsanDirOutput): + if not create_zip_package(hopsan_installation_destination, zip_file, package_output_destination): return False # Execute Inno compile script - if not createInnoInstaller(exeFileName, innoArch, hopsanDirOutput): + if not create_inno_installer(hopsan_installation_destination, exe_file_name, inno_arch, package_output_destination): return False # Copy the compiler if gIncludeCompiler: - print('Copying compiler...') - copyDirTo(mingwDir+r'/../', gTemporaryBuildDir) - mingwDirName = os.path.basename(os.path.normpath(mingwDir+r'/../')) - if gDo64BitRelease: - move(os.path.join(gTemporaryBuildDir, mingwDirName), os.path.join(gTemporaryBuildDir, 'mingw64')) - else: - move(os.path.join(gTemporaryBuildDir, mingwDirName), os.path.join(gTemporaryBuildDir, 'mingw')) + print("Copying compiler...") + mingw_parent = Path(g_mingw_dir).parent + copy_dir_to(str(mingw_parent), hopsan_installation_destination) + + mingw_dir_name = mingw_parent.name + move( + str(Path(hopsan_installation_destination) / mingw_dir_name), + str(Path(hopsan_installation_destination) / "mingw64") + ) + #print('Removing /opt') - #callRd(gTemporaryBuildDir+r'\mingw64\opt') + #remove_dir(gTemporaryBuildDir+r'\mingw64\opt') # Now build zip and installer with compiler included - if not createZipInstaller(zipWithCompilerFile, hopsanDirOutput): + if not create_zip_package(hopsan_installation_destination, zip_with_compiler_file, package_output_destination): return False - if not createInnoInstaller(exeWithCompilerFileName, innoArch, hopsanDirOutput): + if not create_inno_installer(hopsan_installation_destination, exe_with_compiler_file_name, inno_arch, package_output_destination): return False # Copy release notes to output directory - copy_file('Hopsan-release-notes.txt', hopsanDirOutput) + copy_file('Hopsan-release-notes.txt', package_output_destination) return True -def createCleanOutputDirectory(): - global hopsanDirOutput - """Try to remove and recreate the output directory""" - if gDo64BitRelease: - hopsanDirOutput=hopsanDir+r'\output64' - else: - hopsanDirOutput=hopsanDir+r'\output' +def run_validation(hopsan_installation_destination: Path) -> bool: + """Run validation tests and return success status.""" + print("Running validation tests") + test_script = g_hopsan_src_dir / "runValidationTests.bat" + result = subprocess.run( + f"{test_script} nopause", + shell=True, + cwd=hopsan_installation_destination, + check=False + ) + return result.returncode == 0 - # Clear old output folder - callRd(hopsanDirOutput) - if pathExists(hopsanDirOutput): - printWarning("Unable to clear old output folder.") - if not askYesNoQuestion("Continue? (y/n): "): - return False - - # Create new output folder - mkdirs(hopsanDirOutput) - if not pathExists(hopsanDirOutput): - printError("Failed to create output folder.") - return False - - return True +def cleanup(): + """Remove temporary build and install directories""" + print(f"Cleaning up, removing: {g_temporary_build_root}") + remove_dir(g_temporary_build_root) -def renameBinFolder(): - global hopsan_bin_backup_dir - # Move the bin folder to temp storage to avoid packagin dev junk into release - hopsan_bindir = hopsanDir+r'/bin' - hopsan_bin_backup_dir = '' - if pathExists(hopsan_bindir): - hopsan_bin_backup_dir = move_backup(hopsan_bindir, hopsanDir+r'/bin_build_backup') - time.sleep(1) - if pathExists(hopsan_bindir): - printError("Could not move the bin folder to temporary backup before build.") - return False - # Create clean bin directory - mkdirs(hopsan_bindir) - return True +############################################################################### +# Execution of main begins here +############################################################################### +print(""" +/------------------------------------------------------------\\ +| HOPSAN RELEASE BUILD AND PACKAGING SCRIPT | +| | +\\------------------------------------------------------------/ +""") -def cleanUp(): - print "Cleaning up..." - #Remove temporary output directory - callRd(gTemporaryBuildDir) - #Rename backup bin folder, remove build files - hopsan_bindir = hopsanDir+r'\bin' - if pathExists(hopsan_bin_backup_dir): - callRd(hopsanDir+r'\bin_last_build') - move(hopsan_bindir, hopsanDir+r'\bin_last_build') - move(hopsan_bin_backup_dir, hopsan_bindir) +set_color(BColors.WHITE) +g_hopsan_src_dir = Path(os.getcwd()) +g_mingw_dir = extract_hopsan_build_path('x64', 'mingw') +g_qmake_dir = extract_hopsan_build_path('x64', 'qmake') +g_toolpaths = BuildToolPaths() -def extractHopsanBuildPath(arch, path_name): - # Ok this wil run the script for every variable we call, but it is fast so who cares - p = subprocess.Popen([r'dependencies\setHopsanBuildPaths.bat', arch], shell=True, stdout=subprocess.PIPE) - stdout, stderr = p.communicate() - if p.returncode == 0: # is 0 if success - for line in stdout.splitlines(): - #print(line) - if line.startswith(path_name): - substrs = line.split(':', 1) - #print(substrs) - if len(substrs) == 2: - #print(substrs) - #print(substrs[1]) - return substrs[1].strip() - else: - return 'Failed to run setHopsanBuildPaths.bat script' - return path_name+' path Not Found!' - -################################# -# Execution of file begins here # -################################# - -print "\n" -print "/------------------------------------------------------------\\" -print "| HOPSAN RELEASE BUILD AND PACKAGING SCRIPT |" -print "| |" -print "\\------------------------------------------------------------/" -print "\n" +gDoDevRelease = False +gIncludeCompiler = False -success = True pauseOnFailValidation = False doBuild = True +success = True -gARCH = 'x64' -gDo64BitRelease = True -do32BitRelease = askYesNoQuestion("Do you want to build a 32Bit release? (y/n): ") -if do32BitRelease: - gARCH = 'x86' - gDo64BitRelease = False - -mingwDir = extractHopsanBuildPath(gARCH, 'mingw') -qmakeDir = extractHopsanBuildPath(gARCH, 'qmake') -print('MinGW path: '+mingwDir) -print('Qmake path: '+qmakeDir) - -if not verifyPaths(): +if not g_toolpaths.verify_paths(): success = False - # cleanUp() - printError("Compilation script failed while verifying paths.") + print_error("Make release script failed while verifying paths.") + +qt_bins_ok = check_files_exist_in_dir(g_toolpaths.qmake_dir, qtRuntimeBins) +qt_plugins_ok = check_files_exist_in_dir(g_toolpaths.qmake_dir.parent / "plugins", qtPluginBins) +mingw_bins_ok = check_files_exist_in_dir(g_toolpaths.mingw_dir, mingwBins) +mingw_optbins_ok = check_files_exist_in_dir(g_toolpaths.mingw_dir.parent / "opt" / "bin", mingwOptBins) +deps_ok = check_files_exist_in_dir(Path(g_hopsan_src_dir) / "dependencies", dependencyFiles) + +success = success and all([ + qt_bins_ok, + qt_plugins_ok, + mingw_bins_ok, + mingw_optbins_ok, + deps_ok +]) + +if not success: + print_error("Make release script could not find all needed files.") if success: + print("\n") (baseversion, gReleaseRevision, gDoDevRelease) = askForVersion() if baseversion != '': gBaseVersion = baseversion @@ -1003,88 +832,63 @@ def extractHopsanBuildPath(arch, path_name): buildVCpp = askYesNoQuestion("Do you want to build VC++ HopsanCore? (y/n): ") gIncludeCompiler = askYesNoQuestion("Do you want to include the compiler? (y/n): ") - print "---------------------------------------" - print "This is a DEV release: " + str(gDoDevRelease) - print "This is a 64-bit release: " + str(gDo64BitRelease) - print "Release file version name: " + str(gReleaseFileVersionName) - print "Release revision number: " + str(gReleaseRevision) - print "Release full version number: " + str(gFullVersion) - print "Build VC++ HopsanCore: " + str(buildVCpp) - print "Include compiler: " + str(gIncludeCompiler) - print "Pause on failed validation: " + str(pauseOnFailValidation) - print "---------------------------------------" + print(f""" + --------------------------------------- + This is a DEV release: {gDoDevRelease} + Release file version name: {gReleaseFileVersionName} + Release revision number: {gReleaseRevision} + Release full version number: {gFullVersion} + Build MSVC based release: {buildVCpp} + Include compiler: {gIncludeCompiler} + Pause on failed validation: {pauseOnFailValidation} + --------------------------------------- + """) + if askYesNoQuestion("Is this OK? (y/n): "): - success = renameBinFolder() + success = True else: - printError("Aborted by user.") + print_error("Aborted by user.") success = False -if gDo64BitRelease: - gTemporaryBuildDir += r'\Hopsan-'+gReleaseFileVersionName+r'-win64' -else: - qtRuntimeBins = qtRuntimeBins32 - mingwBins = mingwBins32 - mingwOptBins = mingwOptBins32 - gTemporaryBuildDir += r'\Hopsan-'+gReleaseFileVersionName+r'-win32' -print("Using TempDir: "+gTemporaryBuildDir) - -qt_bins_ok = checkFilesExistInDir(qmakeDir, qtRuntimeBins) -qt_plugins_ok = checkFilesExistInDir(qmakeDir+'/../plugins',qtPluginBins) -mingw_bins_ok = checkFilesExistInDir(mingwDir, mingwBins) -mingw_optbins_ok = checkFilesExistInDir(mingwDir+'/../opt/bin', mingwOptBins) -deps_ok = checkFilesExistInDir(hopsanDir+'/dependencies', dependencyFiles) +hopsan_installation_destination = g_temporary_build_root / Path(f"Hopsan-{gReleaseFileVersionName}-win64") +package_output_dir = g_hopsan_src_dir / "output" -success = success and qt_bins_ok and qt_plugins_ok and mingw_bins_ok and mingw_optbins_ok and deps_ok +print(f"Using TempDir: {g_temporary_build_root}") +print(f"Installing to: {hopsan_installation_destination}") +print(f"Saving packages to: {package_output_dir}") -if not success: - cleanUp() - printError("Could not find all needed files.") +if success: + if not create_clean_output_directory(package_output_dir): + success = False + cleanup() if success: - prepareSourceCode(gBaseVersion, gReleaseRevision, gDoDevRelease) + prepare_source_code(gBaseVersion, gReleaseRevision, gDoDevRelease) if doBuild: - if not buildRelease(): + if not build_mingw_release(hopsan_installation_destination): success = False - cleanUp() - printError("Compilation script failed in compilation error.") - -if success: - #Copy dependency bin files to bin directory - for f in qtRuntimeBins: - copyFileToDir(qmakeDir, f, hopsanDir+'/bin') - for f in qtPluginBins: - copyFileToDir(qmakeDir+'/../plugins', f, hopsanDir+'/bin') - for f in mingwBins: - copyFileToDir(mingwDir, f, hopsanDir+'/bin') - for f in mingwOptBins: - copyFileToDir(mingwDir+'/../opt/bin', f, hopsanDir+'/bin') - for f in dependencyFiles: - copyFileToDir(hopsanDir+'/dependencies', f, hopsanDir+'/bin', keep_relative_path=False) - -if success: - if not createCleanOutputDirectory(): - success = False - cleanUp() + cleanup() + print_error("Make release script failed with build error.") if success: - if not copyFiles(): + if not finalize_install_dir(hopsan_installation_destination): success = False - cleanUp() - printError("Compilation script failed when copying files.") + cleanup() + print_error("Make release script failed when finalizing files.") if success: - if not createInstallFiles(): + if not create_installation_packages(hopsan_installation_destination, package_output_dir): success = False - cleanUp() - printError("Compilation script failed while generating install files.") + cleanup() + print_error("Make release script failed while generating installation packages.") if success: - if not runValidation() and pauseOnFailValidation: - printWarning("Compilation script failed in model validation.") + if not run_validation(hopsan_installation_destination) and pauseOnFailValidation: + print_warning("Make release script failed in model validation.") askYesNoQuestion("Press enter to continue!") if success: - cleanUp() - printSuccess("Compilation script finished successfully.") + print_success(f"Make release script finished successfully. The release packages can be found in: {package_output_dir}") + cleanup() -raw_input("Press any key to continue...") +input("Press any key to continue...") diff --git a/packaging/deb/bookworm/debian/control b/packaging/deb/bookworm/debian/control index 74983942d8..47f261ba4f 100644 --- a/packaging/deb/bookworm/debian/control +++ b/packaging/deb/bookworm/debian/control @@ -4,7 +4,9 @@ Section: contrib/science Priority: optional Build-Depends: cmake, debhelper (>= 12~), + doxygen, fakeroot, + graphviz, libhdf5-dev, libmarkdown2-dev, libmsgpack-dev, diff --git a/packaging/deb/bookworm/debian/rules b/packaging/deb/bookworm/debian/rules index 2c6bc6a14c..8a78cd2ce7 100644 --- a/packaging/deb/bookworm/debian/rules +++ b/packaging/deb/bookworm/debian/rules @@ -11,30 +11,33 @@ export QT_SELECT=5 dh $@ override_dh_auto_configure: -# Prevent auto running cmake, since it is not yet the default build system +# Prevent auto running cmake configuration since bundled dependencies must be built first override_dh_auto_build: # First build dependencies - packaging/fixPythonShebang.sh ./ 3 cd dependencies; ./setupAsio.sh + cd dependencies; ./setupLibzip.sh + cd dependencies; ./setupXerces.sh + cd dependencies; ./setupDCPLib.sh + cd dependencies; ./setupDiscount.sh cd dependencies; ./setupFmi4c.sh cd dependencies; ./setupKatex.sh cd dependencies; ./setupTclap.sh - cd dependencies; ./setupXerces.sh - cd dependencies; ./setupLibzip.sh - cd dependencies; ./setupDCPLib.sh + cd dependencies; ./setupSsp4c.sh -# Now build Hopsan using qmake - mkdir -p hopsanShadowBuild - source dependencies/setHopsanBuildPaths.sh; cd hopsanShadowBuild; $${HOPSAN_BUILD_QT_QMAKE} ../HopsanNG.pro -r -spec linux-g++ -config release - make -j8 -C hopsanShadowBuild +# Now build Hopsan + mkdir -p hopsan-build + source dependencies/setHopsanBuildPaths.sh; cd hopsan-build; \ + cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DBUILD_USER_DOCUMENTATION=ON -DBUILD_DEVELOPER_DOCUMENTATION=OFF \ + -DCMAKE_INSTALL_PREFIX=../debian/hopsan/opt/hopsan ../ + source dependencies/setHopsanBuildPaths.sh; cd hopsan-build; cmake --build . --target all override_dh_auto_clean: - rm -rf hopsanShadowBuild + rm -rf hopsan-build dh_auto_clean override_dh_auto_install: - packaging/copyInstallHopsan.sh ./ debian/hopsan/opt/hopsan + cd hopsan-build; cmake --install . dh_install packaging/HopsanGUI.desktop usr/share/applications/ dh_install HopsanGUI/graphics/uiicons/hopsan128x128.png usr/share/icons/hicolor/128x128/apps/ diff --git a/packaging/deb/bullseye/debian/control b/packaging/deb/bullseye/debian/control index 74983942d8..47f261ba4f 100644 --- a/packaging/deb/bullseye/debian/control +++ b/packaging/deb/bullseye/debian/control @@ -4,7 +4,9 @@ Section: contrib/science Priority: optional Build-Depends: cmake, debhelper (>= 12~), + doxygen, fakeroot, + graphviz, libhdf5-dev, libmarkdown2-dev, libmsgpack-dev, diff --git a/packaging/deb/bullseye/debian/rules b/packaging/deb/bullseye/debian/rules index 8e7030d49a..8a78cd2ce7 100644 --- a/packaging/deb/bullseye/debian/rules +++ b/packaging/deb/bullseye/debian/rules @@ -11,30 +11,33 @@ export QT_SELECT=5 dh $@ override_dh_auto_configure: -# Prevent auto running cmake, since it is not yet the default build system +# Prevent auto running cmake configuration since bundled dependencies must be built first override_dh_auto_build: # First build dependencies - packaging/fixPythonShebang.sh ./ 3 - cd dependencies; ./setupAsio.sh + cd dependencies; ./setupAsio.sh + cd dependencies; ./setupLibzip.sh + cd dependencies; ./setupXerces.sh + cd dependencies; ./setupDCPLib.sh + cd dependencies; ./setupDiscount.sh cd dependencies; ./setupFmi4c.sh cd dependencies; ./setupKatex.sh cd dependencies; ./setupTclap.sh - cd dependencies; ./setupXerces.sh - cd dependencies; ./setupLibzip.sh - cd dependencies; ./setupDCPLib.sh + cd dependencies; ./setupSsp4c.sh -# Now build Hopsan using qmake - mkdir -p hopsanShadowBuild - source dependencies/setHopsanBuildPaths.sh; cd hopsanShadowBuild; $${HOPSAN_BUILD_QT_QMAKE} ../HopsanNG.pro -r -spec linux-g++ -config release - make -j8 -C hopsanShadowBuild +# Now build Hopsan + mkdir -p hopsan-build + source dependencies/setHopsanBuildPaths.sh; cd hopsan-build; \ + cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DBUILD_USER_DOCUMENTATION=ON -DBUILD_DEVELOPER_DOCUMENTATION=OFF \ + -DCMAKE_INSTALL_PREFIX=../debian/hopsan/opt/hopsan ../ + source dependencies/setHopsanBuildPaths.sh; cd hopsan-build; cmake --build . --target all override_dh_auto_clean: - rm -rf hopsanShadowBuild + rm -rf hopsan-build dh_auto_clean override_dh_auto_install: - packaging/copyInstallHopsan.sh ./ debian/hopsan/opt/hopsan + cd hopsan-build; cmake --install . dh_install packaging/HopsanGUI.desktop usr/share/applications/ dh_install HopsanGUI/graphics/uiicons/hopsan128x128.png usr/share/icons/hicolor/128x128/apps/ diff --git a/packaging/deb/focal/debian/control b/packaging/deb/focal/debian/control index 57d6e062f3..2e0e7d3642 100644 --- a/packaging/deb/focal/debian/control +++ b/packaging/deb/focal/debian/control @@ -4,7 +4,9 @@ Section: contrib/science Priority: optional Build-Depends: cmake, debhelper (>= 12~), + doxygen, fakeroot, + graphviz, libhdf5-dev, libmarkdown2-dev, libmsgpack-dev, diff --git a/packaging/deb/focal/debian/rules b/packaging/deb/focal/debian/rules index 8c5f5e206e..8a78cd2ce7 100644 --- a/packaging/deb/focal/debian/rules +++ b/packaging/deb/focal/debian/rules @@ -11,30 +11,33 @@ export QT_SELECT=5 dh $@ override_dh_auto_configure: -# Prevent auto running cmake, since it is not yet the default build system +# Prevent auto running cmake configuration since bundled dependencies must be built first override_dh_auto_build: # First build dependencies - packaging/fixPythonShebang.sh ./ 3 cd dependencies; ./setupAsio.sh + cd dependencies; ./setupLibzip.sh + cd dependencies; ./setupXerces.sh + cd dependencies; ./setupDCPLib.sh + cd dependencies; ./setupDiscount.sh cd dependencies; ./setupFmi4c.sh cd dependencies; ./setupKatex.sh cd dependencies; ./setupTclap.sh - cd dependencies; ./setupXerces.sh - cd dependencies; ./setupLibzip.sh - cd dependencies; ./setupDCPLib.sh - -# Now build Hopsan using qmake - mkdir -p hopsanShadowBuild - source dependencies/setHopsanBuildPaths.sh; cd hopsanShadowBuild; $${HOPSAN_BUILD_QT_QMAKE} ../HopsanNG.pro -r -spec linux-g++ -config release - make -j8 -C hopsanShadowBuild + cd dependencies; ./setupSsp4c.sh + +# Now build Hopsan + mkdir -p hopsan-build + source dependencies/setHopsanBuildPaths.sh; cd hopsan-build; \ + cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DBUILD_USER_DOCUMENTATION=ON -DBUILD_DEVELOPER_DOCUMENTATION=OFF \ + -DCMAKE_INSTALL_PREFIX=../debian/hopsan/opt/hopsan ../ + source dependencies/setHopsanBuildPaths.sh; cd hopsan-build; cmake --build . --target all override_dh_auto_clean: - rm -rf hopsanShadowBuild + rm -rf hopsan-build dh_auto_clean override_dh_auto_install: - packaging/copyInstallHopsan.sh ./ debian/hopsan/opt/hopsan + cd hopsan-build; cmake --install . dh_install packaging/HopsanGUI.desktop usr/share/applications/ dh_install HopsanGUI/graphics/uiicons/hopsan128x128.png usr/share/icons/hicolor/128x128/apps/ diff --git a/packaging/deb/qt5py3_buster/debian/README b/packaging/deb/qt5py3_buster/debian/README deleted file mode 100644 index 6349c9611e..0000000000 --- a/packaging/deb/qt5py3_buster/debian/README +++ /dev/null @@ -1,6 +0,0 @@ -The Debian Package for hopsan ----------------------------- - -Comments regarding the Package - - -- Peter Nordin Sun, 04 Mar 2012 18:18:08 +0100 diff --git a/packaging/deb/qt5py3_buster/debian/README.source b/packaging/deb/qt5py3_buster/debian/README.source deleted file mode 100644 index f5a78c2b8d..0000000000 --- a/packaging/deb/qt5py3_buster/debian/README.source +++ /dev/null @@ -1,3 +0,0 @@ -hopsan deb-release ------------------ -The hopsan source code can be found on GitHub https://github.com/Hopsan/hopsan diff --git a/packaging/deb/qt5py3_buster/debian/changelog b/packaging/deb/qt5py3_buster/debian/changelog deleted file mode 100644 index 695c3d459c..0000000000 --- a/packaging/deb/qt5py3_buster/debian/changelog +++ /dev/null @@ -1,5 +0,0 @@ -hopsan (0.0.0) unstable; urgency=low - - * Initial Release. - - -- Peter Nordin Sun, 04 Mar 2012 18:18:08 +0100 diff --git a/packaging/deb/qt5py3_buster/debian/compat b/packaging/deb/qt5py3_buster/debian/compat deleted file mode 100644 index 48082f72f0..0000000000 --- a/packaging/deb/qt5py3_buster/debian/compat +++ /dev/null @@ -1 +0,0 @@ -12 diff --git a/packaging/deb/qt5py3_buster/debian/control b/packaging/deb/qt5py3_buster/debian/control deleted file mode 100644 index 57d6e062f3..0000000000 --- a/packaging/deb/qt5py3_buster/debian/control +++ /dev/null @@ -1,39 +0,0 @@ -Source: hopsan -Maintainer: Peter Nordin -Section: contrib/science -Priority: optional -Build-Depends: cmake, - debhelper (>= 12~), - fakeroot, - libhdf5-dev, - libmarkdown2-dev, - libmsgpack-dev, - libqt5opengl5-dev, - libqt5svg5-dev, - qtwebengine5-dev, - libqwt-qt5-dev, - libtool-bin, - libzmq3-dev, - ninja-build, - patchelf, - pkg-config, - python3, - qt5-default, - qtbase5-dev, - qtbase5-private-dev, - unzip -Standards-Version: 3.9.8 -Homepage: https://github.com/Hopsan/hopsan - -Package: hopsan -Architecture: any -Depends: python3, - zip, - ${misc:Depends}, - ${shlibs:Depends} -Description: This is a free simulation environment for fluid and mechatronic systems. - Hopsan is developed at Linköping University. Although originally - developed for simulation of fluid power systems, it has also been adopted - for other domains such as electric power, flight dynamics and vehicle - dynamics. It uses bi-directional delay lines (or transmission line elements, - TLM) to connect different components. diff --git a/packaging/deb/qt5py3_buster/debian/copyright b/packaging/deb/qt5py3_buster/debian/copyright deleted file mode 100644 index 68b486a3ab..0000000000 --- a/packaging/deb/qt5py3_buster/debian/copyright +++ /dev/null @@ -1,15 +0,0 @@ -Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -upstream-name: hopsan -upstream-contact: Peter Nordin -Source: https://github.com/Hopsan/hopsan - -Files: hopsan/* -Copyright: 2021 Hopsan Group -License: GPL-3+ and Apache-2.0 -/usr/share/common-licenses/GPL-3 -/usr/share/common-licenses/Apache-2.0 - -Files: debian/* -Copyright: 2019 Peter Nordin -License: GPL-3+ -/usr/share/common-licenses/GPL-3 diff --git a/packaging/deb/qt5py3_buster/debian/docs b/packaging/deb/qt5py3_buster/debian/docs deleted file mode 100644 index 8b13789179..0000000000 --- a/packaging/deb/qt5py3_buster/debian/docs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packaging/deb/qt5py3_buster/debian/postinst b/packaging/deb/qt5py3_buster/debian/postinst deleted file mode 100755 index 86cf6b90b5..0000000000 --- a/packaging/deb/qt5py3_buster/debian/postinst +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -set -e - -# This POSTINST script adds a placeholder file to /opt to make -# sure that /opt is not removed when hopsan is uninstalled - -case "$1" in - configure) - touch /opt/.hopsan_placeholder - ;; - - *) - #Do nothing - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/packaging/deb/qt5py3_buster/debian/postrm b/packaging/deb/qt5py3_buster/debian/postrm deleted file mode 100755 index 48e672a149..0000000000 --- a/packaging/deb/qt5py3_buster/debian/postrm +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh -set -e - -# This POSTRM script removes the placeholder file from /opt -# after remove or purge of hopsan - - -case "$1" in - remove) - rm -f /opt/.hopsan_placeholder - ;; - purge) - rm -f /opt/.hopsan_placeholder - ;; - - *) - #Do nothing - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/packaging/deb/qt5py3_buster/debian/rules b/packaging/deb/qt5py3_buster/debian/rules deleted file mode 100644 index 2c6bc6a14c..0000000000 --- a/packaging/deb/qt5py3_buster/debian/rules +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -SHELL := /bin/bash -export QT_SELECT=5 - -%: - dh $@ - -override_dh_auto_configure: -# Prevent auto running cmake, since it is not yet the default build system - -override_dh_auto_build: -# First build dependencies - packaging/fixPythonShebang.sh ./ 3 - cd dependencies; ./setupAsio.sh - cd dependencies; ./setupFmi4c.sh - cd dependencies; ./setupKatex.sh - cd dependencies; ./setupTclap.sh - cd dependencies; ./setupXerces.sh - cd dependencies; ./setupLibzip.sh - cd dependencies; ./setupDCPLib.sh - -# Now build Hopsan using qmake - mkdir -p hopsanShadowBuild - source dependencies/setHopsanBuildPaths.sh; cd hopsanShadowBuild; $${HOPSAN_BUILD_QT_QMAKE} ../HopsanNG.pro -r -spec linux-g++ -config release - make -j8 -C hopsanShadowBuild - -override_dh_auto_clean: - rm -rf hopsanShadowBuild - dh_auto_clean - -override_dh_auto_install: - packaging/copyInstallHopsan.sh ./ debian/hopsan/opt/hopsan - dh_install packaging/HopsanGUI.desktop usr/share/applications/ - dh_install HopsanGUI/graphics/uiicons/hopsan128x128.png usr/share/icons/hicolor/128x128/apps/ - -override_dh_shlibdeps: - dh_shlibdeps -l/opt/hopsan/bin diff --git a/packaging/deb/qt5py3_buster/debian/source/format b/packaging/deb/qt5py3_buster/debian/source/format deleted file mode 100644 index 163aaf8d82..0000000000 --- a/packaging/deb/qt5py3_buster/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/packaging/deb/trixie/debian/control b/packaging/deb/trixie/debian/control index 8ee60904e1..c602904ef7 100644 --- a/packaging/deb/trixie/debian/control +++ b/packaging/deb/trixie/debian/control @@ -5,7 +5,9 @@ Priority: optional Build-Depends: cmake, cppzmq-dev, debhelper (>= 12~), + doxygen, fakeroot, + graphviz, libhdf5-dev, libmarkdown2-dev, libmsgpack-dev, diff --git a/packaging/deb/trixie/debian/rules b/packaging/deb/trixie/debian/rules index 0b14084243..a8d2816e68 100644 --- a/packaging/deb/trixie/debian/rules +++ b/packaging/deb/trixie/debian/rules @@ -11,31 +11,34 @@ export QT_SELECT=5 dh $@ override_dh_auto_configure: -# Prevent auto running cmake, since it is not yet the default build system +# Prevent auto running cmake configuration since bundled dependencies must be built first override_dh_auto_build: # First build dependencies - packaging/fixPythonShebang.sh ./ 3 - cd dependencies; ./setupMsgpack.sh cd dependencies; ./setupAsio.sh + cd dependencies; ./setupLibzip.sh + cd dependencies; ./setupXerces.sh + cd dependencies; ./setupDCPLib.sh + cd dependencies; ./setupDiscount.sh cd dependencies; ./setupFmi4c.sh cd dependencies; ./setupKatex.sh + cd dependencies; ./setupMsgpack.sh cd dependencies; ./setupTclap.sh - cd dependencies; ./setupXerces.sh - cd dependencies; ./setupLibzip.sh - cd dependencies; ./setupDCPLib.sh + cd dependencies; ./setupSsp4c.sh -# Now build Hopsan using qmake - mkdir -p hopsanShadowBuild - source dependencies/setHopsanBuildPaths.sh; cd hopsanShadowBuild; $${HOPSAN_BUILD_QT_QMAKE} ../HopsanNG.pro -r -spec linux-g++ -config release - make -j8 -C hopsanShadowBuild +# Now build Hopsan + mkdir -p hopsan-build + source dependencies/setHopsanBuildPaths.sh; cd hopsan-build; \ + cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DBUILD_USER_DOCUMENTATION=ON -DBUILD_DEVELOPER_DOCUMENTATION=OFF \ + -DCMAKE_INSTALL_PREFIX=../debian/hopsan/opt/hopsan ../ + source dependencies/setHopsanBuildPaths.sh; cd hopsan-build; cmake --build . --target all override_dh_auto_clean: - rm -rf hopsanShadowBuild + rm -rf hopsan-build dh_auto_clean override_dh_auto_install: - packaging/copyInstallHopsan.sh ./ debian/hopsan/opt/hopsan + cd hopsan-build; cmake --install . dh_install packaging/HopsanGUI.desktop usr/share/applications/ dh_install HopsanGUI/graphics/uiicons/hopsan128x128.png usr/share/icons/hicolor/128x128/apps/ diff --git a/packaging/fixPythonShebang.sh b/packaging/fixPythonShebang.sh deleted file mode 100755 index 05e2bdbeb0..0000000000 --- a/packaging/fixPythonShebang.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -set -u -set -e - -if [ $# -lt 2 ]; then - echo "Error: To few input arguments!" - echo "Usage: `basename $0` srcDir python_version" - exit 1 -fi - -src_dir="${1}" -python_version=${2} - -#echo $src_dir -#echo $python_version - -if [ "${python_version}" == "2" ]; then - find ${src_dir} -name "*.py" -exec sed 's|#!/usr/bin/env python3$|#!/usr/bin/python|' -i {} \; - find ${src_dir} -name "*.py" -exec sed 's|#!/usr/bin/env python$|#!/usr/bin/python|' -i {} \; - find ${src_dir} -name "*.py" -exec sed 's|#!/usr/bin/python3$|#!/usr/bin/python|' -i {} \; -elif [ "${python_version}" == "3" ]; then - find ${src_dir} -name "*.py" -exec sed 's|#!/usr/bin/env python3$|#!/usr/bin/python3|' -i {} \; - find ${src_dir} -name "*.py" -exec sed 's|#!/usr/bin/env python$|#!/usr/bin/python3|' -i {} \; - find ${src_dir} -name "*.py" -exec sed 's|#!/usr/bin/python$|#!/usr/bin/python3|' -i {} \; -else - echo "Error: Incorrect Python version: ${python_version} given. Must be 2 or 3" - exit 1 -fi diff --git a/packaging/prepareSourceCode.sh b/packaging/prepareSourceCode.sh index 001e41d329..9e18a51a69 100755 --- a/packaging/prepareSourceCode.sh +++ b/packaging/prepareSourceCode.sh @@ -1,13 +1,11 @@ #!/bin/bash -# $Id$ # Shell script for preparing the Hopsan source code before RELEASE build -# Author: Peter Nordin peter.nordin@liu.se E_BADARGS=65 -if [ $# -lt 7 ]; then +if [ $# -lt 6 ]; then echo "Error: To few input arguments!" - echo "Usage: $(basename $0) {hopsancode_root stage_directory base_version release_revision full_version_string doDevRelease doBuildInComponents}" + echo "Usage: $(basename $0) {hopsancode_root stage_directory base_version release_revision full_version_string doDevRelease}" exit $E_BADARGS fi @@ -17,7 +15,6 @@ readonly base_version="$3" readonly release_revision="$4" readonly full_version_string="$5" readonly doDevRelease=$6 -readonly doBuildInComponents=$7 if [[ "$OSTYPE" == "darwin"* ]]; then inkscape_cmd="/Applications/Inkscape.app/Contents/MacOS/Inkscape" else @@ -66,27 +63,15 @@ fi # Set splash screen version number sed "s|0\.00\.0|$base_version|g" -i HopsanGUI/graphics/splash.svg sed "s|20170000\.0000|$release_revision|g" -i HopsanGUI/graphics/splash.svg -if [[ $(command -v ${inkscape_cmd} > /dev/null) -eq 0 ]]; then +if [[ $(command -v ${inkscape_cmd}) ]]; then if [[ $(inkscape --version | cut -d' ' -f2 | cut -d. -f1) -lt 1 ]]; then ${inkscape_cmd} ./HopsanGUI/graphics/splash.svg --export-background=rgb\(255,255,255\) --export-dpi=90 --export-png ./HopsanGUI/graphics/splash.png else ${inkscape_cmd} ./HopsanGUI/graphics/splash.svg --export-background=rgb\(255,255,255\) --export-dpi=90 --export-type=png --export-filename=./HopsanGUI/graphics/splash.png fi -elif [[ $(command -v convert > /dev/null) -eq 0 ]]; then +elif [[ $(command -v convert) ]]; then echo Warning: Inkscape is not available, falling back to convert convert -background white ./HopsanGUI/graphics/splash.svg ./HopsanGUI/graphics/splash.png else echo Error: Neither Inkscape or convert can be used to generate splash screen fi - -# If selected, make changes to compile defaultLibrary into Hopsan Core -# Deprecated, we should not do this anymore -if [[ $doBuildInComponents == true ]]; then - sed 's|.*DEFINES \*= HOPSAN_INTERNALDEFAULTCOMPONENTS|DEFINES *= HOPSAN_INTERNALDEFAULTCOMPONENTS|g' -i Common.prf - sed 's|#INTERNALCOMPLIB.CPP#|../componentLibraries/defaultLibrary/defaultComponentLibraryInternal.cpp \\|g' -i HopsanCore/HopsanCore.pro - sed '/.*.*/d' -i componentLibraries/defaultLibrary/defaultComponentLibrary.xml - sed 's|componentLibraries||g' -i HopsanNG.pro -fi - -# Build user documentation -./buildDocumentation.sh diff --git a/runValidationTests.bat b/runValidationTests.bat index d82aa8af3f..b8a26cf09c 100755 --- a/runValidationTests.bat +++ b/runValidationTests.bat @@ -1,8 +1,7 @@ -::$Id$ -:: Hopsan model validation script -:: This script calls hopsancli to validate models for all hvc files found. -:: Author: Peter Nordin 2012-05-31 @echo off +REM Hopsan model validation script +REM This script calls hopsancli to validate models for all hvc files found. + SETLOCAL EnableDelayedExpansion set failed=0 @@ -11,7 +10,7 @@ if "%~1"=="nopause" ( set okPause=0 ) -for /F "delims==" %%x in ('dir /B /S *.hvc') do ( +for /F "delims==" %%x in ('dir /B /S %~dp0*.hvc') do ( cd bin if not exist hopsancli_d.exe ( if not exist hopsancli.exe (