Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSVC support; [.github/workflows/cmake.yml] Add macOS and Windows building + testing #282

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e655032
[.github/workflows/cmake.yml] Add macOS and Windows building + testing
SamuelMarks Nov 25, 2021
cf1f760
[.github/workflows/cmake.yml] Bifurcate into macOS & Linux and Window…
SamuelMarks Nov 25, 2021
a7df780
[.github/workflows/cmake.yml] Install gettext with vcpkg; use cmd on …
SamuelMarks Nov 25, 2021
34c8c7d
[CMakeLists.txt] Switch for Cygwin and MSVC support; [src/libfswatch/…
SamuelMarks Nov 25, 2021
b0ce833
[.github/workflows/cmake.yml] Rework caching name ; [src/libfswatch/c…
SamuelMarks Nov 25, 2021
891128b
[libfswatch/CMakeLists.txt] Add `source_group`s ; [.github/workflows/…
SamuelMarks Nov 25, 2021
e90581c
[libfswatch/CMakeLists.txt] Move `cygwin_paths` to else block of `if …
SamuelMarks Nov 25, 2021
facc417
[libfswatch/src/libfswatch/c++/{path_utils.hpp,{fen,inotify,kqueue,po…
SamuelMarks Nov 25, 2021
2cb8e87
[libfswatch\src\libfswatch\c++\windows] Port to MSVC; [cmake\FindPthr…
SamuelMarks Nov 29, 2021
719d31a
[.github\workflows\cmake.yml] Set `VCPKG_TARGET_TRIPLET`; [fswatch\sr…
SamuelMarks Dec 9, 2021
4cb417a
[fswatch/src/fswatch.cpp] Use raw `signal` instead of `sigaction` on …
SamuelMarks Dec 9, 2021
e2d0825
[fswatch/src/fswatch.cpp] Make `signal` calls equivalent to `sigaction`
SamuelMarks Dec 10, 2021
146d7d2
[fswatch/src/fswatch.cpp] Add missing type to `tm_time`
SamuelMarks Dec 10, 2021
5910ad4
[README.windows] Add MSVC instructions
SamuelMarks Dec 10, 2021
0c717c5
[fswatch\src\windows\getopt.c] Use `_dupenv_s` instead of `getenv` on…
SamuelMarks Dec 23, 2021
6b273e1
Merge remote-tracking branch 'origin/multi-os-ci' into multi-os-ci
SamuelMarks Dec 23, 2021
f5b9044
[**/CMakeLists.txt] Quote all vars
SamuelMarks Jan 14, 2022
9576be7
[m4/{lib}fswatch_version.m4,po/fswatch.pot,CMakeLists.txt] Bump version
SamuelMarks Jan 15, 2022
ee32afd
[{fswatch/src,libfswatch}/CMakeLists.txt] Fix iconv support within vcpkg
SamuelMarks Jan 15, 2022
9e0e2c4
[{fswatch/src,fswatch/src/windows,libfswatch}/CMakeLists.txt] Fix `in…
SamuelMarks Jan 15, 2022
5ffbbec
[error.h => fsw_error.h] Fix for vcpkg "Restricted headers paths are …
SamuelMarks Jan 15, 2022
025ec52
[fswatch/src/CMakeLists.txt] Explicitly check `VCPKG_LIBRARY_LINKAGE`…
SamuelMarks Jan 15, 2022
f788575
[**/CMakeLists.txt] Major fixup and refactor to make targets dependen…
SamuelMarks Jan 16, 2022
271eb5a
[libfswatch\src\libfswatch\c\*.h] Export symbols; comment macro closu…
SamuelMarks Jan 16, 2022
aeee7fc
Major refactor adding a `CMakeLists.txt` to every directory with a .h…
SamuelMarks Jan 17, 2022
f2c98cc
[CMakeLists.txt] `generate_export_header` to the default, i.e., ${CMA…
SamuelMarks Jan 17, 2022
c24f9de
[CMakeLists.txt] Set `/EHsc` on MSVC; [libfswatch\src\libfswatch\c++\…
SamuelMarks Jan 17, 2022
ad8228b
[*.cpp,*.hpp] Remove `#include <windows.h>` in favour of including on…
SamuelMarks Jan 18, 2022
045f44c
[libfswatch/src/libfswatch/c/CMakeLists.txt] Guard `"/EHsc"` with `MS…
SamuelMarks Jan 18, 2022
4de20b8
[CMakeLists.txt] Switch from `CMAKE_HOST_SYSTEM_PROCESSOR` to `CMAKE_…
SamuelMarks Jan 19, 2022
a40926c
[CMakeLists.txt] Fallback `TARGET_ARCH` to `CMAKE_C_COMPILER_ARCHITEC…
SamuelMarks Jan 19, 2022
d30c92f
[CMakeLists.txt] Carefully parse `TARGET_ARCH` so that its choice mat…
SamuelMarks Jan 19, 2022
ca7c03d
[CMakeLists.txt] `TARGET_ARCH` now matches what Windows header looks …
SamuelMarks Jan 19, 2022
99d52cb
[**CMakeLists.txt] Export targets for consumption by `find_package`
SamuelMarks Feb 5, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 56 additions & 5 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ env:

jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally
# well on Windows or Mac. You can convert this to a matrix build if you need
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, ubuntu-latest]

steps:
- uses: actions/checkout@v2
Expand All @@ -35,3 +34,55 @@ jobs:
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest -C ${{env.BUILD_TYPE}}

build_windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2

- name: Cache vcpkg
uses: actions/cache@v2
env:
cache-name: cache-vcpkg-d8b9ae5
with:
path: ${{ github.workspace }}/vcpkg
key: ${{ runner.os }}-vcpkg-${{ env.cache-name }}
restore-keys: ${{ runner.os }}-vcpkg-${{ env.cache-name }}

- name: clone and bootstrap vcpkg
run: |
IF NOT EXIST "vcpkg" (
git clone --depth=360 https://github.com/microsoft/vcpkg
cd "vcpkg"
git reset --hard d8b9ae5
.\bootstrap-vcpkg.bat
)
shell: cmd

- name: Install dependencies with vcpkg
run: |
cd "%GITHUB_WORKSPACE%\vcpkg"
IF NOT EXIST "buildtrees\pthreads" (
.\vcpkg --version
.\vcpkg install --triplet "%RUNNER_ARCH%-%RUNNER_OS%" pthreads gettext
)
shell: cmd

- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: |
cmake -B "%GITHUB_WORKSPACE%\build" -DCMAKE_BUILD_TYPE="%BUILD_TYPE%" -DVCPKG_TARGET_TRIPLET="%RUNNER_ARCH%-%RUNNER_OS%" -DCMAKE_TOOLCHAIN_FILE="vcpkg\scripts\buildsystems\vcpkg.cmake"
shell: cmd

- name: Build
# Build your program with the given configuration
run: cmake --build "%GITHUB_WORKSPACE%\build" --config "%BUILD_TYPE%"
shell: cmd

- name: Test
working-directory: ${{github.workspace}}/build
# Execute tests defined by the CMake configuration.
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
run: ctest -C "%BUILD_TYPE%"
shell: cmd
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ fswatch_test
.libs
*.lo
*.o
cmake-build-debug/
*build*/
dist/

# Documentation
Expand Down Expand Up @@ -134,3 +134,4 @@ docker/debian-testing/Dockerfile

# Output files
man/fswatch.7
*_export.h
41 changes: 30 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
# this program. If not, see <http://www.gnu.org/licenses/>.
#
cmake_minimum_required(VERSION 3.8)
project(fswatch VERSION 1.16.0 LANGUAGES C CXX)
project(fs_watch VERSION 1.17.0 LANGUAGES C CXX)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?


#@formatter:off
set(PACKAGE "${PROJECT_NAME}")
set(PACKAGE "fswatch")
set(PACKAGE_NAME "${PACKAGE}")
set(PACKAGE_VERSION "${PROJECT_VERSION}-develop")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_STRING "${PACKAGE} ${PACKAGE_VERSION}")
set(PACKAGE_AUTHOR "[email protected]")
set(PACKAGE_BUGREPORT "${PACKAGE_AUTHOR}")
set(PACKAGE_TARNAME "${PACKAGE}")
Expand All @@ -29,9 +29,18 @@ set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/share/locale" CACHE FILEPATH "loc
#@formatter:on

set(CMAKE_CXX_STANDARD 11)
if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
endif (MSVC)

# control where the static and shared libraries are built so that on windows
# we don't need to tinker with the path to run the executable
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")

# Add option to choose between shared and static libraries
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not change defaults people is relying on: the point of this setting is for anybody to override


# include modules
include(FindGettext)
Expand All @@ -44,7 +53,10 @@ include(CheckCXXSymbolExists)
check_include_file_cxx(getopt.h HAVE_GETOPT_H)

if (HAVE_GETOPT_H)
check_cxx_symbol_exists(getopt_long getopt.h HAVE_GETOPT_LONG)
check_cxx_symbol_exists(getopt_long "getopt.h" HAVE_GETOPT_LONG)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain this change with the else block?

else ()
set(HAVE_GETOPT_H 1)
set(HAVE_GETOPT_LONG 1)
endif (HAVE_GETOPT_H)

# If both gettext and libintl are found, define the USE_NLS variable to
Expand All @@ -60,17 +72,24 @@ if (USE_NLS)
set(LINGUAS en en@quot en@boldquot it es)

foreach (language ${LINGUAS})
configure_file(${PROJECT_SOURCE_DIR}/po/${language}.po ${PROJECT_BINARY_DIR}/${language}.po COPYONLY)
configure_file("${PROJECT_SOURCE_DIR}/po/${language}.po" "${PROJECT_BINARY_DIR}/${language}.po" COPYONLY)
endforeach ()

gettext_process_pot_file(po/${PACKAGE}.pot ALL INSTALL_DESTINATION share/locale LANGUAGES ${LINGUAS})
endif ()
gettext_process_pot_file("po/${PACKAGE}.pot" ALL INSTALL_DESTINATION "${LOCALEDIR}" LANGUAGES ${LINGUAS})
endif (USE_NLS)

# checks
check_cxx_symbol_exists(atexit cstdlib HAVE_ATEXIT)
check_cxx_symbol_exists(setlocale clocale HAVE_SETLOCALE)
check_cxx_symbol_exists(strtod cstdlib HAVE_STRTOD)

add_subdirectory(libfswatch)
add_subdirectory(fswatch/src)
add_subdirectory(test/src)
option(BUILD_FSWATCH "Build ${PROJECT_NAME}" ON)
option(BUILD_TESTS "Build ${PROJECT_NAME} tests" ON)

add_subdirectory("libfswatch")
if (BUILD_FSWATCH)
add_subdirectory("fswatch/src")
endif (BUILD_FSWATCH)
if (BUILD_TESTS)
add_subdirectory("test/src")
endif (BUILD_TESTS)
36 changes: 34 additions & 2 deletions README.windows
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,47 @@ Introduction

This file describes the steps required to build fswatch on Windows. fswatch was
born as a POSIX application and the Windows monitor has been developed trying to
reduce the dependencies on the Windows API at a minimum. To fulfill this goal,
a dependency to Cygwin has been introduced.
reduce the dependencies on the Windows API at a minimum.

There are two variants to fulfill this goal: Cygwin and Microsoft Visual Studio.

Windows has historically provided multiple versions of the same API for single
byte and multibyte character sets. We have decided to only support the
multibyte API: the Windows monitor will thus not build on Windows system
supporting only the single-byte APIs. In this case, the only available monitor
on the Windows OS will be the poll monitor.

Microsoft Visual Studio (MSVC)
==============================

The MSVC variant is configured through CMake and is fully native on Windows.

The three dependencies to get it working are:

0. CMake: https://cmake.org
1. pthreads: https://sourceforge.net/projects/pthreads4w
2. gettext: https://mlocati.github.io/articles/gettext-iconv-windows.html

The pthreads and gettext dependencies are most easily acquirable through use
of a package manager, like Microsoft's open-source cross-platform vcpkg

git clone --depth=1 "https://github.com/microsoft/vcpkg"
cd "vcpkg"
:: Replace "[dir]" in later command with this dir
.\bootstrap-vcpkg.bat
.\vcpkg install --triplet "x64-windows" "pthreads" "gettext"

Then the project can be configured and compiled & built with:

cd <fswatch_directory>
cmake -B "build" \
-DCMAKE_BUILD_TYPE="Debug" \
-DVCPKG_TARGET_TRIPLET="x64-windows" \
-DCMAKE_TOOLCHAIN_FILE="[dir]\vcpkg\scripts\buildsystems\vcpkg.cmake"
cmake --build "build" --config "Debug"

[everything that follows is only applicable to Cygwin]

Cygwin
======

Expand Down
99 changes: 99 additions & 0 deletions cmake/FindPthreads.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# From: https://github.com/healpy/cfitsio/blob/d02e7ce/FindPthreads.cmake
# - Find the Pthreads library
# This module searches for the Pthreads library (including the
# pthreads-win32 port).
#
# This module defines these variables:
#
# PTHREADS_FOUND
# True if the Pthreads library was found
# PTHREADS_LIBRARY
# The location of the Pthreads library
# PTHREADS_INCLUDE_DIR
# The include path of the Pthreads library
# PTHREADS_DEFINITIONS
# Preprocessor definitions to define
#
# This module responds to the PTHREADS_EXCEPTION_SCHEME
# variable on Win32 to allow the user to control the
# library linked against. The Pthreads-win32 port
# provides the ability to link against a version of the
# library with exception handling. IT IS NOT RECOMMENDED
# THAT YOU USE THIS because most POSIX thread implementations
# do not support stack unwinding.
#
# PTHREADS_EXCEPTION_SCHEME
# C = no exceptions (default)
# (NOTE: This is the default scheme on most POSIX thread
# implementations and what you should probably be using)
# CE = C++ Exception Handling
# SE = Structure Exception Handling (MSVC only)
#

#
# Define a default exception scheme to link against
# and validate user choice.
#
IF(NOT DEFINED PTHREADS_EXCEPTION_SCHEME)
# Assign default if needed
SET(PTHREADS_EXCEPTION_SCHEME "C")
ELSE(NOT DEFINED PTHREADS_EXCEPTION_SCHEME)
# Validate
IF(NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "C" AND
NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "CE" AND
NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")

MESSAGE(FATAL_ERROR "See documentation for FindPthreads.cmake, only C, CE, and SE modes are allowed")

ENDIF(NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "C" AND
NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "CE" AND
NOT PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")

IF(NOT MSVC AND PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")
MESSAGE(FATAL_ERROR "Structured Exception Handling is only allowed for MSVC")
ENDIF(NOT MSVC AND PTHREADS_EXCEPTION_SCHEME STREQUAL "SE")

ENDIF(NOT DEFINED PTHREADS_EXCEPTION_SCHEME)

#
# Find the header file
#
FIND_PATH(PTHREADS_INCLUDE_DIR pthread.h)

#
# Find the library
#
SET(names)
IF(MSVC)
SET(names
pthreadV${PTHREADS_EXCEPTION_SCHEME}2
pthread
)
ELSEIF(MINGW)
SET(names
pthreadG${PTHREADS_EXCEPTION_SCHEME}2
pthread
)
ELSE(MSVC) # Unix / Cygwin / Apple
SET(names pthread)
ENDIF(MSVC)

FIND_LIBRARY(PTHREADS_LIBRARY ${names}
DOC "The Portable Threads Library")

IF(PTHREADS_INCLUDE_DIR AND PTHREADS_LIBRARY)
SET(PTHREADS_FOUND true)
SET(PTHREADS_DEFINITIONS -DHAVE_PTHREAD_H)
SET(PTHREADS_INCLUDE_DIRS ${PTHREADS_INCLUDE_DIR})
SET(PTHREADS_LIBRARIES ${PTHREADS_LIBRARY})
ENDIF(PTHREADS_INCLUDE_DIR AND PTHREADS_LIBRARY)

IF(PTHREADS_FOUND)
IF(NOT PTHREADS_FIND_QUIETLY)
MESSAGE(STATUS "Found Pthreads: ${PTHREADS_LIBRARY}")
ENDIF(NOT PTHREADS_FIND_QUIETLY)
ELSE(PTHREADS_FOUND)
IF(PTHREADS_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find the Pthreads Library")
ENDIF(PTHREADS_FIND_REQUIRED)
ENDIF(PTHREADS_FOUND)
49 changes: 34 additions & 15 deletions fswatch/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,41 @@
# You should have received a copy of the GNU General Public License along with
# this program. If not, see <http://www.gnu.org/licenses/>.
#
set(FSWATCH_SRC_FILES
fswatch.cpp
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This applies to many other places: why are we quoting strings when not required?

fswatch.hpp
gettext.h)
set(EXEC_NAME "fswatch_bin")
set(Header_Files "${PACKAGE}.hpp" "gettext.h")
source_group("${PACKAGE} Header Files" FILES "${Header_Files}")

add_executable(fswatch ${FSWATCH_SRC_FILES})
set(Source_Files "${PACKAGE}.cpp")
source_group("${PACKAGE} Source Files" FILES "${Source_Files}")

# check for gettext and libintl
if (USE_NLS)
if (Intl_LIBRARIES)
target_link_libraries(fswatch PRIVATE ${Intl_LIBRARIES})
endif ()
endif ()
add_executable("${EXEC_NAME}" "${Header_Files}" "${Source_Files}")

set_target_properties(
"${EXEC_NAME}"
PROPERTIES
LINKER_LANGUAGE
CXX
)

if (MSVC)
add_subdirectory("./windows")
target_link_libraries("${EXEC_NAME}" PRIVATE "getopt")
endif (MSVC)

target_include_directories(fswatch PUBLIC ../.. .)
target_include_directories(fswatch PRIVATE ${PROJECT_BINARY_DIR})
target_link_libraries(fswatch PUBLIC libfswatch)
target_link_libraries("${EXEC_NAME}" PUBLIC "libfswatch")

install(TARGETS fswatch DESTINATION bin)
if (DEFINED VCPKG_LIBRARY_LINKAGE)
if (VCPKG_LIBRARY_LINKAGE STREQUAL "static")
set(BUILD_IS_STATIC "ON")
endif (VCPKG_LIBRARY_LINKAGE STREQUAL "static")
elseif (BUILD_SHARED_LIBS)
set(BUILD_IS_STATIC "OFF")
endif ()

if (BUILD_IS_STATIC STREQUAL "ON")
set(bin_install_dir "${CURRENT_PACKAGES_DIR}")
else ()
install(FILES ${Header_Files} DESTINATION "include")
set(bin_install_dir "bin")
endif ()
install(TARGETS "${EXEC_NAME}" DESTINATION "${bin_install_dir}")
Loading