Using boost with Bazel under Windows 10 and Visual Studio Community 2019 - c++

I have set up a simple C++ program that makes use of the boost filesystem module. To build the program I use Bazel 0.25.0. I am working under Windows 10 x64.
I installed Visual Studio 2019 Community Edtion and set BAZEL_VC to E:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC. I have installed the MSYS2 shell.
Here are my files (can be found also on GitHub):
WORKSPACE
workspace(name = "BoostFilesystemDemo")
load("#bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
# Boost
git_repository(
name = "com_github_nelhage_rules_boost",
commit = "6681419da0163d097d4e09c0756c0d8b785d2aa8",
remote = "https://github.com/nelhage/rules_boost",
shallow_since = "1556401984 -0700"
)
load("#com_github_nelhage_rules_boost//:boost/boost.bzl", "boost_deps")
boost_deps()
main.cpp
#include <iostream>
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
int main(int argc, char* argv[])
{
if (argc < 2)
{
std::cout << "Usage: tut1 path\n";
return 1;
}
std::cout << argv[1] << " " << file_size(argv[1]) << '\n';
return 0;
}
BUILD
cc_binary(
name = "FilesystemTest",
srcs = ["main.cpp"],
deps = [
"#boost//:filesystem",
],
)
When I try to build I receive the following error message (unfortunately mixed with some German language - Datei kann nicht gefunden werden means file not found)
PS E:\dev\BazelDemos\BoostFilesystemDemo> bazel build //...
INFO: Analyzed target //:FilesystemTest (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
ERROR: E:/dev/bazeldemos/boostfilesystemdemo/BUILD:1:1: Linking of rule '//:FilesystemTest' failed (Exit 1104)
LINK : fatal error LNK1104: Datei "libboost_filesystem-vc141-mt-x64-1_68.lib" kann nicht ge÷ffnet werden.
Target //:FilesystemTest failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 1.175s, Critical Path: 0.12s
INFO: 0 processes.
FAILED: Build did NOT complete successfully
Does anyone have some idea to fix this problem (compiling the source using Bazel 0.25.0 or up, Visual Studio 2019 Community Edition, Windows 10 x64, Target should be x64)? Using Ubuntu 18.04 everything went fine.
Switching to another git repository that provides boost is also fine for me.
I want to also to use other parts of the boost library such as boost signals2, boost log, boost algorithm and boost compute.

Modify the BUILD.boost this way:
diff --git a/BUILD.boost b/BUILD.boost
index a3a2195..2cffdda 100644
--- a/BUILD.boost
+++ b/BUILD.boost
## -623,6 +623,14 ## boost_library(
":system",
":type_traits",
],
+ defines = select({
+ ":linux_arm": [],
+ ":linux_x86_64": [],
+ ":osx_x86_64": [],
+ ":windows_x86_64": [
+ "BOOST_ALL_NO_LIB",
+ ],
+ }),
)
boost_library(
## -1491,6 +1499,14 ## boost_library(
":predef",
":utility",
],
+ defines = select({
+ ":linux_arm": [],
+ ":linux_x86_64": [],
+ ":osx_x86_64": [],
+ ":windows_x86_64": [q
+ "BOOST_ALL_NO_LIB",
I cloned the rules_boost repo and applied the above changes - the cloned repository can be used direclty in the WORKSPACE file:
workspace(name = "BoostFilesystemDemo")
load("#bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
# Boost
git_repository(
name = "com_github_nelhage_rules_boost",
commit = "f0d2a15d6dd5f0667cdaa6da9565ccf87b84c468",
remote = "https://github.com/Vertexwahn/rules_boost",
shallow_since = "1557766870 +0200"
)
load("#com_github_nelhage_rules_boost//:boost/boost.bzl", "boost_deps")
boost_deps()
Currently, a pull request is running to merge these changes into the original repository: https://github.com/nelhage/rules_boost/pull/123

Related

Bazel - gtkmm library - missing dependencies

I have created a Bazel project (C++) and have tried to include the gtkmm library in my project.
I get the below error, that header files are missing, e.g.:
Showing Recent Messages
../mediapipe/external/gtkmm/gtkmm/accelerator.cc:18:10: fatal error: 'glibmm/utility.h' file not found
#include <glibmm/utility.h>
^~~~~~~~~~~~~~~~~~
1 error generated.
Error in child process '/usr/bin/xcrun'. 1
Aspect #tulsi//:tulsi/tulsi_aspects.bzl%tulsi_outputs_aspect of //mediapipe/examples/motionize/motionize:motionize up-to-date:
bazel-bin/mediapipe/examples/motionize/motionize/motionize.tulsiouts
/private/var/tmp/_bazel_{user}/5a416b3c18d355cbf1dfbcf0102ffc0b/external/gtkmm/BUILD.bazel:7:11: Compiling gtkmm/accelerator.cc failed: (Aborted): wrapped_clang_pp failed: error executing command
Elapsed time: 10.459s, Critical Path: 0.45s
12 processes: 12 internal.
<*> Running Bazel completed in 10826.492 ms
Build did NOT complete successfully
The includes in the library do not seem to find the header files in general, not just this one. I have tried different setups and also a local repository instead of http_archive and I still get this kind of errors
Note: I am using Tulsi to create the Bazel xcode project
I have added the following in my WORKSPACE file:
http_archive(
name = "gtkmm",
strip_prefix = "gtkmm-4.8.0/gtk",
urls = ["https://github.com/GNOME/gtkmm/archive/refs/tags/4.8.0.zip"],
build_file = "#//third_party:gtkmm.BUILD",
)
I also added the gtkmm.BUILD file which looks like this:
package(default_visibility = ["//visibility:public"])
licenses(["notice"]) # BSD license
exports_files(["LICENSE"])
cc_library(
name = "main",
srcs = glob(
["**/*.cc"],
),
hdrs = glob([
"*.h",
"gtkmm/**/object_p.h",
"**/*.hg",
"**/*.h",
"**/selectiondata_private.h"
]),
includes = glob([
"*.h",
"gtkmm/**/object_p.h",
"**/*.hg",
"**/*.h",
"**/selectiondata_private.h"
]),
copts = ["-Iexternal/gtkmm-4.8.0/gtk"],
linkopts = ["-pthread"],
visibility = ["//visibility:public"],
)
Finally my BUILD file:
cc_binary(
name="motionize",
srcs=["main.cpp"],
copts = [
"-Iexternal/gtkmm-4.8.0/gtk/gtkmm",
"-Iexternal/gtkmm-4.8.0/gtk/",
"-Iexternal/gtkmm-4.8.0/gtk/src",
"-Iexternal/gtkmm-4.8.0/gtk/gtkmm/private",
],
deps=[
"//mediapipe/framework:calculator_framework",
"//mediapipe/calculators/core:pass_through_calculator",
"//mediapipe/calculators/image:image_cropping_calculator",
"//mediapipe/calculators/image:scale_image_calculator",
"//mediapipe/framework/formats:image_frame",
"//mediapipe/framework/formats:image_frame_opencv",
"//mediapipe/framework/port:opencv_core",
"//mediapipe/framework/port:opencv_highgui",
"//mediapipe/framework/port:opencv_imgproc",
"//mediapipe/framework/port:opencv_imgcodecs",
"//mediapipe/framework/port:opencv_video",
"//mediapipe/framework/port:parse_text_proto",
"//mediapipe/framework/port:status",
"#gtkmm//:main",
],
)

How to pass argument from command line to bazel file

I have a variable declared in .bzl file example: VERSION_NUMBER = "00".
I want to override this variable from command line when i build different version of the project.
example: bazel build target --sunbversion_number= "99"
I want to change this variable because it is invoked in some function to create the name of the output paths.
exammple: for version "00" the outputfile will be: name_00.extension
and for version "99" the outputfile will be: name_99.extension
This is my example:
in .bzl file i declared:
SUBVERSION_NUMBER = "99"
and a fucntion that return a name of the file regarding to the SUBVERSION_NUMBER
def get_name(SUBVERSION_NUMBER):
return "test-"+SUBVERSION_NUMBER
OUTPUT_NAME = get_name("99")
Then my genrule():
genrule(name = "test",
srcs = [srcs],
outs = [OUTPUT_NAME+".tek"],
cmd = "cmd to generate the file" )
when i build this rule i get the output file test-99.tek
what i want is when i run bazel build test --//version=01 or any other suggested solution, i want to get output test-01.tek
Thanks
There is no way to get values from the command line into a bzl file like that, but there are a few options, depending on exactly what you want to do.
One way is to use "stamping" to set the version, and then put the versioned file in a zip file with a known name, e.g. using a genrule. Build stamping is usually used for embedding a version number and other information into the output files themselves, but can be used here too. A zip file is necessary because the output file name has to be known at load time (i.e. before any configuration data from the command line is processed at analysis time).
Something like this:
# out.txt is the original unversioned file
genrule(
name = "gen_out",
outs = ["out.txt"],
cmd = "echo foo > $#",
)
genrule(
name = "gen_versioned_out",
outs = ["out_versioned.zip"],
srcs = [":out.txt"],
tools = ["#bazel_tools//tools/zip:zipper"],
stamp = True,
cmd = """
# bazel-out/stable-status.txt is created when stamp = True
# Value of BUILD_EMBED_LABEL key comes from --embed_label on the command line
version="$$(grep BUILD_EMBED_LABEL bazel-out/stable-status.txt | cut -d ' ' -f 2)"
# Set a reasonable default if --embed_label was not specified
if [ -z "$$version" ]; then version="0"; fi
file="$$(basename $<)"
name="$${file%%.*}"
ext="$${file#*.}"
versioned_file="$${name}_$${version}.$${ext}"
# zipper allows specifying the name of the file in the zip directly, unlike the
# regular zip tool.
# c = create
# $# = output file from "outs"
# $< = input file from "srcs"
# $$versioned_file=$< = "put this file in to the archive with this name"
$(location #bazel_tools//tools/zip:zipper) c "$#" "$$versioned_file=$<"
""",
)
Then:
$ bazel build out_versioned.zip --embed_label=99
INFO: Analyzed target //:out_versioned.zip (7 packages loaded, 19 targets configured).
INFO: Found 1 target...
Target //:out_versioned.zip up-to-date:
bazel-bin/out_versioned.zip
INFO: Elapsed time: 0.340s, Critical Path: 0.10s
INFO: 3 processes: 1 internal, 2 linux-sandbox.
INFO: Build completed successfully, 3 total actions
$ unzip -l bazel-bin/out_versioned.zip
Archive: bazel-bin/out_versioned.zip
Length Date Time Name
--------- ---------- ----- ----
4 2010-01-01 00:00 out_99.txt
--------- -------
4 1 file
So that results in a zip file with a known name containing the versioned file.
Another approach is to use "User-defined build settings":
https://docs.bazel.build/versions/master/skylark/config.html#user-defined-build-settings
Something like this:
defs.bzl:
def _version_file_impl(ctx):
version = ctx.attr._version[VersionProvider].version
name, extension = ctx.file.file.basename.rsplit(".", 1)
versioned_file = ctx.actions.declare_file(
"%s_%s.%s" % (name, version, extension))
copy_args = ctx.actions.args()
copy_args.add_all([ctx.file.file, versioned_file])
ctx.actions.run_shell(
inputs = [ctx.file.file],
outputs = [versioned_file],
command = 'cp "$1" "$2"',
arguments = [copy_args])
return DefaultInfo(files = depset([versioned_file]))
version_file = rule(
implementation = _version_file_impl,
attrs = {
"file": attr.label(mandatory = True, allow_single_file = True),
"_version": attr.label(default = "//:version"),
}
)
VersionProvider = provider(fields = ["version"])
def _version_flag_impl(ctx):
return VersionProvider(version = ctx.build_setting_value)
version_flag = rule(
implementation = _version_flag_impl,
build_setting = config.int(flag = True),
)
BUILD:
load(":defs.bzl", "version_flag", "version_file")
version_flag(
name = "version",
build_setting_default = 0,
)
genrule(
name = "gen_out",
outs = ["out.txt"],
cmd = "echo foo > $#",
)
version_file(
name = "versioned_out",
file = ":out.txt",
)
Then:
$ bazel build :versioned_out --//:version=99
INFO: Analyzed target //:versioned_out (5 packages loaded, 10 targets configured).
INFO: Found 1 target...
Target //:versioned_out up-to-date:
bazel-bin/out_99.txt
INFO: Elapsed time: 0.322s, Critical Path: 0.06s
INFO: 3 processes: 1 internal, 2 linux-sandbox.
INFO: Build completed successfully, 3 total actions
So that results in a file with the version in its name. There's no label to refer to the versioned file itself though, so bazel build :out_99.txt nor srcs = [":out_99.txt"] will work, you have to go through the versioned_out target.
Update:
Here's a version that can version multiple outputs:
defs.bzl:
def _versioned_files_impl(ctx):
version = ctx.attr._version[VersionProvider].version
versioned_files = []
for f in ctx.attr.src.files.to_list():
name, extension = f.basename.rsplit(".", 1)
versioned_file = ctx.actions.declare_file(
"%s_%s.%s" % (name, version, extension))
versioned_files.append(versioned_file)
copy_args = ctx.actions.args()
copy_args.add_all([f, versioned_file])
ctx.actions.run_shell(
inputs = [f],
outputs = [versioned_file],
command = 'cp "$1" "$2"',
arguments = [copy_args])
return DefaultInfo(files = depset(versioned_files))
versioned_files = rule(
implementation = _versioned_files_impl,
attrs = {
"src": attr.label(mandatory = True),
"_version": attr.label(default = "//:version"),
}
)
VersionProvider = provider(fields = ["version"])
def _version_flag_impl(ctx):
return VersionProvider(version = ctx.build_setting_value)
version_flag = rule(
implementation = _version_flag_impl,
build_setting = config.int(flag = True),
)
BUILD:
load(":defs.bzl", "version_flag", "versioned_files")
version_flag(
name = "version",
build_setting_default = 0,
)
genrule(
name = "gen_out",
outs = ["foo.txt", "bar.txt", "baz.txt"],
cmd = """
echo foo > $(location foo.txt)
echo bar > $(location bar.txt)
echo baz > $(location baz.txt)
""",
)
versioned_files(
name = "versioned_files",
src = ":gen_out",
)
usage:
$ bazel build versioned_files --//:version=123
INFO: Analyzed target //:versioned_files (5 packages loaded, 9 targets configured).
INFO: Found 1 target...
Target //:versioned_files up-to-date:
bazel-bin/foo_123.txt
bazel-bin/bar_123.txt
bazel-bin/baz_123.txt
INFO: Elapsed time: 0.491s, Critical Path: 0.06s
INFO: 5 processes: 1 internal, 4 linux-sandbox.
INFO: Build completed successfully, 5 total actions
Update:
An example of putting the version in a cc target's define:
BUILD:
cc_binary(
name = "main",
srcs = ["main.cc"],
defines = ["VERSION=\\\"$(VERSION)\\\""],
)
main.cc:
#include <iostream>
#ifndef VERSION
#define VERSION "0.0.0"
#endif
int main() {
std::cout << "version: " << VERSION << std::endl;
return 0;
}
build and run:
$ bazel run main --define=VERSION=1.2.3
INFO: Analyzed target //:main (15 packages loaded, 52 targets configured).
INFO: Found 1 target...
Target //:main up-to-date:
bazel-bin/main
INFO: Elapsed time: 0.524s, Critical Path: 0.26s
INFO: 6 processes: 4 internal, 2 linux-sandbox.
INFO: Build completed successfully, 6 total actions
INFO: Build completed successfully, 6 total actions
version: 1.2.3
Combining the above methods, you would have to specify both --//:version=1.2.3 and --define=VERSION=1.2.3 on the command line. There's a way to have only --//:version, but it would require another Starlark rule like versioned_files which either
generates a file with the version in it that goes in the data attribute and the program reads at runtime, or
a Starlark rule which generates a C++ file with the version in it, which then gets put in the sources of a cc_library, which the rest of your program can depend on and use at compile time.
These approaches will probably require refactoring your program.

How to fix Cannot find libcocos2dcpp.so when trying to support 64 bit

i have a cocos2dx game in android studio and when I'm trying to make it support 64 bit requirement then i got this error "couldn't find "libcocos2dcpp.so" " when i start project on my phone
what I've done to support the 64 bit :
i searched on cocos2dx forum for solution to support 64 bit and i found a solution :
* i've Modified Application.MK file : adding APP_ABI := armeabi armeabi-v7a arm64-v8a
* gradle.properties : adding PROP_APP_ABI=armeabi-v7a:arm64-v8a
* build.gradle : adding ndk.abiFilters 'armeabi-v7a', 'arm64-v8a'
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.xxxxx.kidslearngame-oq27wbETBHeT2MFhWg9cOw==/base.apk", zip file "/data/app/com.xxx.kidslearngame-oq27wbETBHeT2MFhWg9cOw==/split_lib_dependencies_apk.apk", zip file "/data/app/com.xxx.kidslearngame-oq27wbETBHeT2MFhWg9cOw==/split_lib_resources_apk.apk", zip file "/data/app/com.xxxx.kidslearngame-oq27wbETBHeT2MFhWg9cOw==/split_lib_slice_0_apk.apk", zip file "/data/app/com.xxxx.kidslearngame-oq27wbETBHeT2MFhWg9cOw==/split_lib_slice_1_apk.apk", zip file "/data/app/com.xxx.kidslearngame-oq27wbETBHeT2MFhWg9cOw==/split_lib_slice_2_apk.apk", zip file "/data/app/com.xxxx.kidslearngame-oq27wbETBHeT2MFhWg9cOw==/split_lib_slice_3_apk.apk", zip file "/data/app/com.xxx.kidslearngame-oq27wbETBHeT2MFhWg9cOw==/split_lib_slice_4_apk.apk", zip file "/data/app/com.xxx.kidslearngame-oq27wbETBHeT2MFhWg9cOw==/split_lib_slice_5_apk.apk", zip file "/data/app/com.xxx.kidslearngame-oq27wbETBHeT2MFhWg9cOw==/split_lib_slice_6_apk.apk", zip file "/data/app/com.xxx.kidslearngame-oq27wbETBHeT2MFhWg9cOw==/split_lib_slice_7_apk.apk", zip file "/data/app/com.xxx.kidslearngame-oq27wbETBHeT2MFhWg9cOw==/split_lib_slice_8_apk.apk", zip file "/data/app/com.xxxx.kidslearngame-oq27wbETBHeT2MFhWg9cOw==/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.xxx.kidslearngame-oq27wbETBHeT2MFhWg9cOw==/lib/arm64, /system/lib64, /system/vendor/lib64]]] couldn't find "libcocos2dcpp.so"
those are the solution that i found but when i run the app on my phone it's crashing and giving me the error above but when i removed ndk.abiFilters 'armeabi-v7a', 'arm64-v8a' from gradle.build it's working good but when i upload it to play store they show me the warning message "your app those not support the 64 bit requirement "
Perhaps you should clear the project and in Android Studio select in the menu File -> Invalidate Caches / Restart
Below I give the settings that work for me:
In Application.mk
APP_ABI := arm64-v8a
In gradle.properties
PROP_APP_ABI=armeabi-v7a:arm64-v8a
In app/build.gradle
android {
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
buildToolsVersion PROP_BUILD_TOOLS_VERSION
def versionMajor = 0
def versionMinor = 9
def versionPatch = 0
def versionBuild = 0
defaultConfig {
applicationId "YOUR APP ID"
minSdkVersion PROP_MIN_SDK_VERSION
targetSdkVersion PROP_TARGET_SDK_VERSION
// versionCode 1
// versionName "1.0"
versionCode versionMajor * 10000 + versionMinor * 1000 + versionPatch * 100 + versionBuild
versionName "${versionMajor}.${versionMinor}.${versionPatch}"
externalNativeBuild {
if (PROP_BUILD_TYPE == 'ndk-build') {
ndkBuild {
targets 'MyGame'
arguments 'NDK_TOOLCHAIN_VERSION=clang'
arguments '-j' + Runtime.runtime.availableProcessors()
}
}
else if (PROP_BUILD_TYPE == 'cmake') {
cmake {
targets 'MyGame'
arguments "-DCMAKE_FIND_ROOT_PATH=", "-DANDROID_STL=c++_static", "-DANDROID_TOOLCHAIN=clang", "-DANDROID_ARM_NEON=TRUE", \
"-DUSE_CHIPMUNK=TRUE", "-DUSE_BULLET=TRUE"
cppFlags "-frtti -fexceptions"
// prebuilt root must be defined as a directory which you have right to access or create if you use prebuilt
// set "-DGEN_COCOS_PREBUILT=ON" and "-DUSE_COCOS_PREBUILT=OFF" to generate prebuilt, this way build cocos2d-x libs
// set "-DGEN_COCOS_PREBUILT=OFF" and "-DUSE_COCOS_PREBUILT=ON" to use prebuilt, this way not build cocos2d-x libs
//arguments "-DCOCOS_PREBUILT_ROOT=/Users/laptop/cocos-prebuilt"
//arguments "-DGEN_COCOS_PREBUILT=OFF", "-DUSE_COCOS_PREBUILT=OFF"
}
}
}
ndk {
abiFilters = []
abiFilters.addAll(PROP_APP_ABI.split(':').collect{it as String})
}
}
splits {
// Configures multiple APKs based on ABI.
abi {
// Enables building multiple APKs per ABI.
enable true
//enable gradle.startParameter.taskNames.contains(":app:assembleRelease")
//enable project.hasProperty('splitApks')
// By default all ABIs are included, so use reset() and include to specify that we only
// want APKs for x86, armeabi-v7a, and mips.
reset()
// Specifies a list of ABIs that Gradle should create APKs for.
include "x86", "x86_64", "armeabi-v7a", "arm64-v8a"
// Specifies that we want to also generate a universal APK that includes all ABIs.
universalApk true
}
}
// Map for the version code that gives each ABI a value.
def abiCodes = ['x86':3, 'x86_64':4, 'armeabi-v7a':1, 'arm64-v8a':2]
// APKs for the same app that all have the same version information.
android.applicationVariants.all { variant ->
// Assigns a different version code for each output APK.
variant.outputs.each {
output ->
def abiName = output.getFilter(OutputFile.ABI)
output.versionCodeOverride = abiCodes.get(abiName, 0) * 1000000 + android.defaultConfig.versionCode
}
}
. . . . . . . . .
. . . . . . . . .
I hope this helps.

How to include contrib op in Tensorflow bazel build

I'm building for Android using selective registration and the //tensorflow/contrib/android:libtensorflow_inference.so target:
bazel build -c opt --copt="-DSELECTIVE_REGISTRATION" --copt="-DSUPPORT_SELECTIVE_REGISTRATION" //tensorflow/contrib/android:libtensorflow_inference.so --crosstool_top=//external:android/crosstool --host_crosstool_top=#bazel_tools//tools/cpp:toolchain --cpu=x86_64
Which works fine until I need to use an op that lives in contrib. Specifically I need access to ImageProjectiveTransform, which is part of the //tensorflow/contrib/image:image_ops_cc target. I tried modifying the //tensorflow/core:android_tensorflow_lib target to add it as a dependency:
# Full TensorFlow library with operator support. Use this unless reducing
# binary size (by packaging a reduced operator set) is a concern.
cc_library(
name = "android_tensorflow_lib",
srcs = if_android([":android_op_registrations_and_gradients"]),
copts = tf_copts(),
tags = [
"manual",
"notap",
],
visibility = ["//visibility:public"],
deps = [
":android_tensorflow_lib_lite",
":protos_all_cc_impl",
"//tensorflow/core/kernels:android_tensorflow_kernels",
"//tensorflow/contrib/image:image_ops_cc",
"//third_party/eigen3",
"#protobuf_archive//:protobuf",
],
alwayslink = 1,
)
But now the compile fails:
In file included from external/com_googlesource_code_re2/re2/bitstate.cc:25:
In file included from external/com_googlesource_code_re2/re2/prog.h:14:
In file included from external/androidndk/ndk/sources/cxx-stl/gnu-libstdc++/4.9/include/mutex:35:
external/androidndk/ndk/sources/cxx-stl/gnu-libstdc++/4.9/include/bits/c++0x_warning.h:32:2: error: This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
But if I specify C++11 in the bazel build call:
bazel build -c opt --copt="-std=c++11" --copt="-DSELECTIVE_REGISTRATION" --copt="-DSUPPORT_SELECTIVE_REGISTRATION" //tensorflow/contrib/android:libtensorflow_inference.so --crosstool_top=//external:android/crosstool --host_crosstool_top=#bazel_tools//tools/cpp:toolchain --cpu=x86_64
Then I get a different error:
ERROR: /private/var/tmp/_bazel_json/e38619818ff94aae50ac5b3bdbbe0f32/external/png_archive/BUILD:8:1: C++ compilation of rule '#png_archive//:png' failed (Exit 1)
error: invalid argument '-std=c++11' not allowed with 'C/ObjC'
Target //tensorflow/contrib/android:libtensorflow_inference.so failed to build
(I have no idea why anything in the Android build would be using Objective-C)
I also wanted to include ImageProjectiveTransform and encountered the same errors. I was able to successfully include it via the following steps, which are a modification of the procedure suggested here.
git clone https://github.com/tensorflow/tensorflow.git
git checkout r1.10
python tensorflow/tensorflow/python/tools/print_selective_registration_header.py --graphs PATH_TO_MODEL/model.pb > ops_to_register.h
cp ops_to_register.h tensorflow/tensorflow/core/framework/
cd tensorflow
bazel build -c opt --cxxopt="-DSELECTIVE_REGISTRATION" //tensorflow/contrib/android:libtensorflow_inference.so --host_crosstool_top=#bazel_tools//tools/cpp:toolchain --crosstool_top=//external:android/crosstool --cpu=armeabi-v7a --jobs 10 --cxxopt=-std=c++11
cp bazel-bin/tensorflow/contrib/android/libtensorflow_inference.so ANDROID_PROJECT/libs/armeabi-v7a/
However, before running this, the following modifications were necessary.
These changes resolved compiling errors:
diff --git a/tensorflow/contrib/image/kernels/image_ops.h b/tensorflow/contrib/image/kernels/image_ops.h
index 209aa24..b8ec643 100644
--- a/tensorflow/contrib/image/kernels/image_ops.h
+++ b/tensorflow/contrib/image/kernels/image_ops.h
## -97,8 +97,8 ## class ProjectiveGenerator {
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T
nearest_interpolation(const DenseIndex batch, const float y, const float x,
const DenseIndex channel, const T fill_value) const {
- return read_with_fill_value(batch, DenseIndex(std::round(y)),
- DenseIndex(std::round(x)), channel, fill_value);
+ return read_with_fill_value(batch, DenseIndex(::round(y)),
+ DenseIndex(::round(x)), channel, fill_value);
}
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE T
diff --git a/tensorflow/core/common_runtime/eager/BUILD b/tensorflow/core/common_runtime/eager/BUILD
index 7f28f3b..aa64220 100644
--- a/tensorflow/core/common_runtime/eager/BUILD
+++ b/tensorflow/core/common_runtime/eager/BUILD
## -150,7 +150,7 ## tf_cuda_library(
deps = select({
"//tensorflow:android": [
"//tensorflow/core:android_tensorflow_lib_lite",
- "//util/hash:farmhash_fingerprint",
+ #"//util/hash:farmhash_fingerprint",
],
"//conditions:default": [
"//tensorflow/core:core_cpu_lib",
## -223,7 +223,7 ## tf_cuda_library(
] + select({
"//tensorflow:android": [
"//tensorflow/core:android_tensorflow_lib_lite",
- "//util/hash:farmhash_fingerprint",
+ #"//util/hash:farmhash_fingerprint",
],
"//conditions:default": [
"//tensorflow/core:core_cpu",
This adds the files for missing ops and kernels to the build. For me, this included Asin, Sin, Cos, and ResizeArea in addition to ImageProjectiveTransform.
diff --git a/tensorflow/core/kernels/BUILD b/tensorflow/core/kernels/BUILD
index 7599cf7..8ebb77e 100644
--- a/tensorflow/core/kernels/BUILD
+++ b/tensorflow/core/kernels/BUILD
## -4936,6 +4936,7 ## filegroup(
filegroup(
name = "android_extended_ops_headers",
srcs = [
+ "//tensorflow/contrib/image:image_ops_op_lib",
"argmax_op.h",
"avgpooling_op.h",
"batch_matmul_op_impl.h",
## -4995,6 +4996,11 ## filegroup(
filegroup(
name = "android_extended_ops_group1",
srcs = [
+ "//tensorflow/contrib/image:image_ops_kernels",
+ "resize_area_op.cc",
+ "cwise_op_asin.cc",
+ "cwise_op_cos.cc",
+ "cwise_op_sin.cc",
"argmax_op.cc",
"avgpooling_op.cc",
"batch_matmul_op_real.cc",
This causes tf.contrib to be registered before loading the frozen graph:
diff --git a/tensorflow/python/tools/print_selective_registration_header.py b/tensorflow/python/tools/print_selective_registration_header.py
index 21d7de0..923ad76 100644
--- a/tensorflow/python/tools/print_selective_registration_header.py
+++ b/tensorflow/python/tools/print_selective_registration_header.py
## -40,6 +40,8 ## import sys
from tensorflow.python.platform import app
from tensorflow.python.tools import selective_registration_header_lib
+from tensorflow import contrib
+contrib.resampler
FLAGS = None
This shows how to find the *.cc files with missing ops so they can be added to BUILD.
cd <tensorflow_repo>/tensorflow/core/kernels
for i in <op_list>
do
echo ====
echo $i
echo ====
grep -Rl \”$i\” .
done

Compiling PythonService.cpp from win32 python extension build

I need some help with building pythonservice.exe (PythonService.cpp) from https://github.com/kovidgoyal/pywin32/tree/master/win32/src.
It is said (https://github.com/kovidgoyal/pywin32) that VS2015 is required, so I downloaded the community version. I opened a new win32 console project and imported to source files only the PythonService.cpp.
In project settings I have:
Include directories: C:\Python27_32bit\include;C:\pywin32-master\win32\src;$(VC_IncludePath);$(WindowsSDK_IncludePath);
Library directories: C:\Python27\Lib\site-packages\win32\libs;C:\Python27_32bit\libs;C:\pywin32-master\win32\src;$(LibraryPath);C:\pywin32-master\lib\x32\win32\libs;
Now, when building I get the unresolved external symbol error:
1>PythonService.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) char * __cdecl GetPythonTraceback(struct _object *,struct _object *,struct _object *)" (__imp_?GetPythonTraceback##YAPADPAU_object##00#Z)
GetPythonTraceback is defined in PyWinTypesmodule.cpp but when I add it to my project it gives other errors requiring other unresolved functions. I don't want to compile the whole win32 project. All I need is pythonservices.exe. Is this possible to accomplish without compiling the whole project?
Would be thankful for any help!
Thanks!
Alexei
I eventually found a solution to my question (not without help from #CristiFati 's answer!). I downloaded https://github.com/mhammond/pywin32/tree/b222 and used the setup.py script to build the whole package. Also, I installed the required SDK package (for python 2.6+ Microsoft Windows SDK for Windows 7 and .NET Framework 4 (version 7.1)). After digging a little bit I found that the compilation and linkage are done with Visual C++ for Python 9.0 and below are the compilation and linkage recipes for pythonservice.pyd and pythonservice.exe (python lists for cmd parameter to calls of os.spawnv(os.P_WAIT, executable, cmd):
For pythonservice.pyd:
['"C:\\Users\\username\\AppData\\Local\\Programs\\Common\\Microsoft\\Visual C++ for Python\\9.0\\WinSDK\\Bin\\x64\\mc.exe"','-h', 'win32/src', '-r', 'build\\temp.win-amd64-2.7\\Release\\win32/src', 'win32/src/PythonServiceMessages.mc']
['"C:\\Users\\username\\AppData\\Local\\Programs\\Common\\Microsoft\\Visual C++ for Python\\9.0\\WinSDK\\Bin\\x64\\rc.exe"','/fobuild\\temp.win-amd64-2.7\\Release\\win32/src/PythonServiceMessages.res','build\\temp.win-amd64-2.7\\Release\\win32/src\\PythonServiceMessages.rc']
['"C:\\Users\\username\\AppData\\Local\\Programs\\Common\\Microsoft\\Visual C++ for Python\\9.0\\VC\\Bin\\amd64\\cl.exe"','/c', '/nologo', '/Ox','/W3','/GS', '/DNDEBUG', '/MD', '-DDISTUTILS_BUILD', '-D_CRT_SECURE_NO_WARNINGS','-Icom/win32com/src/include', '-Iwin32/src', '-IC:\\Python27\\include', '-IC:\\Python27\\PC','"-IC:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.1A\\include"', '/Tpwin32/src/PythonService.cpp','/Fobuild\\temp.win-amd64-2.7\\Release\\win32/src/PythonService.obj', '-DPYSERVICE_BUILD_DLL', '/Zi','/Fdbuild\\temp.win-amd64-2.7\\Release\\servicemanager_vc.pdb', '/EHsc', '/DUNICODE', '/D_UNICODE', '/DWINNT']
['"C:\\Users\\username\\AppData\\Local\\Programs\\Common\\Microsoft\\Visual C++ for Python\\9.0\\VC\\Bin\\amd64\\link.exe"', '/DLL', '/nologo', '/INCREMENTAL:NO', '/LIBPATH:C:\\Python27\\libs', '/LIBPATH:C:\\Python27\\PCbuild\\amd64', '/LIBPATH:C:\\Python27\\PC\\VS9.0\\amd64', '/LIBPATH:build\\temp.win-amd64-2.7\\Release', '"/LIBPATH:C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.1A\\lib\\x64"', 'user32.lib', 'ole32.lib', 'advapi32.lib', 'shell32.lib', '/EXPORT:initservicemanager', 'build\\temp.win-amd64-2.7\\Release\\win32/src/PythonServiceMessages.res', 'build\\temp.win-amd64-2.7\\Release\\win32/src/PythonService.obj', '/OUT:build\\lib.win-amd64-2.7\\win32\\servicemanager.pyd', '/IMPLIB:build\\temp.win-amd64-2.7\\Release\\win32/src\\servicemanager.lib', '/MANIFEST:NO', '/MACHINE:amd64', '/BASE:0x1e7d0000', '/DEBUG', '/PDB:build\\temp.win-amd64-2.7\\Release\\servicemanager.pdb']
For pythonservice.exe:
['"C:\\Users\\username\\AppData\\Local\\Programs\\Common\\Microsoft\\Visual C++ for Python\\9.0\\VC\\Bin\\amd64\\cl.exe"','/c', '/nologo', '/Ox', '/W3', '/GS-', '/DNDEBUG', '/MD', '-DDISTUTILS_BUILD', '-D_CRT_SECURE_NO_WARNINGS','-Icom/win32com/src/include', '-Iwin32/src', '-IC:\\Python27\\include', '-IC:\\Python27\\PC','"-IC:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.1A\\include"','/Tpwin32\\src\\PythonService.cpp', '/Fobuild\\temp.win-amd64-2.7\\Release\\pythonservice\\win32\\src\\PythonService.obj','/Zi', '/Fdbuild\\temp.win-amd64-2.7\\Release\\pythonservice_vc.pdb', '/EHsc', '/DUNICODE', '/D_UNICODE', '/DWINNT']
['"C:\\Users\\username\\AppData\\Local\\Programs\\Common\\Microsoft\\Visual C++ for Python\\9.0\\WinSDK\\Bin\\x64\\rc.exe"','-DDISTUTILS_BUILD', '-D_CRT_SECURE_NO_WARNINGS', '-Icom/win32com/src/include', '-Iwin32/src', '-IC:\\Python27\\include','-IC:\\Python27\\PC', '"-IC:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.1A\\include"','/fobuild\\temp.win-amd64-2.7\\Release\\pythonservice\\win32\\src\\PythonService.res', 'win32\\src\\PythonService.rc']
['"C:\\Users\\username\\AppData\\Local\\Programs\\Common\\Microsoft\\Visual C++ for Python\\9.0\\VC\\Bin\\amd64\\link.exe"','/nologo', '/INCREMENTAL:NO', '/LIBPATH:C:\\Python27\\libs', '/LIBPATH:C:\\Python27\\PCbuild\\amd64','/LIBPATH:C:\\Python27\\PC\\VS9.0\\amd64', '/LIBPATH:build\\temp.win-amd64-2.7\\Release','"/LIBPATH:C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.1A\\lib\\x64"', 'user32.lib', 'advapi32.lib', 'ole32.lib','shell32.lib', 'build\\temp.win-amd64-2.7\\Release\\pythonservice\\win32\\src\\PythonService.obj','build\\temp.win-amd64-2.7\\Release\\pythonservice\\win32\\src\\PythonService.res','/OUT:build\\lib.win-amd64-2.7\\win32\\pythonservice.exe','/MANIFESTFILE:build\\temp.win-amd64-2.7\\Release\\pythonservice\\win32\\src\\pythonservice.exe.manifest','/SUBSYSTEM:CONSOLE', '/MACHINE:amd64', '/DEBUG', '/PDB:build\\temp.win-amd64-2.7\\Release\\pythonservice.pdb']
['mt.exe', '-nologo', '-manifest','build\\temp.win-amd64-2.7\\Release\\pythonservice\\win32\\src\\pythonservice.exe.manifest.orig','-outputresource:build\\lib.win-amd64-2.7\\win32\\pythonservice.exe;1']
['C:\\Python27\\python.exe', 'C:\\Python27\\Lib\\site-packages\\win32\\lib\\win32verstamp.py', '--version=2.7.222.1', '--comments=https://github.com/mhammond/pywin32', '--original-filename=pythonservice.exe','--product=PyWin32', '--quiet', 'build\\lib.win-amd64-2.7\\win32\\pythonservice.exe']
The 1st thing that I see here is combining Python 2.7 and VStudio 2015. According to [Python.Wiki]: WindowsCompilers, for VStudion 2015 (or 14.0), you should use Python 3.5 or Python 3.6 (I have the former). Check [SO]: Simstring (python) installation in windows (#CristiFati's answer) - (the 1st part), about compatibilities and restrictions in terms of:
Platform
Tools versions
Architecture
Also, some (basic) information about building C code on Win: [SO]: LNK2005 Error in CLR Windows Form (#CristiFati's answer)
Downloaded original PyWin32 from: [GitHub]: mhammond/pywin32 - (b222) (to pywin32-b222.zip). The "${PYWIN32_SRC_DIR}\win32\src\PythonService.cpp" is identical to its correspondent from the URL you mentioned
Create a dir and cd to it (should be empty). This will be the %ROOT_DIR%, and all the paths that I'm going to use will be relative to it (except of course for absolute ones), and this will be the default dir (when unspecified)
Unpack the downloaded .zip somewhere. We (directly) need from it:
"${PYWIN32_SRC_DIR}\win32\src\PythonService.cpp" - as you mentioned it, the source code
"${PYWIN32_SRC_DIR}\win32\src\PythonServiceMessages.mc" - message text file
I copied them in a dir called src:
E:\Work\Dev\StackOverflow\q048931801>dir /b
src
E:\Work\Dev\StackOverflow\q048931801>dir /b "src"
PythonService.cpp
PythonServiceMessages.mc
Since the build involves resources and Custom Build Steps (that I'm not very good at), and also it doesn't involve lots of files, I'm not going to use the IDE
The next best approach would be to use Makefiles, but since VStudio has a bug [MS.MSDN]: ntwin32.mak not found:
It affects VStudio 2015 as well
It requires a one time fix
I did the fix on my machine and it works, but you most likely didn't on yours, and I don't want to unnecessarily burden you with this step
I am going to do everything manually
Setting up VStudio environment:
[MS.Docs]: Use the MSVC toolset from the command line
You could also check [SO]: How to build a DLL version of libjpeg 9b? (#CristiFati's answer) (1st part) for more details about manually building
I'm using vcvarsall.bat ([MS.MSDN]: Where is vcvarsall.bat file?) from the command line
E:\Work\Dev\StackOverflow\q048931801>"c:\Install\x86\Microsoft\Visual Studio Community\2015\VC\vcvarsall.bat" amd64
You'll (obviously) need to supply your VStudio installation path
amd64 is because I only have the 64bit (x64 or AMD64) version of Python 3.5 installed
Compile the message file into a resource file - using mc.exe ([MS.Docs]: Message Compiler (MC.exe))
E:\Work\Dev\StackOverflow\q048931801>mc "src\PythonServiceMessages.mc"
MC: Compiling src\PythonServiceMessages.mc
E:\Work\Dev\StackOverflow\q048931801>dir /b
MSG00001.bin
PythonServiceMessages.h
PythonServiceMessages.rc
src
As seen, it generated 3 new files
Compile the resource file - using rc.exe ([MS.Docs]: Resource Compiler)
E:\Work\Dev\StackOverflow\q048931801>rc /NOLOGO /r "PythonServiceMessages.rc"
E:\Work\Dev\StackOverflow\q048931801>dir /b
MSG00001.bin
PythonServiceMessages.h
PythonServiceMessages.rc
PythonServiceMessages.res
src
Done with the resources, going to the code (PythonService.cpp). As you already mentioned, it won't compile OOTB. I'm not going to list all the failed attempts, instead I'm going to list the steps I took, and only show the final (successful) compile. So, the file needs code from other files. The simplest way is to copy it from the other files and place it in this one. I chose to paste it around line #1530 (just before the "* Entry points" section):
PyWinTypesModule.cpp - GetPythonTraceback function (lines 1142 - 1235)
PyUnicode.cpp - PyWin_AutoFreeBstr::PyWin_AutoFreeBstr, PyWin_AutoFreeBstr::~PyWin_AutoFreeBstr, PyWin_AutoFreeBstr::SetBstr (lines 204 - 219)
Either apply the changes manually, or save:
--- PythonService.cpp.orig 2018-01-20 21:43:10.000000000 +0200
+++ PythonService.cpp 2018-02-23 20:02:20.186966800 +0200
## -1529,6 +1529,120 ##
}
}
+// #TODO: cfati - copied from PyUnicode.cpp (lines 204 - 219)
+PyWin_AutoFreeBstr::PyWin_AutoFreeBstr( BSTR bstr /*= NULL*/ )
+ : m_bstr(bstr)
+{
+ return;
+}
+
+PyWin_AutoFreeBstr::~PyWin_AutoFreeBstr()
+{
+ SysFreeString(m_bstr);
+}
+
+void PyWin_AutoFreeBstr::SetBstr( BSTR bstr )
+{
+ SysFreeString(m_bstr);
+ m_bstr = bstr;
+}
+
+
+// #TODO: cfati - copied from PyWinTypesModule.cpp (lines 1142 - 1235)
+// Function to format a python traceback into a character string.
+#define GPEM_ERROR(what) {errorMsg = "<Error getting traceback - " ## what ## ">";goto done;}
+char *GetPythonTraceback(PyObject *exc_type, PyObject *exc_value, PyObject *exc_tb)
+{
+ // Sleep (30000); // Time enough to attach the debugger (barely)
+ char *result = NULL;
+ char *errorMsg = NULL;
+ PyObject *modStringIO = NULL;
+ PyObject *modTB = NULL;
+ PyObject *obFuncStringIO = NULL;
+ PyObject *obStringIO = NULL;
+ PyObject *obFuncTB = NULL;
+ PyObject *argsTB = NULL;
+ PyObject *obResult = NULL;
+
+ /* Import the modules we need - cStringIO and traceback */
+#if (PY_VERSION_HEX < 0x03000000)
+ modStringIO = PyImport_ImportModule("cStringIO");
+#else
+ // In py3k, cStringIO is in "io"
+ modStringIO = PyImport_ImportModule("io");
+#endif
+
+ if (modStringIO==NULL) GPEM_ERROR("cant import cStringIO");
+ modTB = PyImport_ImportModule("traceback");
+ if (modTB==NULL) GPEM_ERROR("cant import traceback");
+
+ /* Construct a cStringIO object */
+ obFuncStringIO = PyObject_GetAttrString(modStringIO, "StringIO");
+ if (obFuncStringIO==NULL) GPEM_ERROR("cant find cStringIO.StringIO");
+ obStringIO = PyObject_CallObject(obFuncStringIO, NULL);
+ if (obStringIO==NULL) GPEM_ERROR("cStringIO.StringIO() failed");
+
+ /* Get the traceback.print_exception function, and call it. */
+ obFuncTB = PyObject_GetAttrString(modTB, "print_exception");
+ if (obFuncTB==NULL) GPEM_ERROR("cant find traceback.print_exception");
+ argsTB = Py_BuildValue("OOOOO"
+#if (PY_VERSION_HEX >= 0x03000000)
+ "i"
+ // Py3k has added an undocumented 'chain' argument which defaults to True
+ // and causes all kinds of exceptions while trying to print a goddam exception
+#endif
+ ,
+ exc_type ? exc_type : Py_None,
+ exc_value ? exc_value : Py_None,
+ exc_tb ? exc_tb : Py_None,
+ Py_None, // limit
+ obStringIO
+#if (PY_VERSION_HEX >= 0x03000000)
+ ,0 // Goddam undocumented 'chain' param, which defaults to True
+#endif
+ );
+ if (argsTB==NULL) GPEM_ERROR("cant make print_exception arguments");
+
+ obResult = PyObject_CallObject(obFuncTB, argsTB);
+ if (obResult==NULL){
+ // Chain parameter when True causes traceback.print_exception to fail, leaving no
+ // way to see what the original problem is, or even what error print_exc raises
+ // PyObject *t, *v, *tb;
+ // PyErr_Fetch(&t, &v, &tb);
+ // PyUnicodeObject *uo=(PyUnicodeObject *)v;
+ // DebugBreak();
+ GPEM_ERROR("traceback.print_exception() failed");
+ }
+ /* Now call the getvalue() method in the StringIO instance */
+ Py_DECREF(obFuncStringIO);
+ obFuncStringIO = PyObject_GetAttrString(obStringIO, "getvalue");
+ if (obFuncStringIO==NULL) GPEM_ERROR("cant find getvalue function");
+ Py_DECREF(obResult);
+ obResult = PyObject_CallObject(obFuncStringIO, NULL);
+ if (obResult==NULL) GPEM_ERROR("getvalue() failed.");
+
+ /* And it should be a string all ready to go - duplicate it. */
+ if (PyString_Check(obResult))
+ result = strdup(PyString_AsString(obResult));
+#if (PY_VERSION_HEX >= 0x03000000)
+ else if (PyUnicode_Check(obResult))
+ result = strdup(_PyUnicode_AsString(obResult));
+#endif
+ else
+ GPEM_ERROR("getvalue() did not return a string");
+
+done:
+ if (result==NULL && errorMsg != NULL)
+ result = strdup(errorMsg);
+ Py_XDECREF(modStringIO);
+ Py_XDECREF(modTB);
+ Py_XDECREF(obFuncStringIO);
+ Py_XDECREF(obStringIO);
+ Py_XDECREF(obFuncTB);
+ Py_XDECREF(argsTB);
+ Py_XDECREF(obResult);
+ return result;
+}
/*************************************************************************
*
as "src\PythonService.diff" That 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:
E:\Work\Dev\StackOverflow\q048931801>"c:\Install\x64\Cygwin\Cygwin\AllVers\bin\patch.exe" "src\PythonService.cpp" "src\PythonService.diff"
patching file 'src\PythonService.cpp'
Compile the code - using cl.exe ([MS.Docs]: Compiling a C/C++ Program)
E:\Work\Dev\StackOverflow\q048931801>cl /GS /W1 /Zc:wchar_t /I"." /I"c:\Install\x64\Python\Python\3.5\include" /I"e:\Work\Dev\Fati\WinBuild\OPSWpython27\src\pywin32-b222\win32\src" /Gm- /O2 /Zc:inline /fp:precise /D "UNICODE" /D "_UNICODE" /D "WIN32" /D "WIN64" /D "NDEBUG" /D "BUILD_PYWINTYPES" /errorReport:prompt /WX- /Zc:forScope /Gd /MD /c "src\PythonService.cpp"
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
PythonService.cpp
E:\Work\Dev\StackOverflow\q048931801>dir /b "*.obj"
PythonService.obj
Arguments are standard ones ([MS.Docs]: Compiler Options Listed Alphabetically), specific for this case:
/D "BUILD_PYWINTYPES" (macro definition)
/D "WIN64" - 64bit
Include paths (/I) - you'll have to adapt them to match your paths:
"c:\Install\x64\Python\Python\3.5\include" (Python path)
"e:\Work\Dev\Fati\WinBuild\OPSWpython27\src\pywin32-b222\win32\src" (pywin32 path)
Link everything together - using link.exe ([MS.Docs]: Linking)
E:\Work\Dev\StackOverflow\q048931801>link /NOLOGO /MACHINE:X64 /SUBSYSTEM:CONSOLE /ERRORREPORT:PROMPT /LIBPATH:"c:\Install\x64\Python\Python\3.5\libs" /NXCOMPAT /DYNAMICBASE "kernel32.lib" "user32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "PythonService.obj" "PythonServiceMessages.res" /OUT:"PythonService.exe"
Creating library PythonService.lib and object PythonService.exp
E:\Work\Dev\StackOverflow\q048931801>dir /b "*.exe"
PythonService.exe
Again, arguments are standard ones ([MS.Docs]: Linker Options), specific for this case:
/MACHINE:X64 - 64bit
Library paths (/LIBPATH) - adapt it to match yours:
"c:\Install\x64\Python\Python\3.5\libs (Python path)
One last step before running the service. Since it depends on python35.dll, the OS must know where to look for it. Simplest way is to add its path to %PATH% ([MS.Docs]: Dynamic-Link Library Search Order)
E:\Work\Dev\StackOverflow\q048931801>set PATH=%PATH%;c:\Install\x64\Python\Python\3.5
E:\Work\Dev\StackOverflow\q048931801>PythonService.exe
P - Python Service Manager
Options:
-register - register the EXE - this should generally not be necessary.
-debug servicename [parms] - debug the Python service.
NOTE: You do not start the service using this program - start the
service using Control Panel, or 'net start service_name'