[cmake-developers] Linking projects with no C or CPP files
Brad King
brad.king at kitware.com
Fri Sep 13 10:21:23 EDT 2013
On 09/12/2013 05:36 PM, James Bigler wrote:
> I discovered a long time ago that VS would link the output of a custom command.
I just ran local experiments with VS 6, 7.1, 8, and 9 by manually modifying
the ExternalOBJ test project in the IDE and building. Results:
- MAIN_DEPENDENCY has no effect on whether custom command outputs are
linked. It does not matter where the command is attached.
- VS 6 and 7.1 do link custom command outputs named .obj, and also
*avoid duplicating* them if the .obj files are listed explicitly too.
- VS 8 and 9 do not link custom command outputs, even named .obj. I get
unresolved symbols unless I add the .obj files explicitly.
What changed in VS 10 is that they still link custom command outputs
but also link .obj files explicitly listed *without de-duplication*.
CMake works around this with some fairly complicated logic that detects
for each EXTERNAL_OBJECT file explicitly listed whether it is also the
output of a custom command in the current target. If so, it lists the
object as <None> to avoid duplicate linking. If not, it uses <Object>
to link it since it wouldn't be linked otherwise. This is very tricky
when the same object appears in multiple targets and one of them has it
in a custom command output and others do not.
In order to avoid this complicated, possibly error-prone logic for
VS >= 11, CMake takes advantage of the LinkObjects setting to get the
behavior of VS 8 and 9. Then it can always list all EXTERNAL_OBJECT
files with <Object>.
> I didn't need to add the obj file to the project anymore.
The general intention in the CMake interface is that custom command
outputs are only used in targets that list the outputs as sources.
This goes for object files too. We intend only to link external
objects that are explicitly listed as sources of the target, whether
they are custom command outputs or not. This is the case with all
non-VS generators, and with VS 8, 9, and now 11. It is not possible
to implement on VS 6, 7.1, and 10, but we approximate it by setting
things up to tolerate the duplication.
The solution here is to always list the .obj file in the target. This
is what the ExternalOBJ test covers and is known to work. Depending
on the VS-(version-)specific behavior for linking custom command
outputs is asking for trouble IMO.
> This was great for VS versions that didn't have source groupings.
Every version of VS supported by CMake has source groups, and the
CMake generators put all objects in a dedicated group by default.
> I think this could work a little better if you allowed linking of the
> output of a custom command if MAIN_DEPENDENCY is set and the output of
> that command is only OBJ files or files that have the EXTERNAL_OBJECT
> property set to true.
As reported above that can't be implemented with VS 8 and 9 directly.
Also it is contrary to the only-use-sources-listed intention described
above.
> I should also point out that whatever solution comes into being, it
> should get integrated into 2.8.12 since this affects FindCUDA.cmake.
IMO the solution should be the attached patch. I'm not set up to
test it, so please try it out.
Thanks,
-Brad
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-FindCUDA-Always-list-custom-command-outputs-in-their.patch
Type: text/x-diff
Size: 2251 bytes
Desc: not available
URL: <http://public.kitware.com/pipermail/cmake-developers/attachments/20130913/049a885d/attachment-0001.patch>
More information about the cmake-developers
mailing list