[CMake] Broken Cmake Behavior using --build VS2010

J Decker d3ck0r at gmail.com
Wed Dec 14 22:25:36 EST 2011


On Wed, Dec 14, 2011 at 5:31 PM, David Cole <david.cole at kitware.com> wrote:
> This is because we should really only allow one project command per CMakeLists.txt file, but since we do not error out, it's difficult to change at this point in time...
>
> --build uses the CMAKE_PROJECT_NAME cache variable to decide what sln file to use, and that corresponds to the first project command.
>
> Do you need multiple project commands in your CMakeLists.txt file?

is there a way to test 'is there a project?' suppose I could check
${PROJECT_NAME}

>
> What benefit do you get from it?

It's more a side effect of having to have at least one project....

source project 1 - standalone core library with various examples and
tests inside it... Actually contains at least 3 projects which it
includes in the solution.  Each of these are like 3 lines to add...
and the signature of the maco for BuildProject

macro( BuildProject PROJECT SOLUTION PROJECT_SOURCE INSTALL_RESULT )

set( PROJECT stock_market )
BuildProject( ${PROJECT} ${PROJECT}
${CMAKE_CURRENT_LIST_DIR}/../src/games/stock_market INSTALL
${EXTRA_FLAGS} )
add_dependencies( ${LAST_TARGET} Buildcore )


So then, in my solution which my top level in project 1 has a single
PROJECT(), and the BuildProject adds multiple projects (will append
the content of buildproject at end).

Source project 2 - uses the core libraries and products built from
source project 1; since I wanted to use the same macro, I merely
included the initial source project 1 cmakelists.txt, but wanted to
have a different solution so I set project in this one.


include( ${SACK_SOURCE_DIR}/cmake_all/CMakeLists.txt )
project( Altanik.all )

set( PROJECT filemirror )
BuildProject( ${PROJECT} ${PROJECT}
${CMAKE_CURRENT_LIST_DIR}/../data/filemirror INSTALL ${EXTRA_FLAGS} )
add_dependencies( ${LAST_TARGET} Buildcore Buildbinary )

; I realize there are several ways I could have done this, one would
be to move the macro into a seperate common cmakelists, but then I do
want the targets from the first, because then I can directly reference
them in the solution for project 2.

The top level makefile/solution is then a makefile which runs cmake
against a source and then runs the correct build tool to generate that
source by running a cmake --build . on this.  So 2 tools, and one or
two commands, I can build with multiple targets, each having their own
cmake run appropriate for its own copy actions.


cmake[-gui] [-G "something"] <sourcedir>
(select appropriate target and build type)
cmake --build .

A while ago I questioned about just running a execute_process( cmake
--build . ) if there was an option set... then I could just use the
gui, configure everything, select an option checkbox to do the build
now, then configure one more time.  See, but to even get to that
option, the project had to have been configured in the first place.



>
> I'd like to understand how people are using multiple project commands, so we can fix this the "right" way.
>
>
> Thx,
> David
>
<code>(heh)

macro( BuildProject PROJECT SOLUTION PROJECT_SOURCE INSTALL_RESULT )
  set( LAST_TARGET Build${PROJECT} )
## this is a goofy command, so I can use a batch file and have the
output of this
## be in an entirely differnt place... should ignore this...
#  if( "$ENV{BUILD_COMMAND}" STREQUAL "" )
    set( INSTALL ${CMAKE_BINARY_DIR}/out/${PROJECT} )
    set( BUILD ${CMAKE_BINARY_DIR}/build/${PROJECT} )
#  else()
#    set( INSTALL ${CMAKE_BINARY_DIR}/../../${CMAKE_BUILD_TYPE}_out/${PROJECT} )
#    set( BUILD ${CMAKE_BINARY_DIR}/../${PROJECT} )
#  endif()

# this uses the variable name passed as INSTALL_RESULT to pass back
the install destination
set( ${INSTALL_RESULT} ${INSTALL} )

# if the output directory doesn't exist, create it;
# otherwise launching cmake in that working directory fails.
FILE( MAKE_DIRECTORY ${BUILD} )

if( MSVC )
 # for some reason the .sln file has to exist at this point, even if it's blank
  if( NOT EXISTS ${BUILD}/${SOLUTION}.sln )
    FILE( WRITE ${BUILD}/${SOLUTION}.sln )
  endif()
 # get the build command appropriate for visual studio
 # (I think sometimes I get a extra .vcxproj on this)
  build_command( BUILD_COMMAND CONFIGURATION ${CMAKE_BUILD_TYPE}
PROJECT_NAME ${SOLUTION} TARGET INSTALL.vcxproj )
  SEPARATE_ARGUMENTS( BUILD_COMMAND WINDOWS_COMMAND ${BUILD_COMMAND} )
  SET( ADD_SOURCES  SOURCES ${BUILD}/${SOLUTION}.sln )
else( MSVC )
  build_command( BUILD_COMMAND CONFIGURATION ${CMAKE_BUILD_TYPE}
PROJECT_NAME ${SOLUTION} TARGET install )
  SEPARATE_ARGUMENTS( BUILD_COMMAND UNIX_COMMAND ${BUILD_COMMAND} )
endif( MSVC )

# finally, create a target 'Build<Project>' which has two commands,
# dependancies between this build and other project builds will be
added to the target
add_custom_target( Build${PROJECT} ALL
	COMMAND cmake -G "${CMAKE_GENERATOR}"
		${PROJECT_SOURCE}
		-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
		-DCMAKE_INSTALL_PREFIX=${INSTALL}
		${ARGN}
	COMMAND ${BUILD_COMMAND}
	WORKING_DIRECTORY ${BUILD}
        ${ADD_SOURCES}
)
endmacro( BuildProject )

</code>


More information about the CMake mailing list