1# Copyright (c) 2009, 2021, Oracle and/or its affiliates. 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, version 2.0, 5# as published by the Free Software Foundation. 6# 7# This program is also distributed with certain software (including 8# but not limited to OpenSSL) that is licensed under separate terms, 9# as designated in a particular file or component or in included license 10# documentation. The authors of MySQL hereby grant you an additional 11# permission to link the program and your derivative works with the 12# separately licensed software that they have included with MySQL. 13# 14# This program is distributed in the hope that it will be useful, 15# but WITHOUT ANY WARRANTY; without even the implied warranty of 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17# GNU General Public License, version 2.0, for more details. 18# 19# You should have received a copy of the GNU General Public License 20# along with this program; if not, write to the Free Software 21# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 23# Check if OS supports DTrace 24MACRO(CHECK_DTRACE) 25 IF(DEFINED ENABLE_DTRACE AND NOT ENABLE_DTRACE) 26 MESSAGE(STATUS "DTRACE is disabled") 27 ELSE() 28 FIND_PROGRAM(DTRACE dtrace) 29 MARK_AS_ADVANCED(DTRACE) 30 31 IF(DTRACE) 32 EXECUTE_PROCESS( 33 COMMAND ${DTRACE} -V 34 OUTPUT_VARIABLE out) 35 IF(out MATCHES "Sun D" OR out MATCHES "Oracle D") 36 IF(NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD" AND 37 NOT CMAKE_SYSTEM_NAME MATCHES "Darwin") 38 SET(HAVE_REAL_DTRACE_INSTRUMENTING ON CACHE BOOL "Real DTrace detected") 39 ENDIF() 40 ENDIF() 41 ENDIF() 42 43 # On FreeBSD, dtrace does not handle userland tracing yet 44 IF(DTRACE AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD") 45 # We do not support DTrace 2.0 on Linux 46 IF(LINUX AND HAVE_REAL_DTRACE_INSTRUMENTING) 47 # Break the build if ENABLE_DTRACE set explicitly. 48 IF(DEFINED ENABLE_DTRACE AND ENABLE_DTRACE) 49 MESSAGE(FATAL_ERROR "Found unsupported dtrace at ${DTRACE}\n ${out}") 50 ELSE() 51 MESSAGE(WARNING "Found unsupported dtrace at ${DTRACE}\n ${out}") 52 SET(HAVE_REAL_DTRACE_INSTRUMENTING OFF CACHE BOOL "") 53 SET(ENABLE_DTRACE OFF CACHE BOOL "Enable dtrace") 54 ENDIF() 55 ELSE() 56 SET(ENABLE_DTRACE ON CACHE BOOL "Enable dtrace") 57 MESSAGE(STATUS "DTRACE is enabled") 58 ENDIF() 59 ENDIF() 60 SET(HAVE_DTRACE ${ENABLE_DTRACE}) 61 62 IF(HAVE_REAL_DTRACE_INSTRUMENTING) 63 IF(SIZEOF_VOIDP EQUAL 4) 64 SET(DTRACE_FLAGS -32 CACHE INTERNAL "DTrace architecture flags") 65 ELSE() 66 SET(DTRACE_FLAGS -64 CACHE INTERNAL "DTrace architecture flags") 67 ENDIF() 68 ENDIF() 69 70 ENDIF() 71ENDMACRO() 72 73CHECK_DTRACE() 74 75# Produce a header file with 76# DTrace macros 77MACRO (DTRACE_HEADER provider header header_no_dtrace) 78 IF(ENABLE_DTRACE) 79 ADD_CUSTOM_COMMAND( 80 OUTPUT ${header} ${header_no_dtrace} 81 COMMAND ${DTRACE} -h -s ${provider} -o ${header} 82 COMMAND perl ${CMAKE_SOURCE_DIR}/scripts/dheadgen.pl -f ${provider} > ${header_no_dtrace} 83 DEPENDS ${provider} 84 ) 85 ENDIF() 86ENDMACRO() 87 88 89# Create provider headers 90IF(ENABLE_DTRACE) 91 CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/include/probes_mysql.d.base 92 ${CMAKE_BINARY_DIR}/include/probes_mysql.d COPYONLY) 93 DTRACE_HEADER( 94 ${CMAKE_BINARY_DIR}/include/probes_mysql.d 95 ${CMAKE_BINARY_DIR}/include/probes_mysql_dtrace.h 96 ${CMAKE_BINARY_DIR}/include/probes_mysql_nodtrace.h 97 ) 98 ADD_CUSTOM_TARGET(gen_dtrace_header 99 DEPENDS 100 ${CMAKE_BINARY_DIR}/include/probes_mysql.d 101 ${CMAKE_BINARY_DIR}/include/probes_mysql_dtrace.h 102 ${CMAKE_BINARY_DIR}/include/probes_mysql_nodtrace.h 103 ) 104ENDIF() 105 106FUNCTION(DTRACE_INSTRUMENT target) 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(HAVE_REAL_DTRACE_INSTRUMENTING) 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 # We want to strip off all warning flags, including -Werror=xxx-xx, 131 # but keep flags like 132 # -Wp,-D_FORTIFY_SOURCE=2 133 STRING(REGEX REPLACE "-W[A-Za-z0-9][-A-Za-z0-9=]+" "" 134 C_FLAGS "${CMAKE_C_FLAGS}") 135 136 SET(ENV{CFLAGS} ${C_FLAGS}) 137 SET(outfile "${CMAKE_BINARY_DIR}/probes_mysql.o") 138 # Systemtap object 139 EXECUTE_PROCESS( 140 COMMAND ${DTRACE} -G -s ${CMAKE_SOURCE_DIR}/include/probes_mysql.d.base 141 -o ${outfile} 142 ) 143 SET(ENV{CFLAGS} ${CFLAGS_SAVED}) 144 ENDIF() 145 146 # Do not try to extend the library if we have not built the .o file 147 IF(outfile) 148 # Add full object path to linker flags 149 GET_TARGET_PROPERTY(target_type ${target} TYPE) 150 IF(NOT target_type MATCHES "STATIC") 151 SET_TARGET_PROPERTIES(${target} PROPERTIES LINK_FLAGS "${outfile}") 152 ELSE() 153 # For static library flags, add the object to the library. 154 # Note: DTrace probes in static libraries are unusable currently 155 # (see explanation for DTRACE_INSTRUMENT_STATIC_LIBS below) 156 # but maybe one day this will be fixed. 157 ADD_CUSTOM_COMMAND( 158 TARGET ${target} POST_BUILD 159 COMMAND ${CMAKE_AR} r $<TARGET_FILE:${target}> ${outfile} 160 COMMAND ${CMAKE_RANLIB} $<TARGET_FILE:${target}> 161 ) 162 # Used in DTRACE_INSTRUMENT_WITH_STATIC_LIBS 163 SET(TARGET_OBJECT_DIRECTORY_${target} ${objdir} CACHE INTERNAL "") 164 ENDIF() 165 ENDIF() 166 ENDIF() 167ENDFUNCTION() 168 169 170# Ugly workaround for Solaris' DTrace inability to use probes 171# from static libraries, discussed e.g in this thread 172# (http://opensolaris.org/jive/thread.jspa?messageID=432454) 173# We have to collect all object files that may be instrumented 174# and go into the mysqld (also those that come from in static libs) 175# run them again through dtrace -G to generate an ELF file that links 176# to mysqld. 177MACRO (DTRACE_INSTRUMENT_STATIC_LIBS target libs) 178IF(HAVE_REAL_DTRACE_INSTRUMENTING AND ENABLE_DTRACE) 179 # Filter out non-static libraries in the list, if any 180 SET(static_libs) 181 FOREACH(lib ${libs}) 182 GET_TARGET_PROPERTY(libtype ${lib} TYPE) 183 IF(libtype MATCHES STATIC_LIBRARY) 184 SET(static_libs ${static_libs} ${lib}) 185 ENDIF() 186 ENDFOREACH() 187 188 FOREACH(lib ${static_libs}) 189 SET(dirs ${dirs} ${TARGET_OBJECT_DIRECTORY_${lib}}) 190 ENDFOREACH() 191 192 SET (obj ${CMAKE_CURRENT_BINARY_DIR}/${target}_dtrace_all.o) 193 ADD_CUSTOM_COMMAND( 194 OUTPUT ${obj} 195 DEPENDS ${static_libs} 196 COMMAND ${CMAKE_COMMAND} 197 -DDTRACE=${DTRACE} 198 -DOUTFILE=${obj} 199 -DDFILE=${CMAKE_BINARY_DIR}/include/probes_mysql.d 200 -DDTRACE_FLAGS=${DTRACE_FLAGS} 201 "-DDIRS=${dirs}" 202 -DTYPE=MERGE 203 -P ${CMAKE_SOURCE_DIR}/cmake/dtrace_prelink.cmake 204 VERBATIM 205 ) 206 ADD_CUSTOM_TARGET(${target}_dtrace_all DEPENDS ${obj}) 207 ADD_DEPENDENCIES(${target} ${target}_dtrace_all) 208 TARGET_LINK_LIBRARIES(${target} ${obj}) 209ENDIF() 210ENDMACRO() 211