Kaynağa Gözat

Migrate to package-based generation

- Make single-file generation package-based. Each generated artifact
  now placed inside package-based folder.
- Update tests and examples
Alexey Edelev 5 yıl önce
ebeveyn
işleme
36fa3967a5

+ 4 - 3
cmake/QtProtobufGen.cmake

@@ -103,12 +103,13 @@ function(qtprotobuf_generate)
     unset(GENERATED_SOURCES_FULL)
     unset(GENERATED_HEADERS_FULL)
     foreach(GENERATED_HEADER IN LISTS GENERATED_HEADERS)
+        get_filename_component(GENERATED_DIRECTORY ${GENERATED_HEADER} DIRECTORY)
         get_filename_component(GENERATED_BASENAME ${GENERATED_HEADER} NAME)
         string(REGEX REPLACE "\\.[^.]*$" "" GENERATED_BASENAME ${GENERATED_BASENAME})
 
-        list(APPEND GENERATED_SOURCES_FULL ${OUT_DIR}/${GENERATED_BASENAME}.cpp)
-        list(APPEND GENERATED_HEADERS_FULL ${OUT_DIR}/${GENERATED_BASENAME}.h)
-        set_property(SOURCE ${OUT_DIR}/${GENERATED_BASENAME}.cpp PROPERTY SKIP_AUTOMOC ON)
+        list(APPEND GENERATED_SOURCES_FULL ${OUT_DIR}/${GENERATED_DIRECTORY}/${GENERATED_BASENAME}.cpp)
+        list(APPEND GENERATED_HEADERS_FULL ${OUT_DIR}/${GENERATED_DIRECTORY}/${GENERATED_BASENAME}.h)
+        set_property(SOURCE ${OUT_DIR}/${GENERATED_DIRECTORY}/${GENERATED_BASENAME}.cpp PROPERTY SKIP_AUTOMOC ON)
     endforeach()
 
     set_source_files_properties(${GENERATED_SOURCES_FULL} PROPERTIES GENERATED TRUE)

+ 2 - 2
examples/addressbook/addressbookengine.cpp

@@ -25,8 +25,8 @@
 
 #include "addressbookengine.h"
 
-#include "addressbook.qpb.h"
-#include "addressbook_grpc.qpb.h"
+#include "qtprotobuf/examples/addressbook.qpb.h"
+#include "qtprotobuf/examples/addressbook_grpc.qpb.h"
 
 #include <QGrpcHttp2Channel>
 #include <QGrpcUserPasswordCredentials>

+ 1 - 1
examples/addressbook/addressbookengine.h

@@ -26,7 +26,7 @@
 #pragma once
 
 #include <QObject>
-#include "addressbook.qpb.h"
+#include "qtprotobuf/examples/addressbook.qpb.h"
 
 #include "universallistmodel.h"
 

+ 1 - 1
examples/addressbook/main.cpp

@@ -30,7 +30,7 @@
 #include <QQmlContext>
 
 #include "addressbookengine.h"
-#include "addressbook.qpb.h"
+#include "qtprotobuf/examples/addressbook.qpb.h"
 
 #include <QMetaProperty>
 #include <QQmlPropertyMap>

+ 1 - 1
examples/simplechat/main.cpp

@@ -29,7 +29,7 @@
 #include <QQmlApplicationEngine>
 #include <QQmlContext>
 
-#include "simplechat.qpb.h"
+#include "qtprotobuf/examples/simplechat.qpb.h"
 
 #include "simplechatengine.h"
 

+ 1 - 1
examples/simplechat/simplechatengine.cpp

@@ -25,7 +25,7 @@
 
 #include "simplechatengine.h"
 
-#include "simplechat_grpc.qpb.h"
+#include "qtprotobuf/examples/simplechat_grpc.qpb.h"
 
 #include <QGrpcHttp2Channel>
 #include <QGrpcUserPasswordCredentials>

+ 2 - 2
examples/simplechat/simplechatengine.h

@@ -27,8 +27,8 @@
 
 #include <QObject>
 
-#include "simplechat.qpb.h"
-#include "simplechat_grpc.qpb.h"
+#include "qtprotobuf/examples/simplechat.qpb.h"
+#include "qtprotobuf/examples/simplechat_grpc.qpb.h"
 
 #include "universallistmodel.h"
 

+ 16 - 3
src/generator/singlefilegenerator.cpp

@@ -48,6 +48,19 @@ using namespace ::QtProtobuf::generator;
 using namespace ::google::protobuf;
 using namespace ::google::protobuf::compiler;
 
+std::string generateBaseName(const FileDescriptor *file)
+{
+    std::vector<std::string> packages;
+    utils::split(file->package(), packages, '.');
+    std::string outFileBasename = "";
+    for (auto package : packages) {
+        outFileBasename += package + "/";
+    }
+    outFileBasename += utils::extractFileName(file->name());
+
+    return outFileBasename;
+}
+
 SingleFileGenerator::SingleFileGenerator() : GeneratorBase(GeneratorBase::SingleMode)
 {}
 
@@ -73,7 +86,7 @@ bool SingleFileGenerator::GenerateMessages(const ::google::protobuf::FileDescrip
         return true;
     }
 
-    std::string outFileBasename = utils::extractFileName(file->name());
+    std::string outFileBasename = generateBaseName(file);
     std::set<std::string> internalIncludes;
     std::set<std::string> externalIncludes;
     std::shared_ptr<io::ZeroCopyOutputStream> outHeader(generatorContext->Open(outFileBasename + Templates::ProtoFileSuffix + ".h"));
@@ -96,7 +109,7 @@ bool SingleFileGenerator::GenerateMessages(const ::google::protobuf::FileDescrip
     externalIncludes.insert("QString");
 
     for (int i = 0; i < file->dependency_count(); i++) {
-        internalIncludes.insert(utils::extractFileName(file->dependency(i)->name()) + Templates::ProtoFileSuffix);
+        internalIncludes.insert(generateBaseName(file->dependency(i)) + Templates::ProtoFileSuffix);
     }
 
     for(auto include : externalIncludes) {
@@ -198,7 +211,7 @@ bool SingleFileGenerator::GenerateServices(const ::google::protobuf::FileDescrip
         return true;
     }
 
-    std::string outFileBasename = utils::extractFileName(file->name());
+    std::string outFileBasename = generateBaseName(file);
     std::set<std::string> internalIncludes;
     std::set<std::string> externalIncludes;
     std::shared_ptr<io::ZeroCopyOutputStream> outHeader(generatorContext->Open(outFileBasename + Templates::GrpcFileSuffix + Templates::ProtoFileSuffix + ".h"));

+ 4 - 0
src/generator/utils.h

@@ -80,6 +80,10 @@ static void tolower(std::string &str) {
 static std::string extractFileName(std::string fileName) {
     size_t index = fileName.rfind(".proto");
     fileName.resize(index);
+    index = fileName.rfind("/");
+    if (index != std::string::npos) {
+        return fileName.substr(index + 1, fileName.size() - 1);
+    }
     return fileName;
 }
 

+ 28 - 7
src/protobuf/parsemessages.go

@@ -5,9 +5,10 @@ import (
 	"fmt"
 	"log"
 	"os"
+	"path"
+	filepath "path/filepath"
 	"regexp"
 	"strings"
-	filepath "path/filepath"
 )
 
 func main() {
@@ -16,7 +17,7 @@ func main() {
 	}
 
 	multi := false
-	if len(os.Args) > 2{
+	if len(os.Args) > 2 {
 		if os.Args[2] == "MULTI" {
 			multi = true
 		}
@@ -32,13 +33,30 @@ func main() {
 	if err != nil {
 		log.Fatalf("Invalid regexp %s\n", err)
 	}
-	
+
 	serviceFinder, err := regexp.Compile("^service\\s+([a-zA-Z0-9_]+)")
 	if err != nil {
 		log.Fatalf("Invalid regexp %s\n", err)
 	}
 
+	packageFinder, err := regexp.Compile("^package\\s+(.+);")
+	if err != nil {
+		log.Fatalf("Invalid regexp %s\n", err)
+	}
+
 	scanner := bufio.NewScanner(file)
+
+	fullpath := ""
+	for scanner.Scan() {
+		capture := packageFinder.FindStringSubmatch(scanner.Text())
+		if len(capture) == 2 {
+			packages := strings.Split(capture[1], ".")
+			fullpath = strings.Join(packages, "/")
+			fullpath += "/"
+			break
+		}
+	}
+
 	if multi {
 		for scanner.Scan() {
 			capture := messageFinder.FindStringSubmatch(scanner.Text())
@@ -52,13 +70,16 @@ func main() {
 			}
 		}
 	} else {
+		if fullpath == "" {
+			log.Fatalf("Package is not specified correctly in %s file\n", os.Args[1])
+		}
 		//Singlefile version
 		enumFinder, err := regexp.Compile("^enum\\s+([a-zA-Z0-9_]+)")
 		if err != nil {
 			log.Fatalf("Invalid regexp %s\n", err)
 		}
-
-		basename := strings.TrimSuffix(os.Args[1], filepath.Ext(os.Args[1]))
+		basename := path.Base(os.Args[1])
+		basename = strings.TrimSuffix(basename, filepath.Ext(basename))
 		messageFound := false
 		serviceFound := false
 		for scanner.Scan() {
@@ -79,11 +100,11 @@ func main() {
 		}
 
 		if messageFound {
-			fmt.Printf("%s.qpb.h;", basename)
+			fmt.Printf("%s%s.qpb.h;", fullpath, basename)
 		}
 
 		if serviceFound {
-			fmt.Printf("%s_grpc.qpb.h;", basename)
+			fmt.Printf("%s%s_grpc.qpb.h;", fullpath, basename)
 		}
 	}
 

+ 2 - 4
src/wellknowntypes/CMakeLists.txt

@@ -31,7 +31,7 @@ function(add_wellknowntype TYPENAME)
         if (NOT "${PROTO_FILE}" STREQUAL "")
             message(STATUS "Add well-known type ${PROTO_FILE}")
             qtprotobuf_generate(TARGET ${TARGET} GENERATED_TARGET ${TYPENAME}
-                OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated/google/protobuf
+                OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated
                 PROTO_FILES ${PROTO_FILE}
                 PROTO_INCLUDES -I${INCLUDE_DIR}
                 QML)
@@ -65,12 +65,10 @@ add_wellknowntype(api)
 add_dependencies(api type source_context)
 
 
-protobuf_generate_qt_headers(PUBLIC_HEADER ${PUBLIC_HEADER} COMPONENT ${TARGET})
-
 target_compile_definitions(${TARGET} PRIVATE QT_BUILD_PROTOBUF_WELLKNOWNTYPES_LIB PUBLIC QT_PROTOBUF_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
     QT_PROTOBUF_VERSION_MINOR=${PROJECT_VERSION_MINOR})
 
-set_target_properties(${TARGET} PROPERTIES VERSION ${PROJECT_VERSION} PUBLIC_HEADER "${PUBLIC_HEADER};${GENERATED_PUBLIC_HEADER}" OUTPUT_NAME ${TARGET}
+set_target_properties(${TARGET} PROPERTIES VERSION ${PROJECT_VERSION} PUBLIC_HEADER "${GENERATED_PUBLIC_HEADER}" OUTPUT_NAME ${TARGET}
     PROTO_INCLUDES -I${QT_PROTOBUF_SOURCE_DIR}/3rdparty/grpc/third_party/protobuf/src)
 
 target_compile_features(${TARGET} PUBLIC cxx_std_14

+ 1 - 1
tests/test_grpc/clienttest.cpp

@@ -23,7 +23,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include "testservice_grpc.qpb.h"
+#include "qtprotobufnamespace/tests/testservice_grpc.qpb.h"
 #include <QGrpcHttp2Channel>
 #include <QGrpcCredentials>
 #include <QGrpcInsecureCredentials>

+ 1 - 1
tests/test_grpc/sslclienttest.cpp

@@ -23,7 +23,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include "testservice_grpc.qpb.h"
+#include "qtprotobufnamespace/tests/testservice_grpc.qpb.h"
 
 #include <QGrpcHttp2Channel>
 #include <QGrpcSslCredentials>

+ 1 - 1
tests/test_protobuf/deserializationtest.cpp

@@ -25,7 +25,7 @@
 
 #include "deserializationtest.h"
 
-#include "simpletest.qpb.h"
+#include "qtprotobufnamespace/tests/simpletest.qpb.h"
 
 using namespace qtprotobufnamespace::tests;
 using namespace QtProtobuf::tests;

+ 1 - 1
tests/test_protobuf/jsonserializationtest.cpp

@@ -29,7 +29,7 @@
 
 #include <qprotobufjsonserializer.h>
 
-#include "simpletest.qpb.h"
+#include "qtprotobufnamespace/tests/simpletest.qpb.h"
 
 using namespace qtprotobufnamespace::tests;
 

+ 1 - 1
tests/test_protobuf/serializationcomplexmessagemap.cpp

@@ -25,7 +25,7 @@
 
 #include "serializationtest.h"
 
-#include "simpletest.qpb.h"
+#include "qtprotobufnamespace/tests/simpletest.qpb.h"
 
 using namespace qtprotobufnamespace::tests;
 using namespace QtProtobuf::tests;

+ 1 - 1
tests/test_protobuf/serializationtest.cpp

@@ -25,7 +25,7 @@
 
 #include "serializationtest.h"
 
-#include "simpletest.qpb.h"
+#include "qtprotobufnamespace/tests/simpletest.qpb.h"
 
 using namespace qtprotobufnamespace::tests;
 using namespace QtProtobuf::tests;

+ 5 - 5
tests/test_protobuf/simpletest.cpp

@@ -23,10 +23,10 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include "simpletest.qpb.h"
-#include "sequencetest.qpb.h"
-#include "externalpackagetest.qpb.h"
-#include "globalenums.qpb.h"
-#include "globalenumssamenamespace.qpb.h"
+#include "qtprotobufnamespace/tests/simpletest.qpb.h"
+#include "qtprotobufnamespace/tests/sequence/sequencetest.qpb.h"
+#include "qtprotobufnamespace1/externaltests/externalpackagetest.qpb.h"
+#include "qtprotobufnamespace/tests/globalenums/globalenums.qpb.h"
+#include "qtprotobufnamespace/tests/globalenumssamenamespace.qpb.h"
 
 #include "./simpletest.cpp.inc"

+ 1 - 1
tests/test_qml/main.cpp

@@ -27,7 +27,7 @@
 #include <QQmlEngine>
 #include <QQmlContext>
 
-#include "simpletest.qpb.h"
+#include "qtprotobufnamespace/tests/simpletest.qpb.h"
 
 using namespace qtprotobufnamespace::tests;
 

+ 1 - 1
tests/test_wellknowntypes/simpletest.cpp

@@ -41,7 +41,7 @@
 #include <google/protobuf/wrappers.qpb.h>
 #include <google/protobuf/field_mask.qpb.h>
 
-#include "wellknowntypes.qpb.h"
+#include "qtprotobufnamespace/wellknowntypes/tests/wellknowntypes.qpb.h"
 
 using namespace google::protobuf;