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