PARQUET-662: Compile ParquetException implementation and explicitly export
This was causing downstream failure in ARROW-237. Now thirdparty libraries can safely throw `ParquetException` and be properly recognized on both ends.
Author: Wes McKinney <wesm@apache.org>
Closes #139 from wesm/PARQUET-662 and squashes the following commits:
c1458d2 [Wes McKinney] Move ParquetException impl to object code, explicitly export. Add LINKAGE option to ADD_PARQUET_TEST, test throwing ParquetException via shared lib. Build shared library in gcc build.
diff --git a/.travis.yml b/.travis.yml
index e83aeba..780d9f9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -26,7 +26,7 @@
before_script:
- source $TRAVIS_BUILD_DIR/ci/before_script_travis.sh
- cmake -DCMAKE_CXX_FLAGS="-Werror" -DPARQUET_TEST_MEMCHECK=ON -DPARQUET_BUILD_BENCHMARKS=ON
- -DPARQUET_GENERATE_COVERAGE=1 $TRAVIS_BUILD_DIR -DPARQUET_BUILD_SHARED=OFF -DPARQUET_BUILD_STATIC=ON
+ -DPARQUET_GENERATE_COVERAGE=1 $TRAVIS_BUILD_DIR
- export PARQUET_TEST_DATA=$TRAVIS_BUILD_DIR/data
- compiler: clang
os: linux
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5b594a3..f833f2c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -171,9 +171,32 @@
#
# Arguments after the test name will be passed to set_tests_properties().
function(ADD_PARQUET_TEST REL_TEST_NAME)
- if(NOT PARQUET_BUILD_TESTS OR NOT PARQUET_BUILD_STATIC)
+ set(options)
+ set(one_value_args LINKAGE)
+ set(multi_value_args)
+ cmake_parse_arguments(ARG "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
+
+ if(NOT PARQUET_BUILD_TESTS)
return()
endif()
+
+ # TODO(wesm): not very rigorous error checking
+ if (ARG_LINKAGE AND "${ARG_LINKAGE}" STREQUAL "shared")
+ if(NOT PARQUET_BUILD_SHARED)
+ # Skip this test if we are not building the shared library
+ return()
+ else()
+ set(TEST_LINK_LIBS ${PARQUET_TEST_SHARED_LINK_LIBS})
+ endif()
+ else()
+ if(NOT PARQUET_BUILD_STATIC)
+ # Skip this test if we are not building the static library
+ return()
+ else()
+ set(TEST_LINK_LIBS ${PARQUET_TEST_LINK_LIBS})
+ endif()
+ endif()
+
get_filename_component(TEST_NAME ${REL_TEST_NAME} NAME_WE)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${REL_TEST_NAME}.cc)
@@ -192,7 +215,7 @@
-DGTEST_USE_OWN_TR1_TUPLE=0)
endif()
- target_link_libraries(${TEST_NAME} ${PARQUET_TEST_LINK_LIBS})
+ target_link_libraries(${TEST_NAME} ${TEST_LINK_LIBS})
else()
# No executable, just invoke the test (probably a script) directly.
set(TEST_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${REL_TEST_NAME})
@@ -417,10 +440,13 @@
# Test linking
set(PARQUET_MIN_TEST_LIBS
- parquet_test_main
+ parquet_test_main)
+
+set(PARQUET_TEST_LINK_LIBS ${PARQUET_MIN_TEST_LIBS}
parquet_static)
-set(PARQUET_TEST_LINK_LIBS ${PARQUET_MIN_TEST_LIBS})
+set(PARQUET_TEST_SHARED_LINK_LIBS ${PARQUET_MIN_TEST_LIBS}
+ parquet_shared)
#############################################################
# Benchmark linking
@@ -460,6 +486,7 @@
# Library config
set(LIBPARQUET_SRCS
+ src/parquet/exception.cc
src/parquet/types.cc
src/parquet/column/levels.cc
@@ -533,8 +560,8 @@
LIBRARY_OUTPUT_DIRECTORY "${BUILD_OUTPUT_ROOT_DIRECTORY}"
OUTPUT_NAME "parquet")
target_link_libraries(parquet_static
- LINK_PUBLIC ${LIBPARQUET_LINK_LIBS}
- LINK_PRIVATE ${LIBPARQUET_PRIVATE_LINK_LIBS})
+ LINK_PUBLIC ${LIBPARQUET_LINK_LIBS}
+ LINK_PRIVATE ${LIBPARQUET_PRIVATE_LINK_LIBS})
endif()
add_subdirectory(src/parquet)
diff --git a/src/parquet/CMakeLists.txt b/src/parquet/CMakeLists.txt
index a2ebbad..7d4e905 100644
--- a/src/parquet/CMakeLists.txt
+++ b/src/parquet/CMakeLists.txt
@@ -21,6 +21,8 @@
types.h
DESTINATION include/parquet)
-ADD_PARQUET_TEST(public-api-test)
+ADD_PARQUET_TEST(public-api-test
+ LINKAGE shared)
+
ADD_PARQUET_TEST(types-test)
ADD_PARQUET_TEST(reader-test)
diff --git a/src/parquet/exception.cc b/src/parquet/exception.cc
new file mode 100644
index 0000000..0973e5a
--- /dev/null
+++ b/src/parquet/exception.cc
@@ -0,0 +1,48 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "parquet/exception.h"
+
+#include <exception>
+#include <sstream>
+#include <string>
+
+namespace parquet {
+
+void ParquetException::EofException() {
+ throw ParquetException("Unexpected end of stream.");
+}
+
+void ParquetException::NYI(const std::string& msg) {
+ std::stringstream ss;
+ ss << "Not yet implemented: " << msg << ".";
+ throw ParquetException(ss.str());
+}
+
+ParquetException::ParquetException(const char* msg) : msg_(msg) {}
+
+ParquetException::ParquetException(const std::string& msg) : msg_(msg) {}
+
+ParquetException::ParquetException(const char* msg, std::exception& e) : msg_(msg) {}
+
+ParquetException::~ParquetException() throw() {}
+
+const char* ParquetException::what() const throw() {
+ return msg_.c_str();
+}
+
+} // namespace parquet
diff --git a/src/parquet/exception.h b/src/parquet/exception.h
index 6e6589e..3851018 100644
--- a/src/parquet/exception.h
+++ b/src/parquet/exception.h
@@ -19,28 +19,23 @@
#define PARQUET_EXCEPTION_H
#include <exception>
-#include <sstream>
#include <string>
#include "parquet/util/visibility.h"
namespace parquet {
-class ParquetException : public std::exception {
+class PARQUET_EXPORT ParquetException : public std::exception {
public:
- static void EofException() { throw ParquetException("Unexpected end of stream."); }
- static void NYI(const std::string& msg) {
- std::stringstream ss;
- ss << "Not yet implemented: " << msg << ".";
- throw ParquetException(ss.str());
- }
+ static void EofException();
+ static void NYI(const std::string& msg);
- explicit ParquetException(const char* msg) : msg_(msg) {}
- explicit ParquetException(const std::string& msg) : msg_(msg) {}
- explicit ParquetException(const char* msg, exception& e) : msg_(msg) {}
+ explicit ParquetException(const char* msg);
+ explicit ParquetException(const std::string& msg);
+ explicit ParquetException(const char* msg, exception& e);
- virtual ~ParquetException() throw() {}
- virtual const char* what() const throw() { return msg_.c_str(); }
+ virtual ~ParquetException() throw();
+ virtual const char* what() const throw();
private:
std::string msg_;
diff --git a/src/parquet/public-api-test.cc b/src/parquet/public-api-test.cc
index e307f52..a5c88da 100644
--- a/src/parquet/public-api-test.cc
+++ b/src/parquet/public-api-test.cc
@@ -22,8 +22,6 @@
#include "parquet/api/schema.h"
#include "parquet/api/writer.h"
-namespace parquet {
-
TEST(TestPublicAPI, DoesNotIncludeThrift) {
#ifdef _THRIFT_THRIFT_H_
FAIL() << "Thrift headers should not be in the public API";
@@ -36,4 +34,10 @@
#endif
}
-} // namespace parquet
+void ThrowsParquetException() {
+ throw parquet::ParquetException("This function throws");
+}
+
+TEST(TestPublicAPI, CanThrowParquetException) {
+ ASSERT_THROW(ThrowsParquetException(), parquet::ParquetException);
+}
diff --git a/src/parquet/util/logging.h b/src/parquet/util/logging.h
index 3c873e3..4f2091b 100644
--- a/src/parquet/util/logging.h
+++ b/src/parquet/util/logging.h
@@ -44,9 +44,9 @@
#ifdef NDEBUG
#define PARQUET_DFATAL PARQUET_WARNING
-#define DCHECK(condition) \
- PARQUET_IGNORE_EXPR(condition)\
- while (false) \
+#define DCHECK(condition) \
+ PARQUET_IGNORE_EXPR(condition) \
+ while (false) \
parquet::internal::NullLog()
#define DCHECK_EQ(val1, val2) \
PARQUET_IGNORE_EXPR(val1) \
diff --git a/src/parquet/util/output.cc b/src/parquet/util/output.cc
index 6fc4ed8..422000f 100644
--- a/src/parquet/util/output.cc
+++ b/src/parquet/util/output.cc
@@ -19,6 +19,7 @@
#include <cstring>
#include <memory>
+#include <sstream>
#include "parquet/exception.h"
#include "parquet/util/buffer.h"