@@ -97,7 +97,9 @@ endif()
9797# "...-NOTFOUND" rather than erroring, which only surfaces later as a
9898# baffling "Found relative path while evaluating include directories"
9999# CMake generate-step error. Confirmed via a real macOS CI run.
100+ # PATH_SUFFIXES covers prefixes such as MSYS2's /ucrt64 (#133).
100101find_path (FREETYPE_UNQUALIFIED_INCLUDE_DIR ftoutln.h
102+ PATH_SUFFIXES freetype2/freetype
101103 PATHS /usr/include/freetype2/freetype /usr/include/freetype
102104 /opt/homebrew/include/freetype2/freetype
103105 /usr/local/include/freetype2/freetype )
@@ -137,6 +139,21 @@ if(ECCE_USE_COIN)
137139 find_library (COIN_LIBRARY Coin REQUIRED )
138140endif ()
139141
142+ if (WIN32 )
143+ # MSYS2's Coin is a DLL; moiv is a static library of ours. GL/gl.h pulls in
144+ # <windows.h>, whose full form drags in rpcndr.h's `byte`, ambiguous with
145+ # std::byte under `using namespace std`; and its min/max macros break
146+ # std::min/std::max. _POSIX_THREAD_SAFE_FUNCTIONS declares gmtime_r and
147+ # localtime_r (#133).
148+ add_compile_definitions (COIN_DLL CHEMKIT_NOT_DLL WIN32_LEAN_AND_MEAN NOMINMAX
149+ _POSIX_THREAD_SAFE_FUNCTIONS=200112L )
150+ # PosixCompat.H in every C++ file: it supplies the POSIX calls and strips
151+ # the windows.h macros (ERROR, OPAQUE, ...) that wx pulls in first.
152+ # win32compat/ stands in for the <sys/wait.h>-style headers MinGW lacks.
153+ add_compile_options ("$<$<COMPILE_LANGUAGE :CXX >:SHELL :-include ${CMAKE_SOURCE_DIR } /include /util /PosixCompat .H >" )
154+ include_directories (${CMAKE_SOURCE_DIR } /include/win32compat )
155+ endif ()
156+
140157if (APPLE )
141158 # ~90 files across the tree spell OpenGL headers the Linux/X11 way
142159 # ("GL/gl.h", "GL/glu.h") -- Apple's own OpenGL framework headers live
@@ -173,6 +190,10 @@ function(ecce_library name)
173190 endforeach ()
174191 add_library (${name} STATIC ${_srcs} )
175192 target_include_directories (${name} PRIVATE ${XercesC_INCLUDE_DIRS} )
193+ if (WIN32 )
194+ # The libraries reference each other in cycles; GNU ld needs them repeated.
195+ set_target_properties (${name} PROPERTIES LINK_INTERFACE_MULTIPLICITY 3)
196+ endif ()
176197endfunction ()
177198
178199# --- src/util -> libecceutil.a ---
@@ -189,6 +210,10 @@ target_compile_definitions(ecceutil PRIVATE ECCE_VERSION=\"${ECCE_VERSION_RAW}\"
189210# Messaging (src/util/jms) is MQTT 5 on libmosquitto.
190211pkg_check_modules(MOSQUITTO REQUIRED IMPORTED_TARGET libmosquitto)
191212target_link_libraries(ecceutil PUBLIC PkgConfig::MOSQUITTO)
213+ if(WIN32)
214+ # POSIX regex (libtre) and Winsock, which libssh's callers use directly.
215+ target_link_libraries(ecceutil PUBLIC regex ws2_32)
216+ endif()
192217
193218# ------------------------------------------------------------------------
194219# Where an installed ECCE lives, and where its ecce-<app> wrappers go.
@@ -226,6 +251,9 @@ ecce_library(eccetdat
226251# --- src/dsm -> 5 separate libraries, matching the old per-subdir mapping ---
227252ecce_library(eccexml src/dsm/chemistry src/dsm/xml)
228253ecce_library(eccecipc src/dsm/cipc)
254+ if(WIN32)
255+ target_link_libraries(eccecipc PUBLIC ws2_32)
256+ endif()
229257find_package(OpenSSL REQUIRED)
230258target_link_libraries(eccecipc PUBLIC OpenSSL::SSL OpenSSL::Crypto)
231259ecce_library(eccedav src/dsm/dav)
@@ -268,6 +296,7 @@ endif()
268296# this codebase) live one level down - both are needed.
269297# Same Homebrew-path gap as FREETYPE_UNQUALIFIED_INCLUDE_DIR above.
270298find_path(FREETYPE_ROOT_INCLUDE_DIR ft2build.h
299+ PATH_SUFFIXES freetype2
271300 PATHS /usr/include/freetype2 /usr/include
272301 /opt/homebrew/include/freetype2
273302 /usr/local/include/freetype2)
@@ -414,7 +443,13 @@ function(ecce_app name dir)
414443 if(ECCE_APP_GL)
415444 target_link_libraries(${name} PRIVATE OpenGL::GL OpenGL::GLU)
416445 endif()
417- target_link_libraries(${name} PRIVATE ${ECCE_APP_LINK} ${XercesC_LIBRARIES} )
446+ if(WIN32)
447+ # The static libraries reference each other in cycles; GNU ld rescans a group.
448+ target_link_libraries(${name} PRIVATE
449+ " $<LINK_GROUP :RESCAN ,${ECCE_APP_LINK} >" ${XercesC_LIBRARIES} )
450+ else()
451+ target_link_libraries(${name} PRIVATE ${ECCE_APP_LINK} ${XercesC_LIBRARIES} )
452+ endif()
418453endfunction()
419454
420455# --- apps with no wx dependency ---
@@ -442,7 +477,9 @@ target_link_libraries(mocomp PRIVATE
442477 eccedsi eccedav eccecipc eccefaces eccexml eccetdat eccedsi eccexml ecceutil
443478 ${XercesC_LIBRARIES} )
444479# flock(1) for the session scripts where util-linux is absent (macOS).
445- add_executable(ecce-flock src/apps/flock/ecce-flock.c)
480+ if(NOT WIN32) # the Windows client has no session scripts (#133)
481+ add_executable(ecce-flock src/apps/flock/ecce-flock.c)
482+ endif()
446483# The server half of " ecce -admin " on a -remote client (SiteRequest).
447484add_executable(ecce-site-admin src/apps/siteadmin/ecce-site-admin.C)
448485target_link_libraries(ecce-site-admin PRIVATE eccetdat ecceutil)
@@ -742,6 +779,7 @@ install(PROGRAMS
742779 ${CMAKE_SOURCE_DIR } /packaging/gateway/ecce-gateway-status
743780 ${CMAKE_SOURCE_DIR } /packaging/gateway/ecce-gateway-reap
744781 ${CMAKE_SOURCE_DIR } /packaging/gateway/ecce-find-mosquitto
782+ ${CMAKE_SOURCE_DIR } /packaging/windows/ecce-broker-win
745783 ${CMAKE_SOURCE_DIR } /packaging/nwchem/ecce-nwchem-datadir
746784 DESTINATION bin
747785 COMPONENT client)
@@ -771,7 +809,7 @@ install(FILES ${CMAKE_BINARY_DIR}/systemd/ecce-broker.service
771809# file (a central server's broker, ecce-gateway-start). Needs mosquitto's
772810# plugin header and apr-util, whose apr_password_validate reads htpasswd's
773811# hash formats.
774- if (NOT APPLE ) # macOS runs no central server
812+ if (NOT APPLE AND NOT WIN32 ) # macOS and Windows run no central server
775813 pkg_check_modules (APRUTIL REQUIRED IMPORTED_TARGET apr-util-1 )
776814 find_path (MOSQUITTO_PLUGIN_INCLUDE_DIR mosquitto_plugin.h REQUIRED )
777815 add_library (ecce_users_auth MODULE src/mqttauth/ecce_users_auth.c )
@@ -906,8 +944,21 @@ set(ECCE_GUI_APPS
906944 mddynamics mdenergy mdoptimize mdprepare msgdialog metadyn organizer
907945 passdialog hostkeydialog pertable polyed solvate builder vizthumbnail)
908946set (ECCE_CLI_APPS
909- load_tgbs ecmd eccejobmaster eccejobstore ecce-localdata ecce-flock ecce- site-admin mocomp
947+ load_tgbs ecmd eccejobmaster eccejobstore ecce-localdata ecce-site-admin mocomp
910948 autosym getfrag genmol genmollat cleansym symops)
949+ if (NOT WIN32 )
950+ list (APPEND ECCE_CLI_APPS ecce-flock)
951+ endif ()
952+
953+ if (WIN32 )
954+ # GUI subsystem: no console window opens behind the apps. The command-line
955+ # programs (ECCE_CLI_APPS, the parsers) keep theirs.
956+ foreach (_app ${ECCE_GUI_APPS} )
957+ if (TARGET ${_app} )
958+ set_target_properties (${_app} PROPERTIES WIN32_EXECUTABLE ON )
959+ endif ()
960+ endforeach ()
961+ endif ()
911962
912963install (TARGETS ${ECCE_GUI_APPS} ${ECCE_CLI_APPS} RUNTIME DESTINATION bin
913964 COMPONENT client)
@@ -1691,10 +1742,12 @@ add_executable(session_key_test tests/session/session_key_test.C)
16911742target_link_libraries (session_key_test PRIVATE ecceutil )
16921743add_test (NAME session-key COMMAND session_key_test
16931744 ${CMAKE_SOURCE_DIR } /packaging/gateway/ecce-session-lib.sh )
1745+ if (NOT WIN32 ) # POSIX-only test programs
16941746add_executable (session_lease_test tests/session/session_lease_test.C )
16951747target_link_libraries (session_lease_test PRIVATE ecceutil )
16961748add_test (NAME session-lease COMMAND session_lease_test
16971749 ${CMAKE_SOURCE_DIR } /packaging/gateway/ecce-session-lib.sh )
1750+ endif ()
16981751add_test (NAME session-display-gate COMMAND bash
16991752 ${CMAKE_SOURCE_DIR } /tests/session/display_gate.sh ${CMAKE_SOURCE_DIR } )
17001753set_tests_properties (session-display-gate PROPERTIES SKIP_RETURN_CODE 77)
@@ -1703,6 +1756,7 @@ set_tests_properties(session-display-gate PROPERTIES SKIP_RETURN_CODE 77)
17031756# socket; checks delivery, not just acknowledgement. "auth" is the same on
17041757# a TCP broker with two accounts and the shipped access rules. SKIPs (77)
17051758# without the mosquitto binary.
1759+ if (NOT WIN32 )
17061760add_executable (mqtt_test tests/mqtt/mqtt_test.C )
17071761target_include_directories (mqtt_test PRIVATE ${XercesC_INCLUDE_DIRS} )
17081762target_link_libraries (mqtt_test PRIVATE ecceutil ${XercesC_LIBRARIES} )
@@ -1714,6 +1768,7 @@ if(TARGET ecce_users_auth)
17141768 set_tests_properties (mqtt-auth-plugin PROPERTIES TIMEOUT 120 SKIP_RETURN_CODE 77)
17151769endif ()
17161770set_tests_properties (mqtt mqtt-auth PROPERTIES TIMEOUT 120 SKIP_RETURN_CODE 77)
1771+ endif ()
17171772
17181773# tests/tls -- https data-server client (#236): pinned certificate, CA mode
17191774# with host-name check, certificate rejection, no fallback to plain http.
@@ -1923,10 +1978,18 @@ if(PYTHON3_EXECUTABLE)
19231978 set_tests_properties (filedsi PROPERTIES TIMEOUT 300)
19241979
19251980 # tests/transport -- DirectTransport against a real /bin/sh (#204).
1926- add_executable (testTransport tests/transport/testTransport.C )
1927- target_link_libraries (testTransport PRIVATE eccercmd ecceutil )
1928- add_test (NAME transport COMMAND testTransport )
1929- set_tests_properties (transport PROPERTIES TIMEOUT 120)
1981+ if (NOT WIN32 )
1982+ add_executable (testTransport tests/transport/testTransport.C )
1983+ target_link_libraries (testTransport PRIVATE eccercmd ecceutil )
1984+ add_test (NAME transport COMMAND testTransport )
1985+ set_tests_properties (transport PROPERTIES TIMEOUT 120)
1986+ endif ()
1987+
1988+ # Process launch (POSIX fork/exec and the Windows CreateProcess path, #133).
1989+ add_executable (testWinProcess tests/transport/testWinProcess.C )
1990+ target_link_libraries (testWinProcess PRIVATE eccercmd ecceutil )
1991+ add_test (NAME transport_process COMMAND testWinProcess )
1992+ set_tests_properties (transport_process PROPERTIES TIMEOUT 180)
19301993
19311994 # RCommand on a local machine against results recorded from the old pty
19321995 # path (#204).
@@ -1994,6 +2057,9 @@ if(PYTHON3_EXECUTABLE)
19942057 eccewxguicomm eccewxgui eccecomm eccercmd eccedsi eccedav eccecipc
19952058 eccefaces eccexml eccetdat ecceutil ${wxWidgets_LIBRARIES}
19962059 ${XercesC_LIBRARIES} )
2060+ if (WIN32 ) # GNU ld resolves static libraries in order (#133)
2061+ target_link_libraries (tailwindow PRIVATE "$<LINK_GROUP :RESCAN ,eccewxguicomm ;eccewxgui ;eccecomm ;eccercmd ;eccedsi ;eccedav ;eccecipc ;eccefaces ;eccexml ;eccetdat ;ecceutil >" ${XercesC_LIBRARIES} )
2062+ endif ()
19972063 add_test (NAME transport_tail_window
19982064 COMMAND ${CMAKE_CURRENT_SOURCE_DIR } /tests/transport/tail_window_test.sh
19992065 $<TARGET_FILE :tailwindow > ${CMAKE_CURRENT_SOURCE_DIR } )
0 commit comments