diff --git a/CMakeLists.txt b/CMakeLists.txt index e37d1dbf9920f7fc3f2c3c8375b81870cdd90e17..cd2b6d0526126ef71d68d4d211f794db1e5538ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,9 @@ include(TokuSetupCompiler) include(TokuSetupCTest) include(TokuThirdParty) +set(TOKU_CMAKE_SCRIPT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +include(TokuMergeLibs) + ## need a way to change the name of libs we build set(LIBTOKUPORTABILITY "tokuportability" CACHE STRING "Name of libtokuportability.so") set(LIBTOKUDB "tokudb" CACHE STRING "Name of libtokudb.so") diff --git a/cmake/merge_archives_unix.cmake.in b/cmake/merge_archives_unix.cmake.in new file mode 100644 index 0000000000000000000000000000000000000000..069db6299c14f52bc7f8dd80934c17da0052bc9b --- /dev/null +++ b/cmake/merge_archives_unix.cmake.in @@ -0,0 +1,94 @@ +# Copyright (c) 2009 Sun Microsystems, Inc. +# Use is subject to license terms. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +# This script merges many static libraries into +# one big library on Unix. +SET(TARGET_LOCATION "@TARGET_LOCATION@") +SET(TARGET "@TARGET@") +SET(STATIC_LIBS "@STATIC_LIBS@") +SET(CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@") +SET(CMAKE_AR "@CMAKE_AR@") +SET(CMAKE_RANLIB "@CMAKE_RANLIB@") +SET(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@") +SET(CMAKE_C_COMPILER_ID "@CMAKE_C_COMPILER_ID@") +SET(CMAKE_C_FLAGS "@CMAKE_C_FLAGS@") +SET(CMAKE_C_FLAGS_DEBUG "@CMAKE_C_FLAGS_DEBUG@") +SET(CMAKE_C_FLAGS_RELEASE "@CMAKE_C_FLAGS_RELEASE@") +SET(CMAKE_BUILD_TYPE "@CMAKE_BUILD_TYPE@") +SET(CMAKE_TOP_BINARY_DIR "@CMAKE_TOP_BINARY_DIR@") +SET(LIBTOKUPORTABILITY "@LIBTOKUPORTABILITY@") + + +SET(TEMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/merge_archives_${TARGET}) +MAKE_DIRECTORY(${TEMP_DIR}) +# Extract each archive to its own subdirectory(avoid object filename clashes) +FOREACH(LIB ${STATIC_LIBS}) + GET_FILENAME_COMPONENT(NAME_NO_EXT ${LIB} NAME_WE) + SET(TEMP_SUBDIR ${TEMP_DIR}/${NAME_NO_EXT}) + MAKE_DIRECTORY(${TEMP_SUBDIR}) + EXECUTE_PROCESS( + COMMAND ${CMAKE_AR} -x ${LIB} + WORKING_DIRECTORY ${TEMP_SUBDIR} + ) + + FILE(GLOB_RECURSE LIB_OBJECTS "${TEMP_SUBDIR}/*.ilo") + if (NOT LIB_OBJECTS) + FILE(GLOB_RECURSE NONIPO_LIB_OBJECTS "${TEMP_SUBDIR}/*.o") + ENDIF () + SET(OBJECTS ${OBJECTS} ${LIB_OBJECTS}) + SET(EXTRA_OBJECTS ${EXTRA_OBJECTS} ${NONIPO_LIB_OBJECTS}) +ENDFOREACH() + +# Use relative paths, makes command line shorter. +GET_FILENAME_COMPONENT(ABS_TEMP_DIR ${TEMP_DIR} ABSOLUTE) +FOREACH(OBJ ${OBJECTS}) + FILE(RELATIVE_PATH OBJ ${ABS_TEMP_DIR} ${OBJ}) + FILE(TO_NATIVE_PATH ${OBJ} OBJ) + SET(ALL_OBJECTS ${ALL_OBJECTS} ${OBJ}) +ENDFOREACH() +FOREACH(OBJ ${EXTRA_OBJECTS}) + FILE(RELATIVE_PATH OBJ ${ABS_TEMP_DIR} ${OBJ}) + FILE(TO_NATIVE_PATH ${OBJ} OBJ) + SET(ALL_EXTRA_OBJECTS ${ALL_EXTRA_OBJECTS} ${OBJ}) +ENDFOREACH() + +SET(TARGET_O ${TARGET}_combined.o) + +IF(CMAKE_BUILD_TYPE STREQUAL Release AND CMAKE_C_COMPILER_ID STREQUAL Intel) + SET(flags "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_RELEASE}") + SEPARATE_ARGUMENTS(flags) + EXECUTE_PROCESS( + COMMAND ${CMAKE_C_COMPILER} ${flags} -ipo1 -ipo-c -diag-disable 10015 -o ${TARGET_O} ${ALL_OBJECTS} + WORKING_DIRECTORY ${TEMP_DIR} + ) + SET(TARGET_OBJECTS ${TARGET_O} ${ALL_EXTRA_OBJECTS}) +ELSE() + SET(TARGET_OBJECTS ${ALL_OBJECTS} ${ALL_EXTRA_OBJECTS}) +ENDIF() + +FILE(TO_NATIVE_PATH ${TARGET_LOCATION} ${TARGET_LOCATION}) +# Now pack the objects into library with ar. +EXECUTE_PROCESS( + COMMAND ${CMAKE_AR} -r ${TARGET_LOCATION} ${TARGET_OBJECTS} + WORKING_DIRECTORY ${TEMP_DIR} +) +EXECUTE_PROCESS( + COMMAND ${CMAKE_RANLIB} ${TARGET_LOCATION} + WORKING_DIRECTORY ${TEMP_DIR} +) + +# Cleanup +FILE(REMOVE_RECURSE ${TEMP_DIR}) diff --git a/cmake_modules/TokuMergeLibs.cmake b/cmake_modules/TokuMergeLibs.cmake new file mode 100644 index 0000000000000000000000000000000000000000..9fa620a89403db87ca574d6ae4fd4d3bc6fe0db0 --- /dev/null +++ b/cmake_modules/TokuMergeLibs.cmake @@ -0,0 +1,100 @@ +# Merge static libraries into a big static lib. The resulting library +# should not not have dependencies on other static libraries. +# We use it in MySQL to merge mysys,dbug,vio etc into mysqlclient +FUNCTION(GET_DEPENDEND_OS_LIBS target result) + SET(deps ${${target}_LIB_DEPENDS}) + IF(deps) + FOREACH(lib ${deps}) + # Filter out keywords for used for debug vs optimized builds + IF(NOT lib MATCHES "general" AND NOT lib MATCHES "debug" AND NOT lib MATCHES "optimized") + GET_TARGET_PROPERTY(lib_location ${lib} LOCATION) + IF(NOT lib_location) + SET(ret ${ret} ${lib}) + ENDIF() + ENDIF() + ENDFOREACH() + ENDIF() + SET(${result} ${ret} PARENT_SCOPE) +ENDFUNCTION(GET_DEPENDEND_OS_LIBS) + +MACRO(MERGE_STATIC_LIBS TARGET OUTPUT_NAME LIBS_TO_MERGE) + # To produce a library we need at least one source file. + # It is created by ADD_CUSTOM_COMMAND below and will helps + # also help to track dependencies. + SET(SOURCE_FILE ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_depends.c) + ADD_LIBRARY(${TARGET} STATIC ${SOURCE_FILE}) + SET_TARGET_PROPERTIES(${TARGET} PROPERTIES OUTPUT_NAME ${OUTPUT_NAME}) + + SET(OSLIBS) + FOREACH(LIB ${LIBS_TO_MERGE}) + GET_TARGET_PROPERTY(LIB_LOCATION ${LIB} LOCATION) + GET_TARGET_PROPERTY(LIB_TYPE ${LIB} TYPE) + IF(NOT LIB_LOCATION) + # 3rd party library like libz.so. Make sure that everything + # that links to our library links to this one as well. + LIST(APPEND OSLIBS ${LIB}) + ELSE() + # This is a target in current project + # (can be a static or shared lib) + IF(LIB_TYPE STREQUAL "STATIC_LIBRARY") + SET(STATIC_LIBS ${STATIC_LIBS} ${LIB_LOCATION}) + ADD_DEPENDENCIES(${TARGET} ${LIB}) + # Extract dependend OS libraries + GET_DEPENDEND_OS_LIBS(${LIB} LIB_OSLIBS) + LIST(APPEND OSLIBS ${LIB_OSLIBS}) + ELSE() + # This is a shared library our static lib depends on. + LIST(APPEND OSLIBS ${LIB}) + ENDIF() + ENDIF() + ENDFOREACH() + IF(OSLIBS) + LIST(REMOVE_DUPLICATES OSLIBS) + TARGET_LINK_LIBRARIES(${TARGET} ${OSLIBS}) + ENDIF() + + # Make the generated dummy source file depended on all static input + # libs. If input lib changes,the source file is touched + # which causes the desired effect (relink). + ADD_CUSTOM_COMMAND( + OUTPUT ${SOURCE_FILE} + COMMAND ${CMAKE_COMMAND} -E touch ${SOURCE_FILE} + DEPENDS ${STATIC_LIBS}) + + IF(MSVC) + # To merge libs, just pass them to lib.exe command line. + SET(LINKER_EXTRA_FLAGS "") + FOREACH(LIB ${STATIC_LIBS}) + SET(LINKER_EXTRA_FLAGS "${LINKER_EXTRA_FLAGS} ${LIB}") + ENDFOREACH() + SET_TARGET_PROPERTIES(${TARGET} PROPERTIES STATIC_LIBRARY_FLAGS + "${LINKER_EXTRA_FLAGS}") + ELSE() + GET_TARGET_PROPERTY(TARGET_LOCATION ${TARGET} LOCATION) + IF(APPLE) + # Use OSX's libtool to merge archives (ihandles universal + # binaries properly) + ADD_CUSTOM_COMMAND(TARGET ${TARGET} POST_BUILD + COMMAND rm ${TARGET_LOCATION} + COMMAND /usr/bin/libtool -static -o ${TARGET_LOCATION} + ${STATIC_LIBS} + ) + ELSE() + # Generic Unix, Cygwin or MinGW. In post-build step, call + # script, that extracts objects from archives with "ar x" + # and repacks them with "ar r" + SET(TARGET ${TARGET}) + CONFIGURE_FILE( + ${TOKU_CMAKE_SCRIPT_DIR}/merge_archives_unix.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/merge_archives_${TARGET}.cmake + @ONLY + ) + ADD_CUSTOM_COMMAND(TARGET ${TARGET} POST_BUILD + COMMAND rm ${TARGET_LOCATION} + COMMAND ${CMAKE_COMMAND} -P + ${CMAKE_CURRENT_BINARY_DIR}/merge_archives_${TARGET}.cmake + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/merge_archives_${TARGET}.cmake" + ) + ENDIF() + ENDIF() +ENDMACRO(MERGE_STATIC_LIBS) diff --git a/ft/CMakeLists.txt b/ft/CMakeLists.txt index c9b9399f7c8bd22826ad7c36cd096d10ddf1a9eb..67744b0018740f657fd745e157aa2de52adebd9c 100644 --- a/ft/CMakeLists.txt +++ b/ft/CMakeLists.txt @@ -119,7 +119,7 @@ foreach(bin ${bins}) add_executable(${bin}_static ${bin}.c) add_dependencies(${bin}_static install_tdb_h) - target_link_libraries(${bin}_static ft_static z ${LIBTOKUPORTABILITY}_static ${CMAKE_THREAD_LIBS_INIT} dl) + target_link_libraries(${bin}_static ft_static z lzma ${LIBTOKUPORTABILITY}_static ${CMAKE_THREAD_LIBS_INIT} dl) add_common_options_to_binary_targets(${bin} ${bin}_static) endforeach(bin) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bfe92ea56cdded5a1f8b12b8a88283b56ace1efb..6dea34b54ef50576fdf01191888ff51873cb4e3d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,7 +4,6 @@ add_subdirectory(range_tree) add_subdirectory(lock_tree) set(tokudb_srcs - ydb_lib.c ydb.c ydb_cursor.c ydb_db.c @@ -20,19 +19,27 @@ set(tokudb_srcs ## make the shared library add_library(${LIBTOKUDB} SHARED ${tokudb_srcs}) -add_dependencies(${LIBTOKUDB} install_tdb_h) -target_link_libraries(${LIBTOKUDB} LINK_PRIVATE lock_tree_static range_tree_static ft_static ${LIBTOKUPORTABILITY}) +add_dependencies(${LIBTOKUDB} install_tdb_h generate_log_code) +target_link_libraries(${LIBTOKUDB} LINK_PRIVATE lock_tree_static range_tree_static ft_static lzma ${LIBTOKUPORTABILITY}) target_link_libraries(${LIBTOKUDB} LINK_PUBLIC z) ## make the static library -add_library(${LIBTOKUDB}_static STATIC ${tokudb_srcs}) -add_dependencies(${LIBTOKUDB}_static install_tdb_h) -add_space_separated_property(TARGET ${LIBTOKUDB}_static COMPILE_FLAGS -fPIC) -target_link_libraries(${LIBTOKUDB}_static LINK_PRIVATE lock_tree_static range_tree_static ft_static) +add_library(tokudb_static_conv STATIC ${tokudb_srcs}) +add_dependencies(tokudb_static_conv install_tdb_h generate_log_code) +add_space_separated_property(TARGET tokudb_static_conv COMPILE_FLAGS -fPIC) +set(tokudb_required_libs tokudb_static_conv lock_tree_static range_tree_static + ft_static lzma ${LIBTOKUPORTABILITY} z ${CMAKE_THREAD_LIBS_INIT} dl) +if (CMAKE_C_COMPILER_ID STREQUAL Intel) + find_library(IRC_LIBRARIES NAMES libirc.a irc PATHS ENV LIBRARY_PATH) + add_library(irc_fullpath STATIC IMPORTED) + set_target_properties(irc_fullpath PROPERTIES IMPORTED_LOCATION ${IRC_LIBRARIES}) + list(APPEND tokudb_required_libs irc_fullpath) +endif () +set(CMAKE_TOP_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/..") +merge_static_libs(${LIBTOKUDB}_static ${LIBTOKUDB}_static "${tokudb_required_libs}") if (CMAKE_C_COMPILER_ID STREQUAL Intel) target_link_libraries(${LIBTOKUDB} LINK_PRIVATE -nodefaultlibs) - target_link_libraries(${LIBTOKUDB}_static LINK_PRIVATE -nodefaultlibs) endif () ## add a version script and set -fvisibility=hidden for the shared library @@ -43,13 +50,13 @@ if (NOT CMAKE_SYSTEM_NAME STREQUAL Darwin) endif () ## add gcov and define _GNU_SOURCE -maybe_add_gcov_to_libraries(${LIBTOKUDB} ${LIBTOKUDB}_static) -set_property(TARGET ${LIBTOKUDB} ${LIBTOKUDB}_static APPEND PROPERTY COMPILE_DEFINITIONS _GNU_SOURCE) +maybe_add_gcov_to_libraries(${LIBTOKUDB} tokudb_static_conv) +set_property(TARGET ${LIBTOKUDB} tokudb_static_conv APPEND PROPERTY COMPILE_DEFINITIONS _GNU_SOURCE) set_targets_need_intel_libs(${LIBTOKUDB}) install( - TARGETS ${LIBTOKUDB} + TARGETS ${LIBTOKUDB} ${LIBTOKUDB}_static DESTINATION lib ) diff --git a/src/lock_tree/CMakeLists.txt b/src/lock_tree/CMakeLists.txt index 5840e2970eb883dba0b95433ab2b62dede34551f..93ef460e3eaeda94ede02ab193d0ac6dca4c8cf7 100644 --- a/src/lock_tree/CMakeLists.txt +++ b/src/lock_tree/CMakeLists.txt @@ -15,6 +15,10 @@ target_link_libraries(lock_tree_tlog range_tree_tlog) add_dependencies(lock_tree_tlog install_tdb_h) set_targets_need_intel_libs(lock_tree_lin lock_tree_tlog) +if (CMAKE_C_COMPILER_ID STREQUAL Intel) + add_space_separated_property(TARGET lock_tree_lin LINK_FLAGS "-diag-disable 10237") + add_space_separated_property(TARGET lock_tree_tlog LINK_FLAGS "-diag-disable 10237") +endif () ## make the real library, it's going to go into libtokudb.so so it needs ## to be PIC diff --git a/src/range_tree/CMakeLists.txt b/src/range_tree/CMakeLists.txt index fe1166d4f55cfc88087cb6b9cb2932f2c185a74a..26d2a8863e07135c0b18fbc0d5e58aee68774687 100644 --- a/src/range_tree/CMakeLists.txt +++ b/src/range_tree/CMakeLists.txt @@ -11,6 +11,10 @@ target_link_libraries(range_tree_tlog ft ${LIBTOKUPORTABILITY}) add_dependencies(range_tree_tlog install_tdb_h) set_targets_need_intel_libs(range_tree_lin range_tree_tlog) +if (CMAKE_C_COMPILER_ID STREQUAL Intel) + add_space_separated_property(TARGET range_tree_lin LINK_FLAGS "-diag-disable 10237") + add_space_separated_property(TARGET range_tree_tlog LINK_FLAGS "-diag-disable 10237") +endif () ## make the real library, it's going to go into libtokudb.so so it needs ## to be PIC diff --git a/src/ydb.c b/src/ydb.c index 4eb0450839172a6e49bd56da86a1e140c8cfa246..f2e86e59f61b5452d3c0094b6a12d13876c59d29 100644 --- a/src/ydb.c +++ b/src/ydb.c @@ -42,6 +42,11 @@ const char *toku_copyright_string = "Copyright (c) 2007-2009 Tokutek Inc. All r #include "ydb_txn.h" #include "ft/txn_manager.h" +// Include ydb_lib.c here so that its constructor/destructor gets put into +// ydb.o, to make sure they don't get erased at link time (when linking to +// a static libtokudb.a that was compiled with gcc). See #5094. +#include "ydb_lib.c" + #ifdef TOKUTRACE #define DB_ENV_CREATE_FUN db_env_create_toku10 #define DB_CREATE_FUN db_create_toku10 diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index 6e2e991ed2990341ccd1991c6d68a97058db2c95..eae1d393f56fb81b8b0e970f4d0aae7e9f97d6f5 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -10,7 +10,7 @@ foreach(util ${utils}) add_executable(${util}_static ${util}.c) set_target_properties(${util}_static PROPERTIES COMPILE_DEFINITIONS "IS_TDB=1;USE_TDB=1;TDB_IS_STATIC=1") - target_link_libraries(${util}_static ${LIBTOKUDB}_static lock_tree_static range_tree_static ft_static z ${LIBTOKUPORTABILITY}_static ${CMAKE_THREAD_LIBS_INIT} dl) + target_link_libraries(${util}_static ${LIBTOKUDB}_static lock_tree_static range_tree_static ft_static z lzma ${LIBTOKUPORTABILITY}_static ${CMAKE_THREAD_LIBS_INIT} dl) set_targets_need_intel_libs(${util}_static) add_common_options_to_binary_targets(${util} ${util}_static)