/ CMakeLists.txt
CMakeLists.txt
1 cmake_minimum_required(VERSION 3.15) 2 project(ProgrammingBenchmark) 3 4 set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 5 6 # Set output directory for binaries 7 set(BIN_DIR ${CMAKE_SOURCE_DIR}/bin) 8 file(MAKE_DIRECTORY ${BIN_DIR}) 9 10 # Hyperfine build target 11 set(HYPERFINE_SOURCE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/hyperfine) 12 set(HYPERFINE_BINARY ${HYPERFINE_SOURCE_DIR}/target/release/hyperfine) 13 set(HYPERFINE_OUTPUT ${BIN_DIR}/hyperfine) 14 15 # Check for cargo 16 find_program(CARGO_EXECUTABLE cargo) 17 if(NOT CARGO_EXECUTABLE) 18 message(FATAL_ERROR "Cargo not found. Install Rust from https://rustup.rs/") 19 endif() 20 21 # Custom command to build hyperfine 22 add_custom_command( 23 OUTPUT ${HYPERFINE_BINARY} 24 COMMAND ${CARGO_EXECUTABLE} build --release 25 WORKING_DIRECTORY ${HYPERFINE_SOURCE_DIR} 26 COMMENT "Building hyperfine with cargo..." 27 VERBATIM 28 ) 29 30 # Custom command to copy hyperfine to bin directory 31 add_custom_command( 32 OUTPUT ${HYPERFINE_OUTPUT} 33 COMMAND ${CMAKE_COMMAND} -E copy ${HYPERFINE_BINARY} ${HYPERFINE_OUTPUT} 34 DEPENDS ${HYPERFINE_BINARY} 35 COMMENT "Copying hyperfine to ${BIN_DIR}..." 36 VERBATIM 37 ) 38 39 # Custom target that depends on the copied binary 40 add_custom_target(hyperfine ALL 41 DEPENDS ${HYPERFINE_OUTPUT} 42 ) 43 44 # Print build information 45 message(STATUS "Hyperfine source directory: ${HYPERFINE_SOURCE_DIR}") 46 message(STATUS "Binary output directory: ${BIN_DIR}") 47 48 # ====================================================================== 49 # Build test programs with multiple compilers 50 # ====================================================================== 51 52 set(TEST_SRC_DIR ${CMAKE_SOURCE_DIR}/test_src) 53 set(TEST_BIN_DIR ${CMAKE_SOURCE_DIR}/bin/tests) 54 55 # Detect available compilers 56 find_program(GCC_EXECUTABLE g++) 57 find_program(CLANG_EXECUTABLE clang++) 58 find_program(GCC_C_EXECUTABLE gcc) 59 find_program(CLANG_C_EXECUTABLE clang) 60 find_program(NASM_EXECUTABLE nasm) 61 find_program(YASM_EXECUTABLE yasm) 62 find_program(GAS_EXECUTABLE as) 63 find_program(LD_EXECUTABLE ld) 64 find_program(RUSTC_EXECUTABLE rustc) 65 find_program(ZIG_EXECUTABLE zig) 66 find_program(GO_EXECUTABLE go) 67 find_program(DMD_EXECUTABLE dmd) 68 find_program(LDC2_EXECUTABLE ldc2) 69 find_program(GDC_EXECUTABLE gdc) 70 find_program(NIM_EXECUTABLE nim) 71 find_program(ODIN_EXECUTABLE odin) 72 find_program(V_EXECUTABLE v) 73 find_program(GNAT_EXECUTABLE gnatmake) 74 find_program(GHC_EXECUTABLE ghc) 75 find_program(GFORTRAN_EXECUTABLE gfortran) 76 find_program(FPC_EXECUTABLE fpc) 77 find_program(COBC_EXECUTABLE cobc) 78 find_program(CSC_EXECUTABLE csc) 79 find_program(MCS_EXECUTABLE mcs) 80 find_program(PYTHON_EXECUTABLE python3) 81 find_program(CYTHON_EXECUTABLE cython) 82 find_program(R_EXECUTABLE R) 83 84 # List of compilers to use 85 set(COMPILERS "") 86 if(GCC_EXECUTABLE) 87 list(APPEND COMPILERS "gcc") 88 message(STATUS "GCC found: ${GCC_EXECUTABLE}") 89 endif() 90 if(CLANG_EXECUTABLE) 91 list(APPEND COMPILERS "clang") 92 message(STATUS "Clang found: ${CLANG_EXECUTABLE}") 93 endif() 94 95 if(NOT COMPILERS) 96 message(FATAL_ERROR "No C++ compilers found (need g++ or clang++)") 97 endif() 98 99 # C++ Hello World implementations - build with each compiler 100 set(CPP_IMPLEMENTATIONS 001 002 003 004 005 006) 101 foreach(COMPILER ${COMPILERS}) 102 # Set compiler executable 103 if(COMPILER STREQUAL "gcc") 104 set(COMPILER_EXEC ${GCC_EXECUTABLE}) 105 elseif(COMPILER STREQUAL "clang") 106 set(COMPILER_EXEC ${CLANG_EXECUTABLE}) 107 endif() 108 109 foreach(IMPL ${CPP_IMPLEMENTATIONS}) 110 set(CPP_SRC ${TEST_SRC_DIR}/cpp/hello_world/${IMPL}/hello.cpp) 111 set(CPP_BIN ${TEST_BIN_DIR}/${COMPILER}/cpp/hello_world/${IMPL}/hello) 112 113 if(EXISTS ${CPP_SRC}) 114 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/cpp/hello_world/${IMPL}) 115 116 add_custom_command( 117 OUTPUT ${CPP_BIN} 118 COMMAND ${COMPILER_EXEC} ${CPP_SRC} -o ${CPP_BIN} -O3 -std=c++17 119 DEPENDS ${CPP_SRC} 120 COMMENT "Building C++ hello_world/${IMPL} with ${COMPILER}..." 121 VERBATIM 122 ) 123 124 add_custom_target(${COMPILER}_cpp_hello_${IMPL} ALL DEPENDS ${CPP_BIN}) 125 endif() 126 endforeach() 127 endforeach() 128 129 # ASM Hello World 001 - Support multiple assemblers 130 set(ASSEMBLERS "") 131 if(NASM_EXECUTABLE) 132 list(APPEND ASSEMBLERS "nasm") 133 endif() 134 if(YASM_EXECUTABLE) 135 list(APPEND ASSEMBLERS "yasm") 136 endif() 137 if(GAS_EXECUTABLE) 138 list(APPEND ASSEMBLERS "gas") 139 endif() 140 141 if(ASSEMBLERS AND LD_EXECUTABLE) 142 foreach(ASSEMBLER ${ASSEMBLERS}) 143 foreach(COMPILER ${COMPILERS}) 144 if(ASSEMBLER STREQUAL "nasm") 145 set(ASM_001_SRC ${TEST_SRC_DIR}/asm/hello_world/001/hello.asm) 146 set(ASM_001_OBJ ${TEST_BIN_DIR}/${COMPILER}/asm_${ASSEMBLER}/hello_world/001/hello.o) 147 set(ASM_001_BIN ${TEST_BIN_DIR}/${COMPILER}/asm_${ASSEMBLER}/hello_world/001/hello) 148 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/asm_${ASSEMBLER}/hello_world/001) 149 150 add_custom_command( 151 OUTPUT ${ASM_001_OBJ} 152 COMMAND ${NASM_EXECUTABLE} -f elf64 ${ASM_001_SRC} -o ${ASM_001_OBJ} 153 DEPENDS ${ASM_001_SRC} 154 COMMENT "Assembling ASM hello_world/001 with NASM for ${COMPILER}..." 155 VERBATIM 156 ) 157 158 add_custom_command( 159 OUTPUT ${ASM_001_BIN} 160 COMMAND ${LD_EXECUTABLE} ${ASM_001_OBJ} -o ${ASM_001_BIN} 161 DEPENDS ${ASM_001_OBJ} 162 COMMENT "Linking ASM hello_world/001 (NASM) for ${COMPILER}..." 163 VERBATIM 164 ) 165 166 add_custom_target(${COMPILER}_asm_${ASSEMBLER}_hello_001 ALL DEPENDS ${ASM_001_BIN}) 167 168 elseif(ASSEMBLER STREQUAL "yasm") 169 set(ASM_001_SRC ${TEST_SRC_DIR}/asm/hello_world/001/hello_yasm.asm) 170 set(ASM_001_OBJ ${TEST_BIN_DIR}/${COMPILER}/asm_${ASSEMBLER}/hello_world/001/hello.o) 171 set(ASM_001_BIN ${TEST_BIN_DIR}/${COMPILER}/asm_${ASSEMBLER}/hello_world/001/hello) 172 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/asm_${ASSEMBLER}/hello_world/001) 173 174 add_custom_command( 175 OUTPUT ${ASM_001_OBJ} 176 COMMAND ${YASM_EXECUTABLE} -f elf64 ${ASM_001_SRC} -o ${ASM_001_OBJ} 177 DEPENDS ${ASM_001_SRC} 178 COMMENT "Assembling ASM hello_world/001 with YASM for ${COMPILER}..." 179 VERBATIM 180 ) 181 182 add_custom_command( 183 OUTPUT ${ASM_001_BIN} 184 COMMAND ${LD_EXECUTABLE} ${ASM_001_OBJ} -o ${ASM_001_BIN} 185 DEPENDS ${ASM_001_OBJ} 186 COMMENT "Linking ASM hello_world/001 (YASM) for ${COMPILER}..." 187 VERBATIM 188 ) 189 190 add_custom_target(${COMPILER}_asm_${ASSEMBLER}_hello_001 ALL DEPENDS ${ASM_001_BIN}) 191 192 elseif(ASSEMBLER STREQUAL "gas") 193 set(ASM_001_SRC ${TEST_SRC_DIR}/asm/hello_world/001/hello_gas.s) 194 set(ASM_001_OBJ ${TEST_BIN_DIR}/${COMPILER}/asm_${ASSEMBLER}/hello_world/001/hello.o) 195 set(ASM_001_BIN ${TEST_BIN_DIR}/${COMPILER}/asm_${ASSEMBLER}/hello_world/001/hello) 196 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/asm_${ASSEMBLER}/hello_world/001) 197 198 add_custom_command( 199 OUTPUT ${ASM_001_OBJ} 200 COMMAND ${GAS_EXECUTABLE} ${ASM_001_SRC} -o ${ASM_001_OBJ} 201 DEPENDS ${ASM_001_SRC} 202 COMMENT "Assembling ASM hello_world/001 with GAS for ${COMPILER}..." 203 VERBATIM 204 ) 205 206 add_custom_command( 207 OUTPUT ${ASM_001_BIN} 208 COMMAND ${LD_EXECUTABLE} ${ASM_001_OBJ} -o ${ASM_001_BIN} 209 DEPENDS ${ASM_001_OBJ} 210 COMMENT "Linking ASM hello_world/001 (GAS) for ${COMPILER}..." 211 VERBATIM 212 ) 213 214 add_custom_target(${COMPILER}_asm_${ASSEMBLER}_hello_001 ALL DEPENDS ${ASM_001_BIN}) 215 endif() 216 endforeach() 217 endforeach() 218 message(STATUS "ASM build enabled with assemblers: ${ASSEMBLERS}") 219 else() 220 message(WARNING "No assembler or linker found, skipping ASM builds") 221 endif() 222 223 # Rust Hello World 001 - build with different linkers 224 if(RUSTC_EXECUTABLE) 225 foreach(COMPILER ${COMPILERS}) 226 set(RUST_001_SRC ${TEST_SRC_DIR}/rust/hello_world/001/main.rs) 227 set(RUST_001_BIN ${TEST_BIN_DIR}/${COMPILER}/rust/hello_world/001/hello) 228 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/rust/hello_world/001) 229 230 # Use different linker based on compiler 231 if(COMPILER STREQUAL "gcc") 232 set(RUST_LINKER "gcc") 233 elseif(COMPILER STREQUAL "clang") 234 set(RUST_LINKER "clang") 235 endif() 236 237 add_custom_command( 238 OUTPUT ${RUST_001_BIN} 239 COMMAND ${RUSTC_EXECUTABLE} ${RUST_001_SRC} -o ${RUST_001_BIN} -C opt-level=3 -C linker=${RUST_LINKER} 240 DEPENDS ${RUST_001_SRC} 241 COMMENT "Building Rust hello_world/001 with ${COMPILER} linker..." 242 VERBATIM 243 ) 244 245 add_custom_target(${COMPILER}_rust_hello_001 ALL DEPENDS ${RUST_001_BIN}) 246 endforeach() 247 message(STATUS "Rust build enabled") 248 else() 249 message(WARNING "rustc not found, skipping Rust builds") 250 endif() 251 252 # Zig Hello World 001 - Zig has its own compiler, build for each configuration 253 if(ZIG_EXECUTABLE) 254 foreach(COMPILER ${COMPILERS}) 255 set(ZIG_001_SRC ${TEST_SRC_DIR}/zig/hello_world/001/main.zig) 256 set(ZIG_001_BIN ${TEST_BIN_DIR}/${COMPILER}/zig/hello_world/001/hello) 257 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/zig/hello_world/001) 258 259 add_custom_command( 260 OUTPUT ${ZIG_001_BIN} 261 COMMAND ${ZIG_EXECUTABLE} build-exe ${ZIG_001_SRC} -O ReleaseFast -femit-bin=${ZIG_001_BIN} 262 DEPENDS ${ZIG_001_SRC} 263 COMMENT "Building Zig hello_world/001 for ${COMPILER}..." 264 VERBATIM 265 ) 266 267 add_custom_target(${COMPILER}_zig_hello_001 ALL DEPENDS ${ZIG_001_BIN}) 268 endforeach() 269 message(STATUS "Zig build enabled") 270 else() 271 message(WARNING "zig not found, skipping Zig builds") 272 endif() 273 274 # C Hello World 001 - build with gcc and clang 275 if(GCC_C_EXECUTABLE OR CLANG_C_EXECUTABLE) 276 foreach(COMPILER ${COMPILERS}) 277 # Set C compiler executable 278 if(COMPILER STREQUAL "gcc" AND GCC_C_EXECUTABLE) 279 set(C_COMPILER_EXEC ${GCC_C_EXECUTABLE}) 280 elseif(COMPILER STREQUAL "clang" AND CLANG_C_EXECUTABLE) 281 set(C_COMPILER_EXEC ${CLANG_C_EXECUTABLE}) 282 else() 283 continue() 284 endif() 285 286 set(C_001_SRC ${TEST_SRC_DIR}/c/hello_world/001/hello.c) 287 set(C_001_BIN ${TEST_BIN_DIR}/${COMPILER}/c/hello_world/001/hello) 288 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/c/hello_world/001) 289 290 add_custom_command( 291 OUTPUT ${C_001_BIN} 292 COMMAND ${C_COMPILER_EXEC} ${C_001_SRC} -o ${C_001_BIN} -O3 293 DEPENDS ${C_001_SRC} 294 COMMENT "Building C hello_world/001 with ${COMPILER}..." 295 VERBATIM 296 ) 297 298 add_custom_target(${COMPILER}_c_hello_001 ALL DEPENDS ${C_001_BIN}) 299 endforeach() 300 message(STATUS "C build enabled") 301 else() 302 message(WARNING "gcc or clang not found, skipping C builds") 303 endif() 304 305 # Go Hello World 001 - Go compiler is independent 306 if(GO_EXECUTABLE) 307 foreach(COMPILER ${COMPILERS}) 308 set(GO_001_SRC ${TEST_SRC_DIR}/go/hello_world/001/main.go) 309 set(GO_001_BIN ${TEST_BIN_DIR}/${COMPILER}/go/hello_world/001/hello) 310 set(GO_001_DIR ${TEST_SRC_DIR}/go/hello_world/001) 311 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/go/hello_world/001) 312 313 add_custom_command( 314 OUTPUT ${GO_001_BIN} 315 COMMAND ${GO_EXECUTABLE} build -o ${GO_001_BIN} -ldflags=-s\ -w ${GO_001_SRC} 316 WORKING_DIRECTORY ${GO_001_DIR} 317 DEPENDS ${GO_001_SRC} 318 COMMENT "Building Go hello_world/001 for ${COMPILER}..." 319 VERBATIM 320 ) 321 322 add_custom_target(${COMPILER}_go_hello_001 ALL DEPENDS ${GO_001_BIN}) 323 endforeach() 324 message(STATUS "Go build enabled") 325 else() 326 message(WARNING "go not found, skipping Go builds") 327 endif() 328 329 # D Hello World 001 - try multiple D compilers 330 set(D_COMPILER "") 331 if(LDC2_EXECUTABLE) 332 set(D_COMPILER ${LDC2_EXECUTABLE}) 333 set(D_COMPILER_NAME "ldc2") 334 set(D_FLAGS "-O3;-release") 335 message(STATUS "D compiler: ldc2 (LLVM-based)") 336 elseif(DMD_EXECUTABLE) 337 set(D_COMPILER ${DMD_EXECUTABLE}) 338 set(D_COMPILER_NAME "dmd") 339 set(D_FLAGS "-O;-release") 340 message(STATUS "D compiler: dmd (reference)") 341 elseif(GDC_EXECUTABLE) 342 set(D_COMPILER ${GDC_EXECUTABLE}) 343 set(D_COMPILER_NAME "gdc") 344 set(D_FLAGS "-O3;-frelease") 345 message(STATUS "D compiler: gdc (GCC-based)") 346 endif() 347 348 if(D_COMPILER) 349 foreach(COMPILER ${COMPILERS}) 350 set(D_001_SRC ${TEST_SRC_DIR}/d/hello_world/001/hello.d) 351 set(D_001_BIN ${TEST_BIN_DIR}/${COMPILER}/d/hello_world/001/hello) 352 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/d/hello_world/001) 353 354 add_custom_command( 355 OUTPUT ${D_001_BIN} 356 COMMAND ${D_COMPILER} ${D_001_SRC} -of=${D_001_BIN} ${D_FLAGS} 357 DEPENDS ${D_001_SRC} 358 COMMENT "Building D hello_world/001 with ${D_COMPILER_NAME} for ${COMPILER}..." 359 VERBATIM 360 ) 361 362 add_custom_target(${COMPILER}_d_hello_001 ALL DEPENDS ${D_001_BIN}) 363 endforeach() 364 message(STATUS "D build enabled") 365 else() 366 message(WARNING "No D compiler found (dmd, ldc2, or gdc), skipping D builds") 367 endif() 368 369 # Nim Hello World 001 370 if(NIM_EXECUTABLE) 371 foreach(COMPILER ${COMPILERS}) 372 set(NIM_001_SRC ${TEST_SRC_DIR}/nim/hello_world/001/hello.nim) 373 set(NIM_001_BIN ${TEST_BIN_DIR}/${COMPILER}/nim/hello_world/001/hello) 374 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/nim/hello_world/001) 375 376 add_custom_command( 377 OUTPUT ${NIM_001_BIN} 378 COMMAND ${NIM_EXECUTABLE} c -d:release --opt:speed -o:${NIM_001_BIN} ${NIM_001_SRC} 379 DEPENDS ${NIM_001_SRC} 380 COMMENT "Building Nim hello_world/001 for ${COMPILER}..." 381 VERBATIM 382 ) 383 384 add_custom_target(${COMPILER}_nim_hello_001 ALL DEPENDS ${NIM_001_BIN}) 385 endforeach() 386 message(STATUS "Nim build enabled") 387 else() 388 message(WARNING "nim not found, skipping Nim builds") 389 endif() 390 391 # Odin Hello World 001 392 if(ODIN_EXECUTABLE) 393 foreach(COMPILER ${COMPILERS}) 394 set(ODIN_001_SRC ${TEST_SRC_DIR}/odin/hello_world/001/hello.odin) 395 set(ODIN_001_BIN ${TEST_BIN_DIR}/${COMPILER}/odin/hello_world/001/hello) 396 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/odin/hello_world/001) 397 398 add_custom_command( 399 OUTPUT ${ODIN_001_BIN} 400 COMMAND ${ODIN_EXECUTABLE} build ${ODIN_001_SRC} -file -o:speed -out:${ODIN_001_BIN} 401 DEPENDS ${ODIN_001_SRC} 402 COMMENT "Building Odin hello_world/001 for ${COMPILER}..." 403 VERBATIM 404 ) 405 406 add_custom_target(${COMPILER}_odin_hello_001 ALL DEPENDS ${ODIN_001_BIN}) 407 endforeach() 408 message(STATUS "Odin build enabled") 409 else() 410 message(WARNING "odin not found, skipping Odin builds") 411 endif() 412 413 # V Hello World 001 414 if(V_EXECUTABLE) 415 foreach(COMPILER ${COMPILERS}) 416 set(V_001_SRC ${TEST_SRC_DIR}/v/hello_world/001/hello.v) 417 set(V_001_BIN ${TEST_BIN_DIR}/${COMPILER}/v/hello_world/001/hello) 418 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/v/hello_world/001) 419 420 add_custom_command( 421 OUTPUT ${V_001_BIN} 422 COMMAND ${V_EXECUTABLE} -prod -o ${V_001_BIN} ${V_001_SRC} 423 DEPENDS ${V_001_SRC} 424 COMMENT "Building V hello_world/001 for ${COMPILER}..." 425 VERBATIM 426 ) 427 428 add_custom_target(${COMPILER}_v_hello_001 ALL DEPENDS ${V_001_BIN}) 429 endforeach() 430 message(STATUS "V build enabled") 431 else() 432 message(WARNING "v not found, skipping V builds") 433 endif() 434 435 # Ada Hello World 001 436 if(GNAT_EXECUTABLE) 437 foreach(COMPILER ${COMPILERS}) 438 set(ADA_001_SRC ${TEST_SRC_DIR}/ada/hello_world/001/hello.adb) 439 set(ADA_001_BIN ${TEST_BIN_DIR}/${COMPILER}/ada/hello_world/001/hello) 440 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/ada/hello_world/001) 441 442 add_custom_command( 443 OUTPUT ${ADA_001_BIN} 444 COMMAND ${GNAT_EXECUTABLE} ${ADA_001_SRC} -O3 -o ${ADA_001_BIN} 445 DEPENDS ${ADA_001_SRC} 446 COMMENT "Building Ada hello_world/001 for ${COMPILER}..." 447 VERBATIM 448 ) 449 450 add_custom_target(${COMPILER}_ada_hello_001 ALL DEPENDS ${ADA_001_BIN}) 451 endforeach() 452 message(STATUS "Ada build enabled") 453 else() 454 message(WARNING "gnatmake not found, skipping Ada builds") 455 endif() 456 457 # Haskell Hello World 001 458 if(GHC_EXECUTABLE) 459 foreach(COMPILER ${COMPILERS}) 460 set(HASKELL_001_SRC ${TEST_SRC_DIR}/haskell/hello_world/001/hello.hs) 461 set(HASKELL_001_BIN ${TEST_BIN_DIR}/${COMPILER}/haskell/hello_world/001/hello) 462 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/haskell/hello_world/001) 463 464 add_custom_command( 465 OUTPUT ${HASKELL_001_BIN} 466 COMMAND ${GHC_EXECUTABLE} -O2 -outputdir ${TEST_BIN_DIR}/${COMPILER}/haskell/hello_world/001 -o ${HASKELL_001_BIN} ${HASKELL_001_SRC} 467 DEPENDS ${HASKELL_001_SRC} 468 COMMENT "Building Haskell hello_world/001 for ${COMPILER}..." 469 VERBATIM 470 ) 471 472 add_custom_target(${COMPILER}_haskell_hello_001 ALL DEPENDS ${HASKELL_001_BIN}) 473 endforeach() 474 message(STATUS "Haskell build enabled") 475 else() 476 message(WARNING "ghc not found, skipping Haskell builds") 477 endif() 478 479 # Fortran Hello World 001 480 if(GFORTRAN_EXECUTABLE) 481 foreach(COMPILER ${COMPILERS}) 482 set(FORTRAN_001_SRC ${TEST_SRC_DIR}/fortran/hello_world/001/hello.f90) 483 set(FORTRAN_001_BIN ${TEST_BIN_DIR}/${COMPILER}/fortran/hello_world/001/hello) 484 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/fortran/hello_world/001) 485 486 add_custom_command( 487 OUTPUT ${FORTRAN_001_BIN} 488 COMMAND ${GFORTRAN_EXECUTABLE} ${FORTRAN_001_SRC} -O3 -o ${FORTRAN_001_BIN} 489 DEPENDS ${FORTRAN_001_SRC} 490 COMMENT "Building Fortran hello_world/001 for ${COMPILER}..." 491 VERBATIM 492 ) 493 494 add_custom_target(${COMPILER}_fortran_hello_001 ALL DEPENDS ${FORTRAN_001_BIN}) 495 endforeach() 496 message(STATUS "Fortran build enabled") 497 else() 498 message(WARNING "gfortran not found, skipping Fortran builds") 499 endif() 500 501 # Pascal Hello World 001 502 if(FPC_EXECUTABLE) 503 foreach(COMPILER ${COMPILERS}) 504 set(PASCAL_001_SRC ${TEST_SRC_DIR}/pascal/hello_world/001/hello.pas) 505 set(PASCAL_001_BIN ${TEST_BIN_DIR}/${COMPILER}/pascal/hello_world/001/hello) 506 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/pascal/hello_world/001) 507 508 add_custom_command( 509 OUTPUT ${PASCAL_001_BIN} 510 COMMAND ${FPC_EXECUTABLE} ${PASCAL_001_SRC} -O3 -o${PASCAL_001_BIN} 511 DEPENDS ${PASCAL_001_SRC} 512 COMMENT "Building Pascal hello_world/001 for ${COMPILER}..." 513 VERBATIM 514 ) 515 516 add_custom_target(${COMPILER}_pascal_hello_001 ALL DEPENDS ${PASCAL_001_BIN}) 517 endforeach() 518 message(STATUS "Pascal build enabled") 519 else() 520 message(WARNING "fpc not found, skipping Pascal builds") 521 endif() 522 523 # COBOL Hello World 001 524 if(COBC_EXECUTABLE) 525 foreach(COMPILER ${COMPILERS}) 526 set(COBOL_001_SRC ${TEST_SRC_DIR}/cobol/hello_world/001/hello.cob) 527 set(COBOL_001_BIN ${TEST_BIN_DIR}/${COMPILER}/cobol/hello_world/001/hello) 528 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/cobol/hello_world/001) 529 530 add_custom_command( 531 OUTPUT ${COBOL_001_BIN} 532 COMMAND ${COBC_EXECUTABLE} -x -O3 -o ${COBOL_001_BIN} ${COBOL_001_SRC} 533 DEPENDS ${COBOL_001_SRC} 534 COMMENT "Building COBOL hello_world/001 for ${COMPILER}..." 535 VERBATIM 536 ) 537 538 add_custom_target(${COMPILER}_cobol_hello_001 ALL DEPENDS ${COBOL_001_BIN}) 539 endforeach() 540 message(STATUS "COBOL build enabled") 541 else() 542 message(WARNING "cobc not found, skipping COBOL builds") 543 endif() 544 545 # C# Hello World 001 546 set(CSHARP_COMPILER "") 547 if(MCS_EXECUTABLE) 548 set(CSHARP_COMPILER ${MCS_EXECUTABLE}) 549 set(CSHARP_FLAGS "-optimize+") 550 message(STATUS "C# compiler: mcs (Mono)") 551 endif() 552 553 if(CSHARP_COMPILER) 554 foreach(COMPILER ${COMPILERS}) 555 set(CSHARP_001_SRC ${TEST_SRC_DIR}/csharp/hello_world/001/hello.cs) 556 set(CSHARP_001_BIN ${TEST_BIN_DIR}/${COMPILER}/csharp/hello_world/001/hello.exe) 557 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/csharp/hello_world/001) 558 559 add_custom_command( 560 OUTPUT ${CSHARP_001_BIN} 561 COMMAND ${CSHARP_COMPILER} ${CSHARP_FLAGS} -out:${CSHARP_001_BIN} ${CSHARP_001_SRC} 562 DEPENDS ${CSHARP_001_SRC} 563 COMMENT "Building C# hello_world/001 for ${COMPILER}..." 564 VERBATIM 565 ) 566 567 add_custom_target(${COMPILER}_csharp_hello_001 ALL DEPENDS ${CSHARP_001_BIN}) 568 endforeach() 569 message(STATUS "C# build enabled") 570 else() 571 message(WARNING "No C# compiler found (csc or mcs), skipping C# builds") 572 endif() 573 574 # Python Hello World 001 - Compile with Cython 575 if(CYTHON_EXECUTABLE AND PYTHON_EXECUTABLE) 576 foreach(COMPILER ${COMPILERS}) 577 set(PY_001_SRC ${TEST_SRC_DIR}/python/hello_world/001/hello.py) 578 set(PY_001_C ${TEST_BIN_DIR}/${COMPILER}/python/hello_world/001/hello.c) 579 set(PY_001_BIN ${TEST_BIN_DIR}/${COMPILER}/python/hello_world/001/hello) 580 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/python/hello_world/001) 581 582 # Get Python include and library paths 583 execute_process( 584 COMMAND ${PYTHON_EXECUTABLE} -c "import sysconfig; print(sysconfig.get_path('include'))" 585 OUTPUT_VARIABLE PYTHON_INCLUDE_DIR 586 OUTPUT_STRIP_TRAILING_WHITESPACE 587 ) 588 589 execute_process( 590 COMMAND ${PYTHON_EXECUTABLE} -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))" 591 OUTPUT_VARIABLE PYTHON_LIB_DIR 592 OUTPUT_STRIP_TRAILING_WHITESPACE 593 ) 594 595 execute_process( 596 COMMAND ${PYTHON_EXECUTABLE} -c "import sysconfig; print(sysconfig.get_config_var('LDVERSION'))" 597 OUTPUT_VARIABLE PYTHON_LDVERSION 598 OUTPUT_STRIP_TRAILING_WHITESPACE 599 ) 600 601 # Set compiler executable 602 if(COMPILER STREQUAL "gcc") 603 set(C_COMPILER ${GCC_C_EXECUTABLE}) 604 elseif(COMPILER STREQUAL "clang") 605 set(C_COMPILER ${CLANG_C_EXECUTABLE}) 606 endif() 607 608 # Step 1: Cython compile .py to .c with --embed flag for standalone executable 609 add_custom_command( 610 OUTPUT ${PY_001_C} 611 COMMAND ${CYTHON_EXECUTABLE} --embed -o ${PY_001_C} ${PY_001_SRC} 612 DEPENDS ${PY_001_SRC} 613 COMMENT "Cythonizing Python hello_world/001 for ${COMPILER}..." 614 VERBATIM 615 ) 616 617 # Step 2: Compile .c to executable 618 add_custom_command( 619 OUTPUT ${PY_001_BIN} 620 COMMAND ${C_COMPILER} -O3 ${PY_001_C} -I${PYTHON_INCLUDE_DIR} -L${PYTHON_LIB_DIR} -lpython${PYTHON_LDVERSION} -o ${PY_001_BIN} 621 DEPENDS ${PY_001_C} 622 COMMENT "Compiling Cython hello_world/001 with ${COMPILER}..." 623 VERBATIM 624 ) 625 626 add_custom_target(${COMPILER}_python_hello_001 ALL DEPENDS ${PY_001_BIN}) 627 endforeach() 628 message(STATUS "Python (Cython) build enabled") 629 else() 630 message(WARNING "Cython or Python not found, skipping Python builds") 631 endif() 632 633 # R Hello World 001 - Compile with embedded R 634 if(R_EXECUTABLE) 635 # Get R include and library paths 636 execute_process( 637 COMMAND ${R_EXECUTABLE} CMD config --cppflags 638 OUTPUT_VARIABLE R_INCLUDE_FLAGS_RAW 639 OUTPUT_STRIP_TRAILING_WHITESPACE 640 ) 641 642 execute_process( 643 COMMAND ${R_EXECUTABLE} CMD config --ldflags 644 OUTPUT_VARIABLE R_LD_FLAGS_RAW 645 OUTPUT_STRIP_TRAILING_WHITESPACE 646 ) 647 648 # Remove -ltirpc which may not be available on all systems 649 string(REPLACE "-ltirpc" "" R_LD_FLAGS_RAW "${R_LD_FLAGS_RAW}") 650 651 # Convert to lists for proper handling 652 separate_arguments(R_INCLUDE_FLAGS UNIX_COMMAND "${R_INCLUDE_FLAGS_RAW}") 653 separate_arguments(R_LD_FLAGS UNIX_COMMAND "${R_LD_FLAGS_RAW}") 654 655 foreach(COMPILER ${COMPILERS}) 656 set(R_001_WRAPPER ${TEST_SRC_DIR}/r/hello_world/001/hello_wrapper.c) 657 set(R_001_BIN ${TEST_BIN_DIR}/${COMPILER}/r/hello_world/001/hello) 658 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/r/hello_world/001) 659 660 if(COMPILER STREQUAL "gcc") 661 set(C_COMPILER ${GCC_C_EXECUTABLE}) 662 elseif(COMPILER STREQUAL "clang") 663 set(C_COMPILER ${CLANG_C_EXECUTABLE}) 664 endif() 665 666 add_custom_command( 667 OUTPUT ${R_001_BIN} 668 COMMAND ${C_COMPILER} ${R_001_WRAPPER} ${R_INCLUDE_FLAGS} ${R_LD_FLAGS} -o ${R_001_BIN} 669 DEPENDS ${R_001_WRAPPER} 670 COMMENT "Building R hello_world/001 for ${COMPILER}..." 671 VERBATIM 672 ) 673 674 add_custom_target(${COMPILER}_r_hello_001 ALL DEPENDS ${R_001_BIN}) 675 endforeach() 676 message(STATUS "R build enabled") 677 else() 678 message(WARNING "R not found, skipping R builds") 679 endif() 680 681 message(STATUS "Test binaries output directory: ${TEST_BIN_DIR}") 682 683 # ====================================================================== 684 # Build benchmark tool 685 # ====================================================================== 686 687 set(BENCHMARK_SRC ${CMAKE_SOURCE_DIR}/src/benchmark.cpp) 688 set(BENCHMARK_BIN ${BIN_DIR}/benchmark) 689 690 add_executable(benchmark_tool ${BENCHMARK_SRC}) 691 set_target_properties(benchmark_tool PROPERTIES 692 OUTPUT_NAME benchmark 693 RUNTIME_OUTPUT_DIRECTORY ${BIN_DIR} 694 CXX_STANDARD 17 695 CXX_STANDARD_REQUIRED ON 696 ) 697 698 target_compile_options(benchmark_tool PRIVATE -O3 -Wall -Wextra) 699 target_link_libraries(benchmark_tool stdc++fs) 700 701 message(STATUS "Benchmark tool will be built to: ${BIN_DIR}/benchmark") 702 703 # ====================================================================== 704 # FIRST 1000 PRIMES SERIES 705 # ====================================================================== 706 707 # C++ first1000primes 001 708 foreach(COMPILER ${COMPILERS}) 709 if(COMPILER STREQUAL "gcc") 710 set(COMPILER_EXEC ${GCC_EXECUTABLE}) 711 elseif(COMPILER STREQUAL "clang") 712 set(COMPILER_EXEC ${CLANG_EXECUTABLE}) 713 endif() 714 715 set(CPP_PRIMES_SRC ${TEST_SRC_DIR}/cpp/first1000primes/001/primes.cpp) 716 set(CPP_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/cpp/first1000primes/001/primes) 717 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/cpp/first1000primes/001) 718 719 add_custom_command( 720 OUTPUT ${CPP_PRIMES_BIN} 721 COMMAND ${COMPILER_EXEC} ${CPP_PRIMES_SRC} -o ${CPP_PRIMES_BIN} -O3 -std=c++17 722 DEPENDS ${CPP_PRIMES_SRC} 723 COMMENT "Building C++ first1000primes/001 with ${COMPILER}..." 724 VERBATIM 725 ) 726 727 add_custom_target(${COMPILER}_cpp_primes_001 ALL DEPENDS ${CPP_PRIMES_BIN}) 728 endforeach() 729 730 # C first1000primes 001 731 if(GCC_C_EXECUTABLE OR CLANG_C_EXECUTABLE) 732 foreach(COMPILER ${COMPILERS}) 733 if(COMPILER STREQUAL "gcc") 734 set(C_COMPILER ${GCC_C_EXECUTABLE}) 735 elseif(COMPILER STREQUAL "clang") 736 set(C_COMPILER ${CLANG_C_EXECUTABLE}) 737 endif() 738 739 if(C_COMPILER) 740 set(C_PRIMES_SRC ${TEST_SRC_DIR}/c/first1000primes/001/primes.c) 741 set(C_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/c/first1000primes/001/primes) 742 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/c/first1000primes/001) 743 744 add_custom_command( 745 OUTPUT ${C_PRIMES_BIN} 746 COMMAND ${C_COMPILER} ${C_PRIMES_SRC} -o ${C_PRIMES_BIN} -O3 -std=c11 -lm 747 DEPENDS ${C_PRIMES_SRC} 748 COMMENT "Building C first1000primes/001 with ${COMPILER}..." 749 VERBATIM 750 ) 751 752 add_custom_target(${COMPILER}_c_primes_001 ALL DEPENDS ${C_PRIMES_BIN}) 753 endif() 754 endforeach() 755 endif() 756 757 # ASM first1000primes 001 - NASM only 758 if(NASM_EXECUTABLE AND LD_EXECUTABLE) 759 foreach(COMPILER ${COMPILERS}) 760 set(ASM_PRIMES_SRC ${TEST_SRC_DIR}/asm/first1000primes/001/primes.asm) 761 set(ASM_PRIMES_OBJ ${TEST_BIN_DIR}/${COMPILER}/asm/first1000primes/001/primes.o) 762 set(ASM_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/asm/first1000primes/001/primes) 763 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/asm/first1000primes/001) 764 765 add_custom_command( 766 OUTPUT ${ASM_PRIMES_OBJ} 767 COMMAND ${NASM_EXECUTABLE} -f elf64 ${ASM_PRIMES_SRC} -o ${ASM_PRIMES_OBJ} 768 DEPENDS ${ASM_PRIMES_SRC} 769 COMMENT "Assembling ASM first1000primes/001 for ${COMPILER}..." 770 VERBATIM 771 ) 772 773 add_custom_command( 774 OUTPUT ${ASM_PRIMES_BIN} 775 COMMAND ${LD_EXECUTABLE} ${ASM_PRIMES_OBJ} -o ${ASM_PRIMES_BIN} 776 DEPENDS ${ASM_PRIMES_OBJ} 777 COMMENT "Linking ASM first1000primes/001 for ${COMPILER}..." 778 VERBATIM 779 ) 780 781 add_custom_target(${COMPILER}_asm_primes_001 ALL DEPENDS ${ASM_PRIMES_BIN}) 782 endforeach() 783 endif() 784 785 # Rust first1000primes 001 786 if(RUSTC_EXECUTABLE) 787 foreach(COMPILER ${COMPILERS}) 788 set(RUST_PRIMES_SRC ${TEST_SRC_DIR}/rust/first1000primes/001/primes.rs) 789 set(RUST_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/rust/first1000primes/001/primes) 790 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/rust/first1000primes/001) 791 792 add_custom_command( 793 OUTPUT ${RUST_PRIMES_BIN} 794 COMMAND ${RUSTC_EXECUTABLE} ${RUST_PRIMES_SRC} -o ${RUST_PRIMES_BIN} -C opt-level=3 795 DEPENDS ${RUST_PRIMES_SRC} 796 COMMENT "Building Rust first1000primes/001 for ${COMPILER}..." 797 VERBATIM 798 ) 799 800 add_custom_target(${COMPILER}_rust_primes_001 ALL DEPENDS ${RUST_PRIMES_BIN}) 801 endforeach() 802 endif() 803 804 # Zig first1000primes 001 805 if(ZIG_EXECUTABLE) 806 foreach(COMPILER ${COMPILERS}) 807 set(ZIG_PRIMES_SRC ${TEST_SRC_DIR}/zig/first1000primes/001/primes.zig) 808 set(ZIG_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/zig/first1000primes/001/primes) 809 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/zig/first1000primes/001) 810 811 add_custom_command( 812 OUTPUT ${ZIG_PRIMES_BIN} 813 COMMAND ${ZIG_EXECUTABLE} build-exe ${ZIG_PRIMES_SRC} -O ReleaseFast -femit-bin=${ZIG_PRIMES_BIN} 814 DEPENDS ${ZIG_PRIMES_SRC} 815 COMMENT "Building Zig first1000primes/001 for ${COMPILER}..." 816 VERBATIM 817 ) 818 819 add_custom_target(${COMPILER}_zig_primes_001 ALL DEPENDS ${ZIG_PRIMES_BIN}) 820 endforeach() 821 endif() 822 823 # Go first1000primes 001 824 if(GO_EXECUTABLE) 825 foreach(COMPILER ${COMPILERS}) 826 set(GO_PRIMES_SRC ${TEST_SRC_DIR}/go/first1000primes/001/primes.go) 827 set(GO_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/go/first1000primes/001/primes) 828 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/go/first1000primes/001) 829 830 add_custom_command( 831 OUTPUT ${GO_PRIMES_BIN} 832 COMMAND ${GO_EXECUTABLE} build -o ${GO_PRIMES_BIN} ${GO_PRIMES_SRC} 833 DEPENDS ${GO_PRIMES_SRC} 834 WORKING_DIRECTORY ${TEST_SRC_DIR}/go/first1000primes/001 835 COMMENT "Building Go first1000primes/001 for ${COMPILER}..." 836 VERBATIM 837 ) 838 839 add_custom_target(${COMPILER}_go_primes_001 ALL DEPENDS ${GO_PRIMES_BIN}) 840 endforeach() 841 endif() 842 843 # D first1000primes 001 844 if(LDC2_EXECUTABLE) 845 set(D_PRIMES_FLAGS "-O3") 846 foreach(COMPILER ${COMPILERS}) 847 set(D_PRIMES_SRC ${TEST_SRC_DIR}/d/first1000primes/001/primes.d) 848 set(D_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/d/first1000primes/001/primes) 849 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/d/first1000primes/001) 850 851 add_custom_command( 852 OUTPUT ${D_PRIMES_BIN} 853 COMMAND ${LDC2_EXECUTABLE} ${D_PRIMES_FLAGS} -of=${D_PRIMES_BIN} ${D_PRIMES_SRC} 854 DEPENDS ${D_PRIMES_SRC} 855 COMMENT "Building D first1000primes/001 for ${COMPILER}..." 856 VERBATIM 857 ) 858 859 add_custom_target(${COMPILER}_d_primes_001 ALL DEPENDS ${D_PRIMES_BIN}) 860 endforeach() 861 endif() 862 863 # Nim first1000primes 001 864 if(NIM_EXECUTABLE) 865 foreach(COMPILER ${COMPILERS}) 866 set(NIM_PRIMES_SRC ${TEST_SRC_DIR}/nim/first1000primes/001/primes.nim) 867 set(NIM_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/nim/first1000primes/001/primes) 868 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/nim/first1000primes/001) 869 870 add_custom_command( 871 OUTPUT ${NIM_PRIMES_BIN} 872 COMMAND ${NIM_EXECUTABLE} c -d:release -o:${NIM_PRIMES_BIN} ${NIM_PRIMES_SRC} 873 DEPENDS ${NIM_PRIMES_SRC} 874 COMMENT "Building Nim first1000primes/001 for ${COMPILER}..." 875 VERBATIM 876 ) 877 878 add_custom_target(${COMPILER}_nim_primes_001 ALL DEPENDS ${NIM_PRIMES_BIN}) 879 endforeach() 880 endif() 881 882 # Ada first1000primes 001 883 if(GNAT_EXECUTABLE) 884 foreach(COMPILER ${COMPILERS}) 885 set(ADA_PRIMES_SRC ${TEST_SRC_DIR}/ada/first1000primes/001/primes.adb) 886 set(ADA_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/ada/first1000primes/001/primes) 887 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/ada/first1000primes/001) 888 889 add_custom_command( 890 OUTPUT ${ADA_PRIMES_BIN} 891 COMMAND ${GNAT_EXECUTABLE} ${ADA_PRIMES_SRC} -o ${ADA_PRIMES_BIN} -O3 -gnatpn 892 DEPENDS ${ADA_PRIMES_SRC} 893 WORKING_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/ada/first1000primes/001 894 COMMENT "Building Ada first1000primes/001 for ${COMPILER}..." 895 VERBATIM 896 ) 897 898 add_custom_target(${COMPILER}_ada_primes_001 ALL DEPENDS ${ADA_PRIMES_BIN}) 899 endforeach() 900 endif() 901 902 # Haskell first1000primes 001 903 if(GHC_EXECUTABLE) 904 foreach(COMPILER ${COMPILERS}) 905 set(HS_PRIMES_SRC ${TEST_SRC_DIR}/haskell/first1000primes/001/primes.hs) 906 set(HS_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/haskell/first1000primes/001/primes) 907 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/haskell/first1000primes/001) 908 909 add_custom_command( 910 OUTPUT ${HS_PRIMES_BIN} 911 COMMAND ${GHC_EXECUTABLE} -O2 -o ${HS_PRIMES_BIN} ${HS_PRIMES_SRC} 912 DEPENDS ${HS_PRIMES_SRC} 913 WORKING_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/haskell/first1000primes/001 914 COMMENT "Building Haskell first1000primes/001 for ${COMPILER}..." 915 VERBATIM 916 ) 917 918 add_custom_target(${COMPILER}_haskell_primes_001 ALL DEPENDS ${HS_PRIMES_BIN}) 919 endforeach() 920 endif() 921 922 # Fortran first1000primes 001 923 if(GFORTRAN_EXECUTABLE) 924 foreach(COMPILER ${COMPILERS}) 925 set(F90_PRIMES_SRC ${TEST_SRC_DIR}/fortran/first1000primes/001/primes.f90) 926 set(F90_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/fortran/first1000primes/001/primes) 927 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/fortran/first1000primes/001) 928 929 add_custom_command( 930 OUTPUT ${F90_PRIMES_BIN} 931 COMMAND ${GFORTRAN_EXECUTABLE} ${F90_PRIMES_SRC} -o ${F90_PRIMES_BIN} -O3 932 DEPENDS ${F90_PRIMES_SRC} 933 COMMENT "Building Fortran first1000primes/001 for ${COMPILER}..." 934 VERBATIM 935 ) 936 937 add_custom_target(${COMPILER}_fortran_primes_001 ALL DEPENDS ${F90_PRIMES_BIN}) 938 endforeach() 939 endif() 940 941 # Pascal first1000primes 001 942 if(FPC_EXECUTABLE) 943 foreach(COMPILER ${COMPILERS}) 944 set(PAS_PRIMES_SRC ${TEST_SRC_DIR}/pascal/first1000primes/001/primes.pas) 945 set(PAS_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/pascal/first1000primes/001/primes) 946 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/pascal/first1000primes/001) 947 948 add_custom_command( 949 OUTPUT ${PAS_PRIMES_BIN} 950 COMMAND ${FPC_EXECUTABLE} ${PAS_PRIMES_SRC} -O3 -FE${TEST_BIN_DIR}/${COMPILER}/pascal/first1000primes/001 -oprimes 951 DEPENDS ${PAS_PRIMES_SRC} 952 COMMENT "Building Pascal first1000primes/001 for ${COMPILER}..." 953 VERBATIM 954 ) 955 956 add_custom_target(${COMPILER}_pascal_primes_001 ALL DEPENDS ${PAS_PRIMES_BIN}) 957 endforeach() 958 endif() 959 960 # COBOL first1000primes 001 961 if(COBC_EXECUTABLE) 962 foreach(COMPILER ${COMPILERS}) 963 set(COB_PRIMES_SRC ${TEST_SRC_DIR}/cobol/first1000primes/001/primes.cob) 964 set(COB_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/cobol/first1000primes/001/primes) 965 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/cobol/first1000primes/001) 966 967 add_custom_command( 968 OUTPUT ${COB_PRIMES_BIN} 969 COMMAND ${COBC_EXECUTABLE} -x ${COB_PRIMES_SRC} -o ${COB_PRIMES_BIN} -O3 970 DEPENDS ${COB_PRIMES_SRC} 971 COMMENT "Building COBOL first1000primes/001 for ${COMPILER}..." 972 VERBATIM 973 ) 974 975 add_custom_target(${COMPILER}_cobol_primes_001 ALL DEPENDS ${COB_PRIMES_BIN}) 976 endforeach() 977 endif() 978 979 # C# first1000primes 001 980 if(CSHARP_COMPILER) 981 foreach(COMPILER ${COMPILERS}) 982 set(CS_PRIMES_SRC ${TEST_SRC_DIR}/csharp/first1000primes/001/primes.cs) 983 set(CS_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/csharp/first1000primes/001/primes.exe) 984 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/csharp/first1000primes/001) 985 986 add_custom_command( 987 OUTPUT ${CS_PRIMES_BIN} 988 COMMAND ${CSHARP_COMPILER} ${CSHARP_FLAGS} -out:${CS_PRIMES_BIN} ${CS_PRIMES_SRC} 989 DEPENDS ${CS_PRIMES_SRC} 990 COMMENT "Building C# first1000primes/001 for ${COMPILER}..." 991 VERBATIM 992 ) 993 994 add_custom_target(${COMPILER}_csharp_primes_001 ALL DEPENDS ${CS_PRIMES_BIN}) 995 endforeach() 996 endif() 997 998 # Python first1000primes 001 999 if(CYTHON_EXECUTABLE AND PYTHON_EXECUTABLE) 1000 foreach(COMPILER ${COMPILERS}) 1001 set(PY_PRIMES_SRC ${TEST_SRC_DIR}/python/first1000primes/001/primes.py) 1002 set(PY_PRIMES_C ${TEST_BIN_DIR}/${COMPILER}/python/first1000primes/001/primes.c) 1003 set(PY_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/python/first1000primes/001/primes) 1004 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/python/first1000primes/001) 1005 1006 if(COMPILER STREQUAL "gcc") 1007 set(C_COMPILER ${GCC_C_EXECUTABLE}) 1008 elseif(COMPILER STREQUAL "clang") 1009 set(C_COMPILER ${CLANG_C_EXECUTABLE}) 1010 endif() 1011 1012 add_custom_command( 1013 OUTPUT ${PY_PRIMES_C} 1014 COMMAND ${CYTHON_EXECUTABLE} --embed -o ${PY_PRIMES_C} ${PY_PRIMES_SRC} 1015 DEPENDS ${PY_PRIMES_SRC} 1016 COMMENT "Cythonizing Python first1000primes/001 for ${COMPILER}..." 1017 VERBATIM 1018 ) 1019 1020 add_custom_command( 1021 OUTPUT ${PY_PRIMES_BIN} 1022 COMMAND ${C_COMPILER} -O3 ${PY_PRIMES_C} -I${PYTHON_INCLUDE_DIR} -L${PYTHON_LIB_DIR} -lpython${PYTHON_LDVERSION} -o ${PY_PRIMES_BIN} 1023 DEPENDS ${PY_PRIMES_C} 1024 COMMENT "Compiling Cython first1000primes/001 with ${COMPILER}..." 1025 VERBATIM 1026 ) 1027 1028 add_custom_target(${COMPILER}_python_primes_001 ALL DEPENDS ${PY_PRIMES_BIN}) 1029 endforeach() 1030 endif() 1031 1032 # R first1000primes 001 1033 if(R_EXECUTABLE) 1034 foreach(COMPILER ${COMPILERS}) 1035 set(R_PRIMES_WRAPPER ${TEST_SRC_DIR}/r/first1000primes/001/primes_wrapper.c) 1036 set(R_PRIMES_BIN ${TEST_BIN_DIR}/${COMPILER}/r/first1000primes/001/primes) 1037 file(MAKE_DIRECTORY ${TEST_BIN_DIR}/${COMPILER}/r/first1000primes/001) 1038 1039 if(COMPILER STREQUAL "gcc") 1040 set(C_COMPILER ${GCC_C_EXECUTABLE}) 1041 elseif(COMPILER STREQUAL "clang") 1042 set(C_COMPILER ${CLANG_C_EXECUTABLE}) 1043 endif() 1044 1045 add_custom_command( 1046 OUTPUT ${R_PRIMES_BIN} 1047 COMMAND ${C_COMPILER} ${R_PRIMES_WRAPPER} ${R_INCLUDE_FLAGS} ${R_LD_FLAGS} -o ${R_PRIMES_BIN} 1048 DEPENDS ${R_PRIMES_WRAPPER} 1049 COMMENT "Building R first1000primes/001 for ${COMPILER}..." 1050 VERBATIM 1051 ) 1052 1053 add_custom_target(${COMPILER}_r_primes_001 ALL DEPENDS ${R_PRIMES_BIN}) 1054 endforeach() 1055 endif()