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
>From ef27fa6760ddcfa0add1de956a68f59b134af836 Mon Sep 17 00:00:00 2001
Message-Id: <ef27fa6760ddcfa0add1de956a68f59b134af836.1379081478.git.brad.k...@kitware.com>
From: Brad King <[email protected]>
Date: Fri, 13 Sep 2013 10:08:43 -0400
Subject: [PATCH] FindCUDA: Always list custom command outputs in their targets

CMake's intended interface for linking to explicit object files (marked
with EXTERNAL_OBJECT) is that only those listed as target sources should
be linked.  Drop FindCUDA's attempt to hide the .obj files from VS IDE
project files, which depends on VS-version-specific behavior of linking
custom command outputs that happen to be named "*.obj".  CMake puts
external object files in a dedicated source group anyway.
---
 Modules/FindCUDA.cmake | 17 +----------------
 1 file changed, 1 insertion(+), 16 deletions(-)

diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake
index 0390ae4..8270ad4 100644
--- a/Modules/FindCUDA.cmake
+++ b/Modules/FindCUDA.cmake
@@ -1292,22 +1292,7 @@ macro(CUDA_WRAP_SRCS cuda_target format generated_files)
       # Make sure the build system knows the file is generated.
       set_source_files_properties(${generated_file} PROPERTIES GENERATED TRUE)
 
-      # Don't add the object file to the list of generated files if we are using
-      # visual studio and we are attaching the build rule to the cuda file.  VS
-      # will add our object file to the linker automatically for us.
-      set(cuda_add_generated_file TRUE)
-
-      if(NOT compile_to_ptx AND CMAKE_GENERATOR MATCHES "Visual Studio" AND CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE)
-        # Visual Studio 8 crashes when you close the solution when you don't add the object file.
-        if(NOT CMAKE_GENERATOR MATCHES "Visual Studio 8")
-          #message("Not adding ${generated_file}")
-          set(cuda_add_generated_file FALSE)
-        endif()
-      endif()
-
-      if(cuda_add_generated_file)
-        list(APPEND _cuda_wrap_generated_files ${generated_file})
-      endif()
+      list(APPEND _cuda_wrap_generated_files ${generated_file})
 
       # Add the other files that we want cmake to clean on a cleanup ##########
       list(APPEND CUDA_ADDITIONAL_CLEAN_FILES "${cmake_dependency_file}")
-- 
1.8.4.rc3

--

Powered by www.kitware.com

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-developers

Reply via email to