1 2function(add_dependency_node _node) 3 if(GENERATE_DEPENDENCY_GRAPH) 4 get_target_property(_type ${_node} TYPE) 5 if(_type MATCHES SHARED_LIBRARY|MODULE_LIBRARY OR ${_node} MATCHES ntoskrnl) 6 file(APPEND ${REACTOS_BINARY_DIR}/dependencies.graphml " <node id=\"${_node}\"/>\n") 7 endif() 8 endif() 9endfunction() 10 11function(add_dependency_edge _source _target) 12 if(GENERATE_DEPENDENCY_GRAPH) 13 get_target_property(_type ${_source} TYPE) 14 if(_type MATCHES SHARED_LIBRARY|MODULE_LIBRARY) 15 file(APPEND ${REACTOS_BINARY_DIR}/dependencies.graphml " <edge source=\"${_source}\" target=\"${_target}\"/>\n") 16 endif() 17 endif() 18endfunction() 19 20function(add_dependency_header) 21 if(GENERATE_DEPENDENCY_GRAPH) 22 file(WRITE ${REACTOS_BINARY_DIR}/dependencies.graphml "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<graphml>\n <graph id=\"ReactOS dependencies\" edgedefault=\"directed\">\n") 23 endif() 24endfunction() 25 26function(add_dependency_footer) 27 if(GENERATE_DEPENDENCY_GRAPH) 28 add_dependency_node(ntdll) 29 file(APPEND ${REACTOS_BINARY_DIR}/dependencies.graphml " </graph>\n</graphml>\n") 30 endif() 31endfunction() 32 33function(add_message_headers _type) 34 if(${_type} STREQUAL UNICODE) 35 set(_flag "-U") 36 else() 37 set(_flag "-A") 38 endif() 39 foreach(_file ${ARGN}) 40 get_filename_component(_file_name ${_file} NAME_WE) 41 set(_converted_file ${CMAKE_CURRENT_BINARY_DIR}/${_file}) ## ${_file_name}.mc 42 set(_source_file ${CMAKE_CURRENT_SOURCE_DIR}/${_file}) ## ${_file_name}.mc 43 add_custom_command( 44 OUTPUT "${_converted_file}" 45 COMMAND native-utf16le "${_source_file}" "${_converted_file}" nobom 46 DEPENDS native-utf16le "${_source_file}") 47 macro_mc(${_flag} ${_converted_file}) 48 add_custom_command( 49 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_file_name}.h ${CMAKE_CURRENT_BINARY_DIR}/${_file_name}.rc 50 COMMAND ${COMMAND_MC} 51 DEPENDS "${_converted_file}") 52 set_source_files_properties( 53 ${CMAKE_CURRENT_BINARY_DIR}/${_file_name}.h ${CMAKE_CURRENT_BINARY_DIR}/${_file_name}.rc 54 PROPERTIES GENERATED TRUE) 55 add_custom_target(${_file_name} ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_file_name}.h ${CMAKE_CURRENT_BINARY_DIR}/${_file_name}.rc) 56 endforeach() 57endfunction() 58 59function(add_link) 60 cmake_parse_arguments(_LINK "MINIMIZE" "NAME;PATH;CMD_LINE_ARGS;ICON;GUID" "" ${ARGN}) 61 if(NOT _LINK_NAME OR NOT _LINK_PATH) 62 message(FATAL_ERROR "You must provide name and path") 63 endif() 64 65 if(_LINK_CMD_LINE_ARGS) 66 set(_LINK_CMD_LINE_ARGS -c ${_LINK_CMD_LINE_ARGS}) 67 endif() 68 69 if(_LINK_ICON) 70 set(_LINK_ICON -i ${_LINK_ICON}) 71 endif() 72 73 if(_LINK_GUID) 74 set(_LINK_GUID -g ${_LINK_GUID}) 75 endif() 76 77 if(_LINK_MINIMIZE) 78 set(_LINK_MINIMIZE "-m") 79 endif() 80 81 add_custom_command( 82 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_LINK_NAME}.lnk 83 COMMAND native-mkshelllink -o ${CMAKE_CURRENT_BINARY_DIR}/${_LINK_NAME}.lnk ${_LINK_CMD_LINE_ARGS} ${_LINK_ICON} ${_LINK_GUID} ${_LINK_MINIMIZE} ${_LINK_PATH} 84 DEPENDS native-mkshelllink) 85 set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${_LINK_NAME}.lnk PROPERTIES GENERATED TRUE) 86endfunction() 87 88# 89# WARNING! 90# Please keep the numbering in this list in sync with 91# boot/bootdata/packages/reactos.dff.in 92# 93macro(dir_to_num dir var) 94 if(${dir} STREQUAL reactos) 95 set(${var} 1) 96 elseif(${dir} STREQUAL reactos/system32) 97 set(${var} 2) 98 elseif(${dir} STREQUAL reactos/system32/drivers) 99 set(${var} 3) 100 elseif(${dir} STREQUAL reactos/Fonts) 101 set(${var} 4) 102 elseif(${dir} STREQUAL reactos/system32/drivers/etc) 103 set(${var} 5) 104 elseif(${dir} STREQUAL reactos/inf) 105 set(${var} 6) 106 elseif(${dir} STREQUAL reactos/bin) 107 set(${var} 7) 108 elseif(${dir} STREQUAL reactos/bin/testdata) 109 set(${var} 8) 110 elseif(${dir} STREQUAL reactos/bin/suppl) 111 set(${var} 80) 112 elseif(${dir} STREQUAL reactos/media) 113 set(${var} 9) 114 elseif(${dir} STREQUAL reactos/Microsoft.NET) 115 set(${var} 10) 116 elseif(${dir} STREQUAL reactos/Microsoft.NET/Framework) 117 set(${var} 11) 118 elseif(${dir} STREQUAL reactos/Microsoft.NET/Framework/v1.0.3705) 119 set(${var} 12) 120 elseif(${dir} STREQUAL reactos/Microsoft.NET/Framework/v1.1.4322) 121 set(${var} 13) 122 elseif(${dir} STREQUAL reactos/Microsoft.NET/Framework/v2.0.50727) 123 set(${var} 14) 124 elseif(${dir} STREQUAL reactos/Resources) 125 set(${var} 15) 126 elseif(${dir} STREQUAL reactos/Resources/Themes) 127 set(${var} 16) 128 elseif(${dir} STREQUAL reactos/system32/wbem) 129 set(${var} 17) 130 elseif(${dir} STREQUAL reactos/Resources/Themes/Lautus) 131 set(${var} 18) 132 elseif(${dir} STREQUAL reactos/Help) 133 set(${var} 19) 134 elseif(${dir} STREQUAL reactos/Config) 135 set(${var} 20) 136 elseif(${dir} STREQUAL reactos/Cursors) 137 set(${var} 21) 138 elseif(${dir} STREQUAL reactos/system32/ShellExt) 139 set(${var} 22) 140 elseif(${dir} STREQUAL reactos/Temp) 141 set(${var} 23) 142 elseif(${dir} STREQUAL reactos/system32/spool) 143 set(${var} 24) 144 elseif(${dir} STREQUAL reactos/system32/spool/drivers) 145 set(${var} 25) 146 elseif(${dir} STREQUAL reactos/system32/spool/drivers/color) 147 set(${var} 26) 148 elseif(${dir} STREQUAL reactos/system32/spool/drivers/w32x86) 149 set(${var} 27) 150 elseif(${dir} STREQUAL reactos/system32/spool/drivers/w32x86/3) 151 set(${var} 28) 152 elseif(${dir} STREQUAL reactos/system32/spool/prtprocs) 153 set(${var} 29) 154 elseif(${dir} STREQUAL reactos/system32/spool/prtprocs/w32x86) 155 set(${var} 30) 156 elseif(${dir} STREQUAL reactos/system32/spool/PRINTERS) 157 set(${var} 31) 158 elseif(${dir} STREQUAL reactos/system32/wbem/Repository) 159 set(${var} 32) 160 elseif(${dir} STREQUAL reactos/system32/wbem/Repository/FS) 161 set(${var} 33) 162 elseif(${dir} STREQUAL reactos/system32/wbem/mof/good) 163 set(${var} 34) 164 elseif(${dir} STREQUAL reactos/system32/wbem/mof/bad) 165 set(${var} 35) 166 elseif(${dir} STREQUAL reactos/system32/wbem/AdStatus) 167 set(${var} 36) 168 elseif(${dir} STREQUAL reactos/system32/wbem/xml) 169 set(${var} 37) 170 elseif(${dir} STREQUAL reactos/system32/wbem/Logs) 171 set(${var} 38) 172 elseif(${dir} STREQUAL reactos/system32/wbem/AutoRecover) 173 set(${var} 39) 174 elseif(${dir} STREQUAL reactos/system32/wbem/snmp) 175 set(${var} 40) 176 elseif(${dir} STREQUAL reactos/system32/wbem/Performance) 177 set(${var} 41) 178 elseif(${dir} STREQUAL reactos/twain_32) 179 set(${var} 42) 180 elseif(${dir} STREQUAL reactos/repair) 181 set(${var} 43) 182 elseif(${dir} STREQUAL reactos/Web) 183 set(${var} 44) 184 elseif(${dir} STREQUAL reactos/Web/Wallpaper) 185 set(${var} 45) 186 elseif(${dir} STREQUAL reactos/Prefetch) 187 set(${var} 46) 188 elseif(${dir} STREQUAL reactos/security) 189 set(${var} 47) 190 elseif(${dir} STREQUAL reactos/security/Database) 191 set(${var} 48) 192 elseif(${dir} STREQUAL reactos/security/logs) 193 set(${var} 49) 194 elseif(${dir} STREQUAL reactos/security/templates) 195 set(${var} 50) 196 elseif(${dir} STREQUAL reactos/system32/CatRoot) 197 set(${var} 51) 198 elseif(${dir} STREQUAL reactos/system32/CatRoot2) 199 set(${var} 52) 200 elseif(${dir} STREQUAL reactos/AppPatch) 201 set(${var} 53) 202 elseif(${dir} STREQUAL reactos/winsxs) 203 set(${var} 54) 204 elseif(${dir} STREQUAL reactos/winsxs/manifests) 205 set(${var} 55) 206 elseif(${dir} STREQUAL reactos/winsxs/x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.2600.2982_none_deadbeef) 207 set(${var} 56) 208 elseif(${dir} STREQUAL reactos/winsxs/x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.2600.2982_none_deadbeef) 209 set(${var} 57) 210 elseif(${dir} STREQUAL reactos/winsxs/x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.7601.23038_none_deadbeef) 211 set(${var} 58) 212 elseif(${dir} STREQUAL reactos/winsxs/x86_reactos.apisets_6595b64144ccf1df_1.0.0.0_none_deadbeef) 213 set(${var} 59) 214 elseif(${dir} STREQUAL reactos/winsxs/x86_reactos.newapi_6595b64144ccf1df_1.0.0.0_none_deadbeef) 215 set(${var} 60) 216 elseif(${dir} STREQUAL reactos/winsxs/x86_microsoft.windows.gdiplus_6595b64144ccf1df_1.0.14393.0_none_deadbeef) 217 set(${var} 61) 218 elseif(${dir} STREQUAL reactos/Resources/Themes/Modern) 219 set(${var} 62) 220 elseif(${dir} STREQUAL reactos/3rdParty) 221 set(${var} 63) 222 elseif(${dir} STREQUAL reactos/Resources/Themes/Lunar) 223 set(${var} 64) 224 elseif(${dir} STREQUAL reactos/Resources/Themes/Mizu) 225 set(${var} 65) 226 elseif(${dir} STREQUAL reactos/system32/spool/prtprocs/x64) 227 set(${var} 66) 228 else() 229 message(FATAL_ERROR "Wrong destination: ${dir}") 230 endif() 231endmacro() 232 233function(add_cd_file) 234 cmake_parse_arguments(_CD "NO_CAB;NOT_IN_HYBRIDCD" "DESTINATION;NAME_ON_CD;TARGET" "FILE;FOR" ${ARGN}) 235 if(NOT (_CD_TARGET OR _CD_FILE)) 236 message(FATAL_ERROR "You must provide a target or a file to install!") 237 endif() 238 239 if(NOT _CD_DESTINATION) 240 message(FATAL_ERROR "You must provide a destination") 241 elseif(${_CD_DESTINATION} STREQUAL root) 242 set(_CD_DESTINATION "") 243 endif() 244 245 if(NOT _CD_FOR) 246 message(FATAL_ERROR "You must provide a cd name (or \"all\" for all of them) to install the file on!") 247 endif() 248 249 # get file if we need to 250 if(NOT _CD_FILE) 251 set(_CD_FILE "$<TARGET_FILE:${_CD_TARGET}>") 252 if(NOT _CD_NAME_ON_CD) 253 set(_CD_NAME_ON_CD "$<TARGET_FILE_NAME:${_CD_TARGET}>") 254 endif() 255 endif() 256 257 # do we add it to all CDs? 258 list(FIND _CD_FOR all __cd) 259 if(NOT __cd EQUAL -1) 260 list(REMOVE_AT _CD_FOR __cd) 261 list(INSERT _CD_FOR __cd "bootcd;livecd;regtest") 262 endif() 263 264 # do we add it to bootcd? 265 list(FIND _CD_FOR bootcd __cd) 266 if(NOT __cd EQUAL -1) 267 # whether or not we should put it in reactos.cab or directly on cd 268 if(_CD_NO_CAB) 269 # directly on cd 270 foreach(item ${_CD_FILE}) 271 if(_CD_NAME_ON_CD) 272 # rename it in the cd tree 273 set(__file ${_CD_NAME_ON_CD}) 274 else() 275 get_filename_component(__file ${item} NAME) 276 endif() 277 set_property(GLOBAL APPEND PROPERTY BOOTCD_FILE_LIST "${_CD_DESTINATION}/${__file}=${item}") 278 # add it also into the hybridcd if not specified otherwise 279 if(NOT _CD_NOT_IN_HYBRIDCD) 280 set_property(GLOBAL APPEND PROPERTY HYBRIDCD_FILE_LIST "bootcd/${_CD_DESTINATION}/${__file}=${item}") 281 endif() 282 endforeach() 283 # manage dependency 284 if(_CD_TARGET) 285 add_dependencies(bootcd ${_CD_TARGET} registry_inf) 286 endif() 287 else() 288 dir_to_num(${_CD_DESTINATION} _num) 289 foreach(item ${_CD_FILE}) 290 # add it in reactos.cab 291 file(APPEND ${REACTOS_BINARY_DIR}/boot/bootdata/packages/reactos.dff.cmake "\"${item}\" ${_num}\n") 292 293 # manage dependency - file level 294 set_property(GLOBAL APPEND PROPERTY REACTOS_CAB_DEPENDS ${item}) 295 endforeach() 296 297 # manage dependency - target level 298 if(_CD_TARGET) 299 add_dependencies(reactos_cab_inf ${_CD_TARGET}) 300 endif() 301 endif() 302 endif() #end bootcd 303 304 # do we add it to livecd? 305 list(FIND _CD_FOR livecd __cd) 306 if(NOT __cd EQUAL -1) 307 # manage dependency 308 if(_CD_TARGET) 309 add_dependencies(livecd ${_CD_TARGET} registry_inf) 310 endif() 311 foreach(item ${_CD_FILE}) 312 if(_CD_NAME_ON_CD) 313 # rename it in the cd tree 314 set(__file ${_CD_NAME_ON_CD}) 315 else() 316 get_filename_component(__file ${item} NAME) 317 endif() 318 set_property(GLOBAL APPEND PROPERTY LIVECD_FILE_LIST "${_CD_DESTINATION}/${__file}=${item}") 319 # add it also into the hybridcd if not specified otherwise 320 if(NOT _CD_NOT_IN_HYBRIDCD) 321 set_property(GLOBAL APPEND PROPERTY HYBRIDCD_FILE_LIST "livecd/${_CD_DESTINATION}/${__file}=${item}") 322 endif() 323 endforeach() 324 endif() #end livecd 325 326 # do we need also to add it to hybridcd? 327 list(FIND _CD_FOR hybridcd __cd) 328 if(NOT __cd EQUAL -1) 329 # manage dependency 330 if(_CD_TARGET) 331 add_dependencies(hybridcd ${_CD_TARGET}) 332 endif() 333 foreach(item ${_CD_FILE}) 334 if(_CD_NAME_ON_CD) 335 # rename it in the cd tree 336 set(__file ${_CD_NAME_ON_CD}) 337 else() 338 get_filename_component(__file ${item} NAME) 339 endif() 340 set_property(GLOBAL APPEND PROPERTY HYBRIDCD_FILE_LIST "${_CD_DESTINATION}/${__file}=${item}") 341 endforeach() 342 endif() #end hybridcd 343 344 # do we add it to regtest? 345 list(FIND _CD_FOR regtest __cd) 346 if(NOT __cd EQUAL -1) 347 # whether or not we should put it in reactos.cab or directly on cd 348 if(_CD_NO_CAB) 349 # directly on cd 350 foreach(item ${_CD_FILE}) 351 if(_CD_NAME_ON_CD) 352 # rename it in the cd tree 353 set(__file ${_CD_NAME_ON_CD}) 354 else() 355 get_filename_component(__file ${item} NAME) 356 endif() 357 set_property(GLOBAL APPEND PROPERTY BOOTCDREGTEST_FILE_LIST "${_CD_DESTINATION}/${__file}=${item}") 358 endforeach() 359 # manage dependency 360 if(_CD_TARGET) 361 add_dependencies(bootcdregtest ${_CD_TARGET} registry_inf) 362 endif() 363 else() 364 #add it in reactos.cab 365 #dir_to_num(${_CD_DESTINATION} _num) 366 #file(APPEND ${REACTOS_BINARY_DIR}/boot/bootdata/packages/reactos.dff.dyn "${_CD_FILE} ${_num}\n") 367 #if(_CD_TARGET) 368 # #manage dependency 369 # add_dependencies(reactos_cab ${_CD_TARGET}) 370 #endif() 371 endif() 372 endif() #end bootcd 373endfunction() 374 375function(create_iso_lists) 376 # generate reactos.cab before anything else 377 get_property(_filelist GLOBAL PROPERTY REACTOS_CAB_DEPENDS) 378 379 # begin with reactos.inf. We want this command to be always executed, so we pretend it generates another file although it will never do. 380 add_custom_command( 381 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/reactos.inf ${CMAKE_CURRENT_BINARY_DIR}/__some_non_existent_file 382 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${REACTOS_BINARY_DIR}/boot/bootdata/packages/reactos.inf ${CMAKE_CURRENT_BINARY_DIR}/reactos.inf 383 DEPENDS ${REACTOS_BINARY_DIR}/boot/bootdata/packages/reactos.inf reactos_cab_inf) 384 385 add_custom_command( 386 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/reactos.cab 387 COMMAND native-cabman -C ${REACTOS_BINARY_DIR}/boot/bootdata/packages/reactos.dff -RC ${CMAKE_CURRENT_BINARY_DIR}/reactos.inf -N -P ${REACTOS_SOURCE_DIR} 388 DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/reactos.inf native-cabman ${_filelist}) 389 390 add_custom_target(reactos_cab DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/reactos.cab) 391 add_dependencies(reactos_cab reactos_cab_inf) 392 393 add_cd_file( 394 TARGET reactos_cab 395 FILE ${CMAKE_CURRENT_BINARY_DIR}/reactos.cab 396 DESTINATION reactos 397 NO_CAB FOR bootcd regtest) 398 399 add_cd_file( 400 FILE ${CMAKE_CURRENT_BINARY_DIR}/livecd.iso 401 DESTINATION livecd 402 FOR hybridcd) 403 404 get_property(_filelist GLOBAL PROPERTY BOOTCD_FILE_LIST) 405 string(REPLACE ";" "\n" _filelist "${_filelist}") 406 file(APPEND ${REACTOS_BINARY_DIR}/boot/bootcd.cmake.lst "${_filelist}") 407 unset(_filelist) 408 file(GENERATE 409 OUTPUT ${REACTOS_BINARY_DIR}/boot/bootcd.$<CONFIG>.lst 410 INPUT ${REACTOS_BINARY_DIR}/boot/bootcd.cmake.lst) 411 412 get_property(_filelist GLOBAL PROPERTY LIVECD_FILE_LIST) 413 string(REPLACE ";" "\n" _filelist "${_filelist}") 414 file(APPEND ${REACTOS_BINARY_DIR}/boot/livecd.cmake.lst "${_filelist}") 415 unset(_filelist) 416 file(GENERATE 417 OUTPUT ${REACTOS_BINARY_DIR}/boot/livecd.$<CONFIG>.lst 418 INPUT ${REACTOS_BINARY_DIR}/boot/livecd.cmake.lst) 419 420 get_property(_filelist GLOBAL PROPERTY HYBRIDCD_FILE_LIST) 421 string(REPLACE ";" "\n" _filelist "${_filelist}") 422 file(APPEND ${REACTOS_BINARY_DIR}/boot/hybridcd.cmake.lst "${_filelist}") 423 unset(_filelist) 424 file(GENERATE 425 OUTPUT ${REACTOS_BINARY_DIR}/boot/hybridcd.$<CONFIG>.lst 426 INPUT ${REACTOS_BINARY_DIR}/boot/hybridcd.cmake.lst) 427 428 get_property(_filelist GLOBAL PROPERTY BOOTCDREGTEST_FILE_LIST) 429 string(REPLACE ";" "\n" _filelist "${_filelist}") 430 file(APPEND ${REACTOS_BINARY_DIR}/boot/bootcdregtest.cmake.lst "${_filelist}") 431 unset(_filelist) 432 file(GENERATE 433 OUTPUT ${REACTOS_BINARY_DIR}/boot/bootcdregtest.$<CONFIG>.lst 434 INPUT ${REACTOS_BINARY_DIR}/boot/bootcdregtest.cmake.lst) 435endfunction() 436 437# Create module_clean targets 438function(add_clean_target _target) 439 set(_clean_working_directory ${CMAKE_CURRENT_BINARY_DIR}) 440 if(CMAKE_GENERATOR STREQUAL "Unix Makefiles" OR CMAKE_GENERATOR STREQUAL "MinGW Makefiles") 441 set(_clean_command make clean) 442 elseif(CMAKE_GENERATOR STREQUAL "NMake Makefiles") 443 set(_clean_command nmake /nologo clean) 444 elseif(CMAKE_GENERATOR STREQUAL "Ninja") 445 set(_clean_command ninja -t clean ${_target}) 446 set(_clean_working_directory ${REACTOS_BINARY_DIR}) 447 endif() 448 add_custom_target(${_target}_clean 449 COMMAND ${_clean_command} 450 WORKING_DIRECTORY ${_clean_working_directory} 451 COMMENT "Cleaning ${_target}") 452endfunction() 453 454if(NOT MSVC_IDE) 455 function(add_library name) 456 _add_library(${name} ${ARGN}) 457 add_clean_target(${name}) 458 # cmake adds a module_EXPORTS define when compiling a module or a shared library. We don't use that. 459 get_target_property(_type ${name} TYPE) 460 if(_type MATCHES SHARED_LIBRARY|MODULE_LIBRARY) 461 set_target_properties(${name} PROPERTIES DEFINE_SYMBOL "") 462 endif() 463 endfunction() 464 465 function(add_executable name) 466 _add_executable(${name} ${ARGN}) 467 add_clean_target(${name}) 468 endfunction() 469elseif(USE_FOLDER_STRUCTURE) 470 set_property(GLOBAL PROPERTY USE_FOLDERS ON) 471 string(LENGTH ${CMAKE_SOURCE_DIR} CMAKE_SOURCE_DIR_LENGTH) 472 473 function(add_custom_target name) 474 _add_custom_target(${name} ${ARGN}) 475 string(SUBSTRING ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR_LENGTH} -1 CMAKE_CURRENT_SOURCE_DIR_RELATIVE) 476 set_property(TARGET "${name}" PROPERTY FOLDER "${CMAKE_CURRENT_SOURCE_DIR_RELATIVE}") 477 endfunction() 478 479 function(add_library name) 480 _add_library(${name} ${ARGN}) 481 get_target_property(_type ${name} TYPE) 482 if (NOT _type STREQUAL "INTERFACE_LIBRARY") 483 get_target_property(_target_excluded ${name} EXCLUDE_FROM_ALL) 484 if(_target_excluded AND ${name} MATCHES "^lib.*") 485 set_property(TARGET "${name}" PROPERTY FOLDER "Importlibs") 486 else() 487 string(SUBSTRING ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR_LENGTH} -1 CMAKE_CURRENT_SOURCE_DIR_RELATIVE) 488 set_property(TARGET "${name}" PROPERTY FOLDER "${CMAKE_CURRENT_SOURCE_DIR_RELATIVE}") 489 endif() 490 endif() 491 # cmake adds a module_EXPORTS define when compiling a module or a shared library. We don't use that. 492 if(_type MATCHES SHARED_LIBRARY|MODULE_LIBRARY) 493 set_target_properties(${name} PROPERTIES DEFINE_SYMBOL "") 494 endif() 495 endfunction() 496 497 function(add_executable name) 498 _add_executable(${name} ${ARGN}) 499 string(SUBSTRING ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR_LENGTH} -1 CMAKE_CURRENT_SOURCE_DIR_RELATIVE) 500 set_property(TARGET "${name}" PROPERTY FOLDER "${CMAKE_CURRENT_SOURCE_DIR_RELATIVE}") 501 endfunction() 502else() 503 function(add_library name) 504 _add_library(${name} ${ARGN}) 505 # cmake adds a module_EXPORTS define when compiling a module or a shared library. We don't use that. 506 get_target_property(_type ${name} TYPE) 507 if(_type MATCHES SHARED_LIBRARY|MODULE_LIBRARY) 508 set_target_properties(${name} PROPERTIES DEFINE_SYMBOL "") 509 endif() 510 endfunction() 511endif() 512 513if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") 514 function(concatenate_files _output _file1) 515 file(TO_NATIVE_PATH "${_output}" _real_output) 516 file(TO_NATIVE_PATH "${_file1}" _file_list) 517 foreach(_file ${ARGN}) 518 file(TO_NATIVE_PATH "${_file}" _real_file) 519 set(_file_list "${_file_list} + ${_real_file}") 520 endforeach() 521 add_custom_command( 522 OUTPUT ${_output} 523 COMMAND cmd.exe /C "copy /Y /B ${_file_list} ${_real_output} > nul" 524 DEPENDS ${_file1} ${ARGN}) 525 endfunction() 526else() 527 macro(concatenate_files _output) 528 add_custom_command( 529 OUTPUT ${_output} 530 COMMAND cat ${ARGN} > ${_output} 531 DEPENDS ${ARGN}) 532 endmacro() 533endif() 534 535function(add_importlibs _module) 536 add_dependency_node(${_module}) 537 foreach(LIB ${ARGN}) 538 target_link_libraries(${_module} lib${LIB}) 539 add_dependency_edge(${_module} ${LIB}) 540 endforeach() 541endfunction() 542 543# Some helper lists 544list(APPEND VALID_MODULE_TYPES kernel kerneldll kernelmodedriver wdmdriver nativecui nativedll win32cui win32gui win32dll win32ocx cpl module) 545list(APPEND KERNEL_MODULE_TYPES kernel kerneldll kernelmodedriver wdmdriver) 546list(APPEND NATIVE_MODULE_TYPES kernel kerneldll kernelmodedriver wdmdriver nativecui nativedll) 547 548function(set_module_type MODULE TYPE) 549 cmake_parse_arguments(__module "UNICODE" "IMAGEBASE" "ENTRYPOINT" ${ARGN}) 550 551 if(__module_UNPARSED_ARGUMENTS) 552 message(STATUS "set_module_type : unparsed arguments ${__module_UNPARSED_ARGUMENTS}, module : ${MODULE}") 553 endif() 554 555 # Check this is a type that we know 556 if (NOT TYPE IN_LIST VALID_MODULE_TYPES) 557 message(FATAL_ERROR "Unknown type ${TYPE} for module ${MODULE}") 558 endif() 559 560 # Set our target property 561 set_target_properties(${MODULE} PROPERTIES REACTOS_MODULE_TYPE ${TYPE}) 562 563 # Add the module to the module group list, if it is defined 564 if(DEFINED CURRENT_MODULE_GROUP) 565 set_property(GLOBAL APPEND PROPERTY ${CURRENT_MODULE_GROUP}_MODULE_LIST "${MODULE}") 566 endif() 567 568 # Set subsystem. 569 if(TYPE IN_LIST NATIVE_MODULE_TYPES) 570 set_subsystem(${MODULE} native) 571 elseif(${TYPE} STREQUAL win32cui) 572 set_subsystem(${MODULE} console) 573 elseif(${TYPE} STREQUAL win32gui) 574 set_subsystem(${MODULE} windows) 575 endif() 576 577 # Set unicode definitions 578 if(__module_UNICODE) 579 target_compile_definitions(${MODULE} PRIVATE UNICODE _UNICODE) 580 endif() 581 582 # Set entry point 583 if(__module_ENTRYPOINT OR (__module_ENTRYPOINT STREQUAL "0")) 584 set_entrypoint(${MODULE} ${__module_ENTRYPOINT}) 585 elseif(${TYPE} STREQUAL nativecui) 586 set_entrypoint(${MODULE} NtProcessStartup 4) 587 elseif(${TYPE} STREQUAL win32cui) 588 if(__module_UNICODE) 589 set_entrypoint(${MODULE} wmainCRTStartup) 590 else() 591 set_entrypoint(${MODULE} mainCRTStartup) 592 endif() 593 elseif(${TYPE} STREQUAL win32gui) 594 if(__module_UNICODE) 595 set_entrypoint(${MODULE} wWinMainCRTStartup) 596 else() 597 set_entrypoint(${MODULE} WinMainCRTStartup) 598 endif() 599 elseif((${TYPE} STREQUAL win32dll) OR (${TYPE} STREQUAL win32ocx) 600 OR (${TYPE} STREQUAL cpl)) 601 set_entrypoint(${MODULE} DllMainCRTStartup 12) 602 elseif((${TYPE} STREQUAL kernelmodedriver) OR (${TYPE} STREQUAL wdmdriver)) 603 set_entrypoint(${MODULE} DriverEntry 8) 604 elseif(${TYPE} STREQUAL nativedll) 605 set_entrypoint(${MODULE} DllMain 12) 606 elseif(TYPE STREQUAL kernel) 607 set_entrypoint(${MODULE} KiSystemStartup 4) 608 elseif(${TYPE} STREQUAL module) 609 set_entrypoint(${MODULE} 0) 610 endif() 611 612 # Set base address 613 if(__module_IMAGEBASE) 614 set_image_base(${MODULE} ${__module_IMAGEBASE}) 615 elseif(${TYPE} STREQUAL win32dll) 616 if(DEFINED baseaddress_${MODULE}) 617 set_image_base(${MODULE} ${baseaddress_${MODULE}}) 618 else() 619 message(STATUS "${MODULE} has no base address") 620 endif() 621 elseif(TYPE IN_LIST KERNEL_MODULE_TYPES) 622 # special case for kernel 623 if (TYPE STREQUAL kernel) 624 set_image_base(${MODULE} 0x00400000) 625 else() 626 set_image_base(${MODULE} 0x00010000) 627 endif() 628 endif() 629 630 # Now do some stuff which is specific to each type 631 if(TYPE IN_LIST KERNEL_MODULE_TYPES) 632 add_dependencies(${MODULE} bugcodes xdk) 633 if((${TYPE} STREQUAL kernelmodedriver) OR (${TYPE} STREQUAL wdmdriver)) 634 set_target_properties(${MODULE} PROPERTIES SUFFIX ".sys") 635 endif() 636 endif() 637 638 if(TYPE STREQUAL kernel) 639 # Kernels are executables with exports 640 set_property(TARGET ${MODULE} PROPERTY ENABLE_EXPORTS TRUE) 641 set_target_properties(${MODULE} PROPERTIES DEFINE_SYMBOL "") 642 endif() 643 644 if(${TYPE} STREQUAL win32ocx) 645 set_target_properties(${MODULE} PROPERTIES SUFFIX ".ocx") 646 endif() 647 648 if(${TYPE} STREQUAL cpl) 649 set_target_properties(${MODULE} PROPERTIES SUFFIX ".cpl") 650 endif() 651 652 # Do compiler specific stuff 653 set_module_type_toolchain(${MODULE} ${TYPE}) 654endfunction() 655 656function(start_module_group __name) 657 if(DEFINED CURRENT_MODULE_GROUP) 658 message(FATAL_ERROR "CURRENT_MODULE_GROUP is already set ('${CURRENT_MODULE_GROUP}')") 659 endif() 660 set(CURRENT_MODULE_GROUP ${__name} PARENT_SCOPE) 661endfunction() 662 663function(end_module_group) 664 get_property(__modulelist GLOBAL PROPERTY ${CURRENT_MODULE_GROUP}_MODULE_LIST) 665 add_custom_target(${CURRENT_MODULE_GROUP}) 666 foreach(__module ${__modulelist}) 667 add_dependencies(${CURRENT_MODULE_GROUP} ${__module}) 668 endforeach() 669 set(CURRENT_MODULE_GROUP PARENT_SCOPE) 670endfunction() 671 672function(preprocess_file __in __out) 673 set(__arg ${__in}) 674 foreach(__def ${ARGN}) 675 list(APPEND __arg -D${__def}) 676 endforeach() 677 if(MSVC) 678 add_custom_command(OUTPUT ${_out} 679 COMMAND ${CMAKE_C_COMPILER} /EP ${__arg} 680 DEPENDS ${__in}) 681 else() 682 add_custom_command(OUTPUT ${_out} 683 COMMAND ${CMAKE_C_COMPILER} -E ${__arg} 684 DEPENDS ${__in}) 685 endif() 686endfunction() 687 688function(get_includes OUTPUT_VAR) 689 get_directory_property(_includes INCLUDE_DIRECTORIES) 690 foreach(arg ${_includes}) 691 list(APPEND __tmp_var -I${arg}) 692 endforeach() 693 set(${OUTPUT_VAR} ${__tmp_var} PARENT_SCOPE) 694endfunction() 695 696function(get_defines OUTPUT_VAR) 697 get_directory_property(_defines COMPILE_DEFINITIONS) 698 foreach(arg ${_defines}) 699 # Skip generator expressions 700 if (NOT arg MATCHES [[^\$<.*>$]]) 701 list(APPEND __tmp_var -D${arg}) 702 endif() 703 endforeach() 704 set(${OUTPUT_VAR} ${__tmp_var} PARENT_SCOPE) 705endfunction() 706 707function(add_registry_inf) 708 # Add to the inf files list 709 foreach(_file ${ARGN}) 710 set(_source_file "${CMAKE_CURRENT_SOURCE_DIR}/${_file}") 711 set_property(GLOBAL APPEND PROPERTY REGISTRY_INF_LIST ${_source_file}) 712 endforeach() 713endfunction() 714 715function(create_registry_hives) 716 717 # Shortcut to the registry.inf file 718 set(_registry_inf "${CMAKE_BINARY_DIR}/boot/bootdata/registry.inf") 719 720 # Get the list of inf files 721 get_property(_inf_files GLOBAL PROPERTY REGISTRY_INF_LIST) 722 723 # Convert files to utf16le 724 foreach(_file ${_inf_files}) 725 get_filename_component(_file_name ${_file} NAME_WE) 726 file(RELATIVE_PATH _subdir ${CMAKE_SOURCE_DIR} ${_file}) 727 get_filename_component(_subdir ${_subdir} DIRECTORY) 728 set(_converted_file ${CMAKE_BINARY_DIR}/${_subdir}/${_file_name}_utf16.inf) 729 add_custom_command(OUTPUT ${_converted_file} 730 COMMAND native-utf16le ${_file} ${_converted_file} 731 DEPENDS native-utf16le ${_file}) 732 list(APPEND _converted_files ${_converted_file}) 733 endforeach() 734 735 # Concatenate all registry files to registry.inf 736 concatenate_files(${_registry_inf} ${_converted_files}) 737 738 # Add registry.inf to bootcd 739 add_custom_target(registry_inf DEPENDS ${_registry_inf}) 740 add_cd_file(TARGET registry_inf 741 FILE ${_registry_inf} 742 DESTINATION reactos 743 NO_CAB 744 FOR bootcd regtest) 745 746 # BootCD setup system hive 747 add_custom_command( 748 OUTPUT ${CMAKE_BINARY_DIR}/boot/bootdata/SETUPREG.HIV 749 COMMAND native-mkhive -h:SETUPREG -u -d:${CMAKE_BINARY_DIR}/boot/bootdata ${_registry_inf} ${CMAKE_SOURCE_DIR}/boot/bootdata/setupreg.inf 750 DEPENDS native-mkhive ${_registry_inf}) 751 752 add_custom_target(bootcd_hives 753 DEPENDS ${CMAKE_BINARY_DIR}/boot/bootdata/SETUPREG.HIV) 754 755 add_cd_file( 756 FILE ${CMAKE_BINARY_DIR}/boot/bootdata/SETUPREG.HIV 757 TARGET bootcd_hives 758 DESTINATION reactos 759 NO_CAB 760 FOR bootcd regtest) 761 762 # LiveCD hives 763 list(APPEND _livecd_inf_files 764 ${_registry_inf} 765 ${CMAKE_SOURCE_DIR}/boot/bootdata/livecd.inf) 766 if(SARCH STREQUAL "xbox") 767 list(APPEND _livecd_inf_files 768 ${CMAKE_SOURCE_DIR}/boot/bootdata/hiveinst_xbox.inf) 769 elseif(SARCH STREQUAL "pc98") 770 list(APPEND _livecd_inf_files 771 ${CMAKE_SOURCE_DIR}/boot/bootdata/hiveinst_pc98.inf) 772 else() 773 list(APPEND _livecd_inf_files 774 ${CMAKE_SOURCE_DIR}/boot/bootdata/hiveinst.inf) 775 endif() 776 777 add_custom_command( 778 OUTPUT ${CMAKE_BINARY_DIR}/boot/bootdata/system 779 ${CMAKE_BINARY_DIR}/boot/bootdata/software 780 ${CMAKE_BINARY_DIR}/boot/bootdata/default 781 ${CMAKE_BINARY_DIR}/boot/bootdata/sam 782 ${CMAKE_BINARY_DIR}/boot/bootdata/security 783 COMMAND native-mkhive -h:SYSTEM,SOFTWARE,DEFAULT,SAM,SECURITY -d:${CMAKE_BINARY_DIR}/boot/bootdata ${_livecd_inf_files} 784 DEPENDS native-mkhive ${_livecd_inf_files}) 785 786 add_custom_target(livecd_hives 787 DEPENDS ${CMAKE_BINARY_DIR}/boot/bootdata/system 788 ${CMAKE_BINARY_DIR}/boot/bootdata/software 789 ${CMAKE_BINARY_DIR}/boot/bootdata/default 790 ${CMAKE_BINARY_DIR}/boot/bootdata/sam 791 ${CMAKE_BINARY_DIR}/boot/bootdata/security) 792 793 add_cd_file( 794 FILE ${CMAKE_BINARY_DIR}/boot/bootdata/system 795 ${CMAKE_BINARY_DIR}/boot/bootdata/software 796 ${CMAKE_BINARY_DIR}/boot/bootdata/default 797 ${CMAKE_BINARY_DIR}/boot/bootdata/sam 798 ${CMAKE_BINARY_DIR}/boot/bootdata/security 799 TARGET livecd_hives 800 DESTINATION reactos/system32/config 801 FOR livecd) 802 803 # BCD Hive 804 add_custom_command( 805 OUTPUT ${CMAKE_BINARY_DIR}/boot/bootdata/BCD 806 COMMAND native-mkhive -h:BCD -u -d:${CMAKE_BINARY_DIR}/boot/bootdata ${CMAKE_BINARY_DIR}/boot/bootdata/hivebcd_utf16.inf 807 DEPENDS native-mkhive ${CMAKE_BINARY_DIR}/boot/bootdata/hivebcd_utf16.inf) 808 809 add_custom_target(bcd_hive 810 DEPENDS ${CMAKE_BINARY_DIR}/boot/bootdata/BCD) 811 812 add_cd_file( 813 FILE ${CMAKE_BINARY_DIR}/boot/bootdata/BCD 814 TARGET bcd_hive 815 DESTINATION efi/boot 816 NO_CAB 817 FOR bootcd regtest livecd) 818 819endfunction() 820 821function(add_driver_inf _module) 822 # Add to the inf files list 823 foreach(_file ${ARGN}) 824 set(_converted_item ${CMAKE_CURRENT_BINARY_DIR}/${_file}) 825 set(_source_item ${CMAKE_CURRENT_SOURCE_DIR}/${_file}) 826 add_custom_command(OUTPUT "${_converted_item}" 827 COMMAND native-utf16le "${_source_item}" "${_converted_item}" 828 DEPENDS native-utf16le "${_source_item}") 829 list(APPEND _converted_inf_files ${_converted_item}) 830 endforeach() 831 832 add_custom_target(${_module}_inf_files DEPENDS ${_converted_inf_files}) 833 add_cd_file(FILE ${_converted_inf_files} TARGET ${_module}_inf_files DESTINATION reactos/inf FOR all) 834endfunction() 835 836if(KDBG) 837 set(ROSSYM_LIB "rossym") 838else() 839 set(ROSSYM_LIB "") 840endif() 841 842function(add_rc_deps _target_rc) 843 set_source_files_properties(${_target_rc} PROPERTIES OBJECT_DEPENDS "${ARGN}") 844endfunction() 845 846add_custom_target(rostests_install COMMAND ${CMAKE_COMMAND} -DCOMPONENT=rostests -P ${CMAKE_BINARY_DIR}/cmake_install.cmake) 847function(add_rostests_file) 848 cmake_parse_arguments(_ROSTESTS "" "RENAME;SUBDIR;TARGET" "FILE" ${ARGN}) 849 if(NOT (_ROSTESTS_TARGET OR _ROSTESTS_FILE)) 850 message(FATAL_ERROR "You must provide a target or a file to install!") 851 endif() 852 853 set(_ROSTESTS_NAME_ON_CD "${_ROSTESTS_RENAME}") 854 if(NOT _ROSTESTS_FILE) 855 set(_ROSTESTS_FILE "$<TARGET_FILE:${_ROSTESTS_TARGET}>") 856 if(NOT _ROSTESTS_RENAME) 857 set(_ROSTESTS_NAME_ON_CD "$<TARGET_FILE_NAME:${_ROSTESTS_TARGET}>") 858 endif() 859 else() 860 if(NOT _ROSTESTS_RENAME) 861 get_filename_component(_ROSTESTS_NAME_ON_CD ${_ROSTESTS_FILE} NAME) 862 endif() 863 endif() 864 865 if(_ROSTESTS_SUBDIR) 866 set(_ROSTESTS_SUBDIR "/${_ROSTESTS_SUBDIR}") 867 endif() 868 869 if(_ROSTESTS_TARGET) 870 add_cd_file(TARGET ${_ROSTESTS_TARGET} FILE ${_ROSTESTS_FILE} DESTINATION "reactos/bin${_ROSTESTS_SUBDIR}" NAME_ON_CD ${_ROSTESTS_NAME_ON_CD} FOR all) 871 else() 872 add_cd_file(FILE ${_ROSTESTS_FILE} DESTINATION "reactos/bin${_ROSTESTS_SUBDIR}" NAME_ON_CD ${_ROSTESTS_NAME_ON_CD} FOR all) 873 endif() 874 875 if(DEFINED ENV{ROSTESTS_INSTALL}) 876 if(_ROSTESTS_RENAME) 877 install(FILES ${_ROSTESTS_FILE} DESTINATION "$ENV{ROSTESTS_INSTALL}${_ROSTESTS_SUBDIR}" COMPONENT rostests RENAME ${_ROSTESTS_RENAME}) 878 else() 879 install(FILES ${_ROSTESTS_FILE} DESTINATION "$ENV{ROSTESTS_INSTALL}${_ROSTESTS_SUBDIR}" COMPONENT rostests) 880 endif() 881 endif() 882endfunction() 883 884if(PCH) 885 macro(add_pch _target _pch _skip_list) 886 target_precompile_headers(${_target} PRIVATE ${_pch}) 887 set_source_files_properties(${_skip_list} PROPERTIES SKIP_PRECOMPILE_HEADERS ON) 888 endmacro() 889else() 890 macro(add_pch _target _pch _skip_list) 891 endmacro() 892endif() 893 894function(set_target_cpp_properties _target) 895 cmake_parse_arguments(_CPP "WITH_EXCEPTIONS;WITH_RTTI" "" "" ${ARGN}) 896 897 if (_CPP_WITH_EXCEPTIONS) 898 set_target_properties(${_target} PROPERTIES WITH_CXX_EXCEPTIONS TRUE) 899 endif() 900 901 if (_CPP_WITH_RTTI) 902 set_target_properties(${_target} PROPERTIES WITH_CXX_RTTI TRUE) 903 endif() 904endfunction() 905