11#[=============================================================================[
2- # FindDtrace
2+ # FindDTrace
33
44Find DTrace.
55
6+ Module defines the following `IMPORTED` target(s):
7+
8+ * `DTrace::DTrace` - The package library, if found.
9+
610## Result variables
711
812* `DTrace_FOUND` - Whether DTrace library is found.
@@ -11,28 +15,52 @@ Find DTrace.
1115
1216* `DTrace_INCLUDE_DIR` - Directory containing DTrace library headers.
1317* `DTrace_EXECUTABLE` - Path to the DTrace command-line utility.
14- * `HAVE_DTRACE` - Whether DTrace support is enabled.
1518
1619## Functions provided by this module
1720
1821Module defines the following function to initialize the DTrace support.
1922
2023```cmake
2124dtrace_target(
22- TARGET <target-name>
25+ <target-name>
2326 INPUT <input>
2427 HEADER <header>
2528 SOURCES <source>...
2629 [INCLUDES <includes>...]
2730)
2831```
2932
30- * `TARGET` - Target name to append the generated DTrace probe definition object
31- file.
32- * `INPUT` - Name of the file with DTrace probe descriptions.
33- * `HEADER` - Name of the DTrace probe header file.
34- * `SOURCES` - A list of project source files to build DTrace object.
33+ Generates DTrace header `<header>` and creates `INTERFACE` library
34+ `<target-name>` with probe definition object file added as INTERFACE source.
35+
36+ * `<target-name>` - DTrace INTERFACE library with the generated DTrace probe
37+ definition object file.
38+ * `INPUT` - Name of the file with DTrace probe descriptions. Relative path is
39+ interpreted as being relative to the current source directory.
40+ * `HEADER` - Name of the DTrace probe header file to be generated. Relative path
41+ is interpreted as being relative to the current binary directory.
42+ * `SOURCES` - A list of source files to build DTrace object. Relative paths are
43+ interpreted as being relative to the current source directory.
3544* `INCLUDES` - A list of include directories for appending to DTrace object.
45+
46+ ## Basic usage
47+
48+ ```cmake
49+ # CMakeLists.txt
50+
51+ find_package(DTrace)
52+
53+ dtrace_target(
54+ foo_dtrace
55+ INPUT foo_dtrace.d
56+ HEADER foo_dtrace_generated.h
57+ SOURCES foo.c ...
58+ )
59+ target_link_libraries(foo PRIVATE DTrace::DTrace)
60+
61+ add_executable(bar)
62+ target_link_libraries(bar PRIVATE foo_dtrace)
63+ ```
3664#]=============================================================================]
3765
3866include (FeatureSummary)
@@ -84,15 +112,23 @@ if(NOT DTrace_FOUND)
84112 return ()
85113endif ()
86114
87- set (HAVE_DTRACE 1 CACHE INTERNAL "Whether to enable DTrace support" )
115+ if (NOT TARGET DTrace::DTrace)
116+ add_library (DTrace::DTrace INTERFACE IMPORTED )
117+ set_target_properties (
118+ DTrace::DTrace
119+ PROPERTIES
120+ INTERFACE_INCLUDE_DIRECTORIES ${DTrace_INCLUDE_DIR}
121+ )
122+ endif ()
88123
89124function (dtrace_target)
90125 cmake_parse_arguments (
91- parsed # prefix
92- "" # options
93- "TARGET;INPUT;HEADER" # one-value keywords
94- "SOURCES;INCLUDES" # multi-value keywords
95- ${ARGN} # strings to parse
126+ PARSE_ARGV
127+ 1
128+ parsed # prefix
129+ "" # options
130+ "INPUT;HEADER" # one-value keywords
131+ "SOURCES;INCLUDES" # multi-value keywords
96132 )
97133
98134 if (parsed_UNPARSED_ARGUMENTS)
@@ -103,14 +139,10 @@ function(dtrace_target)
103139 message (FATAL_ERROR "Missing values for: ${parsed_KEYWORDS_MISSING_VALUES} " )
104140 endif ()
105141
106- if (NOT parsed_TARGET )
142+ if (NOT ARGV0 )
107143 message (FATAL_ERROR "dtrace_target expects a target name" )
108144 endif ()
109145
110- if (NOT TARGET ${parsed_TARGET} )
111- message (FATAL_ERROR "dtrace_target: ${parsed_TARGET} is not a target" )
112- endif ()
113-
114146 if (NOT parsed_INPUT)
115147 message (FATAL_ERROR "dtrace_target expects an input filename" )
116148 endif ()
@@ -123,64 +155,92 @@ function(dtrace_target)
123155 message (FATAL_ERROR "dtrace_target expects a list of source files" )
124156 endif ()
125157
126- # Generate DTrace header.
127- add_custom_command (
128- OUTPUT "${parsed_HEADER} "
129- COMMAND ${DTrace_EXECUTABLE}
130- -s "${parsed_INPUT} "
131- -h # Generate a systemtap header file.
132- -C # Run the cpp preprocessor on the input file.
133- -o "${parsed_HEADER} " # Name of the output file.
134- DEPENDS "${parsed_INPUT} "
135- COMMENT "[DTrace] Generating DTrace ${parsed_HEADER} "
136- VERBATIM
137- )
158+ if (NOT IS_ABSOLUTE "${parsed_INPUT} " )
159+ set (parsed_INPUT ${CMAKE_CURRENT_SOURCE_DIR} /${parsed_INPUT} )
160+ endif ()
138161
139- # Patch DTrace header.
162+ if (NOT IS_ABSOLUTE "${parsed_HEADER} " )
163+ set (parsed_HEADER ${CMAKE_CURRENT_BINARY_DIR} /${parsed_HEADER} )
164+ endif ()
165+
166+ set (sources )
167+ foreach (source IN LISTS parsed_SOURCES)
168+ if (NOT IS_ABSOLUTE ${source} )
169+ set (source ${CMAKE_CURRENT_SOURCE_DIR} /${source} )
170+ endif ()
171+ list (APPEND sources ${source} )
172+ endforeach ()
173+ set (parsed_SOURCES ${sources} )
174+
175+ # Generate DTrace header.
140176 file (
141177 GENERATE
142- OUTPUT CMakeFiles/PatchDTraceHeader .cmake
178+ OUTPUT CMakeFiles/GenerateDTraceHeader .cmake
143179 CONTENT [[
144- file(READ "${DTRACE_HEADER_FILE}" content)
180+ execute_process(
181+ COMMAND ${DTrace_EXECUTABLE}
182+ -s "${parsed_INPUT}"
183+ -h # Generate a systemtap header file.
184+ -C # Run the cpp preprocessor on the input file.
185+ -o "${parsed_HEADER}" # Name of the output file.
186+ )
187+ # Patch DTrace header.
188+ file(READ "${parsed_HEADER}" content)
145189 string(REPLACE "PHP_" "DTRACE_" content "${content}")
146- file(WRITE "${DTRACE_HEADER_FILE }" "${content}")
190+ file(WRITE "${parsed_HEADER }" "${content}")
147191 ]]
148192 )
149- add_custom_target (
150- ${parsed_TARGET} _patch_header
193+ cmake_path(
194+ RELATIVE_PATH parsed_HEADER
195+ BASE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
196+ OUTPUT_VARIABLE header
197+ )
198+ add_custom_command (
199+ OUTPUT ${parsed_HEADER}
151200 COMMAND ${CMAKE_COMMAND}
152- -DDTRACE_HEADER_FILE=${parsed_HEADER}
153- -P CMakeFiles/PatchDTraceHeader.cmake
154- DEPENDS ${parsed_HEADER}
155- COMMENT "[DTrace] Patching ${parsed_HEADER} "
201+ -DDTrace_EXECUTABLE=${DTrace_EXECUTABLE}
202+ -Dparsed_HEADER=${parsed_HEADER}
203+ -Dparsed_INPUT=${parsed_INPUT}
204+ -P CMakeFiles/GenerateDTraceHeader.cmake
205+ DEPENDS "${parsed_INPUT} "
206+ COMMENT "[DTrace] Generating ${header} "
207+ VERBATIM
208+ COMMAND_EXPAND_LISTS
156209 )
157210
158- add_library (${parsed_TARGET} _object OBJECT ${parsed_SOURCES} )
159-
160- add_dependencies (${parsed_TARGET} _object ${parsed_TARGET} _patch_header)
161-
162- target_include_directories (
163- ${parsed_TARGET} _object
164- PRIVATE
165- ${DTrace_INCLUDE_DIR}
166- ${parsed_INCLUDES}
167- )
211+ # Generate DTrace object.
212+ set (target ${ARGV0} )
213+ add_library (${target} _object OBJECT ${parsed_SOURCES} ${parsed_HEADER} )
214+ target_link_libraries (${target} _object PRIVATE DTrace::DTrace)
215+ target_include_directories (${target} _object PRIVATE ${parsed_INCLUDES} )
168216
169217 cmake_path(GET parsed_INPUT FILENAME input )
170- set (output_filename CMakeFiles/${input} .o)
218+ set (output CMakeFiles/${input} .o)
219+ cmake_path(GET CMAKE_CURRENT_BINARY_DIR FILENAME parent)
171220
172221 add_custom_command (
173- OUTPUT ${output_filename}
174- COMMAND CC="${CMAKE_C_COMPILER} " ${DTrace_EXECUTABLE}
175- -s ${parsed_INPUT} $<TARGET_OBJECTS:${parsed_TARGET} _object>
222+ OUTPUT ${output}
223+ COMMAND
224+ CC="${CMAKE_C_COMPILER} "
225+ ${DTrace_EXECUTABLE}
226+ -s ${parsed_INPUT} $<TARGET_OBJECTS:${target} _object>
176227 -G # Generate a systemtap probe definition object file.
177- -o ${output_filename }
228+ -o ${output }
178229 -I${DTrace_INCLUDE_DIR}
179- DEPENDS ${parsed_TARGET } _object
180- COMMENT "[DTrace] Generating DTrace probe object ${output_filename } "
230+ DEPENDS ${target } _object
231+ COMMENT "[DTrace] Generating DTrace probe object ${parent} / ${output } "
181232 VERBATIM
233+ COMMAND_EXPAND_LISTS
182234 )
183-
184- target_sources (${parsed_TARGET} PRIVATE ${output_filename} )
185- target_include_directories (${parsed_TARGET} PUBLIC ${DTrace_INCLUDE_DIR} )
235+ add_custom_target (${target} _generator DEPENDS ${output} )
236+
237+ add_library (${target} INTERFACE )
238+ target_sources (${target} INTERFACE ${CMAKE_CURRENT_BINARY_DIR} /${output} )
239+ set_source_files_properties (
240+ ${CMAKE_CURRENT_BINARY_DIR} /${output}
241+ PROPERTIES
242+ EXTERNAL_OBJECT TRUE
243+ GENERATED TRUE
244+ )
245+ add_dependencies (${target} ${target} _generator)
186246endfunction ()
0 commit comments