diff --git a/.gitignore b/.gitignore index 7d7555e..5e1e016 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,32 @@ -*.obj -*.dll.manifest -*.dll -*.exe.manifest -*.exe -*.lib -*.pdb -*.ilk -*.exp -version.res -tests/*.pass -tests/*.bench -tests/pthread.h -tests/sched.h -tests/semaphore.h -tests/benchlib.o -tests/SIZES.* -tests/*.log +*.dll +*.dll.manifest +*.exe +*.exe.manifest +*.exp +*.ilk +*.lib +*.obj +*.pdb +*.un~ +*~ +.vscode /.project -build -PTHREADS-BUILT -.vscode \ No newline at end of file +autom4te.cache +build +cmake-build +config.h.in +config.log +config.status +configure +GNUmakefile +PTHREADS-BUILT +tests/*.bench +tests/*.log +tests/*.pass +tests/benchlib.o +tests/GNUmakefile +tests/pthread.h +tests/sched.h +tests/semaphore.h +tests/SIZES.* +version.res diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..c4e22c7 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,108 @@ +language: shell + +os: windows + +env: + - BUILD_TYPE=Debug VS2017=amd64 TESTING=OFF + - BUILD_TYPE=Release VS2017=amd64 TESTING=OFF + - BUILD_TYPE=MinSizeRel VS2017=amd64 TESTING=OFF + - BUILD_TYPE=MinSizeRel VS2017=amd64 TESTING=OFF + + - BUILD_TYPE=Debug VS2017=amd64_x86 TESTING=OFF + - BUILD_TYPE=Release VS2017=amd64_x86 TESTING=OFF + - BUILD_TYPE=MinSizeRel VS2017=amd64_x86 TESTING=OFF + - BUILD_TYPE=MinSizeRel VS2017=amd64_x86 TESTING=OFF + + #- BUILD_TYPE=Debug VS2017=amd64_arm TESTING=OFF + #- BUILD_TYPE=Release VS2017=amd64_arm TESTING=OFF + #- BUILD_TYPE=MinSizeRel VS2017=amd64_arm TESTING=OFF + #- BUILD_TYPE=MinSizeRel VS2017=amd64_arm TESTING=OFF + + #- BUILD_TYPE=Debug VS2017=amd64_arm64 TESTING=OFF + #- BUILD_TYPE=Release VS2017=amd64_arm64 TESTING=OFF + #- BUILD_TYPE=MinSizeRel VS2017=amd64_arm64 TESTING=OFF + #- BUILD_TYPE=MinSizeRel VS2017=amd64_arm64 TESTING=OFF + +#install: + #- DEPS_DIR="${TRAVIS_BUILD_DIR}/deps" + #- mkdir ${DEPS_DIR} && cd ${DEPS_DIR} && pwd + #- travis_retry wget --no-check-certificate https://cmake.org/files/v3.11/cmake-3.11.0-win64-x64.zip + #- echo "615dfb0813443c1ff56ae0e9d6dbfc61 *cmake-3.11.0-win64-x64.zip" > cmake_md5.txt + #- md5sum -c cmake_md5.txt + #- 7z x -y cmake-3.11.0-win64-x64.zip + #- PATH=${DEPS_DIR}/cmake-3.11.0-win64-x64:${DEPS_DIR}/cmake-3.11.0-win64-x64/bin:$PATH + +before_script: + + # document the version + #- cmake --version + #- cmake --help + + # set enviromental variables + - ls "/c/Progra~2/Microsoft Visual Studio/2017/BuildTools/VC/Auxiliary/Build/" + #vcvars32.bat + #vcvars64.bat + #vcvarsall.bat + #vcvarsamd64_arm.bat + #vcvarsamd64_arm64.bat + #vcvarsamd64_x86.bat + #vcvarsx86_amd64.bat + #vcvarsx86_arm.bat + #vcvarsx86_arm64.bat + #- printenv + + #- msvcenv="__msvc.bat" + #- echo "@echo off" > "$msvcenv" + #- echo "call /c/Progra~2/Microsoft\ Visual\ Studio/2017/BuildTools/VC/Auxiliary/Build/vcvarsall.bat ${VS2017}" >> "$msvcenv" + #- echo "set" >> "$msvcenv" + #- cmd "/K $msvcenv" + # > "$msenv.tmp" + + #- cat "$msvcenv" + #- rm -f "$msvcenv" + + - printenv + + #- cat "$msenv.tmp" + + #- grep -e '^PATH=' "$msenv.tmp" | \ + #sed \ + #-e 's/\(.*\)=\(.*\)/export \1="\2:$PATH"/g' \ + #-e 's/\([a-zA-Z]\):[\\\/]/\/\1\//g' \ + #-e 's/\\/\//g' -e 's/;\//:\//g' + # > "$msenv" + #- grep -e '^(INCLUDE|LIB|LIBPATH)=' "$msenv.tmp" | sed -e 's/\(.*\)=\(.*\)/export \1="\2"/g' >> "$msenv" + #- rm "$msenv.tmp" + #- cat "$msenv" + #- source "$msenv" + + #- printenv + + - call "c:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars32.bat" ${VS2017} + #- cmd "/K C:\\Progra~2\\Microsoft\ Visual\ Studio\\2017\\BuildTools\\VC\\Auxiliary\\Build\\vcvarsall.bat ${VS2017}" + #- /c/Progra~2/Microsoft\ Visual\ Studio/2017/BuildTools/VC/Auxiliary/Build/vcvarsall.bat ${VS2017} > "$msenv.tmp" + #- cat "$msenv.tmp" + #- printenv + + # Visual Studio 2015 + #- ls "/c/Progra~2/Microsoft Visual Studio 14.0/VC/" + #- /c/Progra~2/Microsoft\ Visual\ Studio\ 14.0/VC/vcvarsall.bat amd64 + + # generate the build files + - cd ${TRAVIS_BUILD_DIR} && mkdir build && cd build + - cmake -G"NMake Makefiles" -DCMAKE_VERBOSE_MAKEFILE=FALSE -DCMAKE_BUILD_TYPE=${BUILD_TYPE} + #-DBUILD_NUMBER=${TRAVIS_BUILD_NUMBER} + #-DDIST_ROOT="${TRAVIS_BUILD_DIR}/build/dist" + #-DENABLE_TESTS=${TESTING} + #.. +script: + - cmake --build . --config ${BUILD_TYPE} --target install + +addons: + coverity_scan: + project: + name: “jwinarske/pthreads4w" + notification_email: joel.winarske@gmail.com + build_command_prepend: "mkdir build && cd build && cmake -DCMAKE_VERBOSE_MAKEFILE=TRUE -DDCMAKE_INSTALL_PREFIX=`pwd`/dist .." + build_command: "cmake --build . --target install" + branch_pattern: coverity_scan diff --git a/CMakeLists.txt b/CMakeLists.txt index d749071..654122f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,28 +1,44 @@ -cmake_minimum_required(VERSION 3.11) +cmake_minimum_required(VERSION 3.14) -if(NOT CMAKE_BUILD_TYPE) +set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_SOURCE_DIR}/cmake") + +include (CheckIncludeFile) +include (CheckFunctionExists) +include (CheckSymbolExists) +include (CheckTypeSize) +include (config_h_in) +include (get_version) + +project(pthreads4w VERSION ${PTHREADS4W_VERSION} LANGUAGES C CXX) + +set(PTW32_VER ${PROJECT_VERSION_MAJOR}${EXTRAVERSION}) + +if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "MinSizeRel" CACHE STRING "Choose the type of build, options are: Debug, Release, or MinSizeRel." FORCE) message(STATUS "No build type specified, defaulting to MinSizeRel.") endif() -set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_CURRENT_SOURCE_DIR}/cmake") - -include (get_version) - +message(STATUS "") +message(STATUS "") message(STATUS "Generator ......... ${CMAKE_GENERATOR}") -message(STATUS "Build Type ........ ${CMAKE_BUILD_TYPE}") +if(NOT CMAKE_CONFIGURATION_TYPES) + set(the_build_type ${CMAKE_BUILD_TYPE}) +else () + set(the_build_type "Generator-defined, one of ${CMAKE_CONFIGURATION_TYPES}") +endif () +message(STATUS "Build Type ........ ${the_build_type}") message(STATUS "Version ........... ${PTHREADS4W_VERSION}") -project(pthreads4w VERSION ${PTHREADS4W_VERSION} LANGUAGES C) - -set(PTW32_VER ${PROJECT_VERSION_MAJOR}${EXTRAVERSION}) -set(CMAKE_DEBUG_POSTFIX d) +## Deprecated +## set(CMAKE_DEBUG_POSTFIX d) # Uncomment this if config.h defines RETAIN_WSALASTERROR #set(XLIBS wsock32.lib) -include_directories(.) +# Initial include path set. Look in the build directory first, where the +# generated config.h resides, before looking in the source directory. +include_directories("${CMAKE_BINARY_DIR}/" "${CMAKE_SOURCE_DIR}/") ################################# # Target Arch # @@ -30,125 +46,203 @@ include_directories(.) include (target_arch) get_target_arch(TARGET_ARCH) - +set(build_defines "") if(${TARGET_ARCH} STREQUAL "ARM") - add_definitions(-D__PTW32_ARCHARM -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1) + set(build_defines __PTW32_ARCHARM _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1) elseif(${TARGET_ARCH} STREQUAL "ARM64") - add_definitions(-D__PTW32_ARCHARM64 -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1) + set(build_defines __PTW32_ARCHARM64 _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1) elseif(${TARGET_ARCH} STREQUAL "x86_64") - add_definitions(-D__PTW32_ARCHAMD64) + set(build_defines __PTW32_ARCHAMD64) elseif(${TARGET_ARCH} STREQUAL "x86") - add_definitions(-D__PTW32_ARCHX86) + set(build_defines __PTW32_ARCHX86) elseif(${TARGET_ARCH} STREQUAL "x64") - add_definitions(-D__PTW32_ARCHX64) + set(build_defines __PTW32_ARCHX64) else() MESSAGE(ERROR "\"${TARGET_ARCH}\" not supported in version.rc") endif() + message(STATUS "Target ............ ${TARGET_ARCH}") +set(CMAKE_C_LIBRARY_ARCHITECTURE ${TARGET_ARCH}) +set(CMAKE_CXX_LIBRARY_ARCHITECTURE ${TARGET_ARCH}) +set(CMAKE_LIBRARY_ARCHITECTURE ${TARGET_ARCH}) if(MSVC) message(STATUS "MSVC Version ...... ${MSVC_VERSION}") +else() + message(STATUS "C Compiler ID ..... ${CMAKE_C_COMPILER_ID}") endif() ################################# # Install Path # ################################# -if(DIST_ROOT) - set(CMAKE_INSTALL_PREFIX "${DIST_ROOT}") -else() - set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/PTHREADS-BUILT") +if (DIST_ROOT) + set(CMAKE_INSTALL_PREFIX "${DIST_ROOT}") +elseif (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/PTHREADS-BUILT" CACHE PATH "Install path prefix (default)" FORCE) endif() -message(STATUS "Install Path ${CMAKE_INSTALL_PREFIX}") +message(STATUS "Installing to ${CMAKE_INSTALL_PREFIX}") -set(DLLDEST ${CMAKE_INSTALL_PREFIX}/${TARGET_ARCH}/${CMAKE_BUILD_TYPE}/bin) -set(LIBDEST ${CMAKE_INSTALL_PREFIX}/${TARGET_ARCH}/${CMAKE_BUILD_TYPE}/lib) -set(HDRDEST ${CMAKE_INSTALL_PREFIX}/${TARGET_ARCH}/${CMAKE_BUILD_TYPE}/include) -set(TESTDEST ${CMAKE_INSTALL_PREFIX}/${TARGET_ARCH}/${CMAKE_BUILD_TYPE}/test) +message(STATUS "") +message(STATUS "") + +################################# +# configuration features # +################################# +check_include_file(errno.h HAVE_ERRNO_H) +check_include_file(inttypes.h HAVE_INTTYPES_H) +check_include_file(memory.h HAVE_MEMORY_H) +check_include_file(signal.h HAVE_SIGNAL_H) +check_include_file(stdint.h HAVE_STDINT_H) +check_include_file(stdlib.h HAVE_STDLIB_H) +check_include_file(strings.h HAVE_STRINGS_H) +check_include_file(string.h HAVE_STRING_H) +check_include_file(sys/stat.h HAVE_SYS_STAT_H) +check_include_file(sys/types.h HAVE_SYS_TYPES_H) +check_include_file(time.h HAVE_TIME_H) +check_include_file(unistd.h HAVE_UNISTD_H) +check_function_exists(calloc HAVE_CALLOC) +check_type_size(sigset_t HAVE_SIGSET_T) +check_type_size("struct timespec" HAVE_STRUCT_TIMESPEC) +check_symbol_exists(_beginthreadex process.h HAVE__BEGINTHREADEX) +check_symbol_exists(DuplicateHandle windows.h HAVE_DUPLICATEHANDLE) + +create_config_h_in() +configure_file("${CMAKE_BINARY_DIR}/config.h.in" "${CMAKE_BINARY_DIR}/config.h") ################################# # Defs # ################################# -add_definitions(-D__PTW32_BUILD_INLINED) if(MSVC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /errorReport:none /nologo ") # C++ Exceptions # (Note: If you are using Microsoft VC++6.0, the library needs to be built # with /EHa instead of /EHs or else cancellation won't work properly.) if(MSVC_VERSION EQUAL 1200) - set(VCEFLAGS "/EHa /TP ") + set(VCEFLAGS "/EHa" "/TP") else() - set(VCEFLAGS "/EHs /TP ") + set(VCEFLAGS "/EHs" "/TP") endif() - add_definitions(-DHAVE_CONFIG_H -D__PTW32_RC_MSC) - + set(build_defines ${build_defines} HAVE_CONFIG_H __PTW32_RC_MSC) +elseif (${CMAKE_C_COMPILER_ID} STREQUAL "GNU") + set(build_defines ${build_defines} HAVE_CONFIG_H) endif() + # Update filename with proper version info -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc @ONLY) +configure_file(${CMAKE_SOURCE_DIR}/cmake/version.rc.in ${CMAKE_BINARY_DIR}/version.rc @ONLY) ################################# # Libraries # ################################# -set(targ_suffix "") -if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") - set(targ_suffix ${CMAKE_DEBUG_POSTFIX}) -endif() -macro(shared_lib type def) +function(shared_lib type def) set(targ pthread${type}${PTW32_VER}) - add_library(${targ} SHARED pthread.c ${CMAKE_CURRENT_BINARY_DIR}/version.rc) - message(STATUS ${targ}) - target_compile_definitions(${targ} PUBLIC "-D${def}") - if(${type} STREQUAL "VCE") - set_target_properties(${targ} PROPERTIES COMPILE_FLAGS ${VCEFLAGS}) - endif() - if(${CMAKE_GENERATOR} MATCHES "Visual Studio") - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${targ}${targ_suffix}.dll DESTINATION ${DLLDEST}) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${targ}${targ_suffix}.lib DESTINATION ${LIBDEST}) - else() - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${targ}${targ_suffix}.dll DESTINATION ${DLLDEST}) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${targ}${targ_suffix}.lib DESTINATION ${LIBDEST}) - endif() -endmacro() -macro(static_lib type def) + if (${type} STREQUAL "VCE") + add_library(${targ} SHARED pthread.cxx ${CMAKE_BINARY_DIR}/version.rc) + set_target_properties(${targ} PROPERTIES LINKER_LANGUAGE CXX) + target_compile_options(${targ} PUBLIC "${VCEFLAGS}") + elseif (${CMAKE_C_COMPILER_ID} STREQUAL "GNU") + add_library(${targ} SHARED pthread.cxx ${CMAKE_BINARY_DIR}/version.rc) + target_compile_options(${targ} PRIVATE "-mthreads") + if (${type} STREQUAL "GCE") + set_target_properties(${targ} PROPERTIES LINKER_LANGUAGE CXX) + target_compile_options(${targ} PRIVATE "-xc++") + target_link_libraries(${targ} stdc++) + target_link_options(${targ} PRIVATE "-shared-libgcc") + endif (${type} STREQUAL "GCE") + else () + add_library(${targ} SHARED pthread.c ${CMAKE_BINARY_DIR}/version.rc) + endif (${type} STREQUAL "VCE") + + target_compile_definitions(${targ} PRIVATE ${def} ${build_defines} __PTW32_BUILD_INLINED) + if (MSVC) + # Set resource compiler definition... + target_compile_definitions(${targ} PRIVATE __PTW32_RC_MSC) + endif () + set_target_properties(${targ} PROPERTIES DEBUG_POSTFIX "d") + + message(STATUS "Shared library ${targ}") + + install( + TARGETS ${targ} + ARCHIVE # DESTINATION ${TARGET_ARCH}/${CONFIG}/lib + LIBRARY # DESTINATION ${TARGET_ARCH}/${CONFIG}/lib + RUNTIME # DESTINATION ${TARGET_ARCH}/${CONFIG}/bin + ) + + install( + FILES $ + CONFIGURATION Debug + DESTINATION lib + OPTIONAL + ) +endfunction() + +function(static_lib type def) set(targ libpthread${type}${PTW32_VER}) - add_library(${targ} STATIC pthread.c) - message(STATUS ${targ}) - target_compile_definitions(${targ} PUBLIC "-D${def}" -D__PTW32_STATIC_LIB) + if(${type} STREQUAL "VCE") - set_target_properties(${targ} PROPERTIES COMPILE_FLAGS ${VCEFLAGS}) + add_library(${targ} STATIC pthread.cxx) + target_compile_options(${targ} PRIVATE "/EHs") + elseif (${CMAKE_C_COMPILER_ID} STREQUAL "GNU") + if (${type} STREQUAL "GCE") + add_library(${targ} STATIC pthread.cxx) + target_compile_options(${targ} PRIVATE "-xc++") + target_link_libraries(${targ} stdc++) + target_link_options(${targ} PRIVATE "-shared-libgcc") + endif (${type} STREQUAL "GCE") + else () + add_library(${targ} STATIC pthread.c) endif() - if(${CMAKE_GENERATOR} MATCHES "Visual Studio") - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${targ}${targ_suffix}.lib DESTINATION ${LIBDEST}) - else() - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${targ}${targ_suffix}.lib DESTINATION ${LIBDEST}) - endif() -endmacro() - -shared_lib ( VCE __PTW32_CLEANUP_CXX ) -shared_lib ( VSE __PTW32_CLEANUP_SEH ) -shared_lib ( VC __PTW32_CLEANUP_C ) -static_lib ( VCE __PTW32_CLEANUP_CXX ) -static_lib ( VSE __PTW32_CLEANUP_SEH ) -static_lib ( VC __PTW32_CLEANUP_C ) + target_compile_definitions(${targ} PRIVATE "${def}" ${build_defines} __PTW32_STATIC_LIB __PTW32_BUILD_INLINED) + set_target_properties(${targ} PROPERTIES DEBUG_POSTFIX "d") + + message(STATUS "Static library ${targ}") + + install( + TARGETS ${targ} + ARCHIVE # DESTINATION ${TARGET_ARCH}/${CONFIG}/lib + LIBRARY # DESTINATION ${TARGET_ARCH}/${CONFIG}/lib + RUNTIME # DESTINATION ${TARGET_ARCH}/${CONFIG}/bin + ) +endfunction() + +if (MSVC) + shared_lib ( VCE __PTW32_CLEANUP_CXX ) + shared_lib ( VSE __PTW32_CLEANUP_SEH ) + shared_lib ( VC __PTW32_CLEANUP_C ) + + static_lib ( VCE __PTW32_CLEANUP_CXX ) + static_lib ( VSE __PTW32_CLEANUP_SEH ) + static_lib ( VC __PTW32_CLEANUP_C ) +elseif (${CMAKE_C_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_C_COMPILER_ID} STREQUAL "Clang") + ## NOTE: MinGW64 does support SEH exception handling, BUT it does not yet + ## have the MSVC keywords "__try", "__except" and "__finally". + shared_lib ( GCE __PTW32_CLEANUP_CXX ) + shared_lib ( GC __PTW32_CLEANUP_C ) + + static_lib ( GCE __PTW32_CLEANUP_CXX ) + static_lib ( GC __PTW32_CLEANUP_C ) +endif (MSVC) ################################# # Install # ################################# -install(FILES _ptw32.h pthread.h sched.h semaphore.h DESTINATION ${HDRDEST}) +install(FILES _ptw32.h pthread.h sched.h semaphore.h TYPE INCLUDE) ################################# # Test # ################################# -include (CTest) +option(ENABLE_TESTS "Enable Test code build" FALSE) -if(NOT CMAKE_CROSSCOMPILING AND BUILD_TESTING) - add_subdirectory(tests) +#TODO determine if cross compile... +if(ENABLE_TESTS AND (NOT CMAKE_CROSSCOMPILING AND BUILD_TESTING)) + include (CTest) + add_subdirectory(tests) endif() diff --git a/_ptw32.h b/_ptw32.h index 5821f94..bd83f29 100644 --- a/_ptw32.h +++ b/_ptw32.h @@ -145,7 +145,7 @@ #if defined(__BORLANDC__) # define int64_t LONGLONG # define uint64_t ULONGLONG -#elif !defined(__MINGW32__) +#elif defined(_MSC_VER) && !defined(__x86_64__) typedef _int64 int64_t; typedef unsigned _int64 uint64_t; # if defined (__PTW32_CONFIG_MSVC6) diff --git a/appveyor.yml b/appveyor.yml index cad8256..39ca203 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,6 +6,7 @@ clone_depth: 1 branches: only: - cmake + - gnu_compiler configuration: - MinSizeRel @@ -68,6 +69,51 @@ environment: GENERATOR: 'NMake Makefiles' TESTING: ON + ## MinGW GNU C Compiler: + ## x86 flavor: + - APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2015' + ARCHITECTURE: amd64_x86 + ARCHIVE: VS2015_%CONFIGURATION%_x86_%APPVEYOR_BUILD_NUMBER% + GENERATOR: 'MinGW Makefiles' + TESTING: ON + MINGW: C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin + + - APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2015' + ARCHITECTURE: amd64_x86 + ARCHIVE: VS2015_%CONFIGURATION%_x86_%APPVEYOR_BUILD_NUMBER% + GENERATOR: 'MinGW Makefiles' + TESTING: ON + MINGW: C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin + + ## x64 flavor: + - APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2015' + ARCHITECTURE: amd64_x86 + ARCHIVE: VS2015_%CONFIGURATION%_x86_%APPVEYOR_BUILD_NUMBER% + GENERATOR: 'MinGW Makefiles' + TESTING: OFF + MINGW: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin + + - APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2015' + ARCHITECTURE: amd64_x86 + ARCHIVE: VS2015_%CONFIGURATION%_x86_%APPVEYOR_BUILD_NUMBER% + GENERATOR: 'MinGW Makefiles' + TESTING: OFF + MINGW: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64\bin + + - APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2015' + ARCHITECTURE: amd64_x86 + ARCHIVE: VS2015_%CONFIGURATION%_x86_%APPVEYOR_BUILD_NUMBER% + GENERATOR: 'MinGW Makefiles' + TESTING: ON + MINGW: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin + + - APPVEYOR_BUILD_WORKER_IMAGE: 'Visual Studio 2017' + ARCHITECTURE: amd64_x86 + ARCHIVE: VS2015_%CONFIGURATION%_x86_%APPVEYOR_BUILD_NUMBER% + GENERATOR: 'MinGW Makefiles' + TESTING: ON + MINGW: C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin + init: - echo BUILD_NUMBER=%APPVEYOR_BUILD_NUMBER% @@ -85,14 +131,18 @@ build_script: - cd %APPVEYOR_BUILD_FOLDER% - mkdir build - cd build + ## Remove Git's MSYS from PATH, otherwise CMake borks. + - set PATH=%PATH:C:\Program Files (x86)\Git\bin;=% + - set PATH=%PATH:C:\Program Files\Git\bin;=% + - set PATH=%PATH:C:\Program Files\Git\usr\bin;=% + - if defined MINGW set PATH=%MINGW%;%PATH% - cmake -G"%GENERATOR%" -DCMAKE_BUILD_TYPE=%CONFIGURATION% -DBUILD_NUMBER=%APPVEYOR_BUILD_NUMBER% -DDIST_ROOT="%CMAKE_DIST_DIR%/%APPVEYOR_BUILD_WORKER_IMAGE%" - -DBUILD_TESTING=%TESTING% + -DENABLE_TESTS=%TESTING% .. - - cmake --build . --config %CONFIGURATION% --target install + - cmake --build . --config %CONFIGURATION% --target install after_build: - cd %DIST_DIR% @@ -108,6 +158,6 @@ before_test: - set PATH=%APPVEYOR_BUILD_FOLDER%\build;%PATH% test_script: - if exist %APPVEYOR_BUILD_FOLDER%\build\tests\ cd %APPVEYOR_BUILD_FOLDER%\build\tests - - if exist %APPVEYOR_BUILD_FOLDER%\build\tests\ ctest -C %CONFIGURATION% -V + - if exist %APPVEYOR_BUILD_FOLDER%\build\tests\ ctest -C %CONFIGURATION% -V --timeout 600 after_test: - # TODO process CTest output \ No newline at end of file + # TODO process CTest output diff --git a/cmake/config_h_in.cmake b/cmake/config_h_in.cmake new file mode 100644 index 0000000..320a352 --- /dev/null +++ b/cmake/config_h_in.cmake @@ -0,0 +1,123 @@ +set(PTHREAD_CONFIG_H " +/* config.h, automagically generated by cmake. */ + +#ifndef __PTW32_CONFIG_H +#define __PTW32_CONFIG_H + +/* Define to 1 if you have the `calloc' function. */ +#cmakedefine HAVE_CALLOC 1 + +/* Define if CPU_AFFINITY is supported */ +#define HAVE_CPU_AFFINITY 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ERRNO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MEMORY_H 1 + +/* Define if your compiler knows about mode_t */ +#define HAVE_MODE_T 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SIGNAL_H 1 + +/* Define if your compiler knows about sigset_t */ +#cmakedefine HAVE_SIGSET_T 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H 1 + +/* Define if your compiler knows about struct timespec */ +#cmakedefine HAVE_STRUCT_TIMESPEC 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `_beginthreadex' function. */ +#cmakedefine HAVE__BEGINTHREADEX 1 + +/* Define to 1 if you have the DuplicateHandle function. */ +#cmakedefine HAVE_DUPLICATEHANDLE 1 + +/* Make sure that __PTW32_BUILD is defined. */ +#if !defined(__PTW32_BUILD) +#define __PTW32_BUILD +#endif + +/* Define if you do not have calloc */ +#if !defined(HAVE_CALLOC) || !HAVE_CALLOC +#define NEED_CALLOC +#endif + +#if !defined(HAVE__BEGINTHREADEX) || !HAVE__BEGINTHREADEX +#define NEED_CREATETHREAD +#endif + +/* Define if DuplicateHandle is unsupported */ +#if !defined(HAVE_DUPLICATEHANDLE) || !HAVE_DUPLICATEHANDLE +#define NEED_DUPLICATEHANDLE +#endif + +/* Define if you do not have errno */ +/* #undef NEED_ERRNO */ + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT \"\" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME \"pthreads4w\" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING \"pthreads4w git\" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME \"pthreads4w\" + +/* Define to the home page for this package. */ +#define PACKAGE_URL \"\" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION \"git\" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +#define HAVE_C_INLINE 1 + +#endif +") + + +function (create_config_h_in) + file(WRITE + "${CMAKE_BINARY_DIR}/config.h.in" + "${PTHREAD_CONFIG_H}") +endfunction (create_config_h_in) diff --git a/cmake/get_version.cmake b/cmake/get_version.cmake index 3cca32b..82e92c7 100644 --- a/cmake/get_version.cmake +++ b/cmake/get_version.cmake @@ -1,5 +1,5 @@ -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/_ptw32.h _PTW32_H_CONTENTS) +file(READ ${CMAKE_SOURCE_DIR}/_ptw32.h _PTW32_H_CONTENTS) string(REGEX MATCH "#define __PTW32_VERSION_MAJOR ([a-zA-Z0-9_]+)" PTW32_VERSION_MAJOR "${_PTW32_H_CONTENTS}") string(REPLACE "#define __PTW32_VERSION_MAJOR " "" PTW32_VERSION_MAJOR "${PTW32_VERSION_MAJOR}") diff --git a/cmake/target_arch.cmake b/cmake/target_arch.cmake index 0ba4d3a..0c96f31 100644 --- a/cmake/target_arch.cmake +++ b/cmake/target_arch.cmake @@ -1,30 +1,35 @@ set(TARGET_ARCH_DETECT_CODE " - - #if defined(_M_ARM) - #error cmake_arch ARM - #elif defined(_M_ARM64) - #error cmake_arch ARM64 - #elif defined(_M_AMD64) - #error cmake_arch x86_64 - #elif defined(_M_X64) - #error cmake_arch x64 - #elif defined(_M_IX86) - #error cmake_arch x86 - #else - #error cmake_arch unknown - #endif +#if defined(_M_ARM) +# error cmake_arch ARM +#elif defined(_M_ARM64) +# error cmake_arch ARM64 +#elif defined(_M_AMD64) +# error cmake_arch x86_64 +#elif defined(_M_X64) +# error cmake_arch x64 +#elif defined(_M_IX86) +# error cmake_arch x86 +#elif defined(__MINGW64__) || defined(__x86_64__) +/* NOTE: MinGW64 gcc defined BOTH __MINGW32__ and __MINGW64__, so order + is important. */ +# error cmake_arch x64 +#elif defined(__MINGW32__) +# error cmake_arch x86 +#else +#error cmake_arch unknown +#endif ") function(get_target_arch out) file(WRITE - "${CMAKE_CURRENT_BINARY_DIR}/target_arch_detect.c" + "${CMAKE_BINARY_DIR}/target_arch_detect.c" "${TARGET_ARCH_DETECT_CODE}") try_run( run_result_unused compile_result_unused - "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/target_arch_detect.c" + "${CMAKE_BINARY_DIR}" "${CMAKE_BINARY_DIR}/target_arch_detect.c" COMPILE_OUTPUT_VARIABLE TARGET_ARCH) # parse compiler output diff --git a/implement.h b/implement.h index 81c5f29..fc0c889 100644 --- a/implement.h +++ b/implement.h @@ -109,7 +109,11 @@ static void __ptw32_set_errno(int err) { errno = err; SetLastError(err); } #if defined (__PTW32_BUILD_INLINED) # if defined(HAVE_C_INLINE) || defined(__cplusplus) # undef INLINE -# define INLINE inline +# if defined(__GNUC__) +# define INLINE __inline__ +# else +# define INLINE inline +# endif # endif #endif diff --git a/pthread.cxx b/pthread.cxx new file mode 100644 index 0000000..318041a --- /dev/null +++ b/pthread.cxx @@ -0,0 +1,6 @@ +/* Stub source so that CMake 3.18 and higher actually compile using the C++ + * compiler. CMake 3.18 started enforcing source type (e.g., "/TC" for C source + * and "/TP" for C++ source) on the command line, forcing this as the + * workaround. */ + +#include "pthread.c" diff --git a/ptw32_MCS_lock.c b/ptw32_MCS_lock.c index 2f12107..6de1b70 100644 --- a/ptw32_MCS_lock.c +++ b/ptw32_MCS_lock.c @@ -103,7 +103,7 @@ * Set event if an event handle has been stored in the flag, and * set flag to -1 otherwise. Note that -1 cannot be a valid handle value. */ -INLINE void +static INLINE void __ptw32_mcs_flag_set (HANDLE * flag) { HANDLE e = (HANDLE) (__PTW32_INTERLOCKED_SIZE)__PTW32_INTERLOCKED_COMPARE_EXCHANGE_SIZE( @@ -133,7 +133,7 @@ __ptw32_mcs_flag_set (HANDLE * flag) * Store an event handle in the flag and wait on it if the flag has not been * set, and proceed without creating an event otherwise. */ -INLINE void +static INLINE void __ptw32_mcs_flag_wait (HANDLE * flag) { if ((__PTW32_INTERLOCKED_SIZE)0 == diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index de356b4..9c3099d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,12 +1,20 @@ +include (CTest) + include_directories(..) set(XXLIBS ws2_32.lib) +set(TESTPREFIX "${CMAKE_INSTALL_PREFIX}/${TARGET_ARCH}") set(VCEFLAGS "${VCEFLAGS} -D__PtW32NoCatchWarn") +# Remove "-DNDEBUG" from the compiler's list of command line defs. +# This affects the tests' use of the assert macro. This comes from +# the GNUmakefile command line for tests. +string(REPLACE "-DNDEBUG" "-UNDEBUG" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE}) -macro(add_testcase test type def) +message(STATUS "Test destination prefix: ${TESTPREFIX}") +macro(add_testcase test type def) set(lib_test test-${test}${type}${PTW32_VER}) set(dll_test test-dll-${test}${type}${PTW32_VER}) @@ -21,26 +29,69 @@ macro(add_testcase test type def) set(extra "") if(${test} MATCHES "openmp1") if(MSVC) - set(extra "/openmp -D_OPENMP") + set(extra "/openmp" "-D_OPENMP") + elseif (${CMAKE_C_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_C_COMPILER_ID} STREQUAL "Clang") + set(extra "-fopenmp") endif() endif() add_executable(${lib_test} ${test}.c ${c_dep}) target_link_libraries(${lib_test} ${lib_lib} ${XXLIBS}) - target_compile_definitions(${lib_test} PUBLIC "/nologo -D_CONSOLE -D_MBCS -D${def} ${extra}") + if(MSVC) + target_compile_options(${lib_test} PUBLIC "/nologo") + endif() + target_compile_definitions(${lib_test} PUBLIC _CONSOLE _MBCS ${def} ${extras}) + target_compile_options(${lib_test} PUBLIC ${extra}) + if (${CMAKE_C_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_C_COMPILER_ID} STREQUAL "Clang") + # GNUmakefile compiles every test as C++: + target_compile_definitions(${lib_test} PRIVATE __PtW32NoCatchWarn) + target_compile_options(${lib_test} PRIVATE "-mthreads" "-xc++") + target_link_libraries(${lib_test} stdc++) + target_link_options(${lib_test} PRIVATE "-shared-libgcc") + + if (${test} MATCHES "openmp") + target_link_options(${lib_test} PRIVATE "-fopenmp") + endif () + endif () add_dependencies(${lib_test} ${lib_lib}) add_executable(${dll_test} ${test}.c ${c_dep}) target_link_libraries(${dll_test} ${dll_lib} ${XXLIBS}) - target_compile_definitions(${dll_test} PUBLIC "/nologo -D_CONSOLE -D_MBCS -D${def} ${extra}") + if(MSVC) + target_compile_options(${dll_test} PUBLIC "/nologo") + endif() + target_compile_definitions(${dll_test} PRIVATE _CONSOLE _MBCS ${def}) + target_compile_options(${dll_test} PRIVATE ${extra}) + if (${CMAKE_C_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_C_COMPILER_ID} STREQUAL "Clang") + # GNUmakefile compiles every test as C++: + target_compile_definitions(${dll_test} PRIVATE __PtW32NoCatchWarn) + target_compile_options(${dll_test} PRIVATE "-mthreads" "-xc++") + target_link_libraries(${dll_test} stdc++) + target_link_options(${dll_test} PRIVATE "-shared-libgcc") + if (${test} MATCHES "openmp") + target_link_options(${dll_test} PRIVATE "-fopenmp") + endif () + endif () add_dependencies(${dll_test} ${dll_lib}) - if(${CMAKE_GENERATOR} MATCHES "Visual Studio") - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/tests/${lib_test}.exe DESTINATION ${TESTDEST}) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/tests/${dll_test}.exe DESTINATION ${TESTDEST}) + if (${CMAKE_GENERATOR} MATCHES "Visual Studio") + install( + FILES "${CMAKE_BINARY_DIR}/tests/$/${lib_test}.exe" + DESTINATION "${TESTPREFIX}/$/tests" + ) + install( + FILES "${CMAKE_BINARY_DIR}/tests/$/${dll_test}.exe" + DESTINATION "${TESTPREFIX}/$/tests" + ) else() - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tests/${lib_test}.exe DESTINATION ${TESTDEST}) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tests/${dll_test}.exe DESTINATION ${TESTDEST}) + install( + FILES ${CMAKE_BINARY_DIR}/tests/${lib_test}.exe + DESTINATION "${TESTPREFIX}/$/tests" + ) + install( + FILES ${CMAKE_BINARY_DIR}/tests/${dll_test}.exe + DESTINATION "${TESTPREFIX}/$/tests" + ) endif() if(${type} MATCHES "VCE") @@ -71,8 +122,13 @@ foreach(t ${TESTS}) continue() endif() - add_testcase(${test} VCE __PTW32_CLEANUP_CXX ) - add_testcase(${test} VSE __PTW32_CLEANUP_SEH ) - add_testcase(${test} VC __PTW32_CLEANUP_C ) + if (MSVC) + add_testcase(${test} VCE __PTW32_CLEANUP_CXX ) + add_testcase(${test} VSE __PTW32_CLEANUP_SEH ) + add_testcase(${test} VC __PTW32_CLEANUP_C ) + elseif (${CMAKE_C_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_C_COMPILER_ID} STREQUAL "Clang") + add_testcase (${test} GCE __PTW32_CLEANUP_CXX ) + add_testcase (${test} GC __PTW32_CLEANUP_C ) + endif (MSVC) endforeach(t) diff --git a/tests/benchtest1.c b/tests/benchtest1.c index 23e8d72..f392ef6 100644 --- a/tests/benchtest1.c +++ b/tests/benchtest1.c @@ -74,7 +74,7 @@ int iter; void -runTest (char * testNameString, int mType) +runTest (const char * testNameString, int mType) { #ifdef __PTW32_MUTEX_TYPES assert(pthread_mutexattr_settype(&ma, mType) == 0); diff --git a/tests/benchtest2.c b/tests/benchtest2.c index e28c10e..4666d0a 100644 --- a/tests/benchtest2.c +++ b/tests/benchtest2.c @@ -138,7 +138,7 @@ CSThread(void * arg) } void -runTest (char * testNameString, int mType) +runTest (const char * testNameString, int mType) { #ifdef __PTW32_MUTEX_TYPES assert(pthread_mutexattr_settype(&ma, mType) == 0); diff --git a/tests/benchtest3.c b/tests/benchtest3.c index 1bc5a04..3dd54e3 100644 --- a/tests/benchtest3.c +++ b/tests/benchtest3.c @@ -93,7 +93,7 @@ oldTrylockThread (void * arg) void -runTest (char * testNameString, int mType) +runTest (const char * testNameString, int mType) { pthread_t t; diff --git a/tests/benchtest4.c b/tests/benchtest4.c index 51cd256..7a2b82a 100644 --- a/tests/benchtest4.c +++ b/tests/benchtest4.c @@ -77,7 +77,7 @@ oldRunTest (char * testNameString, int mType) void -runTest (char * testNameString, int mType) +runTest (const char * testNameString, int mType) { #ifdef __PTW32_MUTEX_TYPES pthread_mutexattr_settype(&ma, mType); diff --git a/tests/benchtest5.c b/tests/benchtest5.c index d4fd515..ebadde6 100644 --- a/tests/benchtest5.c +++ b/tests/benchtest5.c @@ -72,7 +72,7 @@ int zero = 0; void -reportTest (char * testNameString) +reportTest (const char * testNameString) { durationMilliSecs = GetDurationMilliSecs(currSysTimeStart, currSysTimeStop) - overHeadMilliSecs; diff --git a/tests/exit2.c b/tests/exit2.c index af25ec0..975cb8f 100644 --- a/tests/exit2.c +++ b/tests/exit2.c @@ -41,7 +41,8 @@ void * func(void * arg) { - int failed = (int) arg; + ptrdiff_t failed = (ptrdiff_t) arg; + /* int failed = (int) arg; */ pthread_exit(arg); @@ -49,7 +50,7 @@ func(void * arg) /* * Trick gcc compiler into not issuing a warning here */ - assert(failed - (int)arg); + assert(failed - (ptrdiff_t) arg); return NULL; } diff --git a/tests/exit3.c b/tests/exit3.c index a4cb122..a3f1073 100644 --- a/tests/exit3.c +++ b/tests/exit3.c @@ -34,12 +34,13 @@ * Depends on API functions: pthread_create(). */ +#include #include "test.h" void * func(void * arg) { - int failed = (int) arg; + ptrdiff_t failed = (ptrdiff_t) arg; pthread_exit(arg); @@ -47,7 +48,7 @@ func(void * arg) /* * assert(0) in a way to prevent warning or optimising away. */ - assert(failed - (int) arg); + assert(failed - (ptrdiff_t) arg); return NULL; }