From b8e16c259c605ffedff2e74bce331b8e3fa98bf8 Mon Sep 17 00:00:00 2001 From: Jorrit Wronski Date: Sun, 25 Sep 2016 23:12:27 +0200 Subject: [PATCH 1/5] EES installer should be moved to the general installer --- CMakeLists.txt | 214 +++++++++++++++++++-------------- dev/buildbot/master/master.cfg | 8 +- externals/ExcelAddinInstaller | 2 +- 3 files changed, 128 insertions(+), 96 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5cb91a94..fe97f57b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,8 +62,8 @@ option (COOLPROP_EES_MODULE "Build the EES module" OFF) -option (COOLPROP_EXCEL_MODULE - "Build the Excel add-in installer" +option (COOLPROP_WINDOWS_PACKAGE + "Build the Windows installer" OFF) option (BUILD_TESTING @@ -469,137 +469,169 @@ if (COOLPROP_MATHCAD15_MODULE) install (FILES "${CMAKE_CURRENT_SOURCE_DIR}/wrappers/MathCAD/CoolProp_EN.xml" DESTINATION MathCAD15) endif() -# EES is only compiled for windows +# EES is only compiled for 32bit Windows if (COOLPROP_EES_MODULE) - list (APPEND APP_SOURCES "wrappers/EES/main.cpp") - list(APPEND APP_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/CoolPropLib.cpp") + IF (NOT "${BITNESS}" STREQUAL "32") + MESSAGE(FATAL_ERROR "You cannot build the EES wrapper as a 64-bit library.") + ENDIF() + # Prepare the sources include_directories(${APP_INCLUDE_DIRS}) + list (APPEND APP_SOURCES "wrappers/EES/main.cpp") + list (APPEND APP_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/${COOLPROP_LIBRARY_SOURCE}") add_library(COOLPROP_EES SHARED ${APP_SOURCES}) + # Modify the target and add dependencies + add_dependencies (COOLPROP_EES generate_headers) set_target_properties (COOLPROP_EES PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -DCOOLPROP_LIB -DCONVENTION=__cdecl") - add_dependencies (COOLPROP_EES generate_headers) - set_target_properties(COOLPROP_EES PROPERTIES SUFFIX ".dlf" PREFIX "") - message(STATUS "Injecting the version COOLPROP_VERSION=${COOLPROP_VERSION}") - # Put the version into the InnoInstaller setup file - CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/wrappers/EES/BuildInnoInstaller.iss.in" "${CMAKE_CURRENT_BINARY_DIR}/BuildInnoInstaller.iss") - if (NOT MSVC) - set_target_properties(COOLPROP_EES PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32") - endif() - - add_dependencies (COOLPROP_EES generate_headers) - - if ( MSVC ) - set_target_properties( COOLPROP_EES PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) - set_target_properties( COOLPROP_EES PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}) - set_target_properties( COOLPROP_EES PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}) + set_target_properties (COOLPROP_EES PROPERTIES SUFFIX ".dlf" PREFIX "") + # Creates "COOLPROP_EES.dlf" + if ( NOT MSVC ) + set_target_properties (COOLPROP_EES PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32") + elseif ( MSVC ) + set_target_properties (COOLPROP_EES PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) + set_target_properties (COOLPROP_EES PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}) + set_target_properties (COOLPROP_EES PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}) # etc for the other available configuration types (MinSizeRel, RelWithDebInfo) endif () # copy required files - set(REQUIRED_FILES - CoolProp.htm - CoolProp.LIB - CoolProp_EES_Sample.EES - ) - foreach (_FILE ${REQUIRED_FILES}) - add_custom_command(TARGET COOLPROP_EES - PRE_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/wrappers/EES/${_FILE} ${CMAKE_CURRENT_BINARY_DIR}/.) - endforeach() - - # Run InnoSetup to make the installer (must be on your path) - add_custom_command(TARGET COOLPROP_EES - POST_BUILD - COMMAND iscc /cc BuildInnoInstaller.iss - WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - # install the generated executable installer from InnoSetup - install( - CODE "file( INSTALL ${CMAKE_CURRENT_BINARY_DIR}/Output/SetupCOOLPROP_EES.exe DESTINATION ${CMAKE_INSTALL_PREFIX}/EES/${CMAKE_SYSTEM_NAME} )" + add_custom_command (TARGET COOLPROP_EES PRE_BUILD + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${CMAKE_CURRENT_SOURCE_DIR}/wrappers/EES/CoolProp.htm" "${CMAKE_CURRENT_BINARY_DIR}/." + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${CMAKE_CURRENT_SOURCE_DIR}/wrappers/EES/CoolProp.LIB" "${CMAKE_CURRENT_BINARY_DIR}/." + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${CMAKE_CURRENT_SOURCE_DIR}/wrappers/EES/CoolProp_EES_Sample.EES" "${CMAKE_CURRENT_BINARY_DIR}/." + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Copying the EES files to the build directory" + VERBATIM ) + ## install the generated executable installer from InnoSetup + #install( + # CODE "file( INSTALL ${CMAKE_CURRENT_BINARY_DIR}/Output/SetupCOOLPROP_EES.exe DESTINATION ${CMAKE_INSTALL_PREFIX}/EES/${CMAKE_SYSTEM_NAME} )" + #) endif() -# Excel add-in -if (COOLPROP_EXCEL_MODULE) +# Windows package +if (COOLPROP_WINDOWS_PACKAGE) + message(STATUS "Creating Excel add-in for COOLPROP_VERSION=${COOLPROP_VERSION}") # Setting some basic build paths - set(COOLPROP_EXCEL_32B_DIR "${CMAKE_CURRENT_BINARY_DIR}/32bitDLL") - set(COOLPROP_EXCEL_32B_DIR_ALT "${CMAKE_CURRENT_BINARY_DIR}/32bitDLL_cdecl") - set(COOLPROP_EXCEL_64B_DIR "${CMAKE_CURRENT_BINARY_DIR}/64bitDLL") - set(COOLPROP_EXCEL_TMP_DIR "${CMAKE_CURRENT_BINARY_DIR}/InnoScript") + set(COOLPROP_WINDOWS_PACKAGE_32B_DIR "${CMAKE_CURRENT_BINARY_DIR}/32bitDLL") + set(COOLPROP_WINDOWS_PACKAGE_32B_DIR_STDCALL "${CMAKE_CURRENT_BINARY_DIR}/32bitDLL_stdcall") + set(COOLPROP_WINDOWS_PACKAGE_32B_DIR_CDECL "${CMAKE_CURRENT_BINARY_DIR}/32bitDLL_cdecl") + set(COOLPROP_WINDOWS_PACKAGE_64B_DIR "${CMAKE_CURRENT_BINARY_DIR}/64bitDLL") + set(COOLPROP_WINDOWS_PACKAGE_EES_DIR "${CMAKE_CURRENT_BINARY_DIR}/EES") + set(COOLPROP_WINDOWS_PACKAGE_TMP_DIR "${CMAKE_CURRENT_BINARY_DIR}/InnoScript") # Pointers to the sources - set(COOLPROP_EXCEL_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wrappers/Excel") - set(COOLPROP_EXCEL_ISS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/externals/ExcelAddinInstaller") + set(COOLPROP_WINDOWS_PACKAGE_EXCEL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wrappers/Excel") + set(COOLPROP_WINDOWS_PACKAGE_ISS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/externals/ExcelAddinInstaller") # Generator for DLLs - set(COOLPROP_EXCEL_DLL_GEN "Visual Studio 10 2010") + set(COOLPROP_WINDOWS_PACKAGE_DLL_GEN "Visual Studio 10 2010") # Configure variables like version number and build year - CONFIGURE_FILE("${COOLPROP_EXCEL_ISS_DIR}/cmake-templates/config.iss" "${COOLPROP_EXCEL_ISS_DIR}/config.iss") + CONFIGURE_FILE("${COOLPROP_WINDOWS_PACKAGE_ISS_DIR}/cmake-templates/config.iss" "${COOLPROP_WINDOWS_PACKAGE_ISS_DIR}/config.iss") # Find the installer generator executable SET(BINDIR32_ENV_NAME "ProgramFiles(x86)") SET(BINDIR32 $ENV{${BINDIR32_ENV_NAME}}) SET(BINDIR64_ENV_NAME "ProgramFiles") SET(BINDIR64 $ENV{${BINDIR64_ENV_NAME}}) - find_program (COOLPROP_EXCEL_ISS_EXE + find_program (COOLPROP_WINDOWS_PACKAGE_ISS_EXE NAMES iscc.exe HINTS "${BINDIR32}/Inno Setup 5" "${BINDIR64}/Inno Setup 5" ) - #message(STATUS "COOLPROP_EXCEL_ISS_EXE='${COOLPROP_EXCEL_ISS_EXE}'") - # ************************************************************* - # Add the target for Excel and populate it with custom commands - # ************************************************************* - add_custom_target(COOLPROP_EXCEL) + + # ****************************************************************** + # Add the target that prepares the build directory for the subbuilds + # ****************************************************************** + add_custom_target(COOLPROP_WINDOWS_PACKAGE_PREPARE) # Prepare directories - add_custom_command(TARGET COOLPROP_EXCEL PRE_BUILD - COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_EXCEL_32B_DIR}" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_EXCEL_32B_DIR_ALT}" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_EXCEL_64B_DIR}" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_EXCEL_TMP_DIR}" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_EXCEL_TMP_DIR}/source" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "remove_directory" "${COOLPROP_EXCEL_TMP_DIR}/deploy" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_EXCEL_TMP_DIR}/deploy" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "remove_directory" "${COOLPROP_EXCEL_TMP_DIR}/bin" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_EXCEL_TMP_DIR}/bin" + add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_PREPARE PRE_BUILD + COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_32B_DIR}" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_32B_DIR_STDCALL}" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_32B_DIR_CDECL}" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_64B_DIR}" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_EES_DIR}" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "remove_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/deploy" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/deploy" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "remove_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/bin" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/bin" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Preparing the directories for the Excel installer" + COMMENT "Preparing the directories for the Windows installer" VERBATIM ) + + # ************************************************************** + # Add the target for the shared libraries, 3x 32bit and 1x 64bit + # ************************************************************** + add_custom_target(COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES) + add_dependencies (COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES COOLPROP_WINDOWS_PACKAGE_PREPARE) # Build the 32bit DLLs - add_custom_command(TARGET COOLPROP_EXCEL PRE_BUILD - COMMAND ${CMAKE_COMMAND} ARGS "-G${COOLPROP_EXCEL_DLL_GEN}" "${CMAKE_CURRENT_SOURCE_DIR}" "-DCOOLPROP_SHARED_LIBRARY=ON" "-DCOOLPROP_STDCALL_LIBRARY=ON" + add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES PRE_BUILD + COMMAND ${CMAKE_COMMAND} ARGS "-G${COOLPROP_WINDOWS_PACKAGE_DLL_GEN}" "${CMAKE_CURRENT_SOURCE_DIR}" "-DCOOLPROP_SHARED_LIBRARY=ON" COMMAND ${CMAKE_COMMAND} ARGS "--build" "." "--target" "CoolProp" "--config" "Release" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_EXCEL_32B_DIR}/Release/CoolProp.dll" "${COOLPROP_EXCEL_TMP_DIR}/source/CoolProp_xls_std.dll" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_EXCEL_32B_DIR}/Release/CoolProp.dll" "${COOLPROP_EXCEL_TMP_DIR}/source/CoolProp_stdcall.dll" - WORKING_DIRECTORY ${COOLPROP_EXCEL_32B_DIR} + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_32B_DIR}/Release/CoolProp.dll" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/CoolProp_x86.dll" + WORKING_DIRECTORY ${COOLPROP_WINDOWS_PACKAGE_32B_DIR} + COMMENT "Building the 32bit shared library with default settings" + VERBATIM ) + add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES PRE_BUILD + COMMAND ${CMAKE_COMMAND} ARGS "-G${COOLPROP_WINDOWS_PACKAGE_DLL_GEN}" "${CMAKE_CURRENT_SOURCE_DIR}" "-DCOOLPROP_SHARED_LIBRARY=ON" "-DCOOLPROP_STDCALL_LIBRARY=ON" + COMMAND ${CMAKE_COMMAND} ARGS "--build" "." "--target" "CoolProp" "--config" "Release" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_32B_DIR}/Release/CoolProp.dll" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/CoolProp_xls_std.dll" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_32B_DIR_STDCALL}/Release/CoolProp.dll" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/CoolProp_stdcall.dll" + WORKING_DIRECTORY ${COOLPROP_WINDOWS_PACKAGE_32B_DIR_STDCALL} COMMENT "Building the 32bit shared library with stdcall" VERBATIM ) - add_custom_command(TARGET COOLPROP_EXCEL PRE_BUILD - COMMAND ${CMAKE_COMMAND} ARGS "-G${COOLPROP_EXCEL_DLL_GEN}" "${CMAKE_CURRENT_SOURCE_DIR}" "-DCOOLPROP_SHARED_LIBRARY=ON" "-DCOOLPROP_CDECL_LIBRARY=ON" + add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES PRE_BUILD + COMMAND ${CMAKE_COMMAND} ARGS "-G${COOLPROP_WINDOWS_PACKAGE_DLL_GEN}" "${CMAKE_CURRENT_SOURCE_DIR}" "-DCOOLPROP_SHARED_LIBRARY=ON" "-DCOOLPROP_CDECL_LIBRARY=ON" COMMAND ${CMAKE_COMMAND} ARGS "--build" "." "--target" "CoolProp" "--config" "Release" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_EXCEL_32B_DIR_ALT}/Release/CoolProp.dll" "${COOLPROP_EXCEL_TMP_DIR}/source/CoolProp_cdecl.dll" - WORKING_DIRECTORY ${COOLPROP_EXCEL_32B_DIR_ALT} + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_32B_DIR_CDECL}/Release/CoolProp.dll" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/CoolProp_cdecl.dll" + WORKING_DIRECTORY ${COOLPROP_WINDOWS_PACKAGE_32B_DIR_CDECL} COMMENT "Building the 32bit shared library with cdecl" VERBATIM ) # Build the 64bit DLL - add_custom_command(TARGET COOLPROP_EXCEL PRE_BUILD - COMMAND ${CMAKE_COMMAND} ARGS "-G${COOLPROP_EXCEL_DLL_GEN} Win64" "${CMAKE_CURRENT_SOURCE_DIR}" "-DCOOLPROP_SHARED_LIBRARY=ON" + add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES PRE_BUILD + COMMAND ${CMAKE_COMMAND} ARGS "-G${COOLPROP_WINDOWS_PACKAGE_DLL_GEN} Win64" "${CMAKE_CURRENT_SOURCE_DIR}" "-DCOOLPROP_SHARED_LIBRARY=ON" COMMAND ${CMAKE_COMMAND} ARGS "--build" "." "--target" "CoolProp" "--config" "Release" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_EXCEL_64B_DIR}/Release/CoolProp.dll" "${COOLPROP_EXCEL_TMP_DIR}/source/CoolProp_xls_x64.dll" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_EXCEL_64B_DIR}/Release/CoolProp.dll" "${COOLPROP_EXCEL_TMP_DIR}/source/CoolProp_x64.dll" - WORKING_DIRECTORY ${COOLPROP_EXCEL_64B_DIR} + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_64B_DIR}/Release/CoolProp.dll" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/CoolProp_xls_x64.dll" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_64B_DIR}/Release/CoolProp.dll" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/CoolProp_x64.dll" + WORKING_DIRECTORY ${COOLPROP_WINDOWS_PACKAGE_64B_DIR} COMMENT "Building the 64bit shared library" VERBATIM ) + + # ************************************************************* + # Add the target for EES and populate it with custom commands + # ************************************************************* + add_custom_target(COOLPROP_WINDOWS_PACKAGE_EES) + add_dependencies (COOLPROP_WINDOWS_PACKAGE_EES COOLPROP_WINDOWS_PACKAGE_PREPARE) + add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_EES PRE_BUILD + COMMAND ${CMAKE_COMMAND} ARGS "-G${COOLPROP_WINDOWS_PACKAGE_DLL_GEN}" "${CMAKE_CURRENT_SOURCE_DIR}" "-DCOOLPROP_EES_MODULE=ON" + COMMAND ${CMAKE_COMMAND} ARGS "--build" "." "--target" "COOLPROP_EES" "--config" "Release" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy_directory" "${COOLPROP_WINDOWS_PACKAGE_EES_DIR}" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/EES" + WORKING_DIRECTORY ${COOLPROP_WINDOWS_PACKAGE_EES_DIR} + COMMENT "Building the 32bit library for EES" + VERBATIM ) + + # ************************************************************* + # Add the target for Excel and populate it with custom commands + # ************************************************************* + add_custom_target(COOLPROP_WINDOWS_PACKAGE_EXCEL) + add_dependencies (COOLPROP_WINDOWS_PACKAGE_EXCEL COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES) # Copy the files - add_custom_command(TARGET COOLPROP_EXCEL PRE_BUILD - COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_EXCEL_SRC_DIR}/CoolProp.xla" "${COOLPROP_EXCEL_TMP_DIR}/source/" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_EXCEL_SRC_DIR}/CoolProp.xlam" "${COOLPROP_EXCEL_TMP_DIR}/source/" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_EXCEL_SRC_DIR}/TestExcel.xlsx" "${COOLPROP_EXCEL_TMP_DIR}/source/" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy_directory" "${COOLPROP_EXCEL_ISS_DIR}" "${COOLPROP_EXCEL_TMP_DIR}" + add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_EXCEL PRE_BUILD + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_EXCEL_DIR}/CoolProp.xla" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_EXCEL_DIR}/CoolProp.xlam" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_EXCEL_DIR}/TestExcel.xlsx" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy_directory" "${COOLPROP_WINDOWS_PACKAGE_ISS_DIR}" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Copying the Excel and Inno Script files for the installer" VERBATIM ) + + add_custom_target(COOLPROP_WINDOWS_PACKAGE_INSTALLER) + add_dependencies (COOLPROP_WINDOWS_PACKAGE_INSTALLER COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES) + add_dependencies (COOLPROP_WINDOWS_PACKAGE_INSTALLER COOLPROP_WINDOWS_PACKAGE_EES) + add_dependencies (COOLPROP_WINDOWS_PACKAGE_INSTALLER COOLPROP_WINDOWS_PACKAGE_EXCEL) # Build the installer and copy it to the bin directory - add_custom_command(TARGET COOLPROP_EXCEL POST_BUILD - COMMAND ${COOLPROP_EXCEL_ISS_EXE} ARGS "addin-installer.iss" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy_directory" "${COOLPROP_EXCEL_TMP_DIR}/deploy" "${COOLPROP_EXCEL_TMP_DIR}/bin/MicrosoftExcel" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy_directory" "${COOLPROP_EXCEL_TMP_DIR}/deploy" "${COOLPROP_EXCEL_TMP_DIR}/bin/shared_library/Windows" - WORKING_DIRECTORY "${COOLPROP_EXCEL_TMP_DIR}" - COMMENT "The new installer is located in '${COOLPROP_EXCEL_TMP_DIR}/bin/MicrosoftExcel' and '${COOLPROP_EXCEL_TMP_DIR}/bin/shared_library/Windows'" + add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_INSTALLER POST_BUILD + COMMAND ${COOLPROP_WINDOWS_PACKAGE_ISS_EXE} ARGS "addin-installer.iss" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/deploy" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/bin/installer/Windows" + WORKING_DIRECTORY "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}" + COMMENT "The new installer is located in '${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/bin/installer/Windows'" VERBATIM ) endif() diff --git a/dev/buildbot/master/master.cfg b/dev/buildbot/master/master.cfg index 713937c2..2b8fc967 100644 --- a/dev/buildbot/master/master.cfg +++ b/dev/buildbot/master/master.cfg @@ -680,19 +680,19 @@ def python_manylinux_builder(bitness="64"): # # return factory -def excel_slave(): +def windows_installer_slave(): """ """ working_folder = "build/build" output_folder = "build/build/InnoScript/deploy" - # Create the factory to add the actions to build the Excel add-in installer + # Create the factory to add the actions to build the Windows installer factory = getBaseFactory() factory.addStep(MakeDirectory(dir=working_folder, haltOnFailure = True)) factory.addStep(RemoveDirectory(dir=output_folder, haltOnFailure = False)) - factory.addStep(ShellCommand(command=["cmake", "..", "-DCOOLPROP_EXCEL_MODULE=ON","-G", "Visual Studio 10 Win64"], + factory.addStep(ShellCommand(command=["cmake", "..", "-DCOOLPROP_WINDOWS_PACKAGE=ON","-G", "Visual Studio 10 Win64"], workdir= working_folder, haltOnFailure = True)) - factory.addStep(ShellCommand(command=["cmake", "--build", ".", "--target", "COOLPROP_EXCEL"], + factory.addStep(ShellCommand(command=["cmake", "--build", ".", "--target", "COOLPROP_WINDOWS_PACKAGE"], workdir = working_folder, haltOnFailure = True)) # Upload the files diff --git a/externals/ExcelAddinInstaller b/externals/ExcelAddinInstaller index 338700e9..9d94026c 160000 --- a/externals/ExcelAddinInstaller +++ b/externals/ExcelAddinInstaller @@ -1 +1 @@ -Subproject commit 338700e9c693f82f5152edcd73f1a9492e160fab +Subproject commit 9d94026c6f0af7b9512d2ddbc345b5a24715a57c From 363affa3ef488c7a178426a2ff42f1f63b27a965 Mon Sep 17 00:00:00 2001 From: Jorrit Wronski Date: Thu, 29 Sep 2016 09:21:12 +0200 Subject: [PATCH 2/5] Updated instalelr files --- externals/ExcelAddinInstaller | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/ExcelAddinInstaller b/externals/ExcelAddinInstaller index 9d94026c..c853c5e3 160000 --- a/externals/ExcelAddinInstaller +++ b/externals/ExcelAddinInstaller @@ -1 +1 @@ -Subproject commit 9d94026c6f0af7b9512d2ddbc345b5a24715a57c +Subproject commit c853c5e3538b5044c7a052d752e7399460e4d9f3 From 89fd68abaf31b66a37cad665e0caa4c862102e0d Mon Sep 17 00:00:00 2001 From: Jorrit Wronski Date: Fri, 7 Oct 2016 14:49:49 +0200 Subject: [PATCH 3/5] Modified CMakeLists.txt to include other files in the installer --- CMakeLists.txt | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eb21db25..51c8e43c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -528,7 +528,7 @@ endif() # Windows package if (COOLPROP_WINDOWS_PACKAGE) - message(STATUS "Creating Excel add-in for COOLPROP_VERSION=${COOLPROP_VERSION}") + message(STATUS "Creating Windows installer for COOLPROP_VERSION=${COOLPROP_VERSION}") # Setting some basic build paths set(COOLPROP_WINDOWS_PACKAGE_32B_DIR "${CMAKE_CURRENT_BINARY_DIR}/32bitDLL") set(COOLPROP_WINDOWS_PACKAGE_32B_DIR_STDCALL "${CMAKE_CURRENT_BINARY_DIR}/32bitDLL_stdcall") @@ -554,7 +554,7 @@ if (COOLPROP_WINDOWS_PACKAGE) ) # ****************************************************************** - # Add the target that prepares the build directory for the subbuilds + # Add the targets that prepare the build directory for the subbuilds # ****************************************************************** add_custom_target(COOLPROP_WINDOWS_PACKAGE_PREPARE) # Prepare directories @@ -565,13 +565,25 @@ if (COOLPROP_WINDOWS_PACKAGE) COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_64B_DIR}" COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_EES_DIR}" COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source" + #COMMAND ${CMAKE_COMMAND} ARGS "-E" "remove_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/deploy" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/deploy" + #COMMAND ${CMAKE_COMMAND} ARGS "-E" "remove_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/bin" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/bin" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Preparing the directories for the Windows installer" + VERBATIM ) + + add_custom_target(COOLPROP_WINDOWS_PACKAGE_DELETE) + # Delete directories + add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_DELETE PRE_BUILD COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source" COMMAND ${CMAKE_COMMAND} ARGS "-E" "remove_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/deploy" COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/deploy" COMMAND ${CMAKE_COMMAND} ARGS "-E" "remove_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/bin" COMMAND ${CMAKE_COMMAND} ARGS "-E" "make_directory" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/bin" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Preparing the directories for the Windows installer" + COMMENT "Removing the old build directories for the Windows installer" VERBATIM ) # ************************************************************** @@ -629,7 +641,7 @@ if (COOLPROP_WINDOWS_PACKAGE) # Add the target for Excel and populate it with custom commands # ************************************************************* add_custom_target(COOLPROP_WINDOWS_PACKAGE_EXCEL) - add_dependencies (COOLPROP_WINDOWS_PACKAGE_EXCEL COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES) + add_dependencies (COOLPROP_WINDOWS_PACKAGE_EXCEL COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES COOLPROP_WINDOWS_PACKAGE_PREPARE) # Copy the files add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_EXCEL PRE_BUILD COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_EXCEL_DIR}/CoolProp.xla" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/" @@ -640,7 +652,12 @@ if (COOLPROP_WINDOWS_PACKAGE) COMMENT "Copying the Excel and Inno Script files for the installer" VERBATIM ) + # ***************************************************************************** + # Add the target for the installer package and populate it with custom commands + # ***************************************************************************** add_custom_target(COOLPROP_WINDOWS_PACKAGE_INSTALLER) + add_dependencies (COOLPROP_WINDOWS_PACKAGE_INSTALLER COOLPROP_WINDOWS_PACKAGE_DELETE) + add_dependencies (COOLPROP_WINDOWS_PACKAGE_INSTALLER COOLPROP_WINDOWS_PACKAGE_PREPARE) add_dependencies (COOLPROP_WINDOWS_PACKAGE_INSTALLER COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES) add_dependencies (COOLPROP_WINDOWS_PACKAGE_INSTALLER COOLPROP_WINDOWS_PACKAGE_EES) add_dependencies (COOLPROP_WINDOWS_PACKAGE_INSTALLER COOLPROP_WINDOWS_PACKAGE_EXCEL) From 1ca6bc57e118f1dfec615ce9e03bd7ca0fd28f68 Mon Sep 17 00:00:00 2001 From: Jorrit Wronski Date: Thu, 13 Oct 2016 18:46:49 +0200 Subject: [PATCH 4/5] Removed the double compilation of the cdecl dll, make Excel use the standard dlls, added the vba code to source control --- CMakeLists.txt | 16 ++- externals/ExcelAddinInstaller | 2 +- wrappers/Excel/CoolProp.xla | Bin 34304 -> 34304 bytes wrappers/Excel/CoolProp.xlam | Bin 33547 -> 30283 bytes wrappers/Excel/XLAM_module.bas | 181 +++++++++++++++++++++++++++++++++ wrappers/Excel/XLA_module.bas | 27 +++++ 6 files changed, 220 insertions(+), 6 deletions(-) create mode 100644 wrappers/Excel/XLAM_module.bas create mode 100644 wrappers/Excel/XLA_module.bas diff --git a/CMakeLists.txt b/CMakeLists.txt index 51c8e43c..effc6184 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -591,14 +591,20 @@ if (COOLPROP_WINDOWS_PACKAGE) # ************************************************************** add_custom_target(COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES) add_dependencies (COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES COOLPROP_WINDOWS_PACKAGE_PREPARE) - # Build the 32bit DLLs + # Copy the header file add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES PRE_BUILD - COMMAND ${CMAKE_COMMAND} ARGS "-G${COOLPROP_WINDOWS_PACKAGE_DLL_GEN}" "${CMAKE_CURRENT_SOURCE_DIR}" "-DCOOLPROP_SHARED_LIBRARY=ON" - COMMAND ${CMAKE_COMMAND} ARGS "--build" "." "--target" "CoolProp" "--config" "Release" - COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_32B_DIR}/Release/CoolProp.dll" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/CoolProp_x86.dll" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${CMAKE_CURRENT_SOURCE_DIR}/include/CoolPropLib.h" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/CoolPropLib.h" WORKING_DIRECTORY ${COOLPROP_WINDOWS_PACKAGE_32B_DIR} - COMMENT "Building the 32bit shared library with default settings" + COMMENT "Copy the header file for the CoolProp library" VERBATIM ) + # # Build the 32bit DLLs + # add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES PRE_BUILD + # COMMAND ${CMAKE_COMMAND} ARGS "-G${COOLPROP_WINDOWS_PACKAGE_DLL_GEN}" "${CMAKE_CURRENT_SOURCE_DIR}" "-DCOOLPROP_SHARED_LIBRARY=ON" + # COMMAND ${CMAKE_COMMAND} ARGS "--build" "." "--target" "CoolProp" "--config" "Release" + # COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_32B_DIR}/Release/CoolProp.dll" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/CoolProp_x86.dll" + # WORKING_DIRECTORY ${COOLPROP_WINDOWS_PACKAGE_32B_DIR} + # COMMENT "Building the 32bit shared library with default settings" + # VERBATIM ) add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES PRE_BUILD COMMAND ${CMAKE_COMMAND} ARGS "-G${COOLPROP_WINDOWS_PACKAGE_DLL_GEN}" "${CMAKE_CURRENT_SOURCE_DIR}" "-DCOOLPROP_SHARED_LIBRARY=ON" "-DCOOLPROP_STDCALL_LIBRARY=ON" COMMAND ${CMAKE_COMMAND} ARGS "--build" "." "--target" "CoolProp" "--config" "Release" diff --git a/externals/ExcelAddinInstaller b/externals/ExcelAddinInstaller index c853c5e3..5eed7656 160000 --- a/externals/ExcelAddinInstaller +++ b/externals/ExcelAddinInstaller @@ -1 +1 @@ -Subproject commit c853c5e3538b5044c7a052d752e7399460e4d9f3 +Subproject commit 5eed765649be3baddc8f13c3a2073a5486a288b9 diff --git a/wrappers/Excel/CoolProp.xla b/wrappers/Excel/CoolProp.xla index 9898601ef031b0988f09a9735b0d5ec0024a6577..5f17554a08d85b9e57a4aab8da711cc9332378c9 100644 GIT binary patch delta 2421 zcmZ`*3v5$W82-<_eRtj3X3h>_yOaSP>$bKlTT#^8b`L;;V;kFGY-`tcQn_wrEstqp z+ZA0RU#e|i+#|Y}8L+G+?rD^Q#66kJJ-*%L3YdLCe`>SSswmcs+xtQ$O&$^2Rfh!{KPXu9-IXP zGW@eFUjm>YyYa8G9R9L=r#MUixEyByjuJ;0q65q%WW)9N<1^qpX26fkfWMrMhtm=t zO()Xu<1^q7&49l?1O9&n)eCPtt)jHVuOfag%QZS2)#}gHewq{f5*wVpR6er&aazIln5Om+H6ALnz{nLi#UnhxK}EH`Sj}H054vMrkDnd4~c%p%kkqBavmc{)I^U5Zt;&qZcDHN8> zb}gT<7V_E1pNoWi1OV@@kM4Hq@Ri2(>j*=(8L!LE(8=uQNA}F}$4aj9LSkVLJH-nJ z;*XiG@~PK!(Rk;YJSsxt!F3C05lMQvsg)Q2zOk7@;s`0*h1(nQ`R~^n5M=^EA%%W!u4(M%kbIhHaLlD>; zV(dYt-VIN8-DPBAO7x6*KT@vjmMTEE+1ICFE4w#$a6WmC<)k*JPod1I^L3&d=!%j; zB#vdx37TIdO?aE_y(KH=oG4b^?wPmDUgHR_eshdlqRQ;hCEHWP{db^pK{oG>vO(SF4 zcW$DQxXEx(ZWKlS&et&B=D(JXt(a&!)!!kBPc(H)CYm}Vnfl6Hrn~^1uh#p@PwI?} zui|93mnwDHI;b(3+Dnz03RMa`S9BvEap%&A<%hj1BzUOam`RcQ5RcPj#^WNuc^hxj zq<(!X>4JDXpVHy@ExGu?jm1~{f-v~_Mt0g-&P`u8aE_}y=_7oIE0D;9j~?I;xbodD zHSMCNZi0b^gxg9lOW0gmmt5l|T}#8i*w1~n`kSoE*Hb2Lyi&6-g%1ymw6WA>Yn1AZaulOW}egX|f6WQ7JfePMo}>2^|(1sXzu+M zHRwdn?ru)_#IUO=-`8^mp|yN(XgMWc09mq;*)r7#{&0&G$G1GG z-ulDvm1uN94PW|bQ8V+}LjLI1MIz}`ApYEa!}My4#bR=r%59daa%cL~s}z;Bj$8FM zr>&~I%4~O7Y>ORb$w{~x=dJqc@@lKu>TsH^R%b=EwNjWi6FwC-?TKtd6?|``A4#0m ZOH9S)J$=XUXy5x{NuBVY)5EbI>R$^R#XSH3 delta 2363 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 1E+30 Then + 'Return error message + PropsSI = get_error_message() + Else + PropsSI = PropsSI_temp + End If + Exit Function + +ErrorHandler: + If Err = 13 Then + Exit Function + End If + + MsgBox "The most recent error number is " & Err & ". Its message text is: " & Error(Err) + Exit Function +End Function + +Public Function PhaseSI(ByVal Name1 As String, ByVal Value1 As Double, ByVal Name2 As String, ByVal Value2 As Double, ByVal fluid As String) + Dim strPhase As String + 'Make a null-terminated string that is plenty big + strPhase = String(2000, vbNullChar) + 'Call PhaseSI_private - any errors will return an empty phase string + Call PhaseSI_private(Name1, Value1, Name2, Value2, fluid, strPhase, 2000) + If Len(strPhase) = 0 Then + PhaseSI = get_error_message() + Else + PhaseSI = strPhase + End If + Exit Function +End Function + +Public Function Props1SI(ByVal fluid As String, ByVal Output As String) + On Error GoTo ErrorHandler + Dim Props1SI_temp As Double + + Props1SI_temp = Props1SI_private(Output, fluid) + + If Abs(Props1SI_temp) > 1E+30 Then + 'Display the error + Props1SI = get_error_message() + Else + Props1SI = Props1SI_temp + End If + Exit Function + +ErrorHandler: + If Err = 13 Then + Exit Function + End If + MsgBox "The most recent error number is " & Err & ". Its message text is: " & Error(Err) + Exit Function +End Function + +Public Function Props(ByVal Output As String, ByVal Name1 As String, ByVal Value1 As Double, ByVal Name2 As String, ByVal Value2 As Double, ByVal fluid As String) + On Error GoTo ErrorHandler + Dim Props_temp As Double + Props_temp = Props_private(Output, Name1, Value1, Name2, Value2, fluid) + If Abs(Props_temp) > 1E+30 Then + Props = get_error_message() + Else + Props = Props_temp + End If + Exit Function +ErrorHandler: + If Err = 13 Then + Exit Function + End If + MsgBox "The most recent error number is " & Err & ". Its message text is: " & Error(Err) + Exit Function +End Function + +Public Function HAPropsSI(ByVal Output As String, ByVal Input1Name As String, ByVal Value1 As Double, ByVal Input2Name As String, ByVal Value2 As Double, ByVal Input3name As String, ByVal Value3 As Double) As Double + On Error GoTo ErrorHandler + Dim HAPropsSI_temp As Double + HAPropsSI_temp = HAPropsSI_private(Output, Input1Name, Value1, Input2Name, Value2, Input3name, Value3) + If Abs(HAPropsSI_temp) > 1E+30 Then + HAPropsSI = get_error_message() + Else + HAPropsSI = HAPropsSI_temp + End If + Exit Function +ErrorHandler: + If Err = 13 Then + Exit Function + End If + MsgBox "The most recent error number is " & Err & ". Its message text is: " & Error(Err) + Exit Function +End Function + +Public Function MixtureString(names As Range, fractions As Range) As String + ' See http://www.functionx.com/vbaexcel/objects/Lesson6.htm + Dim my_names, my_fractions As Collection + Dim Cell, i As Variant + Dim chunk As String + MixtureString = "" + Set my_names = New Collection + Set my_fractions = New Collection + + ' Collect all the names + For Each Cell In names + my_names.Add Cell.Value + Next + ' Collect all the fractions + For Each Cell In fractions + my_fractions.Add Cell.Value + Next + ' Zip them back together + For i = 1 To my_fractions.Count + chunk = my_names.Item(i) & "[" & LTrim(Str(my_fractions.Item(i))) & "]" + If i = 1 Then + MixtureString = MixtureString & chunk + Else + MixtureString = MixtureString & "&" & chunk + End If + Next + +End Function diff --git a/wrappers/Excel/XLA_module.bas b/wrappers/Excel/XLA_module.bas new file mode 100644 index 00000000..80175c92 --- /dev/null +++ b/wrappers/Excel/XLA_module.bas @@ -0,0 +1,27 @@ +Attribute VB_Name = "Module1" +'Information on calling DLL from Excel: +'http://msdn.microsoft.com/en-us/library/office/bb687915.aspx +' +'Information on compiling DLL: +'http://msdn.microsoft.com/en-us/library/office/bb687850.aspx + +Private Declare Function Props_private Lib "CoolProp_stdcall.dll" Alias "_Props@32" (ByVal Output As String, ByVal Name1 As Long, ByVal Value1 As Double, ByVal Name2 As Long, ByVal Value2 As Double, ByVal Ref As String) As Double +Private Declare Function Props1_private Lib "CoolProp_stdcall.dll" Alias "_Props1@8" (ByVal Ref As String, ByVal Output As String) As Double +Private Declare Function HAProps_private Lib "CoolProp_stdcall.dll" Alias "_HAProps@40" (ByVal Output As String, ByVal Input1Name As String, ByVal Value1 As Double, ByVal Input2Name As String, ByVal Value2 As Double, ByVal Input3name As String, ByVal Value3 As Double) As Double + +Public Function Props(ByVal Output As String, ByVal Name1 As String, ByVal Value1 As Double, ByVal Name2 As String, ByVal Value2 As Double, ByVal Ref As String) As Double + 'Get the single character forms + N1 = Asc(Left(Name1, 1)) + N2 = Asc(Left(Name2, 1)) + Props = Props_private(Output, N1, Value1, N2, Value2, Ref) +End Function + +Public Function Props1(ByVal Ref As String, ByVal Output As String) As Double + Props1 = Props1_private(Ref, Output) +End Function + +Public Function HAProps(ByVal Output As String, ByVal Input1Name As String, ByVal Value1 As Double, ByVal Input2Name As String, ByVal Value2 As Double, ByVal Input3name As String, ByVal Value3 As Double) As Double + HAProps = HAProps_private(Output, Input1Name, Value1, Input2Name, Value2, Input3name, Value3) +End Function + + From 930debd741a3f5f3c10f9162c06689bfc89e847b Mon Sep 17 00:00:00 2001 From: Jorrit Wronski Date: Fri, 14 Oct 2016 15:07:28 +0200 Subject: [PATCH 5/5] Added some docs for #1237 and removed a duplicate rst for Excel --- CMakeLists.txt | 19 ++- Web/coolprop/wrappers/Excel/index.rst | 56 ++++---- Web/coolprop/wrappers/index.rst | 2 + dev/buildbot/master/master.cfg | 8 +- externals/ExcelAddinInstaller | 2 +- wrappers/Excel/README.rst | 191 -------------------------- 6 files changed, 55 insertions(+), 223 deletions(-) delete mode 100644 wrappers/Excel/README.rst diff --git a/CMakeLists.txt b/CMakeLists.txt index effc6184..15e84570 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -648,14 +648,28 @@ if (COOLPROP_WINDOWS_PACKAGE) # ************************************************************* add_custom_target(COOLPROP_WINDOWS_PACKAGE_EXCEL) add_dependencies (COOLPROP_WINDOWS_PACKAGE_EXCEL COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES COOLPROP_WINDOWS_PACKAGE_PREPARE) - # Copy the files + # Copy the Excel files add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_EXCEL PRE_BUILD COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_EXCEL_DIR}/CoolProp.xla" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/" COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_EXCEL_DIR}/CoolProp.xlam" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/" COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_EXCEL_DIR}/TestExcel.xlsx" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/source/" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_EXCEL_DIR}/CoolProp.xla" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/bin/MicrosoftExcel/" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_EXCEL_DIR}/CoolProp.xlam" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/bin/MicrosoftExcel/" + COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy" "${COOLPROP_WINDOWS_PACKAGE_EXCEL_DIR}/TestExcel.xlsx" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}/bin/MicrosoftExcel/" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Copying the Excel files for the installer" + VERBATIM ) + + # ******************************************************************* + # Add the target for Inno Script and populate it with custom commands + # ******************************************************************* + add_custom_target(COOLPROP_WINDOWS_PACKAGE_ISS) + add_dependencies (COOLPROP_WINDOWS_PACKAGE_ISS COOLPROP_WINDOWS_PACKAGE_EXCEL COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES COOLPROP_WINDOWS_PACKAGE_PREPARE) + # Copy the ISS files + add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_ISS PRE_BUILD COMMAND ${CMAKE_COMMAND} ARGS "-E" "copy_directory" "${COOLPROP_WINDOWS_PACKAGE_ISS_DIR}" "${COOLPROP_WINDOWS_PACKAGE_TMP_DIR}" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Copying the Excel and Inno Script files for the installer" + COMMENT "Copying the Inno Script files for the installer" VERBATIM ) # ***************************************************************************** @@ -667,6 +681,7 @@ if (COOLPROP_WINDOWS_PACKAGE) add_dependencies (COOLPROP_WINDOWS_PACKAGE_INSTALLER COOLPROP_WINDOWS_PACKAGE_SHARED_LIBRARIES) add_dependencies (COOLPROP_WINDOWS_PACKAGE_INSTALLER COOLPROP_WINDOWS_PACKAGE_EES) add_dependencies (COOLPROP_WINDOWS_PACKAGE_INSTALLER COOLPROP_WINDOWS_PACKAGE_EXCEL) + add_dependencies (COOLPROP_WINDOWS_PACKAGE_INSTALLER COOLPROP_WINDOWS_PACKAGE_ISS) # Build the installer and copy it to the bin directory add_custom_command(TARGET COOLPROP_WINDOWS_PACKAGE_INSTALLER POST_BUILD COMMAND ${COOLPROP_WINDOWS_PACKAGE_ISS_EXE} ARGS "addin-installer.iss" diff --git a/Web/coolprop/wrappers/Excel/index.rst b/Web/coolprop/wrappers/Excel/index.rst index 21e3d193..a8bd543c 100644 --- a/Web/coolprop/wrappers/Excel/index.rst +++ b/Web/coolprop/wrappers/Excel/index.rst @@ -7,38 +7,44 @@ Excel Wrapper Pre-compiled Binaries for windows ================================= -Pre-compiled release binaries can be downloaded from :sfdownloads:`MicrosoftExcel`. Development binaries coming from the buildbot server can be found at :sfnightly:`MicrosoftExcel`. -Download all the files. The basic protocol is: +Automated Installation +---------------------- +As of October 2016, the Excel wrapper for Microsoft Windows can installed from the Windows package as described on the :ref:`page on installation packages `. Please refer to the documentation there for issues related to the installation process on Windows. -Part 1: -------- -1. Copy the files CoolProp.dll and CoolProp_x64.dll to c:\\CoolProp folder. Technically you only need the DLL that matches your system architecture (CoolProp.dll = 32-bit, CoolProp_x64.dll = 64-bit), but it can't hurt to copy both if you don't know which system architecture version you have. +Manual Installation +------------------- +For a manual installation, -Part 2: -------- -1. Open Excel -2. Determine the trusted directory for addins by going to File->Options...->Trust Center->Trust Center Settings...->Trusted Locations . Note the add-ins directory. Put your CoolProp.xlam in that directory -3. Go to the menu File-->Options-->Add-Ins -4. At the bottom, select Manage: Excel Add-ins, then click the Go.. button -5. Click the browse button -6. Browse to the file CoolProp.xlam you downloaded, select it (if necessary, CoolProp might already be visible) -7. Make sure the CoolProp Add-in is selected. -8. Open the file TestExcel.xlsx and try to re-evaluate one of the cells - they should work now +1. Get the shared libraries at :sfdownloads:`shared_library/Windows/32bit__stdcall` and :sfdownloads:`shared_library/Windows/64bit`, put the DLLs into a folder of your choice and rename them to `CoolProp_stdcall.dll` and `CoolProp_x64.dll`. Make sure to add that folder to your path. Technically you only need the DLL that matches your system architecture (`CoolProp_stdcall.dll` = 32-bit, `CoolProp_x64.dll` = 64-bit), but it can’t hurt to copy both if you don’t know which system architecture version you have. The Excel macro will select the correct one and use it. +2. Download the xla and xlam files from :sfdownloads:`MicrosoftExcel` and activate the add-in from Excel as described below. and copy the files to a convenient accessible location. +3. The **TestExcel.xlsx** from :sfdownloads:`MicrosoftExcel` can be copied to a working directory in ``My Documents``. -If you are trying to over-write the CoolProp xlam, you should: -a) In Excel, determine the location of the CoolProp xlam that it wants to load by going to Addins menu -b) Move the xlam somewhere else temporarily -c) In Excel, uncheck the CoolProp add-in - it might have already warned about the addin not being in the right place -d) Restart Excel. Check that the addin has been removed, or at least the path is not the old path to CoolProp -e) Determine the trusted directory for addins by going to File->Options...->Trust Center->Trust Center Settings...->Trusted Locations . Note the add-ins directory. Put your CoolProp.xlam in that directory -f) In Excel, add the add-in for CoolProp again by checking it and browsing to the correct location -g) Restart Excel, add-in should still be there. +1. Open Excel +2. Go to the menu ``File–>Options–>Add-Ins`` +3. At the bottom, select ``Manage: Excel Add-ins``, then click the ``Go...`` button +4. Click the ``Browse`` button on the Add-in Manager panel +5. Browse to the file **CoolProp.xlam** you downloaded and select it +6. Make sure the CoolProp Add-in is selected (box checked) and close the Add-in Manager. +7. Open the file **TestExcel.xlsx** and try to re-evaluate one of the cells; the CoolProp formulas should all be working now. (To recalculate the entire worksheet, press ``Ctrl``-``Alt``-``Shift``-``F9`` ) [#]_ -.. note:: +.. [#] **Alertnate DLL Location** - Some environments, lock down the folders included in the binary search path for normal users for security reasons. If this is the case, you will need to put the DLL files in an alternate location (possibly on a shared network location for all users). Follow the instructions below: + + 1. Place the CoolProp DLL files in the alternate location + 2. Place the CoolProp xlam file in a writable location and open it. + 3. You will get an Excel error, ``File not found - CoolProp_stdcall.dll``. Clicking **Ok** on the error will only clear the first of many. Press and hold the **``Enter``** key until all of the errors clear. + 4. Make sure that the Developer ribbon is visible on the main menu. If not + + - Go to **File | Options** on the main menu and select Cusomize Ribbon + - Make sure that the Developer main tab is checked (ON) + + 5. Open the Visual Basic editor and use **Edit | Replace** to replace all occurances of **CoolProp_stdcall.dll** with the full path to the alternate location for your DLL files, making sure to press the save button (disk image) or **File | Save** before exiting the VBA editor. + 6. Save the CoolProp.xlam file. + + +.. [#] If you are having problems with the path to the XLAM in your worksheet appearing as the complete path to the xlam (but not the correct path), you might need to go into ``Data->Update Links`` in Excel, select CoolProp.xlam, and select ``Change Source...`` and select the location of your xlam file. That should update all the links. - If you are having problems with the path to the XLAM in your worksheet appearing as the complete path to the xlam (but not the correct path), you might need to go into ``Data->Update Links`` in Excel, select CoolProp.xlam, and select "Change Source..." and select the location of your xlam file. That should update all the links. Pre-compiled Binaries for OSX ============================= diff --git a/Web/coolprop/wrappers/index.rst b/Web/coolprop/wrappers/index.rst index d737da67..a11195ec 100644 --- a/Web/coolprop/wrappers/index.rst +++ b/Web/coolprop/wrappers/index.rst @@ -6,6 +6,8 @@ Available Wrappers CoolProp at its core is a C++ library, but it can be of interest to use this code base from other programming environments. For that reason, wrappers have been constructed for most of the programming languages of technical interest to allow users to seamlessly interface CoolProp and existing codebases. +There are also installer packages availbale on the :ref:`page on installation packages `. + Downloads and instructions for each wrapper are included in the page for the wrapper given in the table below. ======================================================= =========================== ======================================= diff --git a/dev/buildbot/master/master.cfg b/dev/buildbot/master/master.cfg index 2b8fc967..e23b7be4 100644 --- a/dev/buildbot/master/master.cfg +++ b/dev/buildbot/master/master.cfg @@ -692,11 +692,11 @@ def windows_installer_slave(): factory.addStep(ShellCommand(command=["cmake", "..", "-DCOOLPROP_WINDOWS_PACKAGE=ON","-G", "Visual Studio 10 Win64"], workdir= working_folder, haltOnFailure = True)) - factory.addStep(ShellCommand(command=["cmake", "--build", ".", "--target", "COOLPROP_WINDOWS_PACKAGE"], + factory.addStep(ShellCommand(command=["cmake", "--build", ".", "--target", "COOLPROP_WINDOWS_PACKAGE_INSTALLER"], workdir = working_folder, haltOnFailure = True)) # Upload the files - factory.addStep(DirectoryUpload(slavesrc="build/InnoScript/bin",masterdest=master_loc_rel,url="MicrosoftExcel",compress="bz2")) + factory.addStep(DirectoryUpload(slavesrc="build/InnoScript/bin",masterdest=master_loc_rel,url="installer",compress="bz2")) fixPermissions(factory) return factory @@ -1030,9 +1030,9 @@ c['builders'] = [] # ) c['builders'].append( - BuilderConfig(name="Excel", + BuilderConfig(name="Windows installer", slavenames=["windows-DTU-slave"], - factory = excel_slave() ) ) + factory = windows_installer_slave() ) ) c['builders'].append( BuilderConfig(name="MathCAD", slavenames=["windows-slave"], diff --git a/externals/ExcelAddinInstaller b/externals/ExcelAddinInstaller index 5eed7656..ba5d2562 160000 --- a/externals/ExcelAddinInstaller +++ b/externals/ExcelAddinInstaller @@ -1 +1 @@ -Subproject commit 5eed765649be3baddc8f13c3a2073a5486a288b9 +Subproject commit ba5d2562539ab744e35010f53eb6abcfcfdb358c diff --git a/wrappers/Excel/README.rst b/wrappers/Excel/README.rst deleted file mode 100644 index 0eb6a157..00000000 --- a/wrappers/Excel/README.rst +++ /dev/null @@ -1,191 +0,0 @@ -Excel Wrapper -============= - -Pre-compiled Binaries for windows ---------------------------------- - -Pre-compiled release binaries can be downloaded from `MicrosoftExcel `_ . Development binaries coming from the buildbot server can be found at `MicrosoftExcel `_. - -Download all the files. The basic protocol is: - -**Part 1:** - -1. Copy the files **CoolProp.dll** and **CoolProp_x64.dll** to **C:\\CoolProp** [#]_ folder. Technically you only need the DLL that matches your system architecture (`CoolProp.dll` = 32-bit, `CoolProp_x64.dll` = 64-bit), but it can’t hurt to copy both if you don’t know which system architecture version you have. The excel macro will select the correct one and use it. -2. Copy the file **CoolProp.xlam** to a convenient accessible location (it could go in the C:\\CoolProp folder as well). -3. **CoolProp.xlsx** can be copied to a working directory in ``My Documents``. - -**Part 2:** - -1. Open Excel -2. Go to the menu ``File–>Options–>Add-Ins`` -3. At the bottom, select ``Manage: Excel Add-ins``, then click the ``Go...`` button -4. Click the ``Browse`` button on the Add-in Manager panel -5. Browse to the file **CoolProp.xlam** you downloaded and select it -6. Make sure the CoolProp Add-in is selected (box checked) and close the Add-in Manager. -7. Open the file **TestExcel.xlsx** and try to re-evaluate one of the cells; the CoolProp formulas should all be working now. (To recalculate the entire worksheet, press ``Ctrl``-``Alt``-``Shift``-``F9`` ) [#]_ - -.. [#] **Alertnate DLL Location** - Some environments, lock down the C:\\ drive from normal users for security reasons. If this is the case, you will need to put the DLL files in an alternate location (possibly on a shared network location for all users). Follow the instructions below: - - 1. Place the CoolProp DLL files in the alternate location - 2. Place the CoolProp xlam file in a writable location and open it. - 3. You will get an Excel error, ``File not found - C:\CoolProp\CoolProp.dll``. Clicking **Ok** on the error will only clear the first of many. Press and hold the **``Enter``** key until all of the errors clear. - 4. Make sure that the Developer ribbon is visible on the main menu. If not - - - Go to **File | Options** on the main menu and select Cusomize Ribbon - - Make sure that the Developer main tab is checked (ON) - - 5. Open the Visual Basic editor and use **Edit | Replace** to replace all occurances of **C:\\CoolProp** with the path to the alternate location for your CoolProp.dll files, making sure to press the save button (disk image) or **File | Save** before exiting the VBA editor. - 6. Save the CoolProp.xlam file. - - -.. [#] If you are having problems with the path to the XLAM in your worksheet appearing as the complete path to the xlam (but not the correct path), you might need to go into ``Data->Update Links`` in Excel, select CoolProp.xlam, and select ``Change Source...`` and select the location of your xlam file. That should update all the links. - - -Pre-compiled Binaries for OSX ------------------------------ - -**Part 1:** - -Download pre-compiled release binaries for OSX from `shared_library/Darwin/32bit/ `_. Development binaries coming from the buildbot server can be found at `shared_library/Darwin/32bit/ `_. Place the downloaded file called libCoolProp.dylib in the ${HOME}/lib folder (make this folder if needed). - -**Part 2:** - -Download the xlam from `MicrosoftExcel `_ or the development version from `MicrosoftExcel `_. - -1. Open Excel 2011 for Mac - -2. Go to the menu ``Tools–>Add-Ins`` - -3. Click the ``Select...`` button - -4. Browse to the file CoolProp.xlam you downloaded, select it - -5. Make sure the CoolProp Add-in is selected. - -6. Add this code to a cell - it should work: :: - - =PropsSI("T","P",101325,"Q",0,"Water") - - -If it doesn’t work and you get error number 53, it might be because you have a 64-bit .dylib file and you want a 32-bit .dylib file. For instance when you run the ``file`` command on your .dylib, you should see something like: :: - - $ file libCoolProp.dylib - libCoolProp.dylib: Mach-O dynamically linked shared library i386 - - -User-compiled Binaries ------------------------- - -**Common Requirements** - -Compilation of the Excel wrapper requires a few `common wrapper pre-requisites `_ - - -**Build (Windows)** - -MS Excel requires the CoolProp shared library, or Dynamic Link Library (DLL) on Windows, and will use either the 64-bit version or the 32-bit, ``__stdcall`` version. The instructions here are for a 64-bit windows system that will use Microsoft Visual Studio 2010 to compile *both* the 64-bit and 32-bit versions of the DLL. - -.. code-block:: bash - - # Check out the sources for CoolProp - git clone https://github.com/CoolProp/CoolProp --recursive - # Move into the folder you just created - cd CoolProp - # Make a build folder for the 32-bit DLL - mkdir build/32bit__stdcall && cd build/32bit__stdcall - # Build the MSVC project using CMake - cmake ../.. -G "Visual Studio 10" -DCOOLPROP_SHARED_LIBRARY=ON -DCOOLPROP_STDCALL_LIBRARY=ON - # Make the shared library - cmake --build . --config Release - cd ../.. - # Make a build folder for the 64-bit DLL - mkdir build/64bit && cd build/64bit - # Build the MSVC project using CMake - cmake ../.. -G "Visual Studio 10 Win64" -DCOOLPROP_SHARED_LIBRARY=ON - # Make the shared library - cmake --build . --config Release - cd ../.. - # Copy the generated DLL - copy build\32bit__stdcall\CoolProp.dll c:\CoolProp\CoolProp.dll - copy build\64bit\CoolProp.dll c:\CoolProp\CoolProp_x64.dll - -The above script should be adjusted for your specific compiler, replacing "Visual Studio 10" with your compiler name/release. - -**Build (OSX)** - -On OSX there is no calling convention to worry about, and only the 32-bit compilation is needed. You can force 32-bit compilation using -DFORCE_BITNESS_32=ON. These instructions will compile both the 32-bit library needed for Excel on OSX. - -.. code-block:: bash - - # Check out the sources for CoolProp - git clone https://github.com/CoolProp/CoolProp --recursive - # Move into the folder you just created - cd CoolProp - # Make a build folder - mkdir build && cd build - # Generate builder - cmake .. -DCOOLPROP_SHARED_LIBRARY=ON -DFORCE_BITNESS_32=ON -DCMAKE_BUILD_TYPE=Release - # Build - cmake --build . - cd .. - # Copy the generated DLL - cp build/libCoolProp.dylib ${HOME}/lib - -Usage ------------------------- - -The following CoolProp funcitons are implemented as Excel Functions (see CoolProp.xlsx for examples) - - -- **get_global_param_string("param")** -- **PropsSI("OutputName","Input1Name",Value1,"Input2Name",Value2,"FluidString")** -- **Props1SI("FluidString","OutputName")** -- **PhaseSI("Input1Name",Value1,"Input2Name",Value2,"FluidString")** -- **HAPropsSI("OutputName","Input1Name",Value1,"Input2Name",Value2,"Input3Name",Value3)** - - -and utility routine - - -- **MixtureString(Names,Fractions)** - - -where - - -"param" = - "version", "gitrevision", "fluids_list","parameter_list", or "predefined_mixtures" - -"OutputName" = - double quoted name of the fluid property to output - -"Input1Name" = - double quoted name of the first input state property - -Value1 = - the value, in SI units, of the first input state property - -"Input2Name" = - double quoted name of the second input state property - -Value2 = - the value, in SI units, of the second input state property - -"Input3Name" = - double quoted name of the third input state property; typically humidity ratio, "R" - -Value3 = - the value, in SI units, of the third input state property - -"FluidString" = - double quoted name of the fluid to evaluate - -Names = - range of cells containing fluid names (as text) - -Fractions = - range of cells containing mole fractions of the corresponding fluids in the **Names** range - - -| See `CoolProp.org `_ for more details on usage. -| See **TestExcel.xlsx** for examples of usage of these functions.