Skip to content

Commit

Permalink
Fix build and tests of statically linked oneTBB (#492)
Browse files Browse the repository at this point in the history
Fix build of libraries and tests while linking statically.

Signed-off-by: buzyaba <isaev.ameninc@gmail.com>

Co-authored-by: Alexey Veprev <alexey.veprev@intel.com>
Co-authored-by: buzyaba <isaev.ameninc@gmail.com>
  • Loading branch information
3 people committed Jul 21, 2021
1 parent 8827ea7 commit 7941f88
Show file tree
Hide file tree
Showing 13 changed files with 63 additions and 24 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Expand Up @@ -107,6 +107,7 @@ if (NOT DEFINED BUILD_SHARED_LIBS)
endif()

if (NOT BUILD_SHARED_LIBS)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
message(WARNING "You are building oneTBB as a static library. This is highly discouraged and such configuration is not supported. Consider building a dynamic library to avoid unforeseen issues.")
endif()

Expand Down
2 changes: 1 addition & 1 deletion cmake/compilers/Clang.cmake
Expand Up @@ -59,7 +59,7 @@ endif()

# Enabling LTO on Android causes the NDK bug.
# NDK throws the warning: "argument unused during compilation: '-Wa,--noexecstack'"
if (NOT ANDROID_PLATFORM)
if (NOT ANDROID_PLATFORM AND BUILD_SHARED_LIBS)
set(TBB_IPO_COMPILE_FLAGS $<$<NOT:$<CONFIG:Debug>>:-flto>)
set(TBB_IPO_LINK_FLAGS $<$<NOT:$<CONFIG:Debug>>:-flto>)
endif()
Expand Down
12 changes: 7 additions & 5 deletions cmake/utils.cmake
Expand Up @@ -36,9 +36,11 @@ macro(tbb_install_target target)
DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT devel)

install(TARGETS ${target}
LIBRARY
DESTINATION ${CMAKE_INSTALL_LIBDIR}
NAMELINK_ONLY
COMPONENT devel)
if (BUILD_SHARED_LIBS)
install(TARGETS ${target}
LIBRARY
DESTINATION ${CMAKE_INSTALL_LIBDIR}
NAMELINK_ONLY
COMPONENT devel)
endif()
endmacro()
12 changes: 12 additions & 0 deletions include/oneapi/tbb/detail/_assert.h
Expand Up @@ -19,20 +19,32 @@

#include "_config.h"

#if __TBBMALLOC_BUILD
namespace rml { namespace internal {
#else
namespace tbb {
namespace detail {
namespace r1 {
#endif
//! Process an assertion failure.
/** Normally called from __TBB_ASSERT macro.
If assertion handler is null, print message for assertion failure and abort.
Otherwise call the assertion handler. */
TBB_EXPORT void __TBB_EXPORTED_FUNC assertion_failure(const char* location, int line, const char* expression, const char* comment);
#if __TBBMALLOC_BUILD
}} // namespaces rml::internal
#else
} // namespace r1
} // namespace detail
} // namespace tbb
#endif

#if __TBBMALLOC_BUILD
//! Release version of assertions
#define __TBB_ASSERT_RELEASE(predicate,message) ((predicate)?((void)0) : rml::internal::assertion_failure(__func__,__LINE__,#predicate,message))
#else
#define __TBB_ASSERT_RELEASE(predicate,message) ((predicate)?((void)0) : tbb::detail::r1::assertion_failure(__func__,__LINE__,#predicate,message))
#endif

#if TBB_USE_ASSERT
//! Assert that predicate is true.
Expand Down
4 changes: 3 additions & 1 deletion src/tbb/CMakeLists.txt
Expand Up @@ -54,7 +54,9 @@ target_compile_definitions(tbb
PUBLIC
$<$<CONFIG:DEBUG>:TBB_USE_DEBUG>
PRIVATE
__TBB_BUILD)
__TBB_BUILD
$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:__TBB_DYNAMIC_LOAD_ENABLED=0>
$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:__TBB_SOURCE_DIRECTLY_INCLUDED=1>)

if (NOT ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(armv7-a|aarch64|mips|arm64)" OR
"${CMAKE_OSX_ARCHITECTURES}" MATCHES "arm64" OR
Expand Down
11 changes: 9 additions & 2 deletions src/tbb/assert_impl.h
Expand Up @@ -30,10 +30,13 @@

#include <mutex>

#if __TBBMALLOC_BUILD
namespace rml { namespace internal {
#else
namespace tbb {
namespace detail {
namespace r1 {

#endif
// TODO: consider extension for formatted error description string
static void assertion_failure_impl(const char* location, int line, const char* expression, const char* comment) {

Expand All @@ -57,7 +60,7 @@ static void assertion_failure_impl(const char* location, int line, const char* e
// Do not move the definition into the assertion_failure function because it will require "magic statics".
// It will bring a dependency on C++ runtime on some platforms while assert_impl.h is reused in tbbmalloc
// that should not depend on C++ runtime
static std::atomic<do_once_state> assertion_state;
static std::atomic<tbb::detail::do_once_state> assertion_state;

void __TBB_EXPORTED_FUNC assertion_failure(const char* location, int line, const char* expression, const char* comment) {
#if __TBB_MSVC_UNREACHABLE_CODE_IGNORED
Expand All @@ -82,9 +85,13 @@ void runtime_warning( const char* format, ... ) {
fprintf(stderr, "TBB Warning: %s\n", str);
}

#if __TBBMALLOC_BUILD
}} // namespaces rml::internal
#else
} // namespace r1
} // namespace detail
} // namespace tbb
#endif

#endif // __TBB_assert_impl_H

4 changes: 3 additions & 1 deletion src/tbbmalloc/CMakeLists.txt
Expand Up @@ -26,7 +26,9 @@ target_compile_definitions(tbbmalloc
PUBLIC
$<$<CONFIG:DEBUG>:TBB_USE_DEBUG>
PRIVATE
__TBBMALLOC_BUILD)
__TBBMALLOC_BUILD
$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:__TBB_DYNAMIC_LOAD_ENABLED=0>
$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:__TBB_SOURCE_DIRECTLY_INCLUDED=1>)

if (NOT ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(armv7-a|aarch64|mips|arm64)" OR
"${CMAKE_OSX_ARCHITECTURES}" MATCHES "arm64" OR
Expand Down
4 changes: 4 additions & 0 deletions src/tbbmalloc_proxy/CMakeLists.txt
Expand Up @@ -12,6 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.

if (NOT BUILD_SHARED_LIBS)
return()
endif()

add_library(tbbmalloc_proxy
function_replacement.cpp
proxy.cpp)
Expand Down
15 changes: 10 additions & 5 deletions test/CMakeLists.txt
Expand Up @@ -69,7 +69,9 @@ function(tbb_add_test)

target_compile_definitions(${_tbb_test_TARGET_NAME} PRIVATE
$<$<CONFIG:DEBUG>:TBB_USE_DEBUG>
$<$<BOOL:${TBB_CPF}>:__TBB_CPF_BUILD=1>)
$<$<BOOL:${TBB_CPF}>:__TBB_CPF_BUILD=1>
$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:__TBB_DYNAMIC_LOAD_ENABLED=0>
$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:__TBB_SOURCE_DIRECTLY_INCLUDED=1>)

target_link_libraries(${_tbb_test_TARGET_NAME} PRIVATE ${_tbb_test_DEPENDENCIES} Threads::Threads ${TBB_COMMON_LINK_LIBS})

Expand Down Expand Up @@ -115,7 +117,7 @@ function(tbb_add_lib_test)
set(multiValueArgs DEPENDENCIES)
cmake_parse_arguments(_tbb_test "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

add_library(_${_tbb_test_NAME} SHARED ${_tbb_test_SUBDIR}/${_tbb_test_NAME}.cpp)
add_library(_${_tbb_test_NAME} ${_tbb_test_SUBDIR}/${_tbb_test_NAME}.cpp)

target_include_directories(_${_tbb_test_NAME}
PUBLIC
Expand Down Expand Up @@ -146,7 +148,10 @@ function(tbb_add_lib_test)

target_compile_definitions(_${_tbb_test_NAME} PRIVATE
$<$<CONFIG:DEBUG>:TBB_USE_DEBUG>
$<$<BOOL:${TBB_CPF}>:__TBB_CPF_BUILD=1>)
$<$<BOOL:${TBB_CPF}>:__TBB_CPF_BUILD=1>
$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:__TBB_DYNAMIC_LOAD_ENABLED=0>
$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:__TBB_SOURCE_DIRECTLY_INCLUDED=1>)


# Prefer using target_link_options instead of target_link_libraries to specify link options because
# target_link_libraries may incorrectly handle some options (on Windows, for example).
Expand Down Expand Up @@ -513,7 +518,7 @@ tbb_add_test(SUBDIR conformance NAME conformance_graph DEPENDENCIES TBB::tbb)
# HWLOC related conformance
tbb_add_tbbbind_test(SUBDIR conformance NAME conformance_arena_constraints)

if (MSVC AND CMAKE_VERSION VERSION_GREATER 3.13) # LINK_OPTIONS property first appeared in 3.13
if (MSVC AND BUILD_SHARED_LIBS AND CMAKE_VERSION VERSION_GREATER 3.13) # LINK_OPTIONS property first appeared in 3.13
# version of the CMake
tbb_add_test(SUBDIR tbb NAME test_implicit_linkage_on_windows)
# TODO: consider setting environment instead of passing additional
Expand Down Expand Up @@ -596,7 +601,7 @@ if (NOT "${CMAKE_SYSTEM_PROCESSOR}" MATCHES "mips")
endif()

# Thread Sanitizer overloads memory management routines that conflicts with tbbmalloc_proxy.
if (NOT TBB_SANITIZE MATCHES "thread")
if (BUILD_SHARED_LIBS AND NOT TBB_SANITIZE MATCHES "thread")
# Define TBB malloc proxy tests
tbb_add_lib_test(SUBDIR tbbmalloc NAME test_malloc_atexit DEPENDENCIES TBB::tbbmalloc_proxy TBB::tbbmalloc)
tbb_add_test(SUBDIR tbbmalloc NAME test_malloc_atexit DEPENDENCIES TBB::tbbmalloc_proxy TBB::tbbmalloc _test_malloc_atexit)
Expand Down
2 changes: 0 additions & 2 deletions test/tbb/test_concurrent_queue_whitebox.cpp
Expand Up @@ -32,8 +32,6 @@
#define private public
#define protected public
#include "tbb/concurrent_queue.h"
#include "../../src/tbb/concurrent_bounded_queue.cpp"
#include "../../src/tbb/misc.cpp"
#undef protected
#undef private

Expand Down
14 changes: 10 additions & 4 deletions test/tbb/test_dynamic_link.cpp
Expand Up @@ -41,24 +41,28 @@ TEST_EXPORT FOO_TYPE foo2() { return FOO_IMPLEMENTATION; }
FOO_TYPE dummy_foo1() { return FOO_DUMMY; }
FOO_TYPE dummy_foo2() { return FOO_DUMMY; }

// Handlers.
static FOO_TYPE (*foo1_handler)() = &dummy_foo1;
static FOO_TYPE (*foo2_handler)() = &dummy_foo2;

#include "oneapi/tbb/detail/_config.h"
// Suppress the weak symbol mechanism to avoid surplus compiler warnings.
#ifdef __TBB_WEAK_SYMBOLS_PRESENT
#undef __TBB_WEAK_SYMBOLS_PRESENT
#endif
#include "src/tbb/dynamic_link.h"

#if __TBB_DYNAMIC_LOAD_ENABLED
// Handlers.
static FOO_TYPE (*foo1_handler)() = &dummy_foo1;
static FOO_TYPE (*foo2_handler)() = &dummy_foo2;

// Table describing how to link the handlers.
static const tbb::detail::r1::dynamic_link_descriptor LinkTable[] = {
{ "foo1", (tbb::detail::r1::pointer_to_handler*)(void*)(&foo1_handler) },
{ "foo2", (tbb::detail::r1::pointer_to_handler*)(void*)(&foo2_handler) }
};
#endif

// The direct include since we want to test internal functionality.
#include "src/tbb/dynamic_link.cpp"
#include "common/utils.h"
#include "common/utils_dynamic_libs.h"

void test_dynamic_link(const char* lib_name) {
Expand All @@ -80,6 +84,8 @@ void test_dynamic_link(const char* lib_name) {
} else {
REQUIRE_MESSAGE((foo1_handler == dummy_foo1 && foo2_handler == dummy_foo2), "The symbols are corrupted by dynamic_link");
}
#else
utils::suppress_unused_warning(lib_name);
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion test/tbbmalloc/test_malloc_lib_unload.cpp
Expand Up @@ -118,7 +118,7 @@ int main() {}
#include "common/config.h"
// harness_defs.h must be included before tbb_stddef.h to overcome exception-dependent
// system headers that come from tbb_stddef.h
#if __TBB_WIN8UI_SUPPORT || __TBB_MIC_OFFLOAD || (__GNUC__ && __GNUC__ < 10 && __TBB_USE_SANITIZERS)
#if __TBB_WIN8UI_SUPPORT || __TBB_MIC_OFFLOAD || (__GNUC__ && __GNUC__ < 10 && __TBB_USE_SANITIZERS) || __TBB_SOURCE_DIRECTLY_INCLUDED
// The test does not work if dynamic load is unavailable.
// For MIC offload, it fails because liboffload brings libiomp which observes and uses the fake scalable_* calls.
// For sanitizers, it fails because RUNPATH is lost: https://github.com/google/sanitizers/issues/1219
Expand Down
4 changes: 2 additions & 2 deletions test/tbbmalloc/test_malloc_used_by_lib.cpp
Expand Up @@ -49,7 +49,7 @@ int main() {}
#include "common/config.h"
// FIXME: fix the test to support Windows* 8 Store Apps mode.
// For sanitizers, it fails because RUNPATH is lost: https://github.com/google/sanitizers/issues/1219
#if !__TBB_WIN8UI_SUPPORT && !(__GNUC__ && __GNUC__ < 10 && __TBB_USE_SANITIZERS)
#if !__TBB_WIN8UI_SUPPORT && !(__GNUC__ && __GNUC__ < 10 && __TBB_USE_SANITIZERS) && __TBB_DYNAMIC_LOAD_ENABLED

#define __TBB_NO_IMPLICIT_LINKAGE 1
#include "common/test.h"
Expand All @@ -59,6 +59,7 @@ int main() {}
#include "common/memory_usage.h"
#include "common/spin_barrier.h"


class UseDll {
utils::FunctionAddress run;
public:
Expand Down Expand Up @@ -145,6 +146,5 @@ TEST_CASE("use test as lib") {
}
}
}

#endif /* Unsupported configurations */
#endif // _USRDLL

0 comments on commit 7941f88

Please sign in to comment.