diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | .travis.yml | 13 | ||||
-rw-r--r-- | BUILD | 1 | ||||
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | conformance/Makefile.am | 14 | ||||
-rw-r--r-- | src/google/protobuf/compiler/objectivec/objectivec_helpers.cc | 101 | ||||
-rwxr-xr-x | travis.sh | 59 |
7 files changed, 140 insertions, 55 deletions
@@ -101,8 +101,11 @@ objectivec/ProtocolBuffers_iOS.xcodeproj/xcuserdata/ conformance/.libs/ conformance/com/ conformance/conformance-cpp +conformance/conformance-csharp +conformance/conformance-java conformance/conformance-test-runner conformance/conformance.pb.cc conformance/conformance.pb.h conformance/conformance.rb +conformance/javac_middleman conformance/protoc_middleman diff --git a/.travis.yml b/.travis.yml index 4edf3b30..7be0d18e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,8 @@ language: cpp os: - linux - osx +# The Objective C build needs Xcode 6.4 or later. +osx_image: xcode7.1 script: - ./travis.sh $CONFIG env: @@ -46,11 +48,22 @@ matrix: # which doesn't work on OS X. - os: osx env: CONFIG=csharp + # Add into the matrix OS X tests of Objective C (needs Xcode, so it won't + # work on other platforms). These are split so it doesn't take as long to run. + include: + - os: osx + env: CONFIG=objectivec_ios + - os: osx + env: CONFIG=objectivec_osx allow_failures: # These currently do not work on OS X but are being worked on by @haberman. - os: osx env: CONFIG=ruby22 - os: osx env: CONFIG=jruby + # Travis seems be flaky in letting the iOS simulator launch, so keep that + # flake from failing builds by marking that build as an allowed failure. + - os: osx + env: CONFIG=objectivec_ios notifications: email: false @@ -157,6 +157,7 @@ cc_proto_library( internal_bootstrap_hack = 1, protoc = ":protoc", default_runtime = ":protobuf", + visibility = ["//visibility:public"], ) ################################################################################ diff --git a/Makefile.am b/Makefile.am index 858e4dc6..8657f821 100644 --- a/Makefile.am +++ b/Makefile.am @@ -35,6 +35,10 @@ clean-local: if test -e conformance/Makefile; then \ echo "Making clean in conformance"; \ cd conformance && $(MAKE) $(AM_MAKEFLAGS) clean; \ + fi; \ + if test -e objectivec/DevTools; then \ + echo "Cleaning any ObjC pyc files"; \ + rm -f objectivec/DevTools/*.pyc; \ fi pkgconfigdir = $(libdir)/pkgconfig diff --git a/conformance/Makefile.am b/conformance/Makefile.am index c74eb1c8..b6fda2a8 100644 --- a/conformance/Makefile.am +++ b/conformance/Makefile.am @@ -7,6 +7,10 @@ protoc_outputs = \ conformance.pb.cc \ conformance.pb.h +other_language_protoc_outputs = \ + conformance.rb \ + com/google/protobuf/conformance/Conformance.java + bin_PROGRAMS = conformance-test-runner conformance-cpp conformance_test_runner_LDADD = $(top_srcdir)/src/libprotobuf.la @@ -38,14 +42,16 @@ endif $(protoc_outputs): protoc_middleman +$(other_language_protoc_outputs): protoc_middleman + BUILT_SOURCES = $(protoc_outputs) -CLEANFILES = $(protoc_outputs) protoc_middleman javac_middleman conformance-java conformance-csharp +CLEANFILES = $(protoc_outputs) protoc_middleman javac_middleman conformance-java conformance-csharp $(other_language_protoc_outputs) MAINTAINERCLEANFILES = \ Makefile.in -javac_middleman: ConformanceJava.java protoc_middleman +javac_middleman: ConformanceJava.java protoc_middleman $(other_language_protoc_outputs) javac -classpath ../java/target/classes ConformanceJava.java com/google/protobuf/conformance/Conformance.java @touch javac_middleman @@ -58,7 +64,7 @@ conformance-java: javac_middleman # Currently the conformance code is alongside the rest of the C# # source, as it's easier to maintain there. We assume we've already # built that, so we just need a script to run it. -conformance-csharp: +conformance-csharp: $(other_language_protoc_outputs) @echo "Writing shortcut script conformance-csharp..." @echo '#! /bin/sh' > conformance-csharp @echo 'mono ../csharp/src/Google.Protobuf.Conformance/bin/Release/Google.Protobuf.Conformance.exe "$$@"' >> conformance-csharp @@ -74,5 +80,5 @@ test_java: protoc_middleman conformance-test-runner conformance-java test_csharp: protoc_middleman conformance-test-runner conformance-csharp ./conformance-test-runner --failure_list failure_list_csharp.txt ./conformance-csharp -test_ruby: protoc_middleman conformance-test-runner +test_ruby: protoc_middleman conformance-test-runner $(other_language_protoc_outputs) RUBYLIB=../ruby/lib:. ./conformance-test-runner --failure_list failure_list_ruby.txt ./conformance_ruby.rb diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index b724d35c..990aca24 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -937,41 +937,17 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, string* out_error) { // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some // error cases, so it seems to be ok to use as a back door for warnings. - // First Check: Warning - if there is a prefix, ensure it is is a reasonable - // value according to Apple's rules. - if (prefix.length()) { - if (!ascii_isupper(prefix[0])) { - cerr << endl - << "protoc:0: warning: Invalid 'option objc_class_prefix = \"" - << prefix << "\";' in '" << file->name() << "';" - << " it should start with a capital letter." << endl; - cerr.flush(); - } - if (prefix.length() < 3) { - cerr << endl - << "protoc:0: warning: Invalid 'option objc_class_prefix = \"" - << prefix << "\";' in '" << file->name() << "';" - << " Apple recommends they should be at least 3 characters long." - << endl; - cerr.flush(); - } - } - // Load any expected package prefixes to validate against those. map<string, string> expected_package_prefixes; string expect_file_path; if (!LoadExpectedPackagePrefixes(&expected_package_prefixes, &expect_file_path, out_error)) { - return false; + // Any error, clear the entries that were read. + expected_package_prefixes.clear(); } - // If there are no expected prefixes, out of here. - if (expected_package_prefixes.size() == 0) { - return true; - } - - // Second Check: Error - See if there was an expected prefix for the package - // and report if it doesn't match. + // Check: Error - See if there was an expected prefix for the package and + // report if it doesn't match (wrong or missing). map<string, string>::iterator package_match = expected_package_prefixes.find(package); if (package_match != expected_package_prefixes.end()) { @@ -991,32 +967,57 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, string* out_error) { } } - // Third Check: Error - If there was a prefix make sure it wasn't expected - // for a different package instead (overlap is allowed, but it has to be - // listed as an expected overlap). - if (prefix.length()) { - for (map<string, string>::iterator i = expected_package_prefixes.begin(); - i != expected_package_prefixes.end(); ++i) { - if (i->second == prefix) { - *out_error = - "protoc:0: error: Found 'option objc_class_prefix = \"" + prefix + - "\";' in '" + file->name() + - "'; that prefix is already used for 'package " + i->first + - ";'. It can only be reused by listing it in the expected file (" + - expect_file_path + ")."; - return false; // Only report first usage of the prefix. - } + // If there was no prefix option, we're done at this point. + if (prefix.length() == 0) { + // No prefix, nothing left to check. + return true; + } + + // Check: Error - Make sure the prefix wasn't expected for a different + // package (overlap is allowed, but it has to be listed as an expected + // overlap). + for (map<string, string>::iterator i = expected_package_prefixes.begin(); + i != expected_package_prefixes.end(); ++i) { + if (i->second == prefix) { + *out_error = + "protoc:0: error: Found 'option objc_class_prefix = \"" + prefix + + "\";' in '" + file->name() + + "'; that prefix is already used for 'package " + i->first + + ";'. It can only be reused by listing it in the expected file (" + + expect_file_path + ")."; + return false; // Only report first usage of the prefix. } } - // Fourth Check: Warning - If there was a prefix, and it wasn't expected, - // issue a warning suggesting it gets added to the file. - if (prefix.length()) { + // Check: Warning - Make sure the prefix is is a reasonable value according + // to Apple's rules (the checks above implicitly whitelist anything that + // doesn't meet these rules). + if (!ascii_isupper(prefix[0])) { + cerr << endl + << "protoc:0: warning: Invalid 'option objc_class_prefix = \"" + << prefix << "\";' in '" << file->name() << "';" + << " it should start with a capital letter." << endl; + cerr.flush(); + } + if (prefix.length() < 3) { + // Apple reserves 2 character prefixes for themselves. They do use some + // 3 character prefixes, but they haven't updated the rules/docs. + cerr << endl + << "protoc:0: warning: Invalid 'option objc_class_prefix = \"" + << prefix << "\";' in '" << file->name() << "';" + << " Apple recommends they should be at least 3 characters long." + << endl; + cerr.flush(); + } + + // Check: Warning - If the given package/prefix pair wasn't expected, issue a + // warning issue a warning suggesting it gets added to the file. + if (!expected_package_prefixes.empty()) { cerr << endl - << "protoc:0: warning: Found 'option objc_class_prefix = \"" << prefix - << "\";' in '" << file->name() << "';" - << " should you add it to the expected prefixes file (" - << expect_file_path << ")?" << endl; + << "protoc:0: warning: Found unexpected 'option objc_class_prefix = \"" + << prefix << "\";' in '" << file->name() << "';" + << " consider adding it to the expected prefixes file (" + << expect_file_path << ")." << endl; cerr.flush(); } @@ -112,7 +112,12 @@ build_javanano_oracle7() { } internal_install_python_deps() { - sudo pip install tox + # Install tox (OS X doesn't have pip). + if [ $(uname -s) == "Darwin" ]; then + sudo easy_install tox + else + sudo pip install tox + fi # Only install Python2.6/3.x on Linux. if [ $(uname -s) == "Linux" ]; then sudo apt-get install -y python-software-properties # for apt-add-repository @@ -124,6 +129,56 @@ internal_install_python_deps() { fi } +internal_objectivec_common () { + # Make sure xctool is up to date. Adapted from + # http://docs.travis-ci.com/user/osx-ci-environment/ + # We don't use a before_install because we test multiple OSes. + brew update + brew outdated xctool || brew upgrade xctool + # Reused the build script that takes care of configuring and ensuring things + # are up to date. + objectivec/DevTools/full_mac_build.sh --core-only --skip-xcode +} + +internal_xctool_debug_and_release() { + xctool -configuration Debug "$@" + xctool -configuration Release "$@" +} + +build_objectivec_ios() { + internal_objectivec_common + # https://github.com/facebook/xctool/issues/509 - unlike xcodebuild, xctool + # doesn't support >1 destination, so we have to build first and then run the + # tests one destination at a time. + internal_xctool_debug_and_release \ + -project objectivec/ProtocolBuffers_iOS.xcodeproj \ + -scheme ProtocolBuffers \ + -sdk iphonesimulator \ + build-tests + IOS_DESTINATIONS=( + "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit + "platform=iOS Simulator,name=iPhone 6,OS=9.1" # 64bit + "platform=iOS Simulator,name=iPad 2,OS=8.1" # 32bit + "platform=iOS Simulator,name=iPad Air,OS=9.1" # 64bit + ) + for i in "${IOS_DESTINATIONS[@]}" ; do + internal_xctool_debug_and_release \ + -project objectivec/ProtocolBuffers_iOS.xcodeproj \ + -scheme ProtocolBuffers \ + -sdk iphonesimulator \ + -destination "${i}" \ + run-tests + done +} + +build_objectivec_osx() { + internal_objectivec_common + internal_xctool_debug_and_release \ + -project objectivec/ProtocolBuffers_OSX.xcodeproj \ + -scheme ProtocolBuffers \ + -destination "platform=OS X,arch=x86_64" \ + test +} build_python() { internal_build_cpp @@ -189,6 +244,8 @@ Usage: $0 { cpp | javanano_jdk6 | javanano_jdk7 | javanano_oracle7 | + objectivec_ios | + objectivec_osx | python | python_cpp | ruby_19 | |