diff --git a/CMakeLists.txt b/CMakeLists.txt index acf11efe28..b129f2ec1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,17 +47,6 @@ set(OPEN_FOR_IDE OFF CACHE BOOL "Open this in an IDE (won't compile/link)") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") -find_package(Python COMPONENTS Interpreter) - -################################################################################ -# Pip -################################################################################ - -find_package(Virtualenv) -if (Virtualenv_FOUND) - set(BUILD_DOCUMENTATION ON) -endif() - ################################################################################ # Compiler configuration ################################################################################ diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt index 077fac75fb..2ef14e428c 100644 --- a/bindings/CMakeLists.txt +++ b/bindings/CMakeLists.txt @@ -4,3 +4,6 @@ add_subdirectory(python) if(BUILD_JAVA) add_subdirectory(java) endif() +if(WITH_GO) + add_subdirectory(go) +endif() diff --git a/bindings/flow/CMakeLists.txt b/bindings/flow/CMakeLists.txt index ef7965ffad..a959bf729a 100644 --- a/bindings/flow/CMakeLists.txt +++ b/bindings/flow/CMakeLists.txt @@ -39,3 +39,4 @@ add_custom_command(OUTPUT ${tar_file} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/packages COMMENT "Build fdb_flow package") add_custom_target(package_flow DEPENDS ${tar_file}) +add_dependencies(packages package_flow) diff --git a/bindings/go/CMakeLists.txt b/bindings/go/CMakeLists.txt new file mode 100644 index 0000000000..86ae628b07 --- /dev/null +++ b/bindings/go/CMakeLists.txt @@ -0,0 +1,110 @@ +set(SRCS + src/_stacktester/directory.go + src/fdb/directory/allocator.go + src/fdb/directory/node.go + src/fdb/futures.go + src/fdb/subspace/subspace.go + src/_stacktester/stacktester.go + src/fdb/directory/directory.go + src/fdb/doc.go + src/fdb/transaction.go + src/fdb/directory/directoryLayer.go + src/fdb/errors.go + src/fdb/keyselector.go + src/fdb/tuple/tuple.go + src/fdb/cluster.go + src/fdb/directory/directoryPartition.go + src/fdb/fdb.go + src/fdb/range.go + src/fdb/tuple/tuple_test.go + src/fdb/database.go + src/fdb/directory/directorySubspace.go + src/fdb/fdb_test.go + src/fdb/snapshot.go) + +set(GOPATH ${CMAKE_CURRENT_BINARY_DIR}) +set(GO_PACKAGE_ROOT github.com/apple/foundationdb/bindings/go) +set(GO_IMPORT_PATH ${GO_PACKAGE_ROOT}/src) +set(GO_DEST ${GOPATH}/src/${GO_PACKAGE_ROOT}) + +set(GO_PACKAGE_OUTDIR ${GOPATH}/pkg/${GOPLATFORM}/${GO_IMPORT_PATH}) + +file(MAKE_DIRECTORY ${GOPATH} + ${GO_DEST}) +set(go_options_file ${GO_DEST}/src/fdb/generated.go) + +set(go_env GOPATH=${GOPATH}) + +foreach(src_file IN LISTS SRCS) + set(dest_file ${GO_DEST}/${src_file}) + get_filename_component(dest_dir ${dest_file} DIRECTORY) + list(APPEND SRCS_OUT ${dest_file}) + add_custom_command(OUTPUT ${dest_file} + COMMAND ${CMAKE_COMMAND} -E make_directory ${dest_dir} && + ${CMAKE_COMMAND} -E copy ${src_file} ${dest_file} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${src_file} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Creating fdb_go_path") +endforeach() +add_custom_target(copy_go_sources DEPENDS ${SRCS_OUT}) +add_custom_command(OUTPUT ${go_options_file} + COMMAND ${GO_EXECUTABLE} run ${CMAKE_CURRENT_SOURCE_DIR}/src/_util/translate_fdb_options.go + -in ${CMAKE_SOURCE_DIR}/fdbclient/vexillographer/fdb.options + -out ${go_options_file} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/src/_util/translate_fdb_options.go + ${CMAKE_SOURCE_DIR}/fdbclient/vexillographer/fdb.options + COMMENT "Generate FDBOptions for GO") +add_custom_target(go_options_file DEPENDS ${go_options_file}) +add_dependencies(go_options_file copy_go_sources) + +function(build_go_package) + set(options LIBRARY EXECUTABLE) + set(oneValueArgs NAME PATH) + set(multiValueArgs) + cmake_parse_arguments(BGP "${options}" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}") + + if(NOT BGP_NAME OR NOT BGP_PATH) + message(FATAL_ERROR "NAME and PATH arguments are missing") + endif() + if(BGP_LIBRARY AND BGP_EXECUTABLE) + message(FATAL_ERROR "Package can't be a library and an executable") + endif() + if(NOT BGP_LIBRARY AND NOT BGP_EXECUTABLE) + message(FATAL_ERROR "Missing type") + endif() + + if(BGP_LIBRARY) + if(WIN32) + set(outfile ${GO_PACKAGE_OUTDIR}/${BGP_NAME}.lib) + else() + set(outfile ${GO_PACKAGE_OUTDIR}/${BGP_NAME}.a) + endif() + else() + if(WIN32) + set(outfile ${GO_PACKAGE_OUTDIR}/${BGP_NAME}.exe) + else() + set(outfile ${GO_PACKAGE_OUTDIR}/${BGP_NAME}) + endif() + endif() + add_custom_command(OUTPUT ${outfile} + COMMAND ${CMAKE_COMMAND} -E env ${go_env} + ${GO_EXECUTABLE} install ${GO_IMPORT_PATH}/${BGP_PATH} + DEPENDS ${fdb_options_file} + COMMENT "Building ${BGP_NAME}") + add_custom_target(${BGP_NAME} ALL DEPENDS ${outfile}) +endfunction() + +build_go_package(LIBRARY NAME fdb_go PATH fdb) +add_dependencies(fdb_go fdb_c go_options_file) + +build_go_package(LIBRARY NAME tuple_go PATH fdb/tuple) +add_dependencies(tuple_go fdb_go) + +build_go_package(LIBRARY NAME subspace_go PATH fdb/subspace) +add_dependencies(subspace_go tuple_go) + +build_go_package(LIBRARY NAME directory_go PATH fdb/directory) +add_dependencies(directory_go tuple_go) + +build_go_package(EXECUTABLE NAME fdb_go_tester PATH _stacktester) +add_dependencies(fdb_go_tester directory_go) diff --git a/bindings/go/src/_util/translate_fdb_options.go b/bindings/go/src/_util/translate_fdb_options.go index 37d64af6c6..f0527683da 100644 --- a/bindings/go/src/_util/translate_fdb_options.go +++ b/bindings/go/src/_util/translate_fdb_options.go @@ -23,6 +23,7 @@ package main import ( + "flag" "encoding/xml" "fmt" "go/doc" @@ -30,6 +31,7 @@ import ( "log" "os" "strings" + "io" ) type Option struct { @@ -48,22 +50,22 @@ type Options struct { Scope []Scope } -func writeOptString(receiver string, function string, opt Option) { - fmt.Printf(`func (o %s) %s(param string) error { +func writeOptString(w io.Writer, receiver string, function string, opt Option) { + fmt.Fprintf(w, `func (o %s) %s(param string) error { return o.setOpt(%d, []byte(param)) } `, receiver, function, opt.Code) } -func writeOptBytes(receiver string, function string, opt Option) { - fmt.Printf(`func (o %s) %s(param []byte) error { +func writeOptBytes(w io.Writer, receiver string, function string, opt Option) { + fmt.Fprintf(w, `func (o %s) %s(param []byte) error { return o.setOpt(%d, param) } `, receiver, function, opt.Code) } -func writeOptInt(receiver string, function string, opt Option) { - fmt.Printf(`func (o %s) %s(param int64) error { +func writeOptInt(w io.Writer, receiver string, function string, opt Option) { + fmt.Fprintf(w, `func (o %s) %s(param int64) error { b, e := int64ToBytes(param) if e != nil { return e @@ -73,36 +75,36 @@ func writeOptInt(receiver string, function string, opt Option) { `, receiver, function, opt.Code) } -func writeOptNone(receiver string, function string, opt Option) { - fmt.Printf(`func (o %s) %s() error { +func writeOptNone(w io.Writer, receiver string, function string, opt Option) { + fmt.Fprintf(w, `func (o %s) %s() error { return o.setOpt(%d, nil) } `, receiver, function, opt.Code) } -func writeOpt(receiver string, opt Option) { +func writeOpt(w io.Writer, receiver string, opt Option) { function := "Set" + translateName(opt.Name) - fmt.Println() + fmt.Fprintln(w) if opt.Description != "" { - fmt.Printf("// %s\n", opt.Description) + fmt.Fprintf(w, "// %s\n", opt.Description) if opt.ParamDesc != "" { - fmt.Printf("//\n// Parameter: %s\n", opt.ParamDesc) + fmt.Fprintf(w, "//\n// Parameter: %s\n", opt.ParamDesc) } } else { - fmt.Printf("// Not yet implemented.\n") + fmt.Fprintf(w, "// Not yet implemented.\n") } switch opt.ParamType { case "String": - writeOptString(receiver, function, opt) + writeOptString(w, receiver, function, opt) case "Bytes": - writeOptBytes(receiver, function, opt) + writeOptBytes(w, receiver, function, opt) case "Int": - writeOptInt(receiver, function, opt) + writeOptInt(w, receiver, function, opt) case "": - writeOptNone(receiver, function, opt) + writeOptNone(w, receiver, function, opt) default: log.Fatalf("Totally unexpected ParamType %s", opt.ParamType) } @@ -112,9 +114,9 @@ func translateName(old string) string { return strings.Replace(strings.Title(strings.Replace(old, "_", " ", -1)), " ", "", -1) } -func writeMutation(opt Option) { +func writeMutation(w io.Writer, opt Option) { tname := translateName(opt.Name) - fmt.Printf(` + fmt.Fprintf(w, ` // %s func (t Transaction) %s(key KeyConvertible, param []byte) { t.atomicOp(key.FDBKey(), param, %d) @@ -122,23 +124,38 @@ func (t Transaction) %s(key KeyConvertible, param []byte) { `, opt.Description, tname, opt.Code) } -func writeEnum(scope Scope, opt Option, delta int) { - fmt.Println() +func writeEnum(w io.Writer, scope Scope, opt Option, delta int) { + fmt.Fprintln(w) if opt.Description != "" { - doc.ToText(os.Stdout, opt.Description, "\t// ", "", 73) + doc.ToText(w, opt.Description, "\t// ", "", 73) // fmt.Printf(" // %s\n", opt.Description) } - fmt.Printf(" %s %s = %d\n", scope.Name+translateName(opt.Name), scope.Name, opt.Code+delta) + fmt.Fprintf(w, " %s %s = %d\n", scope.Name+translateName(opt.Name), scope.Name, opt.Code+delta) } func main() { + var inFile string + var outFile string + flag.StringVar(&inFile, "in", "stdin", "Input file") + flag.StringVar(&outFile, "out", "stdout", "Output file") + flag.Parse() + var err error v := Options{} - data, err := ioutil.ReadAll(os.Stdin) - if err != nil { - log.Fatal(err) + var data []byte + + if inFile == "stdin" { + data, err = ioutil.ReadAll(os.Stdin) + if err != nil { + log.Fatal(err) + } + } else { + data, err = ioutil.ReadFile(inFile) + if err != nil { + log.Fatal(err) + } } err = xml.Unmarshal(data, &v) @@ -146,7 +163,17 @@ func main() { log.Fatal(err) } - fmt.Print(`/* + var out *os.File + if outFile == "stdout" { + out = os.Stdout + } else { + out, err = os.Create(outFile) + if err != nil { + log.Fatal(err) + } + } + + fmt.Fprint(out, `/* * generated.go * * This source file is part of the FoundationDB open source project @@ -197,7 +224,7 @@ func int64ToBytes(i int64) ([]byte, error) { for _, opt := range scope.Option { if !opt.Hidden { - writeOpt(receiver, opt) + writeOpt(out, receiver, opt) } } continue @@ -206,7 +233,7 @@ func int64ToBytes(i int64) ([]byte, error) { if scope.Name == "MutationType" { for _, opt := range scope.Option { if !opt.Hidden { - writeMutation(opt) + writeMutation(out, opt) } } continue @@ -223,16 +250,17 @@ func int64ToBytes(i int64) ([]byte, error) { scope.Name = "conflictRangeType" } - fmt.Printf(` + fmt.Fprintf(out, ` type %s int const ( `, scope.Name) for _, opt := range scope.Option { if !opt.Hidden { - writeEnum(scope, opt, d) + writeEnum(out, scope, opt, d) } } - fmt.Println(")") + fmt.Fprintln(out, ")") } + out.Close() } diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index 4589582a50..cb7a236e1f 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -67,3 +67,4 @@ add_custom_command(OUTPUT ${package_file} COMMENT "Create Python sdist package") add_custom_target(python_package DEPENDS ${package_file}) add_dependencies(python_package python_binding) +add_dependencies(packages python_package) diff --git a/bindings/python/setup.py.cmake b/bindings/python/setup.py.cmake new file mode 100644 index 0000000000..da8bf77c82 --- /dev/null +++ b/bindings/python/setup.py.cmake @@ -0,0 +1,38 @@ +from distutils.core import setup + +try: + with open("README.rst") as f: + long_desc = f.read() +except: + long_desc = "" + +setup(name="foundationdb", + version="${FDB_VERSION}", + author="FoundationDB", + author_email="fdb-dist@apple.com", + description="Python bindings for the FoundationDB database", + url="https://www.foundationdb.org", + packages=['fdb'], + package_data={'fdb': ["fdb/*.py"]}, + long_description=long_desc, + classifiers=[ + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: Apache Software License', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.0', + 'Programming Language :: Python :: 3.1', + 'Programming Language :: Python :: 3.2', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: Implementation :: CPython', + 'Topic :: Database', + 'Topic :: Database :: Front-Ends' + ] + ) diff --git a/cmake/FDBComponents.cmake b/cmake/FDBComponents.cmake index 7fa1f95bfc..e020acaf70 100644 --- a/cmake/FDBComponents.cmake +++ b/cmake/FDBComponents.cmake @@ -1,16 +1,3 @@ -################################################################################ -# Java Bindings -################################################################################ - -set(BUILD_JAVA OFF) -find_package(JNI 1.8 REQUIRED) -find_package(Java 1.8 COMPONENTS Development) -if(JNI_FOUND AND Java_FOUND AND Java_Development_FOUND) - set(BUILD_JAVA ON) - include(UseJava) - enable_language(Java) -endif() - ################################################################################ # LibreSSL ################################################################################ @@ -30,13 +17,62 @@ else() endif() endif() +################################################################################ +# Java Bindings +################################################################################ + +set(BUILD_JAVA OFF) +find_package(JNI 1.8 REQUIRED) +find_package(Java 1.8 COMPONENTS Development) +if(JNI_FOUND AND Java_FOUND AND Java_Development_FOUND) + set(BUILD_JAVA ON) + include(UseJava) + enable_language(Java) +endif() + +################################################################################ +# Python Bindings +################################################################################ + +find_package(Python COMPONENTS Interpreter) +if(Python_Interpreter_FOUND) + set(WITH_PYTHON ON) +else() + set(WITH_PYTHON OFF) +endif() + +################################################################################ +# Pip +################################################################################ + +find_package(Virtualenv) +if (Virtualenv_FOUND) + set(BUILD_DOCUMENTATION ON) +endif() + +################################################################################ +# GO +################################################################################ + +find_program(GO_EXECUTABLE go) +if(GO_EXECUTABLE) + set(WITH_GO ON) +else() + set(WITH_GO OFF) +endif() + +file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/packages) +add_custom_target(packages) + function(print_components) - message(STATUS "=============================") + message(STATUS "=========================================") message(STATUS " Components Build Overview ") - message(STATUS "=============================") - message(STATUS "Build Python Bindings: ON") - message(STATUS "Build Java Bindings: ${BUILD_JAVA}") - message(STATUS "Build with TLS support: ${WITH_TLS}") - message(STATUS "=============================") + message(STATUS "=========================================") + message(STATUS "Build Java Bindings: ${BUILD_JAoA}") + message(STATUS "Build with TLS support: ${WITH_TLS}") + message(STATUS "Build GO bindings: ${WITH_GO}") + message(STATUS "Build Python sdist (make package): ${WITH_PYTHON}") + message(STATUS "Build Documentation (make html): ${BUILD_DOCUMENTATION}") + message(STATUS "=========================================") endfunction() diff --git a/documentation/CMakeLists.txt b/documentation/CMakeLists.txt index ac409fbbc2..20262c29ae 100644 --- a/documentation/CMakeLists.txt +++ b/documentation/CMakeLists.txt @@ -58,10 +58,11 @@ endfunction() message(STATUS "Add html target") add_documentation_target(GENERATOR html) -set(tar_file ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-${CMAKE_PROJECT_VERSION}.tar.gz) +set(tar_file ${CMAKE_BINARY_DIR}/packages/${CMAKE_PROJECT_NAME}-docs-${FDB_VERSION}.tar.gz) add_custom_command( OUTPUT ${tar_file} COMMAND ${CMAKE_COMMAND} -E tar czf ${tar_file} . WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html) add_custom_target(package_html DEPENDS ${tar_file}) add_dependencies(package_html html) +add_dependencies(packages package_html)