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