-
-
Notifications
You must be signed in to change notification settings - Fork 271
cmake: Directly use (g)cc for linking on Unix-like systems #1594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmake: Directly use (g)cc for linking on Unix-like systems #1594
Conversation
|
This could actually speed-up re-builds quite a bit when the D-source hasn't changed! :-) |
|
Yep. I'm also happy to receive suggestions on how to make this more robust, but doing this in CMake is a bit of a pain. |
That's an understatement. :P |
|
@redstar: Assuming we can get this to work reliably, this should probably go into both 1.0 and 1.1, as it should conclusively solve the various build issues people were having after the switch to the D frontend. Of course, we need to make sure that it is reasonably robust still. |
bb59eac to
eee3d1c
Compare
|
Wrt. the AppVeyor failure: I guess the problem are the quotes in the first 2 arguments:
The other args are okay. |
|
Could somebody on Windows give this a quick try? I'd rather we don't ship another release that breaks on various distros, but I can't seem to make sense of the way the |
|
@klickverbot: This works for me: --- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -581,14 +581,21 @@ function(build_d_executable output_exe compiler_args linker_args dependencies)
DEPENDS ${object_file}
)
else()
+ set(dflags "${D_COMPILER_FLAGS} ${DDMD_DFLAGS} ${DDMD_LFLAGS}")
set(lflags ${LDC_TRANSLATED_LINKER_FLAGS})
- separate_arguments(lflags)
+ if(UNIX)
+ separate_arguments(dflags UNIX_COMMAND "${dflags}")
+ separate_arguments(lflags UNIX_COMMAND "${lflags}")
+ else()
+ separate_arguments(dflags WINDOWS_COMMAND "${dflags}")
+ separate_arguments(lflags WINDOWS_COMMAND "${lflags}")
+ endif()
foreach(f ${linker_args})
append("-L\"${f}\"" lflags)
endforeach()
add_custom_command(
OUTPUT ${output_exe}
- COMMAND ${D_COMPILER} ${D_COMPILER_FLAGS} ${DDMD_DFLAGS} ${DDMD_LFLAGS} ${lflags} -I${PROJECT_SOURCE_DIR}/${DDMDFE_PATH} -of${output_exe} ${compiler_args} ${linker_args}
+ COMMAND ${D_COMPILER} ${dflags} ${lflags} -I${PROJECT_SOURCE_DIR}/${DDMDFE_PATH} -of${output_exe} ${compiler_args} ${linker_args}
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
DEPENDS ${dependencies}
) |
|
We need this in 1.1 too. ;) |
eee3d1c to
87ab648
Compare
|
@kinke: Added your patch, thanks. Let's see what the CI systems have to say. |
|
Interesting, LDC 1.1 alpha as front-end compiler now doesn't work anymore for Travis due to multiple definitions of |
|
@kinke Is it a build with |
|
@JohanEngelen: Somehow the build seems to ends up with |
|
@JohanEngelen: I was just trying to summarize the Travis logs. The only difference wrt. the previous successful Travis runs (before the latest commit) is/should be that the arguments in D_COMPILER_FLAGS, DDMD_DFLAGS and DDMD_LFLAGS are now separated too (I thought that was unnecessary for Unixoids and only relevant for Windows...). That could be easily checked by diffing the generated makefiles. I don't get why there's a |
87ab648 to
e67412d
Compare
They are the object files for the D parts of LDMD and LDC, or at least supposed to be. The idea is to then use the system linker with the flags extracted from |
|
Thanks, so how did you just fix it? :) |
This allows us to properly take CMAKE_EXE_LINKER_FLAGS into account without running into gcc/ld layering issues. GitHub: Fixes ldc-developers#1494, alternative fix for ldc-developers#1460.
It is somewhat unclear whether the variable can actually be set in a valid way at this point, though.
e67412d to
557a256
Compare
|
@kinke: Apparently, we were emitting |
|
@JohanEngelen: Okay to merge? |
|
Looks good to me. Things for future work:
|
|
(it works without issue on my machine too btw) |
|
Okay, finally merging, then. ;) This should make our build process fundamentally more robust, since we are no longer trying to pass GCC linker flags directly to ld. There might be some more implementation issues to iron out initially, though, since CMake isn't exactly amenable to defensive programming and testing. |
Currently, we are translating the linker flags for LLVM/libconfig and from
CMAKE_EXE_LINKER_FLAGSinto-Loptions. Since DMD/LDC prefix-Loptions by-Xlinkerbefore passing them to the GCC driver (causing the latter to forward it directly to the underlyingld), this does not work in the general case, causing issues such as #1494.In #1468, a few driver-only flags were special-cased in LDC so that
-Xlinkeris not applied to them. However, I don't think this is a viable strategy in the long run. First of all, there are quite a few more options which are supposed to be passed to the linker driver instead of the linker. But rather more importantly, this only works with an LDC version that contains this fix, and not DMD.Thus, we need a solution that works on the build-system level. One possibility would be to white-list flags we know how to handle in the CMake scripts (e.g. all of them starting with
-Xlinkeror-Wl,…, where we can just strip off the prefix and pass them to the D compiler using-L), and just ignore all the others. However, for some common use cases, we do want to pass flags to the linker driver, such as to link against a static C++ standard library when building binary releases.Since there is no DMD flag for passing flags to the linker driver (we could of course add one in the next LDC version, but this wouldn't help with DMD or older versions), this PR changes the build system to again use the system linker directly from CMake instead of going through the D compiler for linking. Compared to @JohanEngelen's earlier version (sorry!), this now parses the
-voutput to determine the default linker flags used internally by the D compiler instead of trying to guess them.Fixes #1494, #1544.