Native plugin: custom linker args per NativeExecutableSpec or GccLinkerArgsTransformer

hello gradle folks,

asking here helped me after all, though not in the way I expected (yet).

In the documentation Example 56.31. Reconfigure tool arguments there is an example of how to mess with the arguments (along with the hint that it is not a good idea compared to cleanly modeling the dependencies).

Gradle provides a hook that allows the build author to control the exact set of arguments passed to a tool chain executable. This enables the build author to work around any limitations in Gradle, or assumptions that Gradle makes. The arguments hook should be seen as a ‘last-resort’ mechanism, with preference given to truly modelling the underlying domain.

I stumbled upon that before and it did not work. In retrospective I think I missed the surounding tag:

model { 
}

So my current (ugly and very brittle) solution to the above stated problems looks like this:

model {
    toolChains {
        gcc(Gcc) {
            eachPlatform {
                linker.withArguments { args ->
                    List origArgs = new ArrayList(args)
                    List newArgs = new ArrayList()

                    // add the symbol list to the linker if "SrvExecutable" gets linked
                    if (name.contains("SrvExecutable")) {
                        newArgs.add("-Wl,-E")
                        newArgs.add("$generatedSourceAbsolutePath/srvall.exp")
                    }

                    // add --start-group und --end-group in order to allow the linker to resolve circular dependencies.
                    boolean addStartGroup = false;
                    boolean startGroupAdded = false;
                    boolean endGroupAdded = false;
                    origArgs.eachWithIndex { obj, i ->
                        String param = obj as String
                        // insert ‘End a group’ after the libraries (the first argument is always "-o")
                        if(startGroupAdded == true
                        && endGroupAdded == false
                        && param.startsWith("-") ) {
                            newArgs.add("-Wl,--end-group")
                            endGroupAdded = true
                        }

                        // add parameter from original list
                        newArgs.add(param)

                        // add --start-group right after the first "-o", "<fileName>"
                        if (startGroupAdded == false && addStartGroup == true) {
                            newArgs.add("-Wl,--start-group")
                            startGroupAdded = true
                        }

                        if(param.equalsIgnoreCase("-o")) {
                            // The parameter "-o" signals that the next parameter will be the name of the outfile. Right after that follows a list of libraries.
                            addStartGroup = true
                        }
                    }

                    args.clear()
                    args.addAll(newArgs)
                }
            }
        }
    }
}

So this solution is pretty much what @sterling and @Christian2 mentioned in How to resolve circular dependencies between libraries at linking with GCC-Toolchain . The only piece that was missing (for me) was the surounding statements

model {
    toolChains {
        gcc(Gcc) {
            eachPlatform {
            }
        }
    }
}