4 ms·
Those scripts are incredibly simple, and super easy to write and maintain. It's a breath of fresh air compared to other build systems. But I won't defend the cp
by dundarious 4y ago
Those scripts are incredibly simple, and super easy to write and maintain. It's a breath of fresh air compared to other build systems. But I won't defend the cpp, and neither does the author really.
- maccard 4y agoBut the scripts don't work without the cpp - you can't really excuse the build system without excusing the cpp file. All of the actual logic for the build system is in the cpp file, and at least on windows it fails at the first hurdle - it blindly assumes cl.exe is in your path which is not as common on windows as it is on linux for example.
- dundarious 4y agoIt’s perfectly legitimate to say “run the script from a shell where the environment is set up”. In fact, it’s preferable, and you should only attempt to be “smart” and search for that type of thing if you really need it — why use any search logic at all, if it can be avoided. vcvars and its modern incarnations exist to facilitate this. I had already skimmed the cpp (at least the `build` functions). It’s not necessary for what they’re doing. It could be easily replaced with a shell script. I know because I’ve done something very similar, supporting I think even more build variants and compilers. This is mostly copied from a real script, except I mocked up `build` somewhat, since the real one is slightly more complicated. build() (mkdir -p "$1" && cd "$1" && shift && “$@“ ; ) ... declare -a gcc=(-std=c89 -g -D_GNU_SOURCE -fpie -pie -fno-strict-aliasing -Wall -Wextra -Wformat=2 -Wstrict-aliasing=2 -Werror) declare -a clang=(-std=c89 -g -D_GNU_SOURCE -fpie -pie -fno-strict-aliasing -Weverything -Wno-unused-macros -Wno-used-but-marked-unused -Werror) declare -a debug=(-O1 -D_FORTIFY_SOURCE=2 -fno-omit-frame-pointer -fno-optimize-sibling-calls) declare -a asan=("-fsanitize=address,undefined,leak") declare -a msan=(-fsanitize=memory) declare -a isan=(-fsanitize=integer) ... build "$build/x86_64-linux-gnu-gcc-addrsan-debug" gcc "${gcc[@]}" "${debug[@]}" "${asan[@]}" -o example "$src/example.c" build "$build/x86_64-linux-gnu-clang-debug" clang "${clang[@]}" "${debug[@]}" -o example "$src/example.c" build "$build/x86_64-linux-gnu-clang-addrsan-debug" clang "${clang[@]}" "${debug[@]}" "${asan[@]}" -o example "$src/example.c" build "$build/x86_64-linux-gnu-clang-memsan-debug" clang "${clang[@]}" "${debug[@]}" "${msan[@]}" -o example "$src/example.c" build "$build/x86_64-linux-gnu-clang-intsan-debug" clang "${clang[@]}" "${debug[@]}" "${isan[@]}" -o example "$src/example.c" ... Very easy to write a powershell version for Windows. If you know the compiler flags you want, nothing beats literally just writing them all down in a script, when it comes to debugging issues.
- maccard 4y ago> you should only attempt to be “smart” and search for that type of thing if you really need it — why use any search logic at all, if it can be avoided. vcvars and its modern incarnations exist to facilitate this. But that's the standard for how to do things on Windows. That's how it works. Sure you might not like it, but personally I don't like the implicit assumption that everything is configured and "there" that your scripts and the OPs scripts assume. Here's the alternative in cmake though: cmake_minimum_required(VERSION 3.10) project(hello_world) add_executable(app main.cpp) All of a sudden you have support for all major platforms, the workflow is the same (meaning you don't have platform dependent scripts like build_win and build_linux), it works out of the box with all major IDEs/editors, supportd optimised and stripped builds easily, and abstracts that away across platforms (-O2 Vs /O2, /Z7 instead of objcopy +strip). These are problems that have been solved for 30 years, and makeshift bash/batch scripts only make it harder for people to understand what's going on.
- dundarious 4y agoIt’s fine if you want searching, but I disagree that it’s implicitly wrong not to do it because searching is supposedly standard and how everyone else is doing it. Never mind that there exists plenty of software (with far more specific requirements than “give me an object file/dll/executable, compiler version/ABI/options be damned”) that doesn’t use such an approach. For example, try to tell CMake how to create a freestanding executable (one that doesn’t link to the system C library). You end up fighting against the abstractions inherent in its design. Which is to say, depending on what you want to do, it might not be a good fit, and you may be better off just writing out your compiler options yourself. Here’s part of the powershell version of a build script I have used, where I had fewer build variants, so I didn’t even bother to make a `build` function, I just copy paste the `out=... ; if { ... }` block and change the value of `$out` and which compiler and options are called. Note that you can accomplish this with far fewer variables if you don’t want quite as many build variants as this script supports — it was written as an illustration of how flexible you can make things, rather than how simple things can be, so it supports clang, clang-cl, cl, zig cc, with variants for asan, freestanding, for architectures x86, x64, aarch64: $ml = @("-nologo","-c","-Zd","-WX","-W3") ... $clstd = @("-volatile:iso","-permissive-") $clangcl = @("-nologo","-diagnostics:column","-Z7","-Zo","-FC") + $clstd $cl = $clangcl + @("-WL","-Gm-","-utf-8") # -Wall > -W4 but includes very silly things like "function not inlined" for snprintf $clwx = @("-WX","-W4","-wd4100","-wd4127") ... $clfree = @("-D","EXAMPLE_FREESTANDING","-Zl","-GS-","-sdl-","-Gs9999999") $clfreedebug = $clwx + $clodebug + $cldd + $clfree + $clnortti + $clhash + $cllink + $link + $linkfree ... $out = "./x86_64-windows-free-cl-debug" if ("all" -in $targets -or (split-path -path $out -leaf) -in $targets) { new-item -itemtype directory -force $out | out-null try { push-location $out $buildcount++ write-host (split-path -path $out -leaf) ml64 @ml $src/example-x64.asm cl "-Fm./example.map" "-Tc$src/example.c" ./example-x64.obj @cl @clfreedebug } finally { pop-location ; } } If you have an issue, you can easily change compiler options. It will always work and won’t suddenly break if you install a second set of compilers for another project, whereas CMake will have to choose which one and might pick wrong. Likewise, there is no potential for an upgrade to CMake to decide to use different compiler options that interfere with the freestanding stuff. You lose CMake’s abstractions, but like I said, that may be a good thing, depending on what your requirements are, assuming you have detailed knowledge of the compiler (which I’d rather accumulate than detailed knowledge of CMake, and I would know, I have both).