blob: 2be710cd9782bcc910b9554d5c29bf3d7b86f345 [file] [log] [blame]
ptrkrysik12fe7a02014-11-20 11:10:20 +01001# Copyright 2010-2011,2014 Free Software Foundation, Inc.
piotr437f5462014-02-04 17:57:25 +01002#
3# This file is part of GNU Radio
4#
5# GNU Radio is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 3, or (at your option)
8# any later version.
9#
10# GNU Radio is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with GNU Radio; see the file COPYING. If not, write to
17# the Free Software Foundation, Inc., 51 Franklin Street,
18# Boston, MA 02110-1301, USA.
19
20if(DEFINED __INCLUDED_GR_MISC_UTILS_CMAKE)
21 return()
22endif()
23set(__INCLUDED_GR_MISC_UTILS_CMAKE TRUE)
24
25########################################################################
26# Set global variable macro.
27# Used for subdirectories to export settings.
28# Example: include and library paths.
29########################################################################
30function(GR_SET_GLOBAL var)
31 set(${var} ${ARGN} CACHE INTERNAL "" FORCE)
32endfunction(GR_SET_GLOBAL)
33
34########################################################################
35# Set the pre-processor definition if the condition is true.
36# - def the pre-processor definition to set and condition name
37########################################################################
38function(GR_ADD_COND_DEF def)
39 if(${def})
40 add_definitions(-D${def})
41 endif(${def})
42endfunction(GR_ADD_COND_DEF)
43
44########################################################################
45# Check for a header and conditionally set a compile define.
46# - hdr the relative path to the header file
47# - def the pre-processor definition to set
48########################################################################
49function(GR_CHECK_HDR_N_DEF hdr def)
50 include(CheckIncludeFileCXX)
51 CHECK_INCLUDE_FILE_CXX(${hdr} ${def})
52 GR_ADD_COND_DEF(${def})
53endfunction(GR_CHECK_HDR_N_DEF)
54
55########################################################################
56# Include subdirectory macro.
57# Sets the CMake directory variables,
58# includes the subdirectory CMakeLists.txt,
59# resets the CMake directory variables.
60#
61# This macro includes subdirectories rather than adding them
62# so that the subdirectory can affect variables in the level above.
63# This provides a work-around for the lack of convenience libraries.
64# This way a subdirectory can append to the list of library sources.
65########################################################################
66macro(GR_INCLUDE_SUBDIRECTORY subdir)
67 #insert the current directories on the front of the list
68 list(INSERT _cmake_source_dirs 0 ${CMAKE_CURRENT_SOURCE_DIR})
69 list(INSERT _cmake_binary_dirs 0 ${CMAKE_CURRENT_BINARY_DIR})
70
71 #set the current directories to the names of the subdirs
72 set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${subdir})
73 set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${subdir})
74
75 #include the subdirectory CMakeLists to run it
76 file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
77 include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
78
79 #reset the value of the current directories
80 list(GET _cmake_source_dirs 0 CMAKE_CURRENT_SOURCE_DIR)
81 list(GET _cmake_binary_dirs 0 CMAKE_CURRENT_BINARY_DIR)
82
83 #pop the subdir names of the front of the list
84 list(REMOVE_AT _cmake_source_dirs 0)
85 list(REMOVE_AT _cmake_binary_dirs 0)
86endmacro(GR_INCLUDE_SUBDIRECTORY)
87
88########################################################################
89# Check if a compiler flag works and conditionally set a compile define.
90# - flag the compiler flag to check for
91# - have the variable to set with result
92########################################################################
93macro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE flag have)
94 include(CheckCXXCompilerFlag)
95 CHECK_CXX_COMPILER_FLAG(${flag} ${have})
96 if(${have})
ptrkrysik12fe7a02014-11-20 11:10:20 +010097 if(${CMAKE_VERSION} VERSION_GREATER "2.8.4")
98 STRING(FIND "${CMAKE_CXX_FLAGS}" "${flag}" flag_dup)
99 if(${flag_dup} EQUAL -1)
100 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
101 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
102 endif(${flag_dup} EQUAL -1)
103 endif(${CMAKE_VERSION} VERSION_GREATER "2.8.4")
piotr437f5462014-02-04 17:57:25 +0100104 endif(${have})
105endmacro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE)
106
107########################################################################
108# Generates the .la libtool file
109# This appears to generate libtool files that cannot be used by auto*.
110# Usage GR_LIBTOOL(TARGET [target] DESTINATION [dest])
111# Notice: there is not COMPONENT option, these will not get distributed.
112########################################################################
113function(GR_LIBTOOL)
114 if(NOT DEFINED GENERATE_LIBTOOL)
115 set(GENERATE_LIBTOOL OFF) #disabled by default
116 endif()
117
118 if(GENERATE_LIBTOOL)
119 include(CMakeParseArgumentsCopy)
120 CMAKE_PARSE_ARGUMENTS(GR_LIBTOOL "" "TARGET;DESTINATION" "" ${ARGN})
121
122 find_program(LIBTOOL libtool)
123 if(LIBTOOL)
124 include(CMakeMacroLibtoolFile)
125 CREATE_LIBTOOL_FILE(${GR_LIBTOOL_TARGET} /${GR_LIBTOOL_DESTINATION})
126 endif(LIBTOOL)
127 endif(GENERATE_LIBTOOL)
128
129endfunction(GR_LIBTOOL)
130
131########################################################################
132# Do standard things to the library target
133# - set target properties
134# - make install rules
135# Also handle gnuradio custom naming conventions w/ extras mode.
136########################################################################
137function(GR_LIBRARY_FOO target)
138 #parse the arguments for component names
139 include(CMakeParseArgumentsCopy)
140 CMAKE_PARSE_ARGUMENTS(GR_LIBRARY "" "RUNTIME_COMPONENT;DEVEL_COMPONENT" "" ${ARGN})
141
142 #set additional target properties
143 set_target_properties(${target} PROPERTIES SOVERSION ${LIBVER})
144
145 #install the generated files like so...
146 install(TARGETS ${target}
147 LIBRARY DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .so/.dylib file
148 ARCHIVE DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_DEVEL_COMPONENT} # .lib file
149 RUNTIME DESTINATION ${GR_RUNTIME_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .dll file
150 )
151
152 #extras mode enabled automatically on linux
153 if(NOT DEFINED LIBRARY_EXTRAS)
154 set(LIBRARY_EXTRAS ${LINUX})
155 endif()
156
157 #special extras mode to enable alternative naming conventions
158 if(LIBRARY_EXTRAS)
159
160 #create .la file before changing props
161 GR_LIBTOOL(TARGET ${target} DESTINATION ${GR_LIBRARY_DIR})
162
163 #give the library a special name with ultra-zero soversion
ptrkrysik12fe7a02014-11-20 11:10:20 +0100164 set_target_properties(${target} PROPERTIES OUTPUT_NAME ${target}-${LIBVER} SOVERSION "0.0.0")
piotr437f5462014-02-04 17:57:25 +0100165 set(target_name lib${target}-${LIBVER}.so.0.0.0)
166
167 #custom command to generate symlinks
168 add_custom_command(
169 TARGET ${target}
170 POST_BUILD
171 COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so
172 COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0
173 COMMAND ${CMAKE_COMMAND} -E touch ${target_name} #so the symlinks point to something valid so cmake 2.6 will install
174 )
175
176 #and install the extra symlinks
177 install(
178 FILES
179 ${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so
180 ${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0
181 DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT}
182 )
183
184 endif(LIBRARY_EXTRAS)
185endfunction(GR_LIBRARY_FOO)
186
187########################################################################
188# Create a dummy custom command that depends on other targets.
189# Usage:
190# GR_GEN_TARGET_DEPS(unique_name target_deps <target1> <target2> ...)
191# ADD_CUSTOM_COMMAND(<the usual args> ${target_deps})
192#
193# Custom command cant depend on targets, but can depend on executables,
194# and executables can depend on targets. So this is the process:
195########################################################################
196function(GR_GEN_TARGET_DEPS name var)
197 file(
198 WRITE ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in
199 "int main(void){return 0;}\n"
200 )
201 execute_process(
202 COMMAND ${CMAKE_COMMAND} -E copy_if_different
203 ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in
204 ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp
205 )
206 add_executable(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp)
207 if(ARGN)
208 add_dependencies(${name} ${ARGN})
209 endif(ARGN)
210
211 if(CMAKE_CROSSCOMPILING)
212 set(${var} "DEPENDS;${name}" PARENT_SCOPE) #cant call command when cross
213 else()
214 set(${var} "DEPENDS;${name};COMMAND;${name}" PARENT_SCOPE)
215 endif()
216endfunction(GR_GEN_TARGET_DEPS)
ptrkrysik12fe7a02014-11-20 11:10:20 +0100217
218########################################################################
219# Control use of gr_logger
220# Usage:
221# GR_LOGGING()
222#
223# Will set ENABLE_GR_LOG to 1 by default.
224# Can manually set with -DENABLE_GR_LOG=0|1
225########################################################################
226function(GR_LOGGING)
227 find_package(Log4cpp)
228
229 OPTION(ENABLE_GR_LOG "Use gr_logger" ON)
230 if(ENABLE_GR_LOG)
231 # If gr_logger is enabled, make it usable
232 add_definitions( -DENABLE_GR_LOG )
233
234 # also test LOG4CPP; if we have it, use this version of the logger
235 # otherwise, default to the stdout/stderr model.
236 if(LOG4CPP_FOUND)
237 SET(HAVE_LOG4CPP True CACHE INTERNAL "" FORCE)
238 add_definitions( -DHAVE_LOG4CPP )
239 else(not LOG4CPP_FOUND)
240 SET(HAVE_LOG4CPP False CACHE INTERNAL "" FORCE)
241 SET(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE)
242 SET(LOG4CPP_LIBRARY_DIRS "" CACHE INTERNAL "" FORCE)
243 SET(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE)
244 endif(LOG4CPP_FOUND)
245
246 SET(ENABLE_GR_LOG ${ENABLE_GR_LOG} CACHE INTERNAL "" FORCE)
247
248 else(ENABLE_GR_LOG)
249 SET(HAVE_LOG4CPP False CACHE INTERNAL "" FORCE)
250 SET(LOG4CPP_INCLUDE_DIRS "" CACHE INTERNAL "" FORCE)
251 SET(LOG4CPP_LIBRARY_DIRS "" CACHE INTERNAL "" FORCE)
252 SET(LOG4CPP_LIBRARIES "" CACHE INTERNAL "" FORCE)
253 endif(ENABLE_GR_LOG)
254
255 message(STATUS "ENABLE_GR_LOG set to ${ENABLE_GR_LOG}.")
256 message(STATUS "HAVE_LOG4CPP set to ${HAVE_LOG4CPP}.")
257 message(STATUS "LOG4CPP_LIBRARIES set to ${LOG4CPP_LIBRARIES}.")
258
259endfunction(GR_LOGGING)
260
261########################################################################
262# Run GRCC to compile .grc files into .py files.
263#
264# Usage: GRCC(filename, directory)
265# - filenames: List of file name of .grc file
266# - directory: directory of built .py file - usually in
267# ${CMAKE_CURRENT_BINARY_DIR}
268# - Sets PYFILES: output converted GRC file names to Python files.
269########################################################################
270function(GRCC)
271 # Extract directory from list of args, remove it for the list of filenames.
272 list(GET ARGV -1 directory)
273 list(REMOVE_AT ARGV -1)
274 set(filenames ${ARGV})
275 file(MAKE_DIRECTORY ${directory})
276
277 SET(GRCC_COMMAND ${PC_GNURADIO_RUNTIME_PREFIX}/${GR_RUNTIME_DIR}/grcc)
278
279 foreach(f ${filenames})
280 execute_process(
281 COMMAND ${GRCC_COMMAND} -d ${directory} "${CMAKE_CURRENT_SOURCE_DIR}/${f}"
282 )
283 string(REPLACE ".grc" ".py" pyfile ${f})
284 string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "" pyfile "${pyfile}")
285 set(pyfile "${CMAKE_CURRENT_BINARY_DIR}/${pyfile}")
286 list(APPEND pyfiles ${pyfile})
287 endforeach(f)
288
289 set(PYFILES ${pyfiles} PARENT_SCOPE)
290endfunction(GRCC)
291
292########################################################################
293# Check if HAVE_PTHREAD_SETSCHEDPARAM and HAVE_SCHED_SETSCHEDULER
294# should be defined
295########################################################################
296macro(GR_CHECK_LINUX_SCHED_AVAIL)
297set(CMAKE_REQUIRED_LIBRARIES -lpthread)
298 CHECK_CXX_SOURCE_COMPILES("
299 #include <pthread.h>
300 int main(){
301 pthread_t pthread;
302 pthread_setschedparam(pthread, 0, 0);
303 return 0;
304 } " HAVE_PTHREAD_SETSCHEDPARAM
305 )
306 GR_ADD_COND_DEF(HAVE_PTHREAD_SETSCHEDPARAM)
307
308 CHECK_CXX_SOURCE_COMPILES("
309 #include <sched.h>
310 int main(){
311 pid_t pid;
312 sched_setscheduler(pid, 0, 0);
313 return 0;
314 } " HAVE_SCHED_SETSCHEDULER
315 )
316 GR_ADD_COND_DEF(HAVE_SCHED_SETSCHEDULER)
317endmacro(GR_CHECK_LINUX_SCHED_AVAIL)
318
319########################################################################
320# Macros to generate source and header files from template
321########################################################################
322macro(GR_EXPAND_X_H component root)
323
324 include(GrPython)
325
326 file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
327"#!${PYTHON_EXECUTABLE}
328
329import sys, os, re
330sys.path.append('${GR_RUNTIME_PYTHONPATH}')
331os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
332os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
333
334if __name__ == '__main__':
335 import build_utils
336 root, inp = sys.argv[1:3]
337 for sig in sys.argv[3:]:
338 name = re.sub ('X+', sig, root)
339 d = build_utils.standard_dict2(name, sig, '${component}')
340 build_utils.expand_template(d, inp)
341")
342
343 #make a list of all the generated headers
344 unset(expanded_files_h)
345 foreach(sig ${ARGN})
346 string(REGEX REPLACE "X+" ${sig} name ${root})
347 list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
348 endforeach(sig)
349 unset(name)
350
351 #create a command to generate the headers
352 add_custom_command(
353 OUTPUT ${expanded_files_h}
354 DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
355 COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
356 ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
357 ${root} ${root}.h.t ${ARGN}
358 )
359
360 #install rules for the generated headers
361 list(APPEND generated_includes ${expanded_files_h})
362
363endmacro(GR_EXPAND_X_H)
364
365macro(GR_EXPAND_X_CC_H component root)
366
367 include(GrPython)
368
369 file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
370"#!${PYTHON_EXECUTABLE}
371
372import sys, os, re
373sys.path.append('${GR_RUNTIME_PYTHONPATH}')
374os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
375os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
376
377if __name__ == '__main__':
378 import build_utils
379 root, inp = sys.argv[1:3]
380 for sig in sys.argv[3:]:
381 name = re.sub ('X+', sig, root)
382 d = build_utils.standard_impl_dict2(name, sig, '${component}')
383 build_utils.expand_template(d, inp)
384")
385
386 #make a list of all the generated files
387 unset(expanded_files_cc)
388 unset(expanded_files_h)
389 foreach(sig ${ARGN})
390 string(REGEX REPLACE "X+" ${sig} name ${root})
391 list(APPEND expanded_files_cc ${CMAKE_CURRENT_BINARY_DIR}/${name}.cc)
392 list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
393 endforeach(sig)
394 unset(name)
395
396 #create a command to generate the source files
397 add_custom_command(
398 OUTPUT ${expanded_files_cc}
399 DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.cc.t
400 COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
401 ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
402 ${root} ${root}.cc.t ${ARGN}
403 )
404
405 #create a command to generate the header files
406 add_custom_command(
407 OUTPUT ${expanded_files_h}
408 DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
409 COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
410 ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
411 ${root} ${root}.h.t ${ARGN}
412 )
413
414 #make source files depends on headers to force generation
415 set_source_files_properties(${expanded_files_cc}
416 PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
417 )
418
419 #install rules for the generated files
420 list(APPEND generated_sources ${expanded_files_cc})
421 list(APPEND generated_headers ${expanded_files_h})
422
423endmacro(GR_EXPAND_X_CC_H)
424
425macro(GR_EXPAND_X_CC_H_IMPL component root)
426
427 include(GrPython)
428
429 file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
430"#!${PYTHON_EXECUTABLE}
431
432import sys, os, re
433sys.path.append('${GR_RUNTIME_PYTHONPATH}')
434os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
435os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
436
437if __name__ == '__main__':
438 import build_utils
439 root, inp = sys.argv[1:3]
440 for sig in sys.argv[3:]:
441 name = re.sub ('X+', sig, root)
442 d = build_utils.standard_dict(name, sig, '${component}')
443 build_utils.expand_template(d, inp, '_impl')
444")
445
446 #make a list of all the generated files
447 unset(expanded_files_cc_impl)
448 unset(expanded_files_h_impl)
449 unset(expanded_files_h)
450 foreach(sig ${ARGN})
451 string(REGEX REPLACE "X+" ${sig} name ${root})
452 list(APPEND expanded_files_cc_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.cc)
453 list(APPEND expanded_files_h_impl ${CMAKE_CURRENT_BINARY_DIR}/${name}_impl.h)
454 list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/../include/gnuradio/${component}/${name}.h)
455 endforeach(sig)
456 unset(name)
457
458 #create a command to generate the _impl.cc files
459 add_custom_command(
460 OUTPUT ${expanded_files_cc_impl}
461 DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.cc.t
462 COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
463 ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
464 ${root} ${root}_impl.cc.t ${ARGN}
465 )
466
467 #create a command to generate the _impl.h files
468 add_custom_command(
469 OUTPUT ${expanded_files_h_impl}
470 DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}_impl.h.t
471 COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
472 ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
473 ${root} ${root}_impl.h.t ${ARGN}
474 )
475
476 #make _impl.cc source files depend on _impl.h to force generation
477 set_source_files_properties(${expanded_files_cc_impl}
478 PROPERTIES OBJECT_DEPENDS "${expanded_files_h_impl}"
479 )
480
481 #make _impl.h source files depend on headers to force generation
482 set_source_files_properties(${expanded_files_h_impl}
483 PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
484 )
485
486 #install rules for the generated files
487 list(APPEND generated_sources ${expanded_files_cc_impl})
488 list(APPEND generated_headers ${expanded_files_h_impl})
489
490endmacro(GR_EXPAND_X_CC_H_IMPL)