1# Copyright (c) 2009, 2017, 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, 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 FIND_PROGRAM(DTRACE dtrace) 26 MARK_AS_ADVANCED(DTRACE) 27 28 # On FreeBSD, dtrace does not handle userland tracing yet 29 IF(DTRACE AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD") 30 SET(ENABLE_DTRACE ON CACHE BOOL "Enable dtrace") 31 ENDIF() 32 SET(HAVE_DTRACE ${ENABLE_DTRACE}) 33 EXECUTE_PROCESS( 34 COMMAND ${DTRACE} -V 35 OUTPUT_VARIABLE out) 36 IF(out MATCHES "Sun D" OR out MATCHES "Oracle D") 37 IF(NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD" AND 38 NOT CMAKE_SYSTEM_NAME MATCHES "Darwin") 39 SET(HAVE_REAL_DTRACE_INSTRUMENTING ON CACHE BOOL "Real DTrace detected") 40 ENDIF() 41 ENDIF() 42 IF(HAVE_REAL_DTRACE_INSTRUMENTING) 43 IF(SIZEOF_VOIDP EQUAL 4) 44 SET(DTRACE_FLAGS -32 CACHE INTERNAL "DTrace architecture flags") 45 ELSE() 46 SET(DTRACE_FLAGS -64 CACHE INTERNAL "DTrace architecture flags") 47 ENDIF() 48 ENDIF() 49ENDMACRO() 50 51CHECK_DTRACE() 52 53# Produce a header file with 54# DTrace macros 55MACRO (DTRACE_HEADER provider header header_no_dtrace) 56 IF(ENABLE_DTRACE) 57 ADD_CUSTOM_COMMAND( 58 OUTPUT ${header} ${header_no_dtrace} 59 COMMAND ${DTRACE} -h -s ${provider} -o ${header} 60 COMMAND perl ${CMAKE_SOURCE_DIR}/scripts/dheadgen.pl -f ${provider} > ${header_no_dtrace} 61 DEPENDS ${provider} 62 ) 63 ENDIF() 64ENDMACRO() 65 66 67# Create provider headers 68IF(ENABLE_DTRACE) 69 CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/include/probes_mysql.d.base 70 ${CMAKE_BINARY_DIR}/include/probes_mysql.d COPYONLY) 71 DTRACE_HEADER( 72 ${CMAKE_BINARY_DIR}/include/probes_mysql.d 73 ${CMAKE_BINARY_DIR}/include/probes_mysql_dtrace.h 74 ${CMAKE_BINARY_DIR}/include/probes_mysql_nodtrace.h 75 ) 76 ADD_CUSTOM_TARGET(gen_dtrace_header 77 DEPENDS 78 ${CMAKE_BINARY_DIR}/include/probes_mysql.d 79 ${CMAKE_BINARY_DIR}/include/probes_mysql_dtrace.h 80 ${CMAKE_BINARY_DIR}/include/probes_mysql_nodtrace.h 81 ) 82ENDIF() 83 84FUNCTION(DTRACE_INSTRUMENT target) 85 IF(ENABLE_DTRACE) 86 ADD_DEPENDENCIES(${target} gen_dtrace_header) 87 88 # Invoke dtrace to generate object file and link it together with target. 89 IF(HAVE_REAL_DTRACE_INSTRUMENTING) 90 SET(objdir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${target}.dir) 91 SET(outfile ${objdir}/${target}_dtrace.o) 92 GET_TARGET_PROPERTY(target_type ${target} TYPE) 93 ADD_CUSTOM_COMMAND( 94 TARGET ${target} PRE_LINK 95 COMMAND ${CMAKE_COMMAND} 96 -DDTRACE=${DTRACE} 97 -DOUTFILE=${outfile} 98 -DDFILE=${CMAKE_BINARY_DIR}/include/probes_mysql.d 99 -DDTRACE_FLAGS=${DTRACE_FLAGS} 100 -DDIRS=. 101 -DTYPE=${target_type} 102 -P ${CMAKE_SOURCE_DIR}/cmake/dtrace_prelink.cmake 103 WORKING_DIRECTORY ${objdir} 104 ) 105 ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Linux") 106 # dtrace on Linux runs gcc and uses flags from environment 107 SET(CFLAGS_SAVED $ENV{CFLAGS}) 108 # We want to strip off all warning flags, including -Werror=xxx-xx, 109 # but keep flags like 110 # -Wp,-D_FORTIFY_SOURCE=2 111 STRING(REGEX REPLACE "-W[A-Za-z0-9][-A-Za-z0-9=]+" "" 112 C_FLAGS "${CMAKE_C_FLAGS}") 113 114 SET(ENV{CFLAGS} ${C_FLAGS}) 115 SET(outfile "${CMAKE_BINARY_DIR}/probes_mysql.o") 116 # Systemtap object 117 EXECUTE_PROCESS( 118 COMMAND ${DTRACE} -G -s ${CMAKE_SOURCE_DIR}/include/probes_mysql.d.base 119 -o ${outfile} 120 ) 121 SET(ENV{CFLAGS} ${CFLAGS_SAVED}) 122 ENDIF() 123 124 # Do not try to extend the library if we have not built the .o file 125 IF(outfile) 126 # Add full object path to linker flags 127 GET_TARGET_PROPERTY(target_type ${target} TYPE) 128 IF(NOT target_type MATCHES "STATIC") 129 SET_TARGET_PROPERTIES(${target} PROPERTIES LINK_FLAGS "${outfile}") 130 ELSE() 131 # For static library flags, add the object to the library. 132 # Note: DTrace probes in static libraries are unusable currently 133 # (see explanation for DTRACE_INSTRUMENT_STATIC_LIBS below) 134 # but maybe one day this will be fixed. 135 ADD_CUSTOM_COMMAND( 136 TARGET ${target} POST_BUILD 137 COMMAND ${CMAKE_AR} r $<TARGET_FILE:${target}> ${outfile} 138 COMMAND ${CMAKE_RANLIB} $<TARGET_FILE:${target}> 139 ) 140 # Used in DTRACE_INSTRUMENT_WITH_STATIC_LIBS 141 SET(TARGET_OBJECT_DIRECTORY_${target} ${objdir} CACHE INTERNAL "") 142 ENDIF() 143 ENDIF() 144 ENDIF() 145ENDFUNCTION() 146 147 148# Ugly workaround for Solaris' DTrace inability to use probes 149# from static libraries, discussed e.g in this thread 150# (http://opensolaris.org/jive/thread.jspa?messageID=432454) 151# We have to collect all object files that may be instrumented 152# and go into the mysqld (also those that come from in static libs) 153# run them again through dtrace -G to generate an ELF file that links 154# to mysqld. 155MACRO (DTRACE_INSTRUMENT_STATIC_LIBS target libs) 156IF(HAVE_REAL_DTRACE_INSTRUMENTING AND ENABLE_DTRACE) 157 # Filter out non-static libraries in the list, if any 158 SET(static_libs) 159 FOREACH(lib ${libs}) 160 GET_TARGET_PROPERTY(libtype ${lib} TYPE) 161 IF(libtype MATCHES STATIC_LIBRARY) 162 SET(static_libs ${static_libs} ${lib}) 163 ENDIF() 164 ENDFOREACH() 165 166 FOREACH(lib ${static_libs}) 167 SET(dirs ${dirs} ${TARGET_OBJECT_DIRECTORY_${lib}}) 168 ENDFOREACH() 169 170 SET (obj ${CMAKE_CURRENT_BINARY_DIR}/${target}_dtrace_all.o) 171 ADD_CUSTOM_COMMAND( 172 OUTPUT ${obj} 173 DEPENDS ${static_libs} 174 COMMAND ${CMAKE_COMMAND} 175 -DDTRACE=${DTRACE} 176 -DOUTFILE=${obj} 177 -DDFILE=${CMAKE_BINARY_DIR}/include/probes_mysql.d 178 -DDTRACE_FLAGS=${DTRACE_FLAGS} 179 "-DDIRS=${dirs}" 180 -DTYPE=MERGE 181 -P ${CMAKE_SOURCE_DIR}/cmake/dtrace_prelink.cmake 182 VERBATIM 183 ) 184 ADD_CUSTOM_TARGET(${target}_dtrace_all DEPENDS ${obj}) 185 ADD_DEPENDENCIES(${target} ${target}_dtrace_all) 186 TARGET_LINK_LIBRARIES(${target} ${obj}) 187ENDIF() 188ENDMACRO() 189