source: pacpusframework/trunk/cmake/PacpusUtilities.cmake@ 259

Last change on this file since 259 was 259, checked in by Marek Kurdej, 10 years ago

Fixed: not installing .pdb files for static libraries (MSVC).

  • Property svn:executable set to *
File size: 14.4 KB
Line 
1#################################################
2# ___________ ____ ______ __ __ _____ #
3# \____ \__ \ _/ ___\\____ \| | \/ ___/ #
4# | |_> > __ \\ \___| |_> > | /\___ \ #
5# | __(____ /\___ > __/|____//____ > #
6# |__| \/ \/|__| \/ #
7# #
8#################################################
9
10## ========================================
11## Qt macro compatibility Qt4 / Qt5
12## ========================================
13function(qt_wrap_cpp OUT_MOC_SRCS)
14 set(FILES_TO_MOC ${ARGN})
15 if(QT4_FOUND)
16 qt4_wrap_cpp(MOC_SRCS ${FILES_TO_MOC}
17 OPTIONS -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED -DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION # fixes QTBUG-22829
18 )
19 elseif(Qt5Core_FOUND)
20 qt5_wrap_cpp(MOC_SRCS ${FILES_TO_MOC})
21 else()
22 message(WARNING "QT not found, cannot wrap moc files")
23 endif()
24
25 set(${OUT_MOC_SRCS} ${MOC_SRCS} PARENT_SCOPE)
26endfunction(qt_wrap_cpp)
27
28## ========================================
29## Qt macro compatibility Qt4 / Qt5
30## ========================================
31function(qt_wrap_ui OUT_UI_SRCS)
32 set(UI_FILES ${ARGN})
33 if(QT4_FOUND)
34 qt4_wrap_ui( UI_SRCS ${UI_FILES})
35 elseif(Qt5Core_FOUND)
36 qt5_wrap_ui( UI_SRCS ${UI_FILES})
37 else()
38 message(WARNING "QT not found, cannot wrap ui files")
39 endif()
40
41 set(${OUT_UI_SRCS} ${UI_SRCS} PARENT_SCOPE)
42endfunction()
43
44## ========================================
45## Qt macro compatibility Qt4 / Qt5
46## ========================================
47function(qt_add_resources OUT_RESOURCES)
48 set(RCS_FILES ${ARGN})
49 if(QT4_FOUND)
50 qt4_add_resources( RESOURCES ${RCS_FILES})
51 elseif(Qt5Core_FOUND)
52 qt5_add_resources( RESOURCES ${RCS_FILES})
53 else()
54 message(WARNING "QT not found, cannot add resources")
55 endif()
56
57 set(${OUT_RESOURCES} ${RESOURCES} PARENT_SCOPE)
58endfunction()
59
60# ========================================
61# Generic macro for Pacpus plugin
62# ========================================
63function(PACPUS_PLUGIN OUT_CPP OUT_H PLUGIN_NAME)
64 if(QT4_FOUND)
65 pacpus_plugin_qt4(PLUGIN_CPP PLUGIN_H ${PROJECT_NAME} )
66 elseif(Qt5Core_FOUND)
67 pacpus_plugin_qt5(PLUGIN_CPP PLUGIN_H ${PROJECT_NAME} )
68 else()
69 message(WARNING "QT not found, can't create Plugin")
70 endif()
71
72 set(${OUT_CPP} ${PLUGIN_CPP} PARENT_SCOPE)
73 set(${OUT_H} ${PLUGIN_H} PARENT_SCOPE)
74endfunction(PACPUS_PLUGIN)
75
76# ========================================
77# Create a Pacpus plugin QT4
78# ========================================
79function(PACPUS_PLUGIN_QT4 OUT_CPP OUT_H PLUGIN_NAME)
80 set(PLUGIN_NAME ${PLUGIN_NAME}Plugin)
81 set(${OUT_CPP} ${PLUGIN_NAME}.cpp PARENT_SCOPE)
82 set(${OUT_H} ${PLUGIN_NAME}.h PARENT_SCOPE)
83
84 string(TOUPPER ${PLUGIN_NAME} PLUGIN_NAME_UPPER)
85
86 # create the header file
87 file(WRITE ${PLUGIN_NAME}.h
88 "// Autogenerated file by PacpusPlugin.cmake\n"
89 "// DO NOT EDIT!!! ALL CHANGES WOULD BE REMOVED BY THE NEXT CALL OF CMAKE\n"
90 "\n"
91 "#ifndef __${PLUGIN_NAME_UPPER}_H__\n"
92 "#define __${PLUGIN_NAME_UPPER}_H__\n"
93 "\n"
94 "#include <QObject>\n"
95 "#include <qplugin.h>\n"
96 "\n"
97 "#include <Pacpus/kernel/PacpusPluginInterface.h>\n"
98 "\n"
99 "/// Auto-generated plugin class\n"
100 "class ${PLUGIN_NAME}\n"
101 " : public QObject\n"
102 " , public PacpusPluginInterface\n"
103 "{\n"
104 " Q_OBJECT\n"
105 " Q_INTERFACES(PacpusPluginInterface)\n"
106 "\n"
107 "public:\n"
108 " ${PLUGIN_NAME}();\n"
109 " ~${PLUGIN_NAME}();\n"
110 "\n"
111 "protected:\n"
112 " QString name();\n"
113 "};\n"
114 "\n"
115 "#endif // __${PLUGIN_NAME_UPPER}_H__\n"
116 )
117
118 # create the cpp file
119 file(WRITE ${PLUGIN_NAME}.cpp
120 "// Autogenerated file by PacpusPlugin.cmake\n"
121 "// DO NOT EDIT!!! ALL CHANGES WOULD BE REMOVED BY THE NEXT CALL OF CMAKE\n"
122 "\n"
123 "#include \"${PLUGIN_NAME}.h\"\n"
124 "\n"
125 "${PLUGIN_NAME}::${PLUGIN_NAME}()\n"
126 "{\n"
127 "}\n"
128 "\n"
129 "${PLUGIN_NAME}::~${PLUGIN_NAME}()\n"
130 "{\n"
131 "}\n"
132 "\n"
133 "QString ${PLUGIN_NAME}::name()\n"
134 "{\n"
135 " return \"${PLUGIN_NAME}\";\n"
136 "}\n"
137 "\n"
138 "Q_EXPORT_PLUGIN2(${PLUGIN_NAME}, ${PLUGIN_NAME})\n"
139 )
140endfunction(PACPUS_PLUGIN_QT4)
141
142# ========================================
143# Create a Pacpus plugin QT5
144# ========================================
145function(PACPUS_PLUGIN_QT5 OUT_CPP OUT_H PLUGIN_NAME)
146 set(PLUGIN_NAME ${PLUGIN_NAME}Plugin)
147 set(${OUT_CPP} ${PLUGIN_NAME}.cpp ${PLUGIN_NAME}.json PARENT_SCOPE)
148 set(${OUT_H} ${PLUGIN_NAME}.h PARENT_SCOPE)
149
150 string(TOUPPER ${PLUGIN_NAME} PLUGIN_NAME_UPPER)
151
152 # create the header file
153 file(WRITE ${PLUGIN_NAME}.h
154 "// Autogenerated file by PacpusUtilities.cmake\n"
155 "// DO NOT EDIT!!! ALL CHANGES WOULD BE REMOVED BY THE NEXT CALL OF CMAKE\n"
156 "\n"
157 "#ifndef __${PLUGIN_NAME_UPPER}_H__\n"
158 "#define __${PLUGIN_NAME_UPPER}_H__\n"
159 "\n"
160 "#include <QObject>\n"
161 "#include <qplugin.h>\n"
162 "\n"
163 "#include <Pacpus/kernel/PacpusPluginInterface.h>\n"
164 "\n"
165 "/// Auto-generated plugin class\n"
166 "class ${PLUGIN_NAME}\n"
167 " : public QObject\n"
168 " , public PacpusPluginInterface\n"
169 "{\n"
170 " Q_OBJECT\n"
171 " //Qt5 Plugins Macro\n"
172 " Q_PLUGIN_METADATA(IID \"pacpus." ${PLUGIN_NAME} "\" FILE \"" ${PLUGIN_NAME} ".json\")\n"
173 " Q_INTERFACES(PacpusPluginInterface)\n"
174 "\n"
175 "public:\n"
176 " ${PLUGIN_NAME}();\n"
177 " ~${PLUGIN_NAME}();\n"
178 "\n"
179 "protected:\n"
180 " QString name();\n"
181 "};\n"
182 "\n"
183 "#endif // __${PLUGIN_NAME_UPPER}_H__\n"
184 )
185
186 # create the cpp file
187 file(WRITE ${PLUGIN_NAME}.cpp
188 "// Autogenerated file by PacpusUtilities.cmake\n"
189 "// DO NOT EDIT!!! ALL CHANGES WOULD BE REMOVED BY THE NEXT CALL OF CMAKE\n"
190 "\n"
191 "#include \"${PLUGIN_NAME}.h\"\n"
192 "\n"
193 "${PLUGIN_NAME}::${PLUGIN_NAME}()\n"
194 "{\n"
195 "}\n"
196 "\n"
197 "${PLUGIN_NAME}::~${PLUGIN_NAME}()\n"
198 "{\n"
199 "}\n"
200 "\n"
201 "QString ${PLUGIN_NAME}::name()\n"
202 "{\n"
203 " return \"${PLUGIN_NAME}\";\n"
204 "}\n"
205 "\n"
206 "//Qt4 Plugin Macro desactivated\n"
207 "//Q_EXPORT_PLUGIN2(${PLUGIN_NAME}, ${PLUGIN_NAME})\n"
208 )
209
210 file(WRITE ${PLUGIN_NAME}.json
211 "{\n"
212 " \"Keys\": [\"${PLUGIN_NAME}\"]\n"
213 "}\n"
214 )
215endfunction(PACPUS_PLUGIN_QT5)
216
217# ========================================
218# Replace backslashes by slashes
219# ========================================
220macro(pacpus_purge_backslash var)
221 string(REGEX REPLACE "\\\\" "/" ${var} "${${var}}")
222endmacro()
223
224# ========================================
225# Get the version of MSVC as a string
226# ========================================
227macro(pacpus_get_msvc output)
228 # By default, unknown
229 set(${output} "unknown")
230 if(MSVC9)
231 set(${output} "msvc2008")
232 elseif(MSVC10)
233 set(${output} "msvc2010")
234 else(MSVC11)
235 set(${output} "msvc2012")
236 endif()
237endmacro()
238
239# ========================================
240# Print a debug message
241# ========================================
242function(pacpus_output_status msg)
243 message(STATUS "${msg}")
244 string(REPLACE "\\" "\\\\" msg "${msg}")
245 string(REPLACE "\"" "\\\"" msg "${msg}")
246endfunction()
247
248# ========================================
249# Pacpus log message
250# ========================================
251function(pacpus_info text)
252 set(status_cond)
253 set(status_then)
254 set(status_else)
255
256 set(status_current_name "cond")
257 foreach(arg ${ARGN})
258 if(arg STREQUAL "THEN")
259 set(status_current_name "then")
260 elseif(arg STREQUAL "ELSE")
261 set(status_current_name "else")
262 else()
263 list(APPEND status_${status_current_name} ${arg})
264 endif()
265 endforeach()
266
267 if(DEFINED status_cond)
268 set(status_placeholder_length 32)
269 string(RANDOM LENGTH ${status_placeholder_length} ALPHABET " " status_placeholder)
270 string(LENGTH "${text}" status_text_length)
271 if(status_text_length LESS status_placeholder_length)
272 string(SUBSTRING "${text}${status_placeholder}" 0 ${status_placeholder_length} status_text)
273 elseif(DEFINED status_then OR DEFINED status_else)
274 pacpus_output_status("${text}")
275 set(status_text "${status_placeholder}")
276 else()
277 set(status_text "${text}")
278 endif()
279
280 if(DEFINED status_then OR DEFINED status_else)
281 if(${status_cond})
282 string(REPLACE ";" " " status_then "${status_then}")
283 string(REGEX REPLACE "^[ \t]+" "" status_then "${status_then}")
284 pacpus_output_status("${status_text} ${status_then}")
285 else()
286 string(REPLACE ";" " " status_else "${status_else}")
287 string(REGEX REPLACE "^[ \t]+" "" status_else "${status_else}")
288 pacpus_output_status("${status_text} ${status_else}")
289 endif()
290 else()
291 string(REPLACE ";" " " status_cond "${status_cond}")
292 string(REGEX REPLACE "^[ \t]+" "" status_cond "${status_cond}")
293 pacpus_output_status("${status_text} ${status_cond}")
294 endif()
295 else()
296 pacpus_output_status("${text}")
297 endif()
298endfunction()
299
300# ========================================
301# Pacpus add library and set debug postfix
302# ========================================
303function(pacpus_add_library target)
304 add_library(
305 ${ARGV}
306 )
307 set_target_properties(
308 ${target}
309 PROPERTIES DEBUG_POSTFIX "_d"
310 )
311 # Add manifest to the target (Windows SxS)
312 # TODO: do the same for executable (change #2 to #1)
313 #if(MSVC)
314 # pacpus_info("\${CMAKE_CURRENT_SOURCE_DIR}/\${target}.manifest = ${CMAKE_CURRENT_SOURCE_DIR}/${target}.manifest")
315 # if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}\\${target}.manifest")
316 # pacpus_info("Exists: ${CMAKE_CURRENT_SOURCE_DIR}/${target}.manifest")
317 # add_custom_command(
318 # TARGET ${target}
319 # POST_BUILD
320 # COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\${target}.manifest\" -outputresource:\"$(TargetDir)\\$(TargetFileName)\"\;\#2
321 # COMMENT "Adding custom manifest containing MSVCRT80 dependency..."
322 # )
323 # endif()
324 #endif()
325endfunction()
326
327# ========================================
328# Pacpus add executable and set debug postfix
329# ========================================
330function(pacpus_add_executable target)
331 add_executable(
332 ${ARGV}
333 )
334 set_target_properties(
335 ${target}
336 PROPERTIES DEBUG_POSTFIX "_d"
337 )
338endfunction()
339
340# ========================================
341# Pacpus install
342# ========================================
343function(pacpus_install)
344 install(
345 TARGETS ${ARGV}
346 RUNTIME DESTINATION ${PACPUS_INSTALL_DIR}/bin
347 LIBRARY DESTINATION ${PACPUS_INSTALL_DIR}/bin
348 ARCHIVE DESTINATION ${PACPUS_INSTALL_DIR}/lib
349 )
350 if(MSVC)
351 # install debug information files .pdb
352 foreach(target ${ARGV})
353 get_target_property(target_type ${target} TYPE)
354 if(NOT target_type STREQUAL STATIC_LIBRARY)
355 get_target_property(target_filepath ${target} LOCATION_DEBUG)
356 get_filename_component(target_directory ${target_filepath} PATH)
357 get_filename_component(target_basename ${target_filepath} NAME_WE)
358
359 set(target_pdb "${target_directory}/${target_basename}.pdb")
360 install(FILES ${target_pdb}
361 CONFIGURATIONS Debug
362 DESTINATION ${PACPUS_INSTALL_DIR}/lib
363 )
364 endif()
365 endforeach()
366 endif(MSVC)
367endfunction()
368
369# ========================================
370# Pacpus folder
371# ========================================
372function(pacpus_folder target folder_name)
373 if(PACPUS_USE_SOLUTION_FOLDERS AND MSVC)
374 set_target_properties(${target}
375 PROPERTIES FOLDER ${folder_name}
376 )
377 endif()
378endfunction()
379
380# ========================================
381# Get sub directories
382# ========================================
383MACRO(SUBDIRLIST result curdir)
384 FILE(GLOB children RELATIVE ${curdir} ${curdir}/*)
385 SET(dirlist "")
386 FOREACH(child ${children})
387 IF(IS_DIRECTORY ${curdir}/${child})
388 SET(dirlist ${dirlist} ${child})
389 ENDIF()
390 ENDFOREACH()
391 SET(${result} ${dirlist})
392ENDMACRO()
393
394
395# ========================================
396# Create export header for plugins
397#
398# Usage: `create_export(PluginExportHeader "MyPluginName")`
399#
400# DLL export/import will depend on macro `${PLUGIN_NAME_UPPER}_EXPORTS`
401# which can be set using `add_definitions( -D${PLUGIN_NAME_UPPER}_EXPORTS )`
402# ========================================
403function(CREATE_EXPORT OUT_H PLUGIN_NAME)
404 # set output directory if given, otherwise use current directory
405 set(PLUGIN_OUTPUT_DIR "${ARGN}")
406 # set file name to the input variable
407 set(PLUGIN_CONFIG_FILE "${PLUGIN_NAME}Config.h")
408 if (NOT "${PLUGIN_OUTPUT_DIR}" STREQUAL "")
409 set(PLUGIN_CONFIG_FILE "${PLUGIN_OUTPUT_DIR}/${PLUGIN_CONFIG_FILE}")
410 endif()
411
412 set(${OUT_H} "${PLUGIN_CONFIG_FILE}" PARENT_SCOPE)
413
414 string(TOUPPER ${PLUGIN_NAME} PLUGIN_NAME_UPPER)
415 add_definitions( -D${PLUGIN_NAME_UPPER}_EXPORTS )
416
417 # create the header file
418 file(WRITE "${PLUGIN_CONFIG_FILE}"
419 "// Autogenerated file by PacpusUtilities.cmake\n"
420 "// DO NOT EDIT!!! ALL CHANGES WOULD BE REMOVED BY THE NEXT CALL OF CMAKE\n"
421 "\n"
422
423 "#ifndef __${PLUGIN_NAME_UPPER}_CONFIG_H__\n"
424 "#define __${PLUGIN_NAME_UPPER}_CONFIG_H__\n"
425 "\n"
426 "// Export macro for use DLL for Windows only\n"
427 "#ifdef WIN32\n"
428 " #ifdef ${PLUGIN_NAME_UPPER}_EXPORTS\n"
429 "// make DLL\n"
430 " #define ${PLUGIN_NAME_UPPER}_API __declspec(dllexport)\n"
431 " #else\n"
432 "// use DLL\n"
433 " #define ${PLUGIN_NAME_UPPER}_API __declspec(dllimport)\n"
434 " #endif\n"
435 "#else\n"
436 "// On other platforms, simply ignore this\n"
437 " #define ${PLUGIN_NAME_UPPER}_API\n"
438 "#endif\n\n"
439
440 "#endif // __${PLUGIN_NAME_UPPER}_CONFIG_H__\n"
441 )
442endfunction(CREATE_EXPORT)
Note: See TracBrowser for help on using the repository browser.