| 1 | #!/usr/bin/rebol -qs |
|---|
| 2 | |
|---|
| 3 | REBOL [ |
|---|
| 4 | RCS: {$Id: m2,v 1.16 2005/06/21 05:07:06 karl Exp $} |
|---|
| 5 | Title: "m2" |
|---|
| 6 | Version: 0.4.0 |
|---|
| 7 | Rights: "Copyright (C) 2001-2006 Karl Robillard" |
|---|
| 8 | Author: "Karl Robillard" |
|---|
| 9 | Date: 27-May-2001 |
|---|
| 10 | Home: http://wsrebol.sf.net/ |
|---|
| 11 | Purpose: {Generates project makefiles.} |
|---|
| 12 | History: [ |
|---|
| 13 | 0.0.1 [27-May-2001 "Version 2 of rmake."] |
|---|
| 14 | ] |
|---|
| 15 | TODO: { |
|---|
| 16 | * Remove files outside the build directory from dist rule. |
|---|
| 17 | * Add Qt moc files to sources but not to distribution rule. |
|---|
| 18 | } |
|---|
| 19 | |
|---|
| 20 | Template-notes: { |
|---|
| 21 | These words are defined in the template file: |
|---|
| 22 | generate_makefile |
|---|
| 23 | |
|---|
| 24 | exe_target |
|---|
| 25 | lib_target |
|---|
| 26 | shlib_target |
|---|
| 27 | rule_target |
|---|
| 28 | |
|---|
| 29 | makerule_cxx |
|---|
| 30 | makerule_asm |
|---|
| 31 | makerule_c |
|---|
| 32 | } |
|---|
| 33 | |
|---|
| 34 | ; NOTE: Symbolic links don't work! |
|---|
| 35 | ] |
|---|
| 36 | |
|---|
| 37 | |
|---|
| 38 | verbose: false |
|---|
| 39 | |
|---|
| 40 | debug_include: false |
|---|
| 41 | idprint: func [ blk ] [ if debug_include [ print blk ] ] |
|---|
| 42 | |
|---|
| 43 | ; Saving system/script/path before any change-dir. |
|---|
| 44 | start_dir: copy system/script/path |
|---|
| 45 | |
|---|
| 46 | |
|---|
| 47 | m2: context [ |
|---|
| 48 | |
|---|
| 49 | ;-------------------------------------- |
|---|
| 50 | ; These are constant for each makefile. |
|---|
| 51 | |
|---|
| 52 | makefile: %Makefile |
|---|
| 53 | project_name: "project" |
|---|
| 54 | project_ver: none |
|---|
| 55 | default_block: none |
|---|
| 56 | |
|---|
| 57 | project_version: func [{Returns string with name and version}] [ |
|---|
| 58 | either none? project_ver [ |
|---|
| 59 | project_name |
|---|
| 60 | ][ |
|---|
| 61 | rejoin [ project_name "-" project_ver ] |
|---|
| 62 | ] |
|---|
| 63 | ] |
|---|
| 64 | |
|---|
| 65 | ct: none |
|---|
| 66 | targets: [] |
|---|
| 67 | output_buf: make string! 1024 |
|---|
| 68 | |
|---|
| 69 | ; This contains file! block! pairs. The block contains the files |
|---|
| 70 | ; included in the file. |
|---|
| 71 | include_dict: [] |
|---|
| 72 | |
|---|
| 73 | distribution_files: [] |
|---|
| 74 | |
|---|
| 75 | |
|---|
| 76 | ;-------------------------------------- |
|---|
| 77 | ; These can be changed for each target. |
|---|
| 78 | |
|---|
| 79 | configuration: context [ |
|---|
| 80 | release: debug: warn: false |
|---|
| 81 | opengl: qt: qt-static: x11: false |
|---|
| 82 | ] |
|---|
| 83 | |
|---|
| 84 | target_env: context [ |
|---|
| 85 | name: none |
|---|
| 86 | uc_name: none |
|---|
| 87 | output_file: none |
|---|
| 88 | link_cxx: false |
|---|
| 89 | |
|---|
| 90 | objdir: "" |
|---|
| 91 | output_dir: "" |
|---|
| 92 | obj_ext: ".o" |
|---|
| 93 | cxx_ext: ".cpp" |
|---|
| 94 | defines: [] |
|---|
| 95 | |
|---|
| 96 | include_paths: [] |
|---|
| 97 | link_paths: [] |
|---|
| 98 | link_libs: [] |
|---|
| 99 | |
|---|
| 100 | header_files: [] |
|---|
| 101 | source_files: [] |
|---|
| 102 | object_files: [] |
|---|
| 103 | |
|---|
| 104 | moc_files: [] |
|---|
| 105 | srcmoc_files: [] |
|---|
| 106 | |
|---|
| 107 | menv_cflags: {} |
|---|
| 108 | menv_cxxflags: {} |
|---|
| 109 | menv_lflags: {} |
|---|
| 110 | |
|---|
| 111 | cfg: none ;make configuration [] |
|---|
| 112 | |
|---|
| 113 | configure: none |
|---|
| 114 | macro_text: none |
|---|
| 115 | rule_text: none |
|---|
| 116 | |
|---|
| 117 | rule_makeobj: func [cc flags obj src] [ |
|---|
| 118 | ; Default to GNU |
|---|
| 119 | rejoin [ "^(tab)$(" cc ") -c $(" uc_name flags ") -o " obj |
|---|
| 120 | " $(" uc_name "_INCPATH) " src ] |
|---|
| 121 | ] |
|---|
| 122 | makerule_cxx: func [obj src] [ link_cxx: true |
|---|
| 123 | rule_makeobj "CXX" "_CXXFLAGS" obj src ] |
|---|
| 124 | makerule_asm: func [obj src] [ rule_makeobj "AS" "_ASFLAGS" obj src ] |
|---|
| 125 | makerule_c: func [obj src] [ rule_makeobj "CC" "_CFLAGS" obj src ] |
|---|
| 126 | |
|---|
| 127 | file_rules: [ |
|---|
| 128 | ".cpp" makerule_cxx |
|---|
| 129 | ".cxx" makerule_cxx |
|---|
| 130 | ".cc" makerule_cxx |
|---|
| 131 | ".s" makerule_asm |
|---|
| 132 | ".c" makerule_c |
|---|
| 133 | ] |
|---|
| 134 | |
|---|
| 135 | make_obj_rule: func [ |
|---|
| 136 | {Builds rules which make object files. |
|---|
| 137 | Dependencies are automatically generated by recursively searching |
|---|
| 138 | in sources and included files. |
|---|
| 139 | Called from the template.} |
|---|
| 140 | /local str src srcfile dependencies inc common rule |
|---|
| 141 | ][ |
|---|
| 142 | str: make string! 512 |
|---|
| 143 | src: source_files |
|---|
| 144 | foreach obj object_files [ |
|---|
| 145 | append str rejoin [ obj ": " src/1 ] |
|---|
| 146 | |
|---|
| 147 | srcfile: to-file src/1 |
|---|
| 148 | |
|---|
| 149 | either exists? srcfile [ |
|---|
| 150 | dependencies: select m2/include_dict srcfile |
|---|
| 151 | ][ |
|---|
| 152 | print [ "make_obj_rule: Warning -" srcfile "not found" ] |
|---|
| 153 | dependencies: [] |
|---|
| 154 | ] |
|---|
| 155 | |
|---|
| 156 | either none? dependencies [ |
|---|
| 157 | append str "^/" |
|---|
| 158 | ][ |
|---|
| 159 | either empty? dependencies [ |
|---|
| 160 | append str "^/" |
|---|
| 161 | ][ |
|---|
| 162 | append str " \^/" |
|---|
| 163 | foreach dep dependencies [ |
|---|
| 164 | inc: select m2/include_dict dep |
|---|
| 165 | if none? inc [ |
|---|
| 166 | m2/append_include_dict dependencies include_paths |
|---|
| 167 | inc: select m2/include_dict dep |
|---|
| 168 | ] |
|---|
| 169 | common: intersect dependencies inc |
|---|
| 170 | append dependencies difference inc common |
|---|
| 171 | ] |
|---|
| 172 | |
|---|
| 173 | append str expand_list_gnu sort dependencies |
|---|
| 174 | ] |
|---|
| 175 | ] |
|---|
| 176 | |
|---|
| 177 | ; Explicitly state rule |
|---|
| 178 | foreach [ext r] file_rules [ |
|---|
| 179 | ;print [ext get r] |
|---|
| 180 | if find src/1 ext [ |
|---|
| 181 | append str rejoin [ do r obj src/1 "^/^/" ] |
|---|
| 182 | break |
|---|
| 183 | ] |
|---|
| 184 | ] |
|---|
| 185 | |
|---|
| 186 | src: next src |
|---|
| 187 | |
|---|
| 188 | append header_files dependencies |
|---|
| 189 | ] |
|---|
| 190 | |
|---|
| 191 | header_files: sort intersect header_files header_files |
|---|
| 192 | |
|---|
| 193 | str |
|---|
| 194 | ] |
|---|
| 195 | |
|---|
| 196 | moc_rule: func [ /local str src ] [ |
|---|
| 197 | str: make string! 0 |
|---|
| 198 | src: srcmoc_files |
|---|
| 199 | foreach file moc_files [ |
|---|
| 200 | append str rejoin [ src/1 ": " file ] |
|---|
| 201 | append str rejoin [ "^/^(tab)$(MOC) " file " -o " src/1 "^/^/" ] |
|---|
| 202 | |
|---|
| 203 | src: next src |
|---|
| 204 | ] |
|---|
| 205 | str |
|---|
| 206 | ] |
|---|
| 207 | ] |
|---|
| 208 | |
|---|
| 209 | ;-------------------------------------- |
|---|
| 210 | |
|---|
| 211 | static_lib_targets: [] |
|---|
| 212 | |
|---|
| 213 | local_libs: func [ |
|---|
| 214 | ; Returns string of libraries from libs which are built by this |
|---|
| 215 | ; project file. |
|---|
| 216 | libs |
|---|
| 217 | /local l str |
|---|
| 218 | ][ |
|---|
| 219 | str: make string! 0 |
|---|
| 220 | foreach [base path] static_lib_targets [ |
|---|
| 221 | if l: find libs base [ |
|---|
| 222 | append str rejoin [#" " path] |
|---|
| 223 | ;probe first l |
|---|
| 224 | ] |
|---|
| 225 | ] |
|---|
| 226 | str |
|---|
| 227 | ] |
|---|
| 228 | |
|---|
| 229 | |
|---|
| 230 | header_files_used: func [ |
|---|
| 231 | ; Returns a block containing all header files used in the project. |
|---|
| 232 | /local blk |
|---|
| 233 | ][ |
|---|
| 234 | blk: copy [] |
|---|
| 235 | foreach [ f b ] include_dict [ |
|---|
| 236 | append blk b |
|---|
| 237 | ] |
|---|
| 238 | sort intersect blk blk |
|---|
| 239 | ] |
|---|
| 240 | |
|---|
| 241 | |
|---|
| 242 | append_include_dict: func [ |
|---|
| 243 | "Returns a block all files included from files" |
|---|
| 244 | files paths /local headers blk ] |
|---|
| 245 | [ |
|---|
| 246 | headers: copy [] |
|---|
| 247 | |
|---|
| 248 | ; Should make include_dict a hash? |
|---|
| 249 | forall files [ |
|---|
| 250 | if none? (select include_dict files/1) [ |
|---|
| 251 | blk: included_files files/1 paths |
|---|
| 252 | append headers blk |
|---|
| 253 | |
|---|
| 254 | append include_dict files/1 |
|---|
| 255 | append/only include_dict blk |
|---|
| 256 | ] |
|---|
| 257 | ] |
|---|
| 258 | |
|---|
| 259 | sort intersect headers headers |
|---|
| 260 | ] |
|---|
| 261 | |
|---|
| 262 | add_target: function [target blk] [] [ |
|---|
| 263 | ct: target |
|---|
| 264 | append targets ct |
|---|
| 265 | |
|---|
| 266 | do default_block |
|---|
| 267 | do blk |
|---|
| 268 | |
|---|
| 269 | if (length? ct/objdir) > 0 [ |
|---|
| 270 | if not exists? ct/objdir [ |
|---|
| 271 | make-dir ct/objdir |
|---|
| 272 | ] |
|---|
| 273 | ] |
|---|
| 274 | |
|---|
| 275 | ct/configure |
|---|
| 276 | ct/object_files: make_file_list ct/source_files ct/objdir ct/obj_ext |
|---|
| 277 | |
|---|
| 278 | ct/header_files: append_include_dict ct/source_files ct/include_paths |
|---|
| 279 | ;probe include_dict |
|---|
| 280 | ;probe ct/header_files |
|---|
| 281 | |
|---|
| 282 | if ct/cfg/qt [ |
|---|
| 283 | add_moc_files ct ct/header_files |
|---|
| 284 | |
|---|
| 285 | ; Uncomment this to search cpp files for Q_OBJECT. |
|---|
| 286 | ;add_moc_files source_files |
|---|
| 287 | |
|---|
| 288 | append ct/object_files |
|---|
| 289 | make_file_list ct/srcmoc_files ct/objdir ct/obj_ext |
|---|
| 290 | |
|---|
| 291 | append ct/source_files ct/srcmoc_files |
|---|
| 292 | ] |
|---|
| 293 | ] |
|---|
| 294 | |
|---|
| 295 | build_makefile: func [ projfile template ] [ |
|---|
| 296 | do template |
|---|
| 297 | do projfile |
|---|
| 298 | clear output_buf |
|---|
| 299 | write makefile generate_makefile |
|---|
| 300 | ] |
|---|
| 301 | ] |
|---|
| 302 | |
|---|
| 303 | |
|---|
| 304 | ;------------------------------------------------------------------ |
|---|
| 305 | ; Used in template file. |
|---|
| 306 | |
|---|
| 307 | |
|---|
| 308 | emit: func [data] [append m2/output_buf reduce data] |
|---|
| 309 | |
|---|
| 310 | |
|---|
| 311 | ;------------------------------------------------------------------ |
|---|
| 312 | ; Used in project file. |
|---|
| 313 | |
|---|
| 314 | |
|---|
| 315 | project: func [str] [ m2/project_name: str ] |
|---|
| 316 | version: func [str] [ m2/project_ver: str ] |
|---|
| 317 | default: func [blk] [ m2/default_block: blk ] |
|---|
| 318 | objdir: func [dir] [ m2/ct/objdir: dir ] |
|---|
| 319 | into: func [dir] [ m2/ct/output_dir: verify_slash dir ] |
|---|
| 320 | |
|---|
| 321 | cflags: func [str [string!]] [ add_flags m2/ct/menv_cflags str ] |
|---|
| 322 | cxxflags: func [str [string!]] [ add_flags m2/ct/menv_cxxflags str ] |
|---|
| 323 | lflags: func [str [string!]] [ add_flags m2/ct/menv_lflags str ] |
|---|
| 324 | |
|---|
| 325 | linux: |
|---|
| 326 | macx: |
|---|
| 327 | sun: |
|---|
| 328 | unix: |
|---|
| 329 | win32: func [blk [block!]] [] ; skip block by default |
|---|
| 330 | |
|---|
| 331 | opengl: func [{Using OpenGL libraries.}] [ m2/ct/cfg/opengl: true ] |
|---|
| 332 | qt3: func [{Using Troll Tech's Qt 3.}] [ m2/ct/cfg/qt: 3 ] |
|---|
| 333 | qt: func [{Using Troll Tech's Qt 4.} libs [block!]] [ m2/ct/cfg/qt: libs ] |
|---|
| 334 | qt-static: does [m2/ct/cfg/qt-static: true] |
|---|
| 335 | x11: func [{Using X11 libraries.}] [ m2/ct/cfg/x11: true ] |
|---|
| 336 | |
|---|
| 337 | debug: func [{Building debug version.}] [ m2/ct/cfg/debug: true ] |
|---|
| 338 | release: func [{Optimize for release build.}] [ m2/ct/cfg/release: true ] |
|---|
| 339 | warn: func [{Enable compiler warnings.}] [ m2/ct/cfg/warn: true ] |
|---|
| 340 | |
|---|
| 341 | define: func [str [string!]] [ append m2/ct/defines parse str none ] |
|---|
| 342 | |
|---|
| 343 | include_from: func [list [string! block! file!]] [ |
|---|
| 344 | if string? list [ |
|---|
| 345 | list: parse list none |
|---|
| 346 | ] |
|---|
| 347 | ; TODO: Run conv_slash on each item. |
|---|
| 348 | append m2/ct/include_paths reduce list |
|---|
| 349 | ] |
|---|
| 350 | |
|---|
| 351 | libs: func [list [string! block! file!]] [ |
|---|
| 352 | either string? list [ |
|---|
| 353 | append m2/ct/link_libs parse list none |
|---|
| 354 | ][ |
|---|
| 355 | append m2/ct/link_libs list |
|---|
| 356 | ] |
|---|
| 357 | ] |
|---|
| 358 | |
|---|
| 359 | libs_from: func [dir list] [ |
|---|
| 360 | append m2/ct/link_paths dir |
|---|
| 361 | libs list |
|---|
| 362 | ] |
|---|
| 363 | |
|---|
| 364 | dist: func [arg [block!]] [ |
|---|
| 365 | append m2/distribution_files arg |
|---|
| 366 | ] |
|---|
| 367 | |
|---|
| 368 | sources: func [arg [block!]] [ |
|---|
| 369 | append m2/ct/source_files arg |
|---|
| 370 | ] |
|---|
| 371 | |
|---|
| 372 | sources_from: func [path files [block!]] [ |
|---|
| 373 | ;include_from path |
|---|
| 374 | verify_slash path |
|---|
| 375 | forall files [ |
|---|
| 376 | append m2/ct/source_files join path files/1 |
|---|
| 377 | ] |
|---|
| 378 | ] |
|---|
| 379 | |
|---|
| 380 | |
|---|
| 381 | exe: func [{Builds executable rule.} basename blk ] |
|---|
| 382 | [ |
|---|
| 383 | m2/add_target (make exe_target [ |
|---|
| 384 | name: basename |
|---|
| 385 | uc_name: uppercase copy basename |
|---|
| 386 | cfg: make m2/configuration [] |
|---|
| 387 | ]) blk |
|---|
| 388 | ] |
|---|
| 389 | |
|---|
| 390 | |
|---|
| 391 | lib: func [{Builds static library rule.} basename blk ] |
|---|
| 392 | [ |
|---|
| 393 | m2/add_target (make lib_target [ |
|---|
| 394 | name: basename |
|---|
| 395 | uc_name: uppercase copy basename |
|---|
| 396 | cfg: make m2/configuration [] |
|---|
| 397 | ]) blk |
|---|
| 398 | |
|---|
| 399 | append m2/static_lib_targets reduce [basename m2/ct/output_file] |
|---|
| 400 | ] |
|---|
| 401 | |
|---|
| 402 | shlib: func [{Builds shared library rule.} basename blk ] |
|---|
| 403 | [ |
|---|
| 404 | m2/add_target (make shlib_target [ |
|---|
| 405 | name: basename |
|---|
| 406 | uc_name: uppercase copy basename |
|---|
| 407 | cfg: make m2/configuration [] |
|---|
| 408 | ]) blk |
|---|
| 409 | ] |
|---|
| 410 | |
|---|
| 411 | |
|---|
| 412 | rule: func [{Builds generic make rule.} basename blk ] |
|---|
| 413 | [ |
|---|
| 414 | m2/add_target (make rule_target [ |
|---|
| 415 | name: basename |
|---|
| 416 | uc_name: uppercase copy basename |
|---|
| 417 | cfg: make m2/configuration [] |
|---|
| 418 | ]) blk |
|---|
| 419 | ] |
|---|
| 420 | |
|---|
| 421 | |
|---|
| 422 | gnu_string: func [ |
|---|
| 423 | {Returns string of items each with a prefix.} |
|---|
| 424 | prefix [string!] |
|---|
| 425 | items [block!] |
|---|
| 426 | /local str |
|---|
| 427 | ][ |
|---|
| 428 | str: make string! 64 |
|---|
| 429 | forall items [ |
|---|
| 430 | append str either (find items/1 " ") [ |
|---|
| 431 | rejoin [ { } prefix {"} items/1 {"} ] |
|---|
| 432 | ][ |
|---|
| 433 | rejoin [ { } prefix items/1 ] |
|---|
| 434 | ] |
|---|
| 435 | ] |
|---|
| 436 | remove str |
|---|
| 437 | ] |
|---|
| 438 | |
|---|
| 439 | |
|---|
| 440 | comment { |
|---|
| 441 | makesub_gnu: func [ |
|---|
| 442 | {Make subdirectory rule suitable for GNU make.} |
|---|
| 443 | rulename dirs /local dir ] |
|---|
| 444 | [ |
|---|
| 445 | append make_subdirs rejoin [ ".PHONY: " rulename "^/" rulename ":^/" ] |
|---|
| 446 | foreach dir dirs [ |
|---|
| 447 | append make_subdirs rejoin [ "^(tab)make -C " dir "^/" ] |
|---|
| 448 | ] |
|---|
| 449 | |
|---|
| 450 | append make_subdirs rejoin [ "^/" ".PHONY: " rulename "clean^/" |
|---|
| 451 | rulename "clean:^/" ] |
|---|
| 452 | foreach dir dirs [ |
|---|
| 453 | append make_subdirs rejoin [ "^(tab)make -C " dir " clean^/" ] |
|---|
| 454 | ] |
|---|
| 455 | ] |
|---|
| 456 | } |
|---|
| 457 | |
|---|
| 458 | |
|---|
| 459 | ;------------------------------------------------------------------ |
|---|
| 460 | ; Private |
|---|
| 461 | |
|---|
| 462 | |
|---|
| 463 | ;unix-platforms: [ 4 6 7 8 9 10 11 12 19 22 23 ] |
|---|
| 464 | ;unix: if find unix-platforms system/version/4 |
|---|
| 465 | ;windows: if system/version/4 = 3 |
|---|
| 466 | |
|---|
| 467 | |
|---|
| 468 | add_flags: func [ flags str ] [ |
|---|
| 469 | either empty? flags [ |
|---|
| 470 | append flags trim/lines str |
|---|
| 471 | ][ |
|---|
| 472 | append flags join " " (trim/lines str) |
|---|
| 473 | ] |
|---|
| 474 | ] |
|---|
| 475 | |
|---|
| 476 | |
|---|
| 477 | strip_ext: func [ file /local lastdot ] [ |
|---|
| 478 | lastdot: find/last file "." |
|---|
| 479 | if lastdot [ |
|---|
| 480 | remove/part lastdot (tail file) |
|---|
| 481 | ] |
|---|
| 482 | return file |
|---|
| 483 | ] |
|---|
| 484 | |
|---|
| 485 | |
|---|
| 486 | verify_slash: func [path [file! url!] /local lp] [ |
|---|
| 487 | lp: last path |
|---|
| 488 | if all [ |
|---|
| 489 | lp <> #"/" |
|---|
| 490 | lp <> #"\" |
|---|
| 491 | ][ |
|---|
| 492 | append path #"/" |
|---|
| 493 | ] |
|---|
| 494 | path |
|---|
| 495 | ] |
|---|
| 496 | |
|---|
| 497 | |
|---|
| 498 | make_file_list: func [ |
|---|
| 499 | "Copy a block of files with changed path and extension" |
|---|
| 500 | src [block!] |
|---|
| 501 | dir |
|---|
| 502 | extension |
|---|
| 503 | ][ |
|---|
| 504 | obj: copy/deep src |
|---|
| 505 | either empty? dir [ |
|---|
| 506 | forall obj [ |
|---|
| 507 | strip_ext obj/1 |
|---|
| 508 | append obj/1 extension |
|---|
| 509 | ] |
|---|
| 510 | ][ |
|---|
| 511 | forall obj [ |
|---|
| 512 | file: second split-path obj/1 |
|---|
| 513 | obj/1: rejoin [ verify_slash dir strip_ext file extension ] |
|---|
| 514 | ] |
|---|
| 515 | ] |
|---|
| 516 | return head obj |
|---|
| 517 | ] |
|---|
| 518 | |
|---|
| 519 | |
|---|
| 520 | find_include_file: func [ |
|---|
| 521 | {Checks if a file exists in the current directory or any set of paths.} |
|---|
| 522 | file [file!] |
|---|
| 523 | paths [block!] |
|---|
| 524 | /local path full |
|---|
| 525 | ][ |
|---|
| 526 | idprint [ " " file ] |
|---|
| 527 | |
|---|
| 528 | if exists? file [ return file ] |
|---|
| 529 | |
|---|
| 530 | forall paths [ |
|---|
| 531 | path: to-file paths/1 |
|---|
| 532 | verify_slash path |
|---|
| 533 | full: join path file |
|---|
| 534 | |
|---|
| 535 | idprint [ " " full ] |
|---|
| 536 | |
|---|
| 537 | if exists? full [ return full ] |
|---|
| 538 | ] |
|---|
| 539 | none |
|---|
| 540 | ] |
|---|
| 541 | |
|---|
| 542 | |
|---|
| 543 | included_files: func [ |
|---|
| 544 | {Returns a block of the files which are included in a C/C++ file. |
|---|
| 545 | Addes #include "file.h" |
|---|
| 546 | Ignores #include <file.h> |
|---|
| 547 | Ignores #include MACRO} |
|---|
| 548 | file [file!] "File to check for #include statements" |
|---|
| 549 | paths [block!] "Paths to check for included files" |
|---|
| 550 | /local blk header ifile |
|---|
| 551 | ][ |
|---|
| 552 | blk: copy [] |
|---|
| 553 | |
|---|
| 554 | if not exists? file [ |
|---|
| 555 | print [ "included_files: " file "not found" ] |
|---|
| 556 | return blk |
|---|
| 557 | ] |
|---|
| 558 | |
|---|
| 559 | foreach line read/lines file [ |
|---|
| 560 | |
|---|
| 561 | ; BUG: #include can be commented or defined out but will still be |
|---|
| 562 | ; included here. This causes errors when windows-only code includes |
|---|
| 563 | ; files with paths (using backslash) and we are compiling on a |
|---|
| 564 | ; non-windows system. |
|---|
| 565 | |
|---|
| 566 | if find/case line "#include" [ |
|---|
| 567 | if find/any line {"*"} [ |
|---|
| 568 | parse line [thru {"} copy header to {"}] |
|---|
| 569 | append blk to-file header |
|---|
| 570 | ] |
|---|
| 571 | ] |
|---|
| 572 | ] |
|---|
| 573 | |
|---|
| 574 | blk: intersect blk blk ; Removes duplicates. |
|---|
| 575 | |
|---|
| 576 | if debug_include [ print ["Finding include files for" file] probe blk ] |
|---|
| 577 | |
|---|
| 578 | forall blk [ |
|---|
| 579 | ifile: find_include_file blk/1 paths |
|---|
| 580 | either none? ifile [ |
|---|
| 581 | print rejoin ["included_files: " blk/1 " (from " file |
|---|
| 582 | ") not found!"] |
|---|
| 583 | remove blk |
|---|
| 584 | blk: back blk |
|---|
| 585 | ][ |
|---|
| 586 | blk/1: ifile |
|---|
| 587 | ] |
|---|
| 588 | ] |
|---|
| 589 | blk: head blk |
|---|
| 590 | ] |
|---|
| 591 | |
|---|
| 592 | |
|---|
| 593 | do_tags: func [ |
|---|
| 594 | {Replace each tag in a string with the value of the tag. |
|---|
| 595 | Individual '<' and '>' are allowed, but they cannot be used |
|---|
| 596 | between other < > pairs. } |
|---|
| 597 | str [string!] |
|---|
| 598 | /local begin exp |
|---|
| 599 | ][ |
|---|
| 600 | begin: none |
|---|
| 601 | forall str [ |
|---|
| 602 | if str/1 = #"<" [ |
|---|
| 603 | begin: str |
|---|
| 604 | ] |
|---|
| 605 | if str/1 = #">" [ |
|---|
| 606 | if not none? begin [ |
|---|
| 607 | exp: copy/part (next begin) str |
|---|
| 608 | change/part begin (do exp) (next str) |
|---|
| 609 | |
|---|
| 610 | ; Must continue from start of tag because it may have been |
|---|
| 611 | ; replaced with "". If we don't continue from begin we will |
|---|
| 612 | ; miss any closely following '<' or '>'. |
|---|
| 613 | str: begin |
|---|
| 614 | |
|---|
| 615 | begin: none |
|---|
| 616 | ] |
|---|
| 617 | ] |
|---|
| 618 | ] |
|---|
| 619 | |
|---|
| 620 | comment { |
|---|
| 621 | ; This parse rule causes nearby tags to be missed. |
|---|
| 622 | parse str [ |
|---|
| 623 | any [ |
|---|
| 624 | to "<" begin: thru ">" ending: |
|---|
| 625 | (exp: copy/part (next begin) (back ending) |
|---|
| 626 | change/part begin (do exp) ending) |
|---|
| 627 | ] |
|---|
| 628 | ] |
|---|
| 629 | } |
|---|
| 630 | |
|---|
| 631 | head str |
|---|
| 632 | ] |
|---|
| 633 | |
|---|
| 634 | |
|---|
| 635 | ; Nothing by default. |
|---|
| 636 | conv_slash: func [ file ] [ file ] |
|---|
| 637 | |
|---|
| 638 | |
|---|
| 639 | expand_list_gnu: func [ |
|---|
| 640 | {Returns a string with each file on a seperate line.} |
|---|
| 641 | files [block!] |
|---|
| 642 | /part "Do not erase trailing space and slash" |
|---|
| 643 | /local x |
|---|
| 644 | ][ |
|---|
| 645 | str: make string! 64 |
|---|
| 646 | foreach file files [ |
|---|
| 647 | append str rejoin [ {^(tab)} conv_slash file { \^/} ] |
|---|
| 648 | ] |
|---|
| 649 | |
|---|
| 650 | if not part [ |
|---|
| 651 | x: find/last str " " |
|---|
| 652 | if x [ |
|---|
| 653 | remove/part x 2 |
|---|
| 654 | ] |
|---|
| 655 | ] |
|---|
| 656 | return str |
|---|
| 657 | ] |
|---|
| 658 | |
|---|
| 659 | |
|---|
| 660 | add_moc_files: function [ ct files [block!] ][ blk found ] |
|---|
| 661 | [ |
|---|
| 662 | blk: make block! 0 |
|---|
| 663 | |
|---|
| 664 | foreach file files [ |
|---|
| 665 | if find/case read file "Q_OBJECT" [ |
|---|
| 666 | append ct/moc_files file |
|---|
| 667 | |
|---|
| 668 | set [ path file ] split-path file |
|---|
| 669 | |
|---|
| 670 | ; MOC bug - specifying "./" on output file creates bad include |
|---|
| 671 | ; statements. |
|---|
| 672 | if path = %"./" [ path: %"" ] |
|---|
| 673 | |
|---|
| 674 | append ct/srcmoc_files join path |
|---|
| 675 | ["moc_" (strip_ext file) ct/cxx_ext] |
|---|
| 676 | ] |
|---|
| 677 | ] |
|---|
| 678 | |
|---|
| 679 | return blk |
|---|
| 680 | ] |
|---|
| 681 | |
|---|
| 682 | |
|---|
| 683 | ;------------------------------------------------------------------ |
|---|
| 684 | |
|---|
| 685 | |
|---|
| 686 | project_file: %project.r |
|---|
| 687 | |
|---|
| 688 | ; Assuming template resides with m2 by defualt. |
|---|
| 689 | template_file: join start_dir %m2_template.r |
|---|
| 690 | |
|---|
| 691 | |
|---|
| 692 | change-dir system/script/parent/path |
|---|
| 693 | if string? system/script/args [ |
|---|
| 694 | args: parse system/script/args none |
|---|
| 695 | forall args [ |
|---|
| 696 | switch/default args/1 [ |
|---|
| 697 | "-t" [ |
|---|
| 698 | args: next args |
|---|
| 699 | template_file: to-file args/1 |
|---|
| 700 | ] |
|---|
| 701 | "-o" [ |
|---|
| 702 | args: next args |
|---|
| 703 | m2/makefile: to-file args/1 |
|---|
| 704 | ] |
|---|
| 705 | ][ |
|---|
| 706 | project_file: to-file args/1 |
|---|
| 707 | ] |
|---|
| 708 | ] |
|---|
| 709 | ] |
|---|
| 710 | |
|---|
| 711 | ;print [ project_file template_file m2/makefile ] |
|---|
| 712 | |
|---|
| 713 | if not exists? template_file [ |
|---|
| 714 | print [ "Template" template_file "not found." ] |
|---|
| 715 | quit |
|---|
| 716 | ] |
|---|
| 717 | |
|---|
| 718 | either exists? project_file [ |
|---|
| 719 | m2/build_makefile project_file template_file |
|---|
| 720 | ][ |
|---|
| 721 | print [ project_file "does not exist; Please specify project file." ] |
|---|
| 722 | ] |
|---|
| 723 | |
|---|
| 724 | ;probe m2/header_files_used |
|---|
| 725 | |
|---|
| 726 | quit |
|---|
| 727 | |
|---|
| 728 | |
|---|
| 729 | ;EOF |
|---|