1# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. 2# 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; version 2 of the License. 6# 7# This program is distributed in the hope that it will be useful, 8# but WITHOUT ANY WARRANTY; without even the implied warranty of 9# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10# GNU General Public License for more details. 11# 12# You should have received a copy of the GNU General Public License 13# along with this program; if not, write to the Free Software 14# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA 15 16IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND CMAKE_COMPILER_IS_GNUCXX 17 AND CMAKE_SIZEOF_VOID_P EQUAL 4) 18 IF(NOT DEFINED BUGGY_GCC_NO_DTRACE_MODULES) 19 EXECUTE_PROCESS( 20 COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1} --version 21 OUTPUT_VARIABLE out) 22 IF(out MATCHES "3.4.6") 23 # This gcc causes crashes in dlopen() for dtraced shared libs, 24 # while standard shipped with Solaris10 3.4.3 is ok 25 SET(BUGGY_GCC_NO_DTRACE_MODULES 1 CACHE INTERNAL "") 26 ELSE() 27 SET(BUGGY_GCC_NO_DTRACE_MODULES 0 CACHE INTERNAL "") 28 ENDIF() 29 ENDIF() 30ENDIF() 31 32# Check if OS supports DTrace 33MACRO(CHECK_DTRACE) 34 FIND_PROGRAM(DTRACE dtrace) 35 MARK_AS_ADVANCED(DTRACE) 36 37 IF(CMAKE_C_COMPILER MATCHES "ccache" AND CMAKE_SYSTEM_NAME MATCHES "Linux") 38 # dtrace fails on fedora if CC='ccache gcc' is used 39 SET(BUGGY_LINUX_DTRACE 1) 40 ENDIF() 41 42 # On FreeBSD, dtrace does not handle userland tracing yet 43 IF(DTRACE AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD" 44 AND NOT BUGGY_GCC_NO_DTRACE_MODULES 45 AND NOT BUGGY_LINUX_DTRACE 46 AND NOT CMAKE_SYSTEM_NAME MATCHES "SunOS" 47 AND NOT WIN32) 48 SET(ENABLE_DTRACE ON CACHE BOOL "Enable dtrace") 49 ENDIF() 50 # On GNU/Hurd, dtrace is not supported 51 IF(DTRACE AND CMAKE_SYSTEM_NAME MATCHES "GNU") 52 SET(ENABLE_DTRACE OFF CACHE BOOL "Disable dtrace") 53 ENDIF() 54 SET(HAVE_DTRACE ${ENABLE_DTRACE}) 55 IF(CMAKE_SYSTEM_NAME MATCHES "SunOS") 56 IF(CMAKE_SIZEOF_VOID_P EQUAL 4) 57 SET(DTRACE_FLAGS -32 CACHE INTERNAL "DTrace architecture flags") 58 ELSE() 59 SET(DTRACE_FLAGS -64 CACHE INTERNAL "DTrace architecture flags") 60 ENDIF() 61 ENDIF() 62ENDMACRO() 63 64CHECK_DTRACE() 65 66# Produce a header file with 67# DTrace macros 68MACRO (DTRACE_HEADER provider header header_no_dtrace) 69 IF(ENABLE_DTRACE) 70 ADD_CUSTOM_COMMAND( 71 OUTPUT ${header} ${header_no_dtrace} 72 COMMAND ${DTRACE} -h -s ${provider} -o ${header} 73 COMMAND perl ${CMAKE_SOURCE_DIR}/scripts/dheadgen.pl -f ${provider} > ${header_no_dtrace} 74 DEPENDS ${provider} 75 ) 76 ENDIF() 77ENDMACRO() 78 79 80# Create provider headers 81IF(ENABLE_DTRACE) 82 CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/include/probes_mysql.d.base 83 ${CMAKE_BINARY_DIR}/include/probes_mysql.d COPYONLY) 84 DTRACE_HEADER( 85 ${CMAKE_BINARY_DIR}/include/probes_mysql.d 86 ${CMAKE_BINARY_DIR}/include/probes_mysql_dtrace.h 87 ${CMAKE_BINARY_DIR}/include/probes_mysql_nodtrace.h 88 ) 89 ADD_CUSTOM_TARGET(gen_dtrace_header 90 DEPENDS 91 ${CMAKE_BINARY_DIR}/include/probes_mysql.d 92 ${CMAKE_BINARY_DIR}/include/probes_mysql_dtrace.h 93 ${CMAKE_BINARY_DIR}/include/probes_mysql_nodtrace.h 94 ) 95ELSE() 96 CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/include/probes_mysql_nodtrace.h.in 97 ${CMAKE_BINARY_DIR}/include/probes_mysql_nodtrace.h COPYONLY) 98ENDIF() 99 100FUNCTION(DTRACE_INSTRUMENT target) 101 IF(BUGGY_GCC_NO_DTRACE_MODULES) 102 GET_TARGET_PROPERTY(target_type ${target} TYPE) 103 IF(target_type MATCHES "MODULE_LIBRARY") 104 RETURN() 105 ENDIF() 106 ENDIF() 107 IF(ENABLE_DTRACE) 108 ADD_DEPENDENCIES(${target} gen_dtrace_header) 109 110 # Invoke dtrace to generate object file and link it together with target. 111 IF(CMAKE_SYSTEM_NAME MATCHES "SunOS") 112 SET(objdir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${target}.dir) 113 SET(outfile ${objdir}/${target}_dtrace.o) 114 GET_TARGET_PROPERTY(target_type ${target} TYPE) 115 ADD_CUSTOM_COMMAND( 116 TARGET ${target} PRE_LINK 117 COMMAND ${CMAKE_COMMAND} 118 -DDTRACE=${DTRACE} 119 -DOUTFILE=${outfile} 120 -DDFILE=${CMAKE_BINARY_DIR}/include/probes_mysql.d 121 -DDTRACE_FLAGS=${DTRACE_FLAGS} 122 -DDIRS=. 123 -DTYPE=${target_type} 124 -P ${CMAKE_SOURCE_DIR}/cmake/dtrace_prelink.cmake 125 WORKING_DIRECTORY ${objdir} 126 ) 127 ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Linux") 128 # dtrace on Linux runs gcc and uses flags from environment 129 SET(CFLAGS_SAVED $ENV{CFLAGS}) 130 SET(ENV{CFLAGS} ${CMAKE_C_FLAGS}) 131 SET(outfile "${CMAKE_BINARY_DIR}/probes_mysql.o") 132 # Systemtap object 133 EXECUTE_PROCESS( 134 COMMAND ${DTRACE} -G -s ${CMAKE_SOURCE_DIR}/include/probes_mysql.d.base 135 -o ${outfile} 136 ) 137 SET(ENV{CFLAGS} ${CFLAGS_SAVED}) 138 ENDIF() 139 140 # Do not try to extend the library if we have not built the .o file 141 IF(outfile) 142 # Add full object path to linker flags 143 GET_TARGET_PROPERTY(target_type ${target} TYPE) 144 IF(NOT target_type MATCHES "STATIC") 145 SET_TARGET_PROPERTIES(${target} PROPERTIES LINK_FLAGS "${outfile}") 146 ELSE() 147 # For static library flags, add the object to the library. 148 # Note: DTrace probes in static libraries are unusable currently 149 # (see explanation for DTRACE_INSTRUMENT_STATIC_LIBS below) 150 # but maybe one day this will be fixed. 151 ADD_CUSTOM_COMMAND( 152 TARGET ${target} POST_BUILD 153 COMMAND ${CMAKE_AR} r $<TARGET_FILE:${target}> ${outfile} 154 COMMAND ${CMAKE_RANLIB} $<TARGET_FILE:${target}> 155 ) 156 # Used in DTRACE_INSTRUMENT_WITH_STATIC_LIBS 157 SET(TARGET_OBJECT_DIRECTORY_${target} ${objdir} CACHE INTERNAL "") 158 ENDIF() 159 ENDIF() 160 ENDIF() 161ENDFUNCTION() 162 163 164# Ugly workaround for Solaris' DTrace inability to use probes 165# from static libraries, discussed e.g in this thread 166# (http://opensolaris.org/jive/thread.jspa?messageID=432454) 167# We have to collect all object files that may be instrumented 168# and go into the mysqld (also those that come from in static libs) 169# run them again through dtrace -G to generate an ELF file that links 170# to mysqld. 171MACRO (DTRACE_INSTRUMENT_STATIC_LIBS target libs) 172IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND ENABLE_DTRACE) 173 # Filter out non-static libraries in the list, if any 174 SET(static_libs) 175 FOREACH(lib ${libs}) 176 GET_TARGET_PROPERTY(libtype ${lib} TYPE) 177 IF(libtype MATCHES STATIC_LIBRARY) 178 SET(static_libs ${static_libs} ${lib}) 179 ENDIF() 180 ENDFOREACH() 181 182 FOREACH(lib ${static_libs}) 183 SET(dirs ${dirs} ${TARGET_OBJECT_DIRECTORY_${lib}}) 184 ENDFOREACH() 185 186 SET (obj ${CMAKE_CURRENT_BINARY_DIR}/${target}_dtrace_all.o) 187 ADD_CUSTOM_COMMAND( 188 OUTPUT ${obj} 189 DEPENDS ${static_libs} 190 COMMAND ${CMAKE_COMMAND} 191 -DDTRACE=${DTRACE} 192 -DOUTFILE=${obj} 193 -DDFILE=${CMAKE_BINARY_DIR}/include/probes_mysql.d 194 -DDTRACE_FLAGS=${DTRACE_FLAGS} 195 "-DDIRS=${dirs}" 196 -DTYPE=MERGE 197 -P ${CMAKE_SOURCE_DIR}/cmake/dtrace_prelink.cmake 198 VERBATIM 199 ) 200 ADD_CUSTOM_TARGET(${target}_dtrace_all DEPENDS ${obj}) 201 ADD_DEPENDENCIES(${target} ${target}_dtrace_all) 202 TARGET_LINK_LIBRARIES(${target} ${obj}) 203ENDIF() 204ENDMACRO() 205