I am working on v7.6.1 (latest at this point). Downloaded it from [SourceForge]: ninja9578/libjson - libjson_7.6.1.zip.
At the beginning, I thought it was a half hour problem (minor changes in the makefile, since Win's mkdir creates nested dirs by default, and doesn't accept a -p argument).
To make things clear, I tried running MinGW's mingw32-make from Win's cmd window (no additional wrappers involved).
So, I started inserting (in the makefile) conditional commands (based on OS), but it was not enough. The changes needed by the original makefile to accommodate this scenario, seemed simply too large (making the file harder to understand) compared to the gain: work on an environment that too few people care about, so the logical solution was to create a separate makefile (called it Makefile.mak)
Nevertheless, the official doc ("${LIBJSON_SRC_DIR}/Documentation.pdf") states that:
MinGW (Windows) - Supported, partially tested
I didn't get through the whole .pdf to see what are the required conditions for that to happen, but (besides that it doesn't work - hence the existence of this question) looking at the makefile, there are some things that don't look right:
- Shell (Nix (sh, bash, ...) vs. Win (batch (cmd), PS, VBS, ...)) commands (qualified as usable in a GNU makefile) difference (
rm -f
vs. del /Q /S
)
- The way makefile commands are carried (CreateProcess for each of them: including
cd
- which doesn't change the environment (cwd), leading to the next command failure), also the command separator (;), doesn't work as expected
- FS path separators (/ vs. \) handled by the above commands
I "converted" the makefile, considering that current Nix (Lnx) behavior should be preserved on Win, and I also found some (syntax) errors (so, apparently the Nix version was not working either - well the library was built, but that's about it). Fixed the errors, and then wanted to post the answer on the official site (so that anyone who used to follow it, should be aware of the changes).
Briefly looked, and noticed that last action is from 180622 (there are more, around that date). But when took a closer look, it seems that the last actual work was done 5 years ago (2013), so I'm not sure if it's maintained (also quick browsed GitHub, but didn't find it).
Anyway, I contacted the author, as I don't have permissions to open tickets (submit patches), but I got no reply, so I started a thread: [SourceForge]: ninja9578/libjson - Request for permissions to submit a patch. I will submit the patch (provided that the permissions will be granted to me).
Long story short
Anyway, here's the Win makefile (mostly copied from original one):
Makefile.mak:
###############################################################################
#
# Copyright 2010 Jonathan Wallace. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY JONATHAN WALLACE ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JONATHAN WALLACE OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
#
# The views and conclusions contained in the software and documentation are
# those of the authors and should not be interpreted as representing official
# policies, either expressed or implied, of Jonathan Wallace....
#
#
# Author Bernhard Fluehmann
#
# bernhard.fluehmann@patton-inalp.com
#
#
# Adapted for Windows (MinGW) by Cristi Fati (fati_utcluj@yahoo.com)
#
#
# TARGETS
# all
# Builds either a shared or a static library, depending of the value
# of the SHARED variable.
# Default: static
#
# banner
# Displays the library version and the target
#
# install
# Installs either the shared of the static library, depending of the value
# of the SHARED variable. Installs the header files as well.
# Builds the library before installing if it does not exist already.
# Ececutes ldconfig in case of the shared library.
# Default locations:
# library: $(exec_prefix)/$(libdir) => /usr/lib
# headers: $(prefix)/$(includedir) => /usr/include
#
# install_headers
# Installs the header files.
# Default location: $(prefix)/$(includedir) => /usr/include
#
# clean
# Removes the shared or the static library, depending of the value
# of the SHARED variable, from this folder and all the folders and objects
# which were created to build it.
#
# uninstall
# Removes the shared or the static library, depending of the value
# of the SHARED variable from the system. In case of the shared library,
# removes the symbolic links as well and executes ldconfig.
#
# uninstall_headers
# Remove the headers from the system.
#
# Variables
# prefix
# The general installation root directory. Default: /usr
#
# exec_prefix
# The installation root directory to place executables and libraries.
# Default: prefix
#
# libdir
# The directory where the libraries are installed, as a subdirectory of
# exec_prefix. Default: lib
#
# includedir
# The directory where the header files are installed, as a subdirectory of
# prefix. Default: include
#
# srcdir
# The directory where the object source files are located.
# Default: _internal/Source
#
# CXX
# The compiler to be used. Default: c++
#
# CXXFLAGS
# The compiler flags used to compile the object files.
# Default:
# cxxflags_default for default
# cxxflags_small for BUILD_TYPE=small
# cxxflags_debug for BUILD_TYPE=debug
#
# AR
# The archiver to be used. Default: ar
#
# PIC
# The PIC to be used. Default: PIC
#
# BUILD_TYPE
# Used to select a specific set of predefined configuration parameters.
# Default: undefined: The default settings are used
# Options:
# small
# debug
#
# SHARED
# Used to select if the library is a shared or a dynamic one
# Default: undefined: static
# Options:
# 0: static
# 1: shared
#
#
#
# Shell (cmd) commands
movefile = move /Y
copyfile = copy /Y
removefile = del /Q /S
makedirs = -mkdir
copydir = xcopy /B /E /H /K /Y
removedir = -rmdir /Q /S
makelink = mklink
# JSON source files to build
objects = internalJSONNode.o JSONAllocator.o JSONChildren.o \
JSONDebug.o JSONIterators.o JSONMemory.o JSONNode.o \
JSONNode_Mutex.o JSONPreparse.o JSONStream.o JSONValidator.o \
JSONWorker.o JSONWriter.o libjson.o
# Defaults
cxxflags_default = -O3 -ffast-math -fexpensive-optimizations -DNDEBUG
cxxflags_small = -Os -ffast-math -DJSON_LESS_MEMORY -DNDEBUG
cxxflags_debug = -g -DJSON_SAFE -DJSON_DEBUG
cxxflags_shared = -f$(PIC)
libname = libjson
libname_hdr := $(libname)
libname_debug = $(libname)_dbg
suffix_shared = so
suffix_static = a
major_version = 7
minor_version = 6.1
objdir = Objects
# Variables
prefix ?= ../install_libjson
exec_prefix ?= $(prefix)
libdir ?= lib
includedir ?= include
intdir ?= _internal
srcdir ?= $(intdir)/Source
CXX ?= c++
AR ?= ar
PIC ?= PIC
BUILD_TYPE ?= "default"
SHARED ?= "1"
# Internal Variables
inst_path = $(exec_prefix)/$(libdir)
include_path = $(prefix)/$(includedir)
install_include_lib_dir = $(include_path)/$(libname_hdr)
install_include_lib_src_dir = $(install_include_lib_dir)/$(srcdir)
# Usage check
ifdef CXXFLAGS
ifdef BUILD_TYPE
$(error CXXFLAGS and BUILD_TYPE are mutually exclusive)
endif
endif
# BUILD_TYPE specific settings
ifeq ($(BUILD_TYPE),small)
CXXFLAGS = $(cxxflags_small)
else ifeq ($(BUILD_TYPE),debug)
CXXFLAGS = $(cxxflags_debug)
libname := $(libname_debug)
else
CXXFLAGS ?= $(cxxflags_default)
endif
# SHARED specific settings
ifeq ($(SHARED),1)
libname_shared = $(libname).$(suffix_shared)
libname_shared_major_version = $(libname_shared).$(major_version)
lib_target = $(libname_shared_major_version).$(minor_version)
objdir := $(objdir)_shared
CXXFLAGS := $(CXXFLAGS) $(cxxflags_shared)
else
lib_target = $(libname).$(suffix_static)
objdir := $(objdir)_static
endif
# Win styple paths - to be used by shell commands
objdir_win = $(subst /,\,$(objdir))
inst_path_win = $(subst /,\,$(inst_path))
intdir_win = $(subst /,\,$(intdir))
srcdir_win = $(subst /,\,$(srcdir))
install_include_lib_dir_win = $(subst /,\,$(install_include_lib_dir))
install_include_lib_src_dir_win = $(subst /,\,$(install_include_lib_src_dir))
# Phony targets
.PHONY: all banner installdirs install install_headers clean uninstall uninstall_headers
# Targets
all: $(lib_target)
@echo "============================================================"
@echo "Done"
@echo "============================================================"
banner:
@echo "============================================================"
@echo "libjson version: "$(major_version).$(minor_version) "target: "$(target) "OS: "Windows
@echo "============================================================"
installdirs: banner
$(makedirs) $(objdir_win)
# Libraries
ifeq ($(SHARED),1)
$(lib_target): banner installdirs $(addprefix $(objdir)/, $(objects))
@echo "Link "
cd $(objdir_win) && \
$(CXX) -shared -Wl,-soname,$(libname_shared_major_version) -o $@ $(objects) && \
$(movefile) $@ ..
@echo "Link: Done"
else
$(lib_target): banner installdirs $(addprefix $(objdir)/, $(objects))
@echo "Archive"
cd $(objdir_win) && \
$(AR) -cvq $@ $(objects) && \
$(movefile) $@ ..
@echo "Archive: Done"
endif
# Compile object files
$(objdir)/%.o: $(srcdir)/%.cpp
$(CXX) $< -o $@ -c $(CXXFLAGS)
ifeq ($(SHARED),1)
install: banner install_headers $(lib_target)
@echo "Install shared library"
$(makedirs) $(inst_path_win)
$(copyfile) $(lib_target) $(inst_path_win)
cd $(inst_path_win) && \
$(removefile) $(libname_shared_major_version) && $(makelink) $(libname_shared_major_version) $(lib_target) && \
$(removefile) $(libname_shared) && $(makelink) $(libname_shared) $(libname_shared_major_version)
@echo ldconfig
@echo "Install shared library: Done."
else
install: banner install_headers $(lib_target)
@echo "Install static library"
$(makedirs) $(inst_path_win)
$(copyfile) .\$(lib_target) $(inst_path_win)
@echo "Install static library: Done."
endif
install_headers: banner
@echo "Install header files"
$(makedirs) $(install_include_lib_src_dir_win)\JSONDefs
$(makedirs) $(install_include_lib_src_dir_win)\Dependencies
$(copyfile) .\*.h $(install_include_lib_dir_win)
-$(removefile) $(install_include_lib_dir_win)\.*.h
$(copyfile) .\$(srcdir_win)\*.h $(install_include_lib_src_dir_win)
-$(removefile) $(install_include_lib_src_dir_win)\.*.h
$(copydir) .\$(srcdir_win)\JSONDefs $(install_include_lib_src_dir_win)\JSONDefs
$(copydir) $(intdir_win)\Dependencies $(install_include_lib_src_dir_win)\Dependencies
@echo "Install header files: Done."
clean: banner
@echo "Clean library and object folder"
$(removedir) $(objdir_win)
-$(removefile) $(lib_target)
@echo "Clean library and object folder: Done"
ifeq ($(SHARED),1)
uninstall: banner uninstall_headers
@echo "Uninstall shared library"
-$(removefile) $(inst_path_win)\$(libname)*
@echo ldconfig
@echo "Uninstall shared library: Done"
else
uninstall: banner uninstall_headers
@echo "Uninstall static library"
-$(removefile) $(inst_path_win)\$(lib_target)
@echo "Uninstall static library: Done"
endif
uninstall_headers: banner
@echo "Uninstall header files"
$(removedir) $(install_include_lib_dir_win)
@echo "Uninstall header files: Done"
test:
$(CXX) _internal/TestSuite/main.cpp _internal/TestSuite/TestAssign.cpp _internal/TestSuite/TestChildren.cpp \
_internal/TestSuite/TestComments.cpp _internal/TestSuite/TestConverters.cpp _internal/TestSuite/TestCtors.cpp \
_internal/TestSuite/TestEquality.cpp _internal/TestSuite/TestFunctions.cpp _internal/TestSuite/TestInequality.cpp \
_internal/TestSuite/TestInspectors.cpp _internal/TestSuite/TestIterators.cpp _internal/TestSuite/TestMutex.cpp \
_internal/TestSuite/TestNamespace.cpp _internal/TestSuite/TestRefCounting.cpp _internal/TestSuite/TestSuite.cpp \
_internal/TestSuite/TestWriter.cpp _internal/TestSuite/TestString.cpp _internal/TestSuite/UnitTest.cpp \
_internal/TestSuite/TestValidator.cpp _internal/TestSuite/TestStreams.cpp _internal/TestSuite/TestBinary.cpp \
_internal/TestSuite/RunTestSuite2.cpp _internal/TestSuite/TestSharedString.cpp \
_internal/Source/internalJSONNode.cpp _internal/Source/JSONPreparse.cpp _internal/Source/JSONChildren.cpp \
_internal/Source/JSONDebug.cpp _internal/Source/JSONIterators.cpp _internal/Source/JSONMemory.cpp \
_internal/Source/JSONNode_Mutex.cpp _internal/Source/JSONNode.cpp _internal/Source/JSONWorker.cpp \
_internal/Source/JSONWriter.cpp _internal/Source/libjson.cpp _internal/Source/JSONValidator.cpp \
_internal/Source/JSONStream.cpp _internal/Source/JSONAllocator.cpp \
_internal/TestSuite2/JSON_Base64/json_decode64.cpp \
_internal/TestSuite2/JSON_Base64/json_encode64.cpp \
_internal/TestSuite2/JSONDebug/JSON_ASSERT_SAFE.cpp \
_internal/TestSuite2/JSONDebug/JSON_ASSERT.cpp \
_internal/TestSuite2/JSONDebug/JSON_FAIL_SAFE.cpp \
_internal/TestSuite2/JSONDebug/JSON_FAIL.cpp \
_internal/TestSuite2/JSONGlobals/jsonSingleton.cpp \
_internal/TestSuite2/JSONValidator/isValidArray.cpp \
_internal/TestSuite2/JSONValidator/isValidMember.cpp \
_internal/TestSuite2/JSONValidator/isValidNamedObject.cpp \
_internal/TestSuite2/JSONValidator/isValidNumber.cpp \
_internal/TestSuite2/JSONValidator/isValidObject.cpp \
_internal/TestSuite2/JSONValidator/isValidPartialRoot.cpp \
_internal/TestSuite2/JSONValidator/isValidRoot.cpp \
_internal/TestSuite2/JSONValidator/isValidString.cpp \
_internal/TestSuite2/JSONValidator/securityTest.cpp \
_internal/TestSuite2/NumberToString/_areFloatsEqual.cpp \
_internal/TestSuite2/NumberToString/_atof.cpp \
_internal/TestSuite2/NumberToString/_ftoa.cpp \
_internal/TestSuite2/NumberToString/_itoa.cpp \
_internal/TestSuite2/NumberToString/_uitoa.cpp \
_internal/TestSuite2/NumberToString/getLenSize.cpp \
_internal/TestSuite2/NumberToString/isNumeric.cpp \
$(CXXFLAGS) -o ./testapp
./testapp
Steps:
- Unpack the sources archive (I have them in a dir called libjson)
- Copy Makefile.mak in that dir
- From inside the dir, call (in a cmd window) mingw32-make against this file (
mingw32-make -f Makefile.mak
)
- In order for everything to work normally, mingw32-make's dir must be in %PATH% (which you already know)
- If you want the dynamic version (.so - which is actually a .dll), you must
set SHARED=1
before invoking mingw32-make
- Due to mklink, the install target won't work on older Win versions (e.g. XP)
When building the lib, I've encountered a strange thing that you should be aware of. Here are the tool versions / environments that I've worked on:
- g++ 5.3.0 on Win - part of MinGW (installed by Qt)
- g++ 5.4.0 on Lnx (Ubtu)
- g++ 7.2.0 on Win - part of MinGW (built by me)
- g++ 7.3.0 on Cygwin
3 of those worked fine, but for #3., I got:
_internal/Source/JSONWorker.cpp:297:26: error: cast from 'const char*' to 'long int' loses precision [-fpermissive]
JSON_ASSERT_SAFE(((long)end - (long)pos) > 4, JSON_TEXT("UTF will go out of bounds"), return JSON_TEXT('\0'););
^
I don't know why this happens (probably a g++ config issue?), but in order to get around it, you should add the -fpermissive compile flag (as instructed by the error message) to cxxflags_default variable in line #146:
cxxflags_default = -O3 -ffast-math -fexpensive-optimizations -fpermissive -DNDEBUG
This is for the default build, if you choose another variant (debug, small) you'll have to modify the appropriate variable.
Although it wasn't required in the question, I'm also posting the fixes for the Nix part (which are somehow related, since I've discovered them while working on this answer).
libjson-7.6.1-nix_makefile.patch:
--- libjson/makefile.orig 2012-05-30 05:15:42.000000000 +0300
+++ libjson/makefile 2018-08-31 01:09:57.484855300 +0300
@@ -131,7 +131,7 @@
OS=$(shell uname)
# Defaults
-ifeq ($(OS), Darwin)
+ifeq ($(OS),Darwin)
cxxflags_default = -fast -ffast-math -fexpensive-optimizations -DNDEBUG
else
cxxflags_default = -O3 -ffast-math -fexpensive-optimizations -DNDEBUG
@@ -154,7 +154,8 @@
exec_prefix ?= $(prefix)
libdir ?= lib
includedir ?= include
-srcdir ?= _internal/Source
+intdir ?= _internal
+srcdir ?= $(intdir)/Source
CXX ?= c++
AR ?= ar
PIC ?= PIC
@@ -175,9 +176,9 @@
endif
# BUILD_TYPE specific settings
-ifeq ($(BUILD_TYPE), small)
+ifeq ($(BUILD_TYPE),small)
CXXFLAGS = $(cxxflags_small)
-else ifeq ($(BUILD_TYPE), debug)
+else ifeq ($(BUILD_TYPE),debug)
CXXFLAGS = $(cxxflags_debug)
libname := $(libname_debug)
else
@@ -185,7 +186,7 @@
endif
# SHARED specific settings
-ifeq ($(SHARED), 1)
+ifeq ($(SHARED),1)
libname_shared = $(libname).$(suffix_shared)
libname_shared_major_version = $(libname_shared).$(major_version)
lib_target = $(libname_shared_major_version).$(minor_version)
@@ -242,6 +243,7 @@
ifeq ($(SHARED),1)
install: banner install_headers $(lib_target)
@echo "Install shared library"
+ mkdir -p $(inst_path)
cp -f ./$(lib_target) $(inst_path)
cd $(inst_path) ; \
ln -sf $(lib_target) $(libname_shared_major_version) ; \
@@ -253,6 +255,7 @@
else
install: banner install_headers $(lib_target)
@echo "Install static library"
+ mkdir -p $(inst_path)
cp -f ./$(lib_target) $(inst_path)
@echo "Install static library: Done."
endif
@@ -265,8 +268,8 @@
cp -f ./$(srcdir)/*.h $(include_path)/$(libname_hdr)/$(srcdir)
cp -r ./$(srcdir)/JSONDefs $(include_path)/$(libname_hdr)/$(srcdir)
chmod -R a+r $(include_path)/$(libname_hdr)
- find $(include_path)/$(libname_hdr) -type d -exec chmod a+x {} \;
- cp -rv $(srcdir)/Dependencies/ $(include_path)/$(libname_hdr)/$(srcdir)
+ find $(include_path)/$(libname_hdr) -type d -exec chmod a+x {} \;
+ cp -rv $(intdir)/Dependencies/ $(include_path)/$(libname_hdr)/$(srcdir)
@echo "Install header files: Done."
clean: banner
@@ -311,28 +314,28 @@
_internal/Source/JSONNode_Mutex.cpp _internal/Source/JSONNode.cpp _internal/Source/JSONWorker.cpp \
_internal/Source/JSONWriter.cpp _internal/Source/libjson.cpp _internal/Source/JSONValidator.cpp \
_internal/Source/JSONStream.cpp _internal/Source/JSONAllocator.cpp \
- _internal/TestSuite/TestSuite2/JSON_Base64/json_decode64.cpp \
- _internal/TestSuite/TestSuite2/JSON_Base64/json_encode64.cpp \
- _internal/TestSuite/TestSuite2/JSONDebug/JSON_ASSERT_SAFE.cpp \
- _internal/TestSuite/TestSuite2/JSONDebug/JSON_ASSERT.cpp \
- _internal/TestSuite/TestSuite2/JSONDebug/JSON_FAIL_SAFE.cpp \
- _internal/TestSuite/TestSuite2/JSONDebug/JSON_FAIL.cpp \
- _internal/TestSuite/TestSuite2/JSONGlobals/jsonSingleton.cpp \
- _internal/TestSuite/TestSuite2/JSONValidator/isValidArray.cpp \
- _internal/TestSuite/TestSuite2/JSONValidator/isValidMember.cpp \
- _internal/TestSuite/TestSuite2/JSONValidator/isValidNamedObject.cpp \
- _internal/TestSuite/TestSuite2/JSONValidator/isValidNumber.cpp \
- _internal/TestSuite/TestSuite2/JSONValidator/isValidObject.cpp \
- _internal/TestSuite/TestSuite2/JSONValidator/isValidPartialRoot.cpp \
- _internal/TestSuite/TestSuite2/JSONValidator/isValidRoot.cpp \
- _internal/TestSuite/TestSuite2/JSONValidator/isValidString.cpp \
- _internal/TestSuite/TestSuite2/JSONValidator/securityTest.cpp \
- _internal/TestSuite/TestSuite2/NumberToString/_areFloatsEqual.cpp \
- _internal/TestSuite/TestSuite2/NumberToString/_atof.cpp \
- _internal/TestSuite/TestSuite2/NumberToString/_ftoa.cpp \
- _internal/TestSuite/TestSuite2/NumberToString/_itoa.cpp \
- _internal/TestSuite/TestSuite2/NumberToString/_uitoa.cpp \
- _internal/TestSuite/TestSuite2/NumberToString/getLenSize.cpp \
- _internal/TestSuite/TestSuite2/NumberToString/isNumeric.cpp \
+ _internal/TestSuite2/JSON_Base64/json_decode64.cpp \
+ _internal/TestSuite2/JSON_Base64/json_encode64.cpp \
+ _internal/TestSuite2/JSONDebug/JSON_ASSERT_SAFE.cpp \
+ _internal/TestSuite2/JSONDebug/JSON_ASSERT.cpp \
+ _internal/TestSuite2/JSONDebug/JSON_FAIL_SAFE.cpp \
+ _internal/TestSuite2/JSONDebug/JSON_FAIL.cpp \
+ _internal/TestSuite2/JSONGlobals/jsonSingleton.cpp \
+ _internal/TestSuite2/JSONValidator/isValidArray.cpp \
+ _internal/TestSuite2/JSONValidator/isValidMember.cpp \
+ _internal/TestSuite2/JSONValidator/isValidNamedObject.cpp \
+ _internal/TestSuite2/JSONValidator/isValidNumber.cpp \
+ _internal/TestSuite2/JSONValidator/isValidObject.cpp \
+ _internal/TestSuite2/JSONValidator/isValidPartialRoot.cpp \
+ _internal/TestSuite2/JSONValidator/isValidRoot.cpp \
+ _internal/TestSuite2/JSONValidator/isValidString.cpp \
+ _internal/TestSuite2/JSONValidator/securityTest.cpp \
+ _internal/TestSuite2/NumberToString/_areFloatsEqual.cpp \
+ _internal/TestSuite2/NumberToString/_atof.cpp \
+ _internal/TestSuite2/NumberToString/_ftoa.cpp \
+ _internal/TestSuite2/NumberToString/_itoa.cpp \
+ _internal/TestSuite2/NumberToString/_uitoa.cpp \
+ _internal/TestSuite2/NumberToString/getLenSize.cpp \
+ _internal/TestSuite2/NumberToString/isNumeric.cpp \
$(CXXFLAGS) -o ./testapp
./testapp
The above is a diff. See [SO]: Run/Debug a Django application's UnitTests from the mouse right click context menu in PyCharm Community Edition? (@CristiFati's answer) (Patching utrunner section) for how to apply patches on Win (basically, every line that starts with one "+" sign goes in, and every line that starts with one "-" sign goes out). I am using Cygwin, btw.