1# - try to find VRJuggler 2.2-related packages (main finder)
2#  VRJUGGLER22_LIBRARY_DIRS, library search paths
3#  VRJUGGLER22_INCLUDE_DIRS, include search paths
4#  VRJUGGLER22_LIBRARIES, the libraries to link against
5#  VRJUGGLER22_ENVIRONMENT
6#  VRJUGGLER22_RUNTIME_LIBRARY_DIRS
7#  VRJUGGLER22_CXX_FLAGS
8#  VRJUGGLER22_DEFINITIONS
9#  VRJUGGLER22_FOUND, If false, do not try to use VR Juggler 2.2.
10#
11# Components available to search for (uses "VRJOGL22" by default):
12#  VRJOGL22
13#  VRJ22
14#  Gadgeteer12
15#  JCCL12
16#  VPR20
17#  Sonix12
18#  Tweek12
19#
20# Additionally, a full setup requires these packages and their Find_.cmake scripts
21#  CPPDOM
22#  GMTL
23#
24# Optionally uses Flagpoll (and FindFlagpoll.cmake)
25#
26# Notes on components:
27#  - All components automatically include their dependencies.
28#  - You can search for the name above with or without the version suffix.
29#  - If you do not specify a component, VRJOGL22(the OpenGL view manager)
30#    will be used by default.
31#  - Capitalization of component names does not matter, but it's best to
32#    pretend it does and use the above capitalization.
33#  - Since this script calls find_package for your requested components and
34#    their dependencies, you can use any of the variables specified in those
35#    files in addition to the "summary" ones listed here, for more finely
36#    controlled building and linking.
37#
38# This CMake script requires all of the Find*.cmake scripts for the
39# components listed above, as it is only a "meta-script" designed to make
40# using those scripts more developer-friendly.
41#
42# Useful configuration variables you might want to add to your cache:
43#  (CAPS COMPONENT NAME)_ROOT_DIR - A directory prefix to search
44#                         (a path that contains include/ as a subdirectory)
45#
46# The VJ_BASE_DIR environment variable is also searched (preferentially)
47# when seeking any of the above components, as well as Flagpoll, CPPDOM,
48# and Boost (from within VPR20), so most sane build environments should
49# "just work."
50#
51# IMPORTANT: Note that you need to manually re-run CMake if you change
52# this environment variable, because it cannot auto-detect this change
53# and trigger an automatic re-run.
54#
55# Original Author:
56# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>
57# http://academic.cleardefinition.com
58# Iowa State University HCI Graduate Program/VRAC
59#
60# Copyright Iowa State University 2009-2010.
61# Distributed under the Boost Software License, Version 1.0.
62# (See accompanying file LICENSE_1_0.txt or copy at
63# http://www.boost.org/LICENSE_1_0.txt)
64
65include(CleanLibraryList)
66include(CleanDirectoryList)
67include(FindPackageMessage)
68
69set(VRJUGGLER22_ROOT_DIR
70	"${VRJUGGLER22_ROOT_DIR}"
71	CACHE
72	PATH
73	"Additional root directory to search for VR Juggler and its dependencies.")
74if(NOT VRJUGGLER22_ROOT_DIR)
75	file(TO_CMAKE_PATH "$ENV{VJ_BASE_DIR}" VRJUGGLER22_ROOT_DIR)
76endif()
77
78# Default required components
79if(NOT VRJuggler22_FIND_COMPONENTS)
80	set(VRJuggler22_FIND_COMPONENTS vrjogl22)
81endif()
82
83if(VRJuggler22_FIND_QUIETLY)
84	set(_FIND_FLAGS "QUIET")
85else()
86	set(_FIND_FLAGS "")
87endif()
88
89set(VRJUGGLER22_SUBMODULES
90	VRJ22
91	VRJOGL22
92	Gadgeteer12
93	JCCL12
94	VPR20
95	Sonix12
96	Tweek12)
97string(TOUPPER "${VRJUGGLER22_SUBMODULES}" VRJUGGLER22_SUBMODULES_UC)
98string(TOUPPER
99	"${VRJuggler22_FIND_COMPONENTS}"
100	VRJUGGLER22_FIND_COMPONENTS_UC)
101
102# Turn a potentially messy components list into a nice one with versions.
103set(VRJUGGLER22_REQUESTED_COMPONENTS)
104foreach(VRJUGGLER22_LONG_NAME ${VRJUGGLER22_SUBMODULES_UC})
105	# Look at requested components
106	foreach(VRJUGGLER22_REQUEST ${VRJUGGLER22_FIND_COMPONENTS_UC})
107		string(REGEX
108			MATCH
109			"${VRJUGGLER22_REQUEST}"
110			VRJUGGLER22_MATCHING
111			"${VRJUGGLER22_LONG_NAME}")
112		if(VRJUGGLER22_MATCHING)
113			list(APPEND
114				VRJUGGLER22_REQUESTED_COMPONENTS
115				${VRJUGGLER22_LONG_NAME})
116			list(APPEND
117				VRJUGGLER22_COMPONENTS_FOUND
118				${VRJUGGLER22_LONG_NAME}_FOUND)
119		endif()
120	endforeach()
121endforeach()
122
123if(VRJUGGLER22_REQUESTED_COMPONENTS)
124	list(REMOVE_DUPLICATES VRJUGGLER22_REQUESTED_COMPONENTS)
125endif()
126
127if(VRJUGGLER22_COMPONENTS_FOUND)
128	list(REMOVE_DUPLICATES VRJUGGLER22_COMPONENTS_FOUND)
129endif()
130
131if(CMAKE_SIZEOF_VOID_P MATCHES "8")
132	set(_VRJ_LIBSUFFIXES lib64 lib)
133	set(_VRJ_LIBDSUFFIXES
134		debug
135		lib64/x86_64/debug
136		lib64/debug
137		lib64
138		lib/x86_64/debug
139		lib/debug
140		lib)
141	set(_VRJ_LIBDSUFFIXES_ONLY
142		debug
143		lib64/x86_64/debug
144		lib64/debug
145		lib/x86_64/debug
146		lib/debug)
147else()
148	set(_VRJ_LIBSUFFIXES lib)
149	set(_VRJ_LIBDSUFFIXES debug lib/i686/debug lib/debug lib)
150	set(_VRJ_LIBDSUFFIXES_ONLY debug lib/i686/debug lib/debug)
151endif()
152
153if(NOT VRJuggler22_FIND_QUIETLY
154	AND NOT VRJUGGLER22_FOUND
155	AND NOT "${_VRJUGGLER22_SEARCH_COMPONENTS}"	STREQUAL "${VRJUGGLER22_REQUESTED_COMPONENTS}")
156	message(STATUS
157		"Searching for these requested VR Juggler 2.2 components and their dependencies: ${VRJUGGLER22_REQUESTED_COMPONENTS}")
158endif()
159
160# Find components
161if("${VRJUGGLER22_REQUESTED_COMPONENTS}" MATCHES "VRJOGL22" AND NOT VRJOGL22_FOUND)
162	find_package(VRJOGL22 ${_FIND_FLAGS})
163endif()
164
165if("${VRJUGGLER22_REQUESTED_COMPONENTS}" MATCHES "VRJ22" AND NOT VRJ22_FOUND)
166	find_package(VRJ22 ${_FIND_FLAGS})
167endif()
168
169if("${VRJUGGLER22_REQUESTED_COMPONENTS}" MATCHES "JCCL12" AND NOT JCCL12_FOUND)
170	find_package(JCCL22 ${_FIND_FLAGS})
171endif()
172
173if("${VRJUGGLER22_REQUESTED_COMPONENTS}" MATCHES "GADGETEER12" AND NOT GADGETEER12_FOUND)
174	find_package(Gadgeteer12 ${_FIND_FLAGS})
175endif()
176
177if("${VRJUGGLER22_REQUESTED_COMPONENTS}" MATCHES "SONIX12" AND NOT SONIX12_FOUND)
178	find_package(Sonix12 ${_FIND_FLAGS})
179endif()
180
181if("${VRJUGGLER22_REQUESTED_COMPONENTS}" MATCHES "TWEEK12" AND NOT TWEEK12_FOUND)
182	find_package(Tweek12 ${_FIND_FLAGS})
183endif()
184
185if("${VRJUGGLER22_REQUESTED_COMPONENTS}" MATCHES "VPR20" AND NOT VPR20_FOUND)
186	find_package(VPR20 ${_FIND_FLAGS})
187endif()
188
189# handle the QUIETLY and REQUIRED arguments and set xxx_FOUND to TRUE if
190# all listed variables are TRUE
191include(FindPackageHandleStandardArgs)
192find_package_handle_standard_args(VRJuggler22
193	DEFAULT_MSG
194	${VRJUGGLER22_COMPONENTS_FOUND})
195
196if(VRJUGGLER22_FOUND)
197	foreach(VRJUGGLER22_REQUEST ${VRJUGGLER22_REQUESTED_COMPONENTS})
198		list(APPEND VRJUGGLER22_LIBRARIES ${${VRJUGGLER22_REQUEST}_LIBRARIES})
199		list(APPEND
200			VRJUGGLER22_INCLUDE_DIRS
201			${${VRJUGGLER22_REQUEST}_INCLUDE_DIRS})
202	endforeach()
203
204	clean_library_list(VRJUGGLER22_LIBRARIES)
205
206	clean_directory_list(VRJUGGLER22_INCLUDE_DIRS)
207
208	set(_vjbase)
209	set(_vjbaseclean)
210	foreach(_lib
211		${VPR20_LIBRARY}
212		${VRJ22_LIBRARY}
213		${VRJOGL22_LIBRARY}
214		${JCCL12_LIBRARY}
215		${GADGETEER12_LIBRARY})
216		get_filename_component(_libpath "${_lib}" PATH)
217		get_filename_component(_abspath "${_libpath}/.." ABSOLUTE)
218		list(APPEND _vjbase "${_abspath}")
219	endforeach()
220
221	clean_directory_list(_vjbase)
222
223	set(_vrj22_have_base_dir NO)
224	list(LENGTH _vjbase _vjbaselen)
225	if("${_vjbaselen}" EQUAL 1 AND NOT VRJUGGLER22_VJ_BASE_DIR)
226		list(GET _vjbase 0 VRJUGGLER22_VJ_BASE_DIR)
227		mark_as_advanced(VRJUGGLER22_VJ_BASE_DIR)
228		if(NOT VRJUGGLER22_VJ_BASE_DIR STREQUAL _vrj22_base_dir)
229			unset(VRJUGGLER22_VJ_CFG_DIR)
230		endif()
231		set(_vrj22_have_base_dir YES)
232	else()
233		list(GET _vjbase 0 _calculated_base_dir)
234		if(NOT
235			"${_calculated_base_dir}"
236			STREQUAL
237			"${VRJUGGLER22_VJ_BASE_DIR}")
238			message("It looks like you might be mixing VR Juggler versions... ${_vjbaselen} ${_vjbase}")
239			message("If you are, fix your libraries then remove the VRJUGGLER22_VJ_BASE_DIR variable in CMake, then configure again")
240			message("If you aren't, set the VRJUGGLER22_VJ_BASE_DIR variable to the desired VJ_BASE_DIR to use when running")
241		else()
242			if(NOT VRJUGGLER22_VJ_BASE_DIR STREQUAL _vrj22_base_dir)
243				unset(VRJUGGLER22_VJ_CFG_DIR)
244			endif()
245			set(_vrj22_have_base_dir YES)
246		endif()
247	endif()
248
249	set(_vrj22_base_dir "${VRJUGGLER22_VJ_BASE_DIR}")
250	set(_vrj22_base_dir "${_vrj22_base_dir}" CACHE INTERNAL "" FORCE)
251
252	if(_vrj22_have_base_dir)
253		find_path(VRJUGGLER22_VJ_CFG_DIR
254			standalone.jconf
255			PATHS
256			${VRJUGGLER22_VJ_BASE_DIR}/share/vrjuggler-2.2/data/configFiles
257			${VRJUGGLER22_VJ_BASE_DIR}/share/vrjuggler/data/configFiles
258			NO_DEFAULT_PATH)
259		mark_as_advanced(VRJUGGLER22_VJ_CFG_DIR)
260	endif()
261
262	set(VRJUGGLER22_VJ_BASE_DIR
263		"${VRJUGGLER22_VJ_BASE_DIR}"
264		CACHE
265		PATH
266		"Base directory to use as VJ_BASE_DIR when running your app."
267		FORCE)
268	set(VRJUGGLER22_ENVIRONMENT
269		"VJ_BASE_DIR=${VRJUGGLER22_VJ_BASE_DIR}"
270		"JCCL_BASE_DIR=${VRJUGGLER22_VJ_BASE_DIR}"
271		"SONIX_BASE_DIR=${VRJUGGLER22_VJ_BASE_DIR}"
272		"TWEEK_BASE_DIR=${VRJUGGLER22_VJ_BASE_DIR}"
273		"VJ_CFG_DIR=${VRJUGGLER22_VJ_CFG_DIR}")
274
275	include(GetDirectoryList)
276
277	get_directory_list(VRJUGGLER22_RUNTIME_LIBRARY_DIRS
278		${VRJUGGLER22_LIBRARIES})
279	if(WIN32)
280		foreach(dir ${VRJUGGLER22_RUNTIME_LIBRARY_DIRS})
281			list(APPEND VRJUGGLER22_RUNTIME_LIBRARY_DIRS "${dir}/../bin")
282		endforeach()
283	endif()
284
285	if(MSVC)
286		# Needed to make linking against boost work with 2.2.1 binaries - rp20091022
287		# BOOST_ALL_DYN_LINK
288		set(VRJUGGLER22_DEFINITIONS
289			"-DBOOST_ALL_DYN_LINK"
290			"-DCPPDOM_DYN_LINK"
291			"-DCPPDOM_AUTO_LINK")
292
293		# Disable these annoying warnings
294		# 4275: non dll-interface class used as base for dll-interface class
295		# 4251: needs to have dll-interface to be used by clients of class
296		# 4100: unused parameter
297		# 4512: assignment operator could not be generated
298		# 4127: (Not currently disabled) conditional expression in loop evaluates to constant
299
300		set(VRJUGGLER22_CXX_FLAGS "/wd4275 /wd4251 /wd4100 /wd4512")
301	elseif(CMAKE_COMPILER_IS_GNUCXX)
302		# Silence annoying warnings about deprecated hash_map.
303		set(VRJUGGLER22_CXX_FLAGS "-Wno-deprecated")
304
305		set(VRJUGGLER22_DEFINITIONS "")
306	endif()
307	set(VRJUGGLER22_CXX_FLAGS
308		"${VRJUGGLER22_CXX_FLAGS} ${CPPDOM_CXX_FLAGS}")
309
310	set(_VRJUGGLER22_SEARCH_COMPONENTS
311		"${VRJUGGLER22_REQUESTED_COMPONENTS}"
312		CACHE
313		INTERNAL
314		"Requested components, used as a flag.")
315
316
317
318	set(_plugin_dirs)
319	foreach(_libdir ${VRJUGGLER22_RUNTIME_LIBRARY_DIRS})
320		# Find directories of Gadgeteer plugins and drivers
321		if(EXISTS "${_libdir}/gadgeteer")
322			list(APPEND
323				_plugin_dirs
324				"${_libdir}/gadgeteer/drivers"
325				"${_libdir}/gadgeteer/plugins")
326		elseif(EXISTS "${_libdir}/gadgeteer-1.2")
327			list(APPEND
328				_plugin_dirs
329				"${_libdir}/gadgeteer-1.2/drivers"
330				"${_libdir}/gadgeteer-1.2/plugins")
331		endif()
332
333		# Find directories of Sonix plugins
334		if(EXISTS "${_libdir}/sonix")
335			list(APPEND _plugin_dirs "${_libdir}/sonix/plugins/dbg")
336			list(APPEND _plugin_dirs "${_libdir}/sonix/plugins/opt")
337		elseif(EXISTS "${_libdir}/sonix-1.2")
338			list(APPEND _plugin_dirs "${_libdir}/sonix-1.2/plugins/dbg")
339			list(APPEND _plugin_dirs "${_libdir}/sonix-1.2/plugins/opt")
340		endif()
341	endforeach()
342
343	# Grab the actual plugins
344	foreach(_libdir ${_plugin_dirs})
345		if(EXISTS "${_libdir}")
346			list(APPEND VRJUGGLER22_RUNTIME_LIBRARY_DIRS "${_libdir}")
347			file(GLOB _plugins "${_libdir}/*${CMAKE_SHARED_LIBRARY_SUFFIX}")
348			list(APPEND VRJUGGLER22_BUNDLE_PLUGINS ${_plugins})
349		endif()
350	endforeach()
351
352	mark_as_advanced(VRJUGGLER22_ROOT_DIR)
353endif()
354
355mark_as_advanced(VRJUGGLER22_DEFINITIONS)
356
357function(install_vrjuggler22_data_files prefix)
358	set(base "${VRJUGGLER22_VJ_CFG_DIR}/..")
359	get_filename_component(base "${base}" ABSOLUTE)
360	file(RELATIVE_PATH reldest "${VRJUGGLER22_VJ_BASE_DIR}" "${base}")
361	if(prefix STREQUAL "" OR prefix STREQUAL "." OR prefix STREQUAL "./")
362		set(DEST "${reldest}")
363	else()
364		set(DEST "${prefix}/${reldest}")
365	endif()
366
367	# configFiles *.jconf
368	file(GLOB
369		_vj_config_files
370		"${base}/configFiles/*.jconf")
371	install(FILES ${_vj_config_files} DESTINATION "${DEST}/configFiles/")
372
373	# definitions *.jdef
374	file(GLOB
375		_vj_defs_files
376		"${base}/definitions/*.jdef")
377	install(FILES ${_vj_defs_files} DESTINATION "${DEST}/definitions/")
378
379	# models *.flt
380	file(GLOB
381		_vj_model_files
382		"${base}/models/*.flt")
383	install(FILES ${_vj_model_files} DESTINATION "${DEST}/models/")
384
385	# sounds *.wav
386	file(GLOB
387		_vj_sound_files
388		"${base}/sounds/*.wav")
389	install(FILES ${_vj_sound_files} DESTINATION "${DEST}/sounds/")
390
391	# calibration.table - needed?
392	file(GLOB
393		_vj_config_files
394		"${base}/configFiles/*.jconf")
395	install(FILES "${base}/calibration.table" DESTINATION "${DEST}")
396endfunction()
397
398function(install_vrjuggler22_plugins prefix varForFilenames)
399	set(DEST "${prefix}")
400
401	set(out)
402	foreach(plugin ${VRJUGGLER22_BUNDLE_PLUGINS})
403		get_filename_component(full "${plugin}" ABSOLUTE)
404		file(RELATIVE_PATH relloc "${VRJUGGLER22_VJ_BASE_DIR}" "${full}")
405		set(filedest "${DEST}/${relloc}")
406		get_filename_component(path "${filedest}" PATH)
407		list(APPEND out "${filedest}")
408		install(FILES "${full}" DESTINATION "${path}")
409	endforeach()
410
411	set(${varForFilenames} ${out} PARENT_SCOPE)
412
413endfunction()
414
415function(get_vrjuggler_bundle_sources _target_sources)
416	if(APPLE)
417		set(_bundledir "${VRJUGGLER22_VJ_CFG_DIR}/../bundle")
418		get_filename_component(_bundledir "${_bundledir}" ABSOLUTE)
419
420		set(_vj_base_dir .)
421		set(_vj_data_dir ${vj_base_dir}/share/vrjuggler-2.2)
422
423		# Append Mac-specific sources to source list
424		set(_vj_bundle_src
425			${_bundledir}/vrjuggler.icns
426			${_bundledir}/vrjuggler.plist
427			${_bundledir}/en.lproj/MainMenu.nib/classes.nib
428			${_bundledir}/MainMenu.nib/info.nib
429			${_bundledir}/MainMenu.nib/keyedobjects.nib)
430
431		message(STATUS "vjbundlesrc: ${_vj_bundle_src}")
432		set(${_target_sources}
433			${${_target_sources}}
434			${_vj_bundle_src}
435			PARENT_SCOPE)
436
437		# Set destination of nib files
438		set_source_files_properties(${_bundledir}/MainMenu.nib/classes.nib
439			${_bundledir}/MainMenu.nib/info.nib
440			${_bundledir}/MainMenu.nib/keyedobjects.nib
441			PROPERTIES
442			MACOSX_PACKAGE_LOCATION
443			Resources/en.lproj/MainMenu.nib/)
444
445		# Set destination of Resources
446		set_source_files_properties(${_bundledir}/vrjuggler.icns
447			${_bundledir}/vrjuggler.plist
448			PROPERTIES
449			MACOSX_PACKAGE_LOCATION
450			Resources/)
451	endif()
452endfunction()
453
454get_filename_component(_vrjuggler22moddir
455	${CMAKE_CURRENT_LIST_FILE}
456	PATH)
457function(fixup_vrjuggler_app_bundle
458	_target
459	_targetInstallDest
460	_extralibs
461	_libdirs)
462
463	if(NOT VRJUGGLER22_FOUND)
464		return()
465	endif()
466
467	set(PACKAGE_DIR ${_vrjuggler22moddir}/package)
468	set(MACOSX_PACKAGE_DIR ${PACKAGE_DIR}/macosx)
469
470	set(TARGET_LOCATION
471		"${_targetInstallDest}/${_target}${CMAKE_EXECUTABLE_SUFFIX}")
472	if(APPLE)
473		set(TARGET_LOCATION "${TARGET_LOCATION}.app")
474	endif()
475
476	set_target_properties(${_target}
477		PROPERTIES
478		MACOSX_BUNDLE_INFO_PLIST
479		${MACOSX_PACKAGE_DIR}/VRJuggler22BundleInfo.plist.in
480		MACOSX_BUNDLE_ICON_FILE
481		vrjuggler.icns
482		MACOSX_BUNDLE_INFO_STRING
483		"${PROJECT_NAME} (VR Juggler Application) version ${CPACK_PACKAGE_VERSION}, created by ${CPACK_PACKAGE_VENDOR}"
484		MACOSX_BUNDLE_GUI_IDENTIFIER
485		org.vrjuggler.${PROJECT_NAME}
486		MACOSX_BUNDLE_SHORT_VERSION_STRING
487		${CPACK_PACKAGE_VERSION}
488		MACOSX_BUNDLE_BUNDLE_VERSION
489		${CPACK_PACKAGE_VERSION})
490
491	if(WIN32)
492		list(APPEND _libdirs "${VRJUGGLER22_VJ_BASE_DIR}/bin")
493	endif()
494
495	set(BUNDLE_LIBS ${_extralibs})
496	set(BUNDLE_LIB_DIRS "${VRJUGGLER22_VJ_BASE_DIR}" ${_libdirs})
497
498	configure_file(${PACKAGE_DIR}/fixupbundle.cmake.in
499		${CMAKE_CURRENT_BINARY_DIR}/${_target}-fixupbundle-juggler.cmake
500		@ONLY)
501	install(SCRIPT
502		"${CMAKE_CURRENT_BINARY_DIR}/${_target}-fixupbundle-juggler.cmake")
503endfunction()
504