Re: [CMake] runtime dependencies for tests

2012-01-31 Thread Michael Hertling
On 01/31/2012 02:43 PM, Massaro Alessio wrote:
> Hi There
> 
> I googled near and far, but could not find a way to tell CTest where to find 
> the 3rd-party DLLs required to run the test executables.
> In particular my executable targets link with a few Boost DLLs/SOs and 
> obviously require them to run.
> 
> I understand on the Linux/Solaris I can use RPATH support in CMake.
> But I can't find a way to do it on my primary target platform, WIN32-msvc9.
> 
> I've already tried several variants of calling configure_file in a function 
> the following way:
> 
>configure_file("${some_dbg_boost_dll_file}" 
> "${CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG}" COPYONLY)
> 
> I'm open to all sorts of solutions: copy DLLs in place, set the PATH 
> environment variable, ... anything!
> 
> I just need a pointer to show me some way to do it.
> 
> Thank you in advance!

IMO, the easiest approach is to use the ENVIRONMENT test property to
tweak the PATH environment variable for the tests, e.g. by appending/
prepending ${Boost_LIBRARY_DIRS} etc. A more radical but cumbersome
approach is to use the BundleUtilities to perform a completed test
installation - preferably beneath the build tree - and run the tests
therein. Finally, you might copy the required libraries to the build
tree by a custom target or custom commands, or by a test on its own
in conjunction with the DEPENDS test property, but that's even more
cumbersome.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Making a variable a dependency...

2012-02-06 Thread Michael Hertling
On 02/06/2012 10:56 PM, Alexander Neundorf wrote:
> On Saturday 04 February 2012, Oliver Smith wrote:
>> My CMakeLists uses the Subversion repository information in a couple of
>> places (it configures a file revision.h and it uses it for the CPack
>> package name).
>>
>> The problem is that this variable is cached and retained until the cache
>> is rebuilt, instead of being calculated or evaluated per make. So if I
>> do a build, then do an svn update and pull some changes, it will build a
>> new executable but it will stamp it with the revision number from when
>> CMake last regenerated the make files...
>>
>> Is there a way to mark a variable as volatile or something so that CMake
>> will always recalculate it and check if it has changed?
> 
> Would it be acceptable if cmake would rerun after every build ?
> You could enforce that e.g. with a add_custom_command( POST_BUILD ... ) which 
> could e.g. touch CMakeCache.txt or something.
> 
> Better ideas ?

Delay the generation of the revision.h header until build phase
via a custom command; look at the following exemplary project:

# CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(P C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
ADD_CUSTOM_COMMAND(OUTPUT dummy revision.h
COMMAND ${CMAKE_COMMAND}
-DBD=${CMAKE_BINARY_DIR}
-DWC=${CMAKE_SOURCE_DIR}
-P ${CMAKE_SOURCE_DIR}/revision.cmake)
FILE(WRITE ${CMAKE_BINARY_DIR}/main.c
"#include 
#include \"revision.h\"
int main(void)
{
printf(\"%d\\n\",REVISION); return 0;
}
")
ADD_EXECUTABLE(main main.c revision.h)

# revision.cmake:
FIND_PACKAGE(Subversion)
Subversion_WC_INFO(${WC}@HEAD P)
FILE(WRITE ${BD}/revision.h.in "#define REVISION @P_WC_REVISION@\n")
CONFIGURE_FILE(${BD}/revision.h.in ${BD}/revision.h @ONLY)

A "make" run rebuilds the main target whenever the repository's head
revision has changed - possibly inappropriate for actual usage, just
for demonstration purposes; adapt the revision.cmake script to suit
the needs.

BTW, can anybody confirm that the above-noted example doesn't work
if the order of "dummy" and "revision.h" in the custom command is
reversed? AFAICS, revision.h is removed after being generated in
this case, so the subsequent compilation fails.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] How to use CMake with icc via configuration options when needing interprocedural optimization?

2012-02-09 Thread Michael Hertling
On 02/07/2012 02:43 PM, janitor 048 wrote:
> Hello,
> 
> this is a question I recently asked on stackoverflow (
> http://stackoverflow.com/questions/9129233/recommended-ways-to-use-cmake-with-icc-via-configuration-options)
> but that has not received any response since then. Maybe this mailing list
> is a better place to ask... Here goes
> 
> I would like to use the Intel compiler icc (or icpc) with a CMake-based
> project (on Linux for what it's worth). I can of course export the CXX
> variable when calling cmake, e.g. like
> 
> CXX=icpc cmake ../
> 
> and this works fine. I would however like to make this choice available via
> a custom option. For this I parse custom option, e.g.
> 
> cmake -DMY_COMPILER_OPTION=Intel ..
> 
> as
> 
> IF (MY_COMPILER_OPTION STREQUAL "Intel")
>   MESSAGE(STATUS "** Compiling with Intel settings **")
>   SET(CMAKE_CXX_COMPILER "icpc")
>   SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -w")
>   SET(CMAKE_CXX_FLAGS_DEBUG "-g")
> ENDIF ()
> 
> and set CMAKE_CXX_COMPILER together with some compiler flags. This also
> works, however there is an important "but".
> 
> I would also like to use the option -ipo (interprocedural optimization) for
> my code when compiling with icc plus I need to compile a static library
> within the build process. For this to work, I need to use Intel's xiar (and
> also xilink I guess).
> 
> cmake actually offers a special property for this
> 
> set_property(TARGET mytarget PROPERTY INTERPROCEDURAL_OPTIMIZATION 1)
> 
> however this only seems to works properly when the compiler has been set
> via the environment variable (then xiar is used). When setting the compiler
> via CMAKE_CXX_COMPILER this property is ignored.
> 
> Is there another way to do this?. Some recommended way? Or at least a
> work-around?

If it actually works well when the compiler is specified via the
respective environment variable, you might try the following:

IF (MY_COMPILER_OPTION STREQUAL "Intel")
  MESSAGE(STATUS "** Compiling with Intel settings **")
  SET(ENV{CXX} "icpc")
  SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -w")
  SET(CMAKE_CXX_FLAGS_DEBUG "-g")
ENDIF ()

However, note that you must do this *before* the language is enabled,
i.e. before the PROJECT() or ENABLE_LANGUAGE() commands. Note further
that this can be done only for the *initial* configuration of a build
tree; afterwards, the compiler can't be changed anymore. In order to
make that approach more robust, you might consider some refinements:

IF (MY_COMPILER_OPTION STREQUAL "Intel")
  FIND_PROGRAM(ICPC_PROGRAM icpc ...)
  IF(ICPC_PROGRAM)
MESSAGE(STATUS "** Compiling with Intel settings **")
IF(ENV{CXX})
  MESSAGE(WARNING "Overwriting CXX envvar")
ENDIF()
SET(ENV{CXX} "${ICPC_PROGRAM}")
SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -w")
SET(CMAKE_CXX_FLAGS_DEBUG "-g")
  ELSE()
MESSAGE(FATAL_ERROR "Intel compiler not found")
  ENDIF()
ENDIF ()

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Making a variable a dependency...

2012-02-09 Thread Michael Hertling
On 02/08/2012 11:13 PM, Oliver kfsone Smith wrote:
> Michael Hertling said the following on 2/6/2012 6:39 PM:
>> On 02/06/2012 10:56 PM, Alexander Neundorf wrote:
>>> On Saturday 04 February 2012, Oliver Smith wrote:
>>>> My CMakeLists uses the Subversion repository information in a couple of
>>>> places (it configures a file revision.h and it uses it for the CPack
>>>> package name).
>>>>
>>>> The problem is that this variable is cached and retained until the cache
>>>> is rebuilt, instead of being calculated or evaluated per make. So if I
>>>> do a build, then do an svn update and pull some changes, it will build a
>>>> new executable but it will stamp it with the revision number from when
>>>> CMake last regenerated the make files...
>>>>
>>>> Is there a way to mark a variable as volatile or something so that CMake
>>>> will always recalculate it and check if it has changed?
>>> Would it be acceptable if cmake would rerun after every build ?
>>> You could enforce that e.g. with a add_custom_command( POST_BUILD ... ) 
>>> which
>>> could e.g. touch CMakeCache.txt or something.
>>>
>>> Better ideas ?
>> Delay the generation of the revision.h header until build phase
>> via a custom command; look at the following exemplary project:
>>
>> # CMakeLists.txt:
>> CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
>> PROJECT(P C)
>> SET(CMAKE_VERBOSE_MAKEFILE ON)
>> ADD_CUSTOM_COMMAND(OUTPUT dummy revision.h
>>  COMMAND ${CMAKE_COMMAND}
>>  -DBD=${CMAKE_BINARY_DIR}
>>  -DWC=${CMAKE_SOURCE_DIR}
>>  -P ${CMAKE_SOURCE_DIR}/revision.cmake)
>> FILE(WRITE ${CMAKE_BINARY_DIR}/main.c
>> "#include
>> #include \"revision.h\"
>> int main(void)
>> {
>>  printf(\"%d\\n\",REVISION); return 0;
>> }
>> ")
>> ADD_EXECUTABLE(main main.c revision.h)
>>
>> # revision.cmake:
>> FIND_PACKAGE(Subversion)
>> Subversion_WC_INFO(${WC}@HEAD P)
>> FILE(WRITE ${BD}/revision.h.in "#define REVISION @P_WC_REVISION@\n")
>> CONFIGURE_FILE(${BD}/revision.h.in ${BD}/revision.h @ONLY)
>>
>> A "make" run rebuilds the main target whenever the repository's head
>> revision has changed - possibly inappropriate for actual usage, just
>> for demonstration purposes; adapt the revision.cmake script to suit
>> the needs.
>>
>> BTW, can anybody confirm that the above-noted example doesn't work
>> if the order of "dummy" and "revision.h" in the custom command is
>> reversed? AFAICS, revision.h is removed after being generated in
>> this case, so the subsequent compilation fails.
>>
> Unless I'm missing something, that won't work because P_WC_REVISION gets 
> cached in the CMakeCache.txt -- or does using -P cause it to skip the 
> caching?

That's exactly the point: CMake scripts launched by "cmake -P" don't
have access to the cache - refer to the manual - so you can use the
services of FindSubversion.cmake without bothering whether variables
might be stuck in the cache or not. Try the example from my previous
reply and you'll see that P_WC_REVISION doesn't even show up in the
cache at all.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] MSBuild and automatic project file regenation

2012-02-09 Thread Michael Hertling
On 01/13/2012 08:02 PM, Michael Hertling wrote:
> On 01/13/2012 03:42 PM, Bill Hoffman wrote:
>> On 1/13/2012 9:10 AM, Michael Hertling wrote:
>>
>>> With CMake 2.8.7 and VS 2008, I can report the following findings:
>>>
>>> (1) Starting out from within an empty build directory: "cmake .."
>>>  followed by "cmake --build ." configures/builds as expected.
>>> (2) Tweaking CMakeLists.txt file only and leaving sources alone.
>>> (3) "cmake --build ." rebuilds the ZERO_CHECK target and, thus,
>>>  updates the project file to reflect the changes from (2).
>>>  However, the corresponding target is not rebuilt and,
>>>  thus, does not reflect the changes from (2).
>>> (4) A further "cmake --build ." does *nothing* - definitely.
>>> (5) To get the concerned target rebuilt, I need to apply
>>>  David's hint, i.e. "cmake .&&  cmake --build .", or
>>>  clean first, i.e. "cmake --build . --clean-first".
>>
>> Can you provide an example and how to reproduce this?
>>
>> I find it hard to believe that
>>
>> cmake --build .
>> cmake --build .
>>
>> will not build everything.
>>
>> I get that the ZERO_TARGET does not get things to reload, but I don't 
>> see how the second build would not get things up to date.  It has 
>> nothing to do with the project files depending on the targets.  I assume 
>> something really changed and there really needs to be a rebuild?  What 
>> type of thing are you changing in the CMakeLists.txt?
>>
>> -Bill
> 
> Look at the following exemplary project:
> 
> CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
> PROJECT(BUILD C)
> FILE(WRITE ${CMAKE_BINARY_DIR}/main.c
> "#include 
> int main(void)
> {
> printf(\"%d\\n\",NUMBER); return 0;
> }
> ")
> ADD_EXECUTABLE(main main.c)
> SET_TARGET_PROPERTIES(main PROPERTIES
> COMPILE_DEFINITIONS NUMBER=0)
> 
> Steps to reproduce with CMake 2.8.7 and VS 2008:
> 
> (1) From within an empty build directory: "cmake " followed
> by "cmake --build ." configures/builds correctly; "Debug\main"
> yields "0" as expected.
> (2) At the end of CMakeLists.txt, change "NUMBER=0" to "NUMBER=1".
> (3) "cmake --build ." triggers the ZERO_CHECK target, regenerates
> main.vcproj but doesn't use the latter for rebuilding "main".
> Accordingly, "Debug\main" still yields "0".
> Assuming that MSBuild/devenv/ doesn't load the re-
> generated project file into the currently running instance,
> I can well understand this behavior, but:
> (4) A further "cmake --build ." does nothing; in particular, it
> does not rebuild "main", and "Debug\main" still yields "0".
> Here, I'd expect that the regenerated project file is
> loaded and the associated target rebuilt.
> 
> (5) Rebuilding the "main" target can be achieved via David's hint
> "cmake . && cmake --build ." or by cleaning before, e.g. via
> "cmake --build . --clean-first". Afterwards, "Debug\main"
> finally yields "1".
> 
> For additional information, if one modifies the main.vcproj file by
> hand, a subsequent "cmake --build ." also does nothing, as well as
> "msbuild BUILD.sln /t:main" or "msbuild main.vcproj".
> 
> Regards,
> 
> Michael

Any findings w.r.t. this issue? Can anyone reproduce it? Is it actually
faulty behavior, possibly worth a bug report? If so, can it be fixed in
some way? David Cole mentioned something like that. Although this isn't
really disastrous, it would be quite nice if everything is up-to-date
after a "cmake --build ." command, as one is used to with Makefiles.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Copying Files into build-dir under Visual Studio vs. Codeblocks/Win32 vs. Codeblocks/Linux

2012-02-10 Thread Michael Hertling
On 02/10/2012 09:41 AM, Eric Noulard wrote:
> 2012/2/10 Stefan Fendt :
>> Hi,
>>
>> I'm (still) quite unsure if this isn't an FAQ (or if not maybe should be
>> one), but I have read through everything I could google-up regarding
>> this topic and found nothing usable...
>>
>> I'm writing an x-platform-project which will be compiled using different
>> compilers and or under different systems... for this project I am
>> required to move some files from some location (source/data) into the
>> build-directory. Whileas this works under Linux/Codeblocks/GCC as well
>> as Windows/Codeblocks/MinGW it doesn't for Visual Studio... Under Visual
>> Studio the files always are copied to some directory-location directly
>> above the actual binary-directory.
>>
>> I've tried using ${CMAKE_CURRENT_BINARY} and it copies the files to the
>> marked position:
>>
>> build/<--- copies  into this directory
>> build/Debug
>> build/Release
>> build/source
>>
>> After that I tried to do it with GET_TARGET_PROPERTY(... PROPERTY
>> LOCATION). I then get something like this...
>>
>> 'build/$(Configuration)'
>>
>> ...which of course doesn't solve the problem, too... because the
>> configuration under Visual Studio is only known after CMake-Generation
>> of the solution and running the compiler...
>>
>> So, what is the suggested method of (if you can't avoid it) copying
>> files from anywhere into the build-directory, which is as compiler
>> agnostic as possible..?
> 
> You may use CMAKE_CFG_INTDIR.
> 
> Try:
> cmake --help-variable CMAKE_CFG_INTDIR
> 
> You'll get some example with custom command/target.

Alternatively, you might use generator expressions in custom commands/
targets like $. Both, a generator expression and
CMAKE_CFG_INTDIR, are evaluated at build time, but the former is able
to handle the case of targets with individual output directories, i.e.
with RUNTIME_OUTPUT_DIRECTORY[_] properties set. Thus, if you
actually intend to copy the files to the build directories of certain
targets instead of "the" build directory, generator expressions might
be the more robust choice.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] PARENT_SCOPE for unset()?

2012-02-10 Thread Michael Hertling
On 02/10/2012 03:59 PM, Robert Dailey wrote:
> I actually found that using the following worked the exact same for me:
> 
> set( var "" PARENT_SCOPE )
> 
> It passed the "NOT" test in my if condition:
> 
> if( NOT var )
> ...
> endif()

Does it pass the "NOT DEFINED" test, too? There's a difference between
an empty and an undefined variable, and that's sometimes significant.

Regards,

Michael

> It might make more sense to require 2 parameters for set() (the variable
> name and its value). If setting to nothing, use a blank string. That way
> there is no ambiguity between PARENT_SCOPE and parameter 2.
> 
> If people really want to unset the variable, I don't believe set() is the
> way... that's why unset() exists. Just my opinion. Only problem is, if you
> make this change, it isn't backward compatible and will probably break a
> lot of scripts. Looks like CMake is kind of boned here. Herb Sutter made a
> great point during GoingNative 2012 about how it's better to "not have a
> feature" than to misdesign it and be stuck supporting it forever. I think
> the latter part of the statement applies here :)
> 
> This isn't a big deal though, just one of those "if we could change it,
> this would make more sense" kind of things.
> 
> Big thanks for your help David, as usual.
> 
> -
> Robert Dailey
> 
> 
> On Thu, Feb 9, 2012 at 6:19 PM, David Cole  wrote:
> 
>> Yes, PARENT_SCOPE must occur as the last argument. Each command has its
>> own code for processing its argument list. See Source/cmSetCommand.cxx for
>> details on this one.
>>
>> Interesting (not quite the right adjective?) side effect: it's difficult
>> to set a variable to the value "PARENT_SCOPE" because you have to do it
>> indirectly...
>>
>>
>> On Thu, Feb 9, 2012 at 7:12 PM, Robert Dailey  wrote:
>>
>>> That worked, thanks David.
>>>
>>> I guess CMake goes right-to-left for function parameters? I don't see how
>>> else it doesn't think PARENT_SCOPE is a value instead of an option.
>>>
>>> -
>>> Robert Dailey
>>>
>>>
>>>
>>> On Thu, Feb 9, 2012 at 1:45 PM, David Cole wrote:
>>>
 On Thu, Feb 9, 2012 at 2:41 PM, Robert Dailey wrote:

> I didn't try that because I thought it would actually treat
> PARENT_SCOPE as a string and add it to the variable. I did this instead:
>
> set( var "" PARENT_SCOPE )
>

 That leaves it set, with a value of the empty string, in the parent
 scope. Give the one I sent a try.



>
> -
> Robert Dailey
>
>
>
> On Thu, Feb 9, 2012 at 1:26 PM, David Cole wrote:
>
>> On Thu, Feb 9, 2012 at 2:22 PM, Alexander Neundorf <
>> a.neundorf-w...@gmx.net> wrote:
>>
>>> On Thursday 09 February 2012, Robert Dailey wrote:
 It would seem useful to have a PARENT_SCOPE option for the unset()
>>> command,
 just like its set() counterpart. Is there a particular reason why
>>> it does
 not have it now?
>>>
>>> No, I think there is not particular reason.
>>>
>>> Alex
>>> --
>>>
>>> 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://www.cmake.org/mailman/listinfo/cmake
>>>
>>
>>
>> Does:
>>
>>   set(var PARENT_SCOPE)
>>
>> have the intended effect?
>>
>> (If so, you could use that until such time as PARENT_SCOPE is added to
>> unset.)
>>
>>
>> --
>>
>> 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://www.cmake.org/mailman/listinfo/cmake
>>
>
>

>>>
>>
> 
> 
> 
> --
> 
> 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://www.cmake.org/mailman/listinfo/cmake

--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] ansi color

2012-02-10 Thread Michael Hertling
On 02/10/2012 09:15 AM, Matt Fair wrote:
> I'd like to be able to pipe cmake output and still have the ansi color
> codes when the output is not TTY, is there a way to do this?
> Thanks,
> Matt

You might do this by yourself using sed/awk/perl/... and the ANSI CSIs;
refer to [1] for a similar example. Instead of multiple "-e" command
line sed expressions, it is probably more convenient to use a sed
script with one line per color as last part of your pipe.

Regards,

Michael

[1] http://www.mail-archive.com/cmake@cmake.org/msg40328.html
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] How to use CMake with icc via configuration options when needing interprocedural optimization?

2012-02-10 Thread Michael Hertling
On 02/10/2012 12:48 PM, janitor 048 wrote:
> Thank you so much for the hint. Setting the environment variable CXX from
> within my CMakeLists.txt via
> SET(ENV{CXX} "icpc")
> but before any call to project() or enable_language() seems indeed to do
> the trick.
> 
> Setting CMAKE_CXX_FLAGS_RELEASE or CMAKE_CXX_FLAGS_DEBUG at this stage
> however does not work. This apparently needs to go after the project()
> statement.

Sorry, my bad: CMAKE_CXX_FLAGS_ are typical cache variables,
i.e. they are meant to receive their values on the command line or
in the GUI, and their default fallback values are set when C++ is
enabled in Modules/CMakeCXXInformation.cmake by:

SET(CMAKE_CXX_FLAGS_... "${CMAKE_CXX_FLAGS_..._INIT}" CACHE STRING "...")

This SET() command overwrites the value in the current scope if there's
not already a value in the cache. Thus, in order to set these variables
along with the compiler in your IF()-ENDIF() block before PROJECT() or
ENABLE_LANGUAGE() - where there're placed well, IMO - just cache them:

IF (MY_COMPILER_OPTION STREQUAL "Intel")
  MESSAGE(STATUS "** Compiling with Intel settings **")
  SET(ENV{CXX} "icpc")
  SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -w" CACHE STRING "...")
  SET(CMAKE_CXX_FLAGS_DEBUG "-g" CACHE STRING "...")
ENDIF ()

This will make the above-noted SET() command a no-op. Consider to use
the FORCE option if you want to modify/enhance/replace flags the user
might have already specified on the command line or in the GUI.

> I could of course set the environment cxx-flags in the same way as above.
> This would somewhat sacrifice the nice RELEASE / DEBUG distinction but
> maybe this can be done by some if-statements (there certainly is a way to
> query the CMAKE_BUILD_TYPE variable, right?).

Constructs like

IF(CMAKE_BUILD_TYPE STREQUAL Debug)
...
ENDIF()

or better

STRING(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE)
IF(CMAKE_BUILD_TYPE STREQUAL DEBUG)
...
ENDIF()

are possible, but only meaningful for single-configuration generators.
The CMAKE_CXX_FLAGS_ variables are definitely the way to go.

Regards,

Michael

> 2012/2/9 Michael Hertling 
> 
>> On 02/07/2012 02:43 PM, janitor 048 wrote:
>>> Hello,
>>>
>>> this is a question I recently asked on stackoverflow (
>>>
>> http://stackoverflow.com/questions/9129233/recommended-ways-to-use-cmake-with-icc-via-configuration-options
>> )
>>> but that has not received any response since then. Maybe this mailing
>> list
>>> is a better place to ask... Here goes
>>>
>>> I would like to use the Intel compiler icc (or icpc) with a CMake-based
>>> project (on Linux for what it's worth). I can of course export the CXX
>>> variable when calling cmake, e.g. like
>>>
>>> CXX=icpc cmake ../
>>>
>>> and this works fine. I would however like to make this choice available
>> via
>>> a custom option. For this I parse custom option, e.g.
>>>
>>> cmake -DMY_COMPILER_OPTION=Intel ..
>>>
>>> as
>>>
>>> IF (MY_COMPILER_OPTION STREQUAL "Intel")
>>>   MESSAGE(STATUS "** Compiling with Intel settings **")
>>>   SET(CMAKE_CXX_COMPILER "icpc")
>>>   SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -w")
>>>   SET(CMAKE_CXX_FLAGS_DEBUG "-g")
>>> ENDIF ()
>>>
>>> and set CMAKE_CXX_COMPILER together with some compiler flags. This also
>>> works, however there is an important "but".
>>>
>>> I would also like to use the option -ipo (interprocedural optimization)
>> for
>>> my code when compiling with icc plus I need to compile a static library
>>> within the build process. For this to work, I need to use Intel's xiar
>> (and
>>> also xilink I guess).
>>>
>>> cmake actually offers a special property for this
>>>
>>> set_property(TARGET mytarget PROPERTY INTERPROCEDURAL_OPTIMIZATION 1)
>>>
>>> however this only seems to works properly when the compiler has been set
>>> via the environment variable (then xiar is used). When setting the
>> compiler
>>> via CMAKE_CXX_COMPILER this property is ignored.
>>>
>>> Is there another way to do this?. Some recommended way? Or at least a
>>> work-around?
>>
>> If it actually works well when the compiler is specified via the
>> respective environment variable, you might try the following:
>>
>> IF (MY_COMPILER_OPTION STREQUAL "Intel")
>>  MESSAGE(STATUS "** Compiling with Intel settings **")
>>  

Re: [CMake] External project source

2012-02-13 Thread Michael Hertling
On 02/13/2012 09:02 AM, Nicholas Yue wrote:
> On 13/02/12 6:47 PM, Eric Noulard wrote:
>> 2012/2/13 Nicholas Yue:
>>> Hi,
>>>
>>> There is an existing project I have access to that already have CMake
>>> configuration file but the way it is written requires alot of preprocessing
>>> steps (python, shell etc) before it is usable.
>>>
>>> I wanted to investigate a cleaner (truer to CMake original design
>>> purpose) usage of CMake,
>>>
>>> So, I have an  original-project directory which contains both the source
>>> and the CMakeLists.txt in a nested directory structure.
>>>
>>> I want to create my own CMake hierarchy (structure the same way) but
>>> reference the source code in the original-project directory location.
>>>
>>> How do I tell CMake to refer to source code at some other top level
>>> directory as a starting point.
>>>
>>> Is there such a concept in CMake ?
>> I am not sure to fully understand you request but in a CMakeLists.txt
>> you can perfectly
>> refer to source located outside the directory the CMakeLists.txt is in,
>> you can use either relative or absolute path and do something like:
>>
>> add_executable(NiceTarget ../../relpath/to/source.c
>> ${CMAKE_SOURCE_DIR}/abspath/to/another.c)
> Yes, I know I can do that. I am hoping to avoid maintaining a hierarchy 
> of such modification.
> 
> There are 42 CMakeLists.txt files each with multiple libraries, test and 
> such.
> 
> I was hoping there is a way to (assuming I maintain the same hierarchy) 
> tell CMake to start looking for source from some other top level 
> directory 'once' and it will be able to find the source in the 'other' 
> location that is different to my 'cleaned-up' version of CMakeLists.txt
> 
> Regards
> 
>> this is usually a bad idea but this should work.
>>
>> Now that said if you do that for compatibility purpose in order to
>> maintain the legacy build
>> before doing the switch to "genuine" CMake build then may be using a
>> VCS like git would
>> be a better way to go.
> I have this as a fall back.

You might consider to use your own versions of ADD_EXECUTABLE/LIBRARY()
which modify the source files' paths appropriately; see the following:

FUNCTION(ADD_EXECUTABLE name)
UNSET(args)
FOREACH(i IN LISTS ARGN)
IF(i STREQUAL WIN32
 OR i STREQUAL MACOSX_BUNDLE
   OR i STREQUAL EXCLUDE_FROM_ALL)
LIST(APPEND args ${i})
ELSE()
FILE(GLOB p RELATIVE ${CMAKE_SOURCE_DIR}
 ${CMAKE_CURRENT_SOURCE_DIR})
LIST(APPEND args ${EXTERNAL_SOURCE_DIR}/${p}/${i})
ENDIF()
ENDFOREACH()
_ADD_EXECUTABLE(${name} ${args})
ENDFUNCTION()

FUNCTION(ADD_LIBRARY name)
UNSET(args)
FOREACH(i IN LISTS ARGN)
IF(i STREQUAL STATIC
 OR i STREQUAL SHARED
   OR i STREQUAL MODULE
 OR i STREQUAL EXCLUDE_FROM_ALL)
LIST(APPEND args ${i})
ELSE()
FILE(GLOB p RELATIVE ${CMAKE_SOURCE_DIR}
 ${CMAKE_CURRENT_SOURCE_DIR})
LIST(APPEND args ${EXTERNAL_SOURCE_DIR}/${p}/${i})
ENDIF()
ENDFOREACH()
_ADD_LIBRARY(${name} ${args})
ENDFUNCTION()

In this manner, the path of each source file is turned into a full path
pointing into the project's source tree denoted by EXTERNAL_SOURCE_DIR
and respecting the file's location within that tree. Thus, you can set
up a, say, shallow copy of the project, mimicking its directory tree
and populating it only with your adapted CMakeLists.txt files. Note
that this approach would need some refinements, e.g.:

- Be aware of source files generated in the build tree, i.e. check the
  GENERATED source file property and don't modify the path if it's set.

- Be aware of source files with full paths within the project's source
  tree from the first, i.e. check if paths start with CMAKE_SOURCE_DIR
  and replace this prefix with your EXTERNAL_SOURCE_DIR accordingly.

Moreover, note that ADD_EXECUTABLE/LIBRARY() can be overwritten only
once. Personally, however, I would prefer Eric's suggestion to use a
repository managed by a nice branch-capable VCS like Git; IMO, this
will turn out to be much more robust and versatile in the long run.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] MSBuild and automatic project file regenation

2012-02-13 Thread Michael Hertling
On 02/09/2012 05:35 PM, Bill Hoffman wrote:
> I took a look at this, and it is behaving as expected with VS.  VS does 
> NOT have a depend on compile flags.  You can change a .vcproj file and 
> the flags it uses all you want, and VS will NOT rebuild any files 
> because of that.

OK, I see. So, it's a shortcoming of VS, if I understand correctly: No
dependency of object files on project files, and I guess that this is
not amendable by the means of CMake.

> So, as far as VS is concerned your source file has not changed and does 
> not need to rebuild.  I modified your example and --build works 
> perfectly (I change the NUMBER in the CMakeLists.txt and main is rebuilt 
> with one invocation of cmake --build .)
> 
> 
> 
> CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
> PROJECT(BUILD C)
> FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "#include 
> #include 
> int main(void)
> {
>printf(\"%d\\n\",NUMBER);
>return 0;
> }
> ")
> include_directories(${CMAKE_BINARY_DIR})
> ADD_EXECUTABLE(main main.c)
> set(NUMBER 2)
> configure_file(main.h.in main.h)
> 
> 
> $ cat ../main.h.in
> #define NUMBER @NUMBER@

I.e., in order to trigger a rebuild with VS, an actual change in the
sources must have taken place - good to know. Many thanks, Bill and
Aaron, for spending time on this issue.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] How to have a static/shared option in a Find script ?

2012-02-15 Thread Michael Hertling
On 02/15/2012 03:48 PM, Barth wrote:
> Hello, 
> 
> I am trying to write a Find script for a library called DIM. It is something
> basic but I have a problem with caching. I have an option to force choosing
> the static library over the shared one : 
> 
> Then, I decide what is the name of the library to search depending on
> DIM_USE_STATIC and I find it with find_library : 
> 
> 
> The problem is that modifying DIM_USE_STATIC in ccmake doesn't work even
> though DIM_LIB_NAME is correct (ie. libdim.a). DIM_LIBRARY sticks to the
> previous value (the shared library). 
> I know that find_library will not run again if it has already found the
> library in the past, thus how should I do ? 
> 
> Thank you in advance for your help, 
> Barth

Probably, you just need to reset DIM_LIBRARY to an empty string in
ccmake each time you change DIM_USE_STATIC; see the FIND_LIBRARY()
documentation for more information: "If the library is found the
result is stored in the variable and the search will not be
repeated *unless the variable is cleared*."

However, a conceptually cleaner approach is to consider the shared and
the static version of a library as two components of a multi-component
package, and write the find module / configuration file accordingly:

(1) Use FIND_LIBRARY() to look for the shared and the static library
and define DIM_SHARED_LIBRARY and DIM_STATIC_LIBRARY in the cache.
(2) Inspect DIM_FIND_COMPONENTS to see which flavor has been requested,
defaulting to "shared" if no components have been requested at all.
(3) Warn or bail out if "shared" and "static" have both been requested
unless they can be used together - rare but not impossible a priori.
(4) DIM_USE_STATIC decides if DIM_LIBRARIES receives DIM_STATIC_LIBRARY
or DIM_SHARED_LIBRARY, and because DIM_LIBRARIES is not cached, it
can be set anew each time FIND_PACKAGE(DIM ...) is called, so the
issue you report on will go away.

IMO, most packages providing a library with shared and static versions
should be considered in this manner, as this would be a robust mean to
specifically select one or the other without the need to reset cache
entries or bother with CMAKE_FIND_LIBRARY_SUFFIXES or the like.

BTW, this approach would also account for the long-standing annoyance
how to have FIND_LIBRARY() differentiate between a static library and
an import library on Windows; each library type would simply have its
own FIND_LIBRARY() call, and this would make things much easier.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] How to have a static/shared option in a Find script ?

2012-02-16 Thread Michael Hertling
On 02/16/2012 11:10 AM, Barth wrote:
> Hello again, 
> 
> A short question about your proposal :
> 
> Michael Hertling wrote
>>
>> (4) DIM_USE_STATIC decides if DIM_LIBRARIES receives DIM_STATIC_LIBRARY
>> or DIM_SHARED_LIBRARY, and because DIM_LIBRARIES is not cached, it
>> can be set anew each time FIND_PACKAGE(DIM ...) is called, so the
>> issue you report on will go away.
>>
> Why use DIM_USE_STATIC here, and not DIM_FIND_COMPONENTS ? 
> I would think that we get rid of DIM_USE_STATIC if we use components. 

Uhhh, yes, you're absolutely right. Of course, with a component-
aware find module, one would request the static library via

FIND_PACKAGE(DIM COMPONENTS static)

instead of DIM_USE_STATIC. In fact, the latter becomes obsolete
and can be dropped. Thanks for the hint, and sorry for not re-
reading my own reply carefully before hitting "Send"... ;-)

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] How to have a static/shared option in a Find script ?

2012-02-16 Thread Michael Hertling
On 02/16/2012 03:14 PM, Barth wrote:
> Hi again,
> 
> I have understood what you meant :)

Hhm, actually, I talked nonsense w.r.t. DIM_USE_STATIC. ;)

> For records here is what I did :
> 
> # (1) Use FIND_LIBRARY() to look for the shared and the static library
> # and define DIM_SHARED_LIBRARY and DIM_STATIC_LIBRARY in the cache. 
> find_library(DIM_STATIC_LIBRARY NAMES libdim.a PATHS $ENV{DIMDIR}
> PATH_SUFFIXES linux)
> find_library(DIM_SHARED_LIBRARY NAMES dim PATHS $ENV{DIMDIR} PATH_SUFFIXES
> linux)

If libdim.so doesn't exist, but libdim.a does, the last FIND_LIBRARY()
call would return libdim.a, too, which is probably not desired. Here,
one should consider to narrow the search for the respective library
type, e.g. by manipulating CMAKE_FIND_LIBRARY_SUFFIXES; see also
CMAKE_{SHARED,STATIC}_LIBRARY_{PREFIX,SUFFIX} in this regard.

> # (2) Inspect DIM_FIND_COMPONENTS to see which flavor has been requested,
> # defaulting to "shared" if no components have been requested at all. 
> LIST(FIND DIM_FIND_COMPONENTS static ASK_STATIC_COMP) 
> LIST(FIND DIM_FIND_COMPONENTS shared ASK_SHARED_COMP) 

No need for them; use DIM_FIND_REQUIRED_{STATIC,SHARED} - predefined
by FIND_PACKAGE(). Refer to Modules/readme.txt for more information.

> # (3) Warn or bail out if "shared" and "static" have both been requested
> if ( ${ASK_STATIC_COMP} GREATER -1 AND ${ASK_SHARED_COMP} GREATER -1)
> message(WARNING "Two incompatible components specified : static and
> shared. We are going to ignore the static component.")
> endif ( ${ASK_STATIC_COMP} GREATER -1 AND ${ASK_SHARED_COMP} GREATER -1)

IF(DIM_FIND_REQUIRED_SHARED AND DIM_FIND_REQUIRED_STATIC)
MESSAGE(WARNING ...)
LIST(REMOVE_ITEM DIM_FIND_COMPONENTS static)
UNSET(DIM_FIND_REQUIRED_STATIC)
ENDIF()

Do something to the contrary if DIM_FIND_COMPONENTS is empty:

IF(NOT DIM_FIND_COMPONENTS)
LIST(APPEND DIM_FIND_COMPONENTS shared)
SET(DIM_FIND_REQUIRED_SHARED TRUE)
ENDIF()

The point is that DIM_FIND_COMPONENTS and DIM_FIND_REQUIRED_* are set
up properly *before* you are going to actually enable the components.

> # (4) DIM_USE_STATIC decides if DIM_LIBRARIES receives DIM_STATIC_LIBRARY
> # or DIM_SHARED_LIBRARY
> option(DIM_FORCE_STATIC "Turn on to force the use of the static library"
> OFF)
> if( ${DIM_FORCE_STATIC} OR ${ASK_STATIC_COMP} GREATER -1) 
> set(DIM_LIBRARIES ${DIM_STATIC_LIBRARY} )
> else ( ${DIM_FORCE_STATIC} OR ${ASK_STATIC_COMP} GREATER -1) 
> set(DIM_LIBRARIES ${DIM_SHARED_LIBRARY} )
> endif( ${DIM_FORCE_STATIC} OR ${ASK_STATIC_COMP} GREATER -1) 

UNSET(DIM_INCLUDE_DIRS)
UNSET(DIM_LIBRARIES)

SET(DIM_FOUND FALSE)

FIND_PATH(DIM_INCLUDE_DIR ...)

IF(DIM_INCLUDE_DIR)
SET(DIM_FOUND TRUE)
ENDIF

IF(DIM_FIND_REQUIRED_SHARED)
FIND_LIBRARY(DIM_SHARED_LIBRARY ...)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(
DIM_SHARED
DEFAULT_MSG
DIM_INCLUDE_DIR
DIM_SHARED_LIBRARY)
IF(DIM_SHARED_FOUND)
LIST(APPEND DIM_INCLUDE_DIRS ${DIM_INCLUDE_DIR} ...)
LIST(APPEND DIM_LIBRARIES ${DIM_SHARED_LIBRARY} ...)
   ENDIF()
   LIST(REMOVE DIM_FIND_COMPONENTS shared)
   UNSET(DIM_FIND_REQUIRED_SHARED)
ENDIF()

IF(DIM_FIND_REQUIRED_STATIC)
FIND_LIBRARY(DIM_STATIC_LIBRARY ...)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(
DIM_STATIC
DEFAULT_MSG
DIM_INCLUDE_DIR
DIM_STATIC_LIBRARY)
IF(DIM_STATIC_FOUND)
LIST(APPEND DIM_INCLUDE_DIRS ${DIM_INCLUDE_DIR} ...)
LIST(APPEND DIM_LIBRARIES ${DIM_STATIC_LIBRARY} ...)
   ENDIF()
   LIST(REMOVE DIM_FIND_COMPONENTS static)
   UNSET(DIM_FIND_REQUIRED_STATIC)
ENDIF()

# Consider to handle remaining components in DIM_FIND_COMPONENTS.

Note that due to the preparatory work on DIM_FIND_COMPONENTS and the
DIM_FIND_REQUIRED_* variables, the blocks for enabling the shared and
static component have a straight forward structure. Note further that
this can be achieved only with a quite simple package like yours with
two mutually exclusive libraries; with packages providing more subtly
related components - e.g. with inter-component dependencies - things
can be much more complicated. Note finally that the user must issue

IF(DIM_FOUND AND DIM_SHARED_FOUND)

e.g., in order to check for the library's availability unless the
REQUIRED flag was given to FIND_PACKAGE(). Checking for DIM_FOUND
or DIM_SHARED_FOUND alone is *not* reliable, just as referring to
a component that hasn't been requested explicitly - or enabled by
default which, in turn, should be documented explicitly.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] find both shared and static versions?

2012-02-17 Thread Michael Hertling
On 02/17/2012 01:36 AM, Dougal Sutherland wrote:
> I have an application where I want to link some targets against shared
> versions of Boost and some against static versions.
> 
> (I'd prefer shared in general, but I need to link against the static
> version of boost for my matlab mex interface, to avoid loading the
> different version of boost shipped by matlab on runtime. I'm using this
> approachof
> a custom target calling the mex command to compile the mex file.)
> 
> FindBoost.cmake honors the Boost_USE_STATIC_LIBS variable, but that doesn't
> quite solve it.
> 
> I've had the following ideas, none of which I'm happy with:
> 
>1. Use -L${Boost_LIBRARY_DIRS} and then construct the name by doing a
>string replacement from .so/.dylib to .a in ${Boost_THREAD_LIBRARY}.
>Definitely won't work on Windows, might not work for some types of Boost
>installations on Linux/Mac, and fails at link-time instead of
>configure-time if the static version doesn't exist. Maybe there's an
>equivalent transformation that'll probably work on Windows; I don't know,
>I'm not a Windows user.
> 
>2. Copy FindBoost.cmake to FindBoostS.cmake and replace all the
>variables to use a BoostS prefix, as well as making the conditionals for
>USE_STATIC_LIBS always be on; then I can run find_package(Boost) as well as
>find_package(BoostS).
> 
>3. There might be some trickery to approximate (2) without actually
>modifying FindBoost, but I haven't figured it out.
> 
>4. Modify FindBoost.cmake either to look for both dynamic and shared
>libraries and set e.g. Boost_THREAD_LIBRARY_STATIC and
>Boost_THREAD_LIBRARY_SHARED if found, or to add shared and static versions
>for each component, as in
>http://www.cmake.org/pipermail/cmake/2012-February/049142.html
> 
> (4) is obviously the "best" approach, but it's also probably much more work
> than I really want to do on this.
> 
> Any suggestions? Some other approach I haven't thought of, a way to do (3),
> a copy of (4) floating around somewhere?
> 
> Thanks,
> Dougal

You might use multiple invocations of FIND_PACKAGE(Boost ...):

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(P CXX)
SET(CMAKE_VERBOSE_MAKEFILE ON)
FILE(WRITE ${CMAKE_BINARY_DIR}/main.cxx "int main(void){return 0;}\n")
# main1:
FIND_PACKAGE(Boost COMPONENTS thread)
MESSAGE("Boost_LIBRARIES: ${Boost_LIBRARIES}")
ADD_EXECUTABLE(main1 main.cxx)
TARGET_LINK_LIBRARIES(main1 ${Boost_LIBRARIES})
# re-set up:
UNSET(Boost_LIBRARIES)
SET(Boost_USE_STATIC_LIBS ON)
#main2:
FIND_PACKAGE(Boost COMPONENTS regex)
MESSAGE("Boost_LIBRARIES: ${Boost_LIBRARIES}")
ADD_EXECUTABLE(main2 main.cxx)
TARGET_LINK_LIBRARIES(main2 ${Boost_LIBRARIES})

The main1 target is linked against the shared thread library whereas
main2 is linked against the static regex one. Note the switch in the
Boost_USE_STATIC_LIBS variable between the two FIND_PACKAGE() calls.

IMO, FindBoost.cmake behaves bad in one regard: It accumulates results
from different invocations within the same scope. For this reason, you
must intermediately unset the Boost_LIBRARIES variable - and probably
all further uncached result variables like Boost_INCLUDE_DIRS also.
Otherwise, main2 would be linked against the shared thread library,
too, although the latter has not been requested by the latest FIND_
PACKAGE() call. With Boost, AFAIK, it's sufficient to simply reset
the uncached result variables, but with {Find,Use}Qt4.cmake, e.g.,
and their QT_USE_QT* variables, it's a real annoyance to link two
targets against different sets of Qt modules within the same scope.

In summary, my vision of an improved FindBoost.cmake comprises:

- Explicitly shared and static components, e.g. "thread_shared" and
  "regex_static", so one can specifically select them even in mixed
  cases: FIND_PACKAGE(Boost COMPONENTS thread_shared regex_static)

- For convenience and backward compatibility, the usual components
  like "thread" and "regex" as always, with Boost_USE_STATIC_LIBS
  deciding whether component X is turned into X_shared or X_static.
  AFAICS, this can be accomplished as a kind of preprocessing the
  Boost_FIND_COMPONENTS variable quite early in FindBoost.cmake.

- No accumulation of uncached results across multiple invocations
  of FindBoost.cmake; in other words: The uncached results should
  depend only on the parameters of the FindBoost.cmake invocation,
  i.e. the components list, well-known variables as CMAKE_MODULE_
  PATH and well-documented ones as BOOST_ROOT - though the latter
  isn't mentioned in FindBoost.cmake's online documentation ATM.
  In contrast, results of previous FindBoost.cmake calls should
  not show up in the uncached result variables for exactly the
  reason mentioned above.

Feel free to file a feature request; maybe, PL can be persuaded. ;)

Regards,

Michael
--

Powered by www.kitware.com

Visit other Kitware open-source p

Re: [CMake] External projects and make clean

2012-02-20 Thread Michael Hertling
On 02/17/2012 10:16 AM, Oliver Boesche wrote:
> Hi,
> 
> I use external projects e.g. to build BOOST for my own project. In that 
> case I want to prevent the project to be system or version dependent.
> 
> So I build my dependencies successful with external project (and its 
> great), but if use make clean it will clean all stuff and I have to 
> rebuild the external projects again (take some time with BOOST).
> 
> Is there a solution to prevent an external project from cleaning when I 
> call 'make clean'?
> 
> Kind regards
> 
> Oliver Boesche

For the Makefile generators, I could offer the following approach:

# CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(P C)
SET(CMAKE_VERBOSE_MAKEFILE ON)

INCLUDE(ExternalProject)

ExternalProject_Add(external
SOURCE_DIR ${CMAKE_SOURCE_DIR}/external
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=
)

FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "int main(void){return 0;}\n")
ADD_EXECUTABLE(main main.c)
ExternalProject_Get_Property(external INSTALL_DIR)
TARGET_LINK_LIBRARIES(main ${INSTALL_DIR}/lib/libf.so)

ExternalProject_Get_Property(external STAMP_DIR)

ADD_CUSTOM_TARGET(restorestampfiles
COMMAND ${CMAKE_COMMAND}
-DSTAMP_DIR="${STAMP_DIR}"
-P "${CMAKE_SOURCE_DIR}/restorestampfiles.cmake"
COMMENT "Restoring stamp files")

ADD_CUSTOM_TARGET(backupstampfiles
COMMAND ${CMAKE_COMMAND}
-DSTAMP_DIR="${STAMP_DIR}"
-P "${CMAKE_SOURCE_DIR}/backupstampfiles.cmake"
COMMENT "Backing up stamp files")

ADD_CUSTOM_TARGET(toplevel-clean
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}
 --target backupstampfiles
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}
 --target clean
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}
 --target restorestampfiles)

# external/CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(EXTERNAL C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
FILE(WRITE ${CMAKE_BINARY_DIR}/f.c "void f(void){}\n")
ADD_LIBRARY(f SHARED f.c)
INSTALL(TARGETS f DESTINATION lib)

# backupstampfiles.cmake:
FILE(GLOB_RECURSE STAMP_FILES "${STAMP_DIR}/*")
FOREACH(i IN LISTS STAMP_FILES)
IF(NOT i MATCHES "\\.bak$" AND NOT IS_DIRECTORY "${i}")
FILE(RENAME "${i}" "${i}.bak")
ENDIF()
ENDFOREACH()

# restorestampfiles.cmake:
FILE(GLOB_RECURSE STAMP_FILES "${STAMP_DIR}/*")
FOREACH(i IN LISTS STAMP_FILES)
IF(i MATCHES "\\.bak$")
STRING(REGEX REPLACE "\\.bak$" "" j "${i}")
FILE(RENAME "${i}" "${j}")
ENDIF()
ENDFOREACH()

The basic idea is to backup the external project's stamp files before
cleaning, and restore them afterwards. In this way, the steps of the
external project aren't performed during the next build. As a proof,
configure and build the above-noted exemplary project, then issue:

make clean; make

You'll see that the external and the toplevel project are both rebuild
although the external one's binary survives the cleaning. Now, issue:

make toplevel-clean; make

This time, the external project's steps are left out, and only the
toplevel project is rebuilt. In order to be absolutely sure, remove
the ${CMAKE_BINARY_DIR}/external-prefix/lib/libf.so library file to
see "make toplevel-clean; make" fail, whereas "make clean; make" re-
builds the missing file and, thus, succeeds.

Regrettably, the targets "restorestampfiles" and "backupstampfiles"
can not be turned into a custom step of the external project:

ExternalProject_Add_Step(external restore
COMMAND ${CMAKE_COMMAND} ... -P ...restorestampfiles.cmake
DEPENDERS mkdir)

ExternalProject_Add_Step(external backup
COMMAND ${CMAKE_COMMAND} ... -P ...backupstampfiles.cmake
DEPENDEES install)

This would be quite elegant, but apparently, the out-of-dateness of the
external project's steps is recognized before the stamp files are re-
stored. Moreover, I didn't manage to make this appoach work with VS.

IMO, the principal question in this regard is: What do we expect from
the "clean" target w.r.t. external projects? Usually, the latters are
not subject to the toplevel project's development, so one would like
to build them once, but omit them from cleaning. OTOH, there must be
a possibility to clean the toplevel project along with the external
ones in order to perform a full rebuild. AFAICS, the EP module does
not support both variants. A conceptual solution I can imagine is:

- Add a "clean" step - running a CLEAN_COMMAND, possibly defaulting
  to "make clean" - to the external project which is performed when
  the toplevel project is cleaned.

- Add a flag, say, EXCLUDE_FROM_CLEAN that, when specified, excludes
  the external project from the toplevel project's "clean" target.

This EXCLUDE_FROM_CLEAN flag in conjunction with the STEP_TARGETS option
of ExternalProject_Add() would allow for the definition of fine-grained
"clean" targets for external projects. E.g.,

External_Project_Add(boost
...
E

Re: [CMake] delayed target

2012-02-22 Thread Michael Hertling
On 02/22/2012 05:02 PM, Andrea Crotti wrote:
> Again I'm having some troubles with the different building stages:
> 
> I would like to have a target that simply unzips all the files contained 
> in a directory,
> which can be found with a simple globbing.
> 
>   add_custom_target(unzip_all_eggs
> file(GLOB eggs RELATIVE ${EGG_BUILD_DIRECTORY}/*egg)
> COMMAND ${PYTHON_EXECUTABLE} ${UNZIP_SCRIPT} ${egg}
> )
> 
> 
> The problem is that [...]

...FILE(GLOB ...) is a CMake command executed by CMake, whereas the
custom target's COMMANDs are executed by the build tool at build
time, so this approach fails from the first.

> A possible solution is to make my UNZIP_SCRIPT smarter and just do the 
> globbing
> itself, is there any other more CMake-like solution?

ADD_CUSTOM_TARGET(unzip_all_eggs
${CMAKE_COMMAND}
-DEGGDIR=${EGG_BUILD_DIRECTORY}
-P ${CMAKE_SOURCE_DIR}/unzip_all_eggs.cmake)

# ${CMAKE_SOURCE_DIR}/unzip_all_eggs.cmake:
SET(PYTHON_EXECUTABLE ...)
SET(UNZIP_SCRIPT ...)
FILE(GLOB eggs RELATIVE ${EGGDIR}/*egg)
EXECUTE_PROCESS(
COMMAND ${PYTHON_EXECUTABLE} ${UNZIP_SCRIPT} ${eggs}
WORKING_DIRECTORY ...
)

You might want to provide an unzip_all_eggs.cmake.in template including

SET(PYTHON_EXECUTABLE @PYTHON_EXECUTABLE@)
SET(UNZIP_SCRIPT @UNZIP_SCRIPT@)

use CONFIGURE_FILE(unzip_all_eggs.cmake.in unzip_all_eggs.cmake @ONLY)
to generate the actual unzip_all_eggs.cmake after searching Python and
your script, and specify -P ${CMAKE_BINARY_DIR}/unzip_all_eggs.cmake.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] passing arguments to the final make

2012-02-22 Thread Michael Hertling
On 02/22/2012 04:43 PM, Andrea Crotti wrote:
> I would like to be able to pass arguments to my generated Makefile.
> 
> Suppose I use an environment variable like this:
> 
> add_custom_target(run_dev_script
>COMMAND ${PYTHON_EXECUTABLE} ${PREREQUISITE}
>COMMAND ${PYTHON_EXECUTABLE} ${SCRIPT}
>)
> 
> Would that actually work?
> In theory ${SCRIPT} is substituted at cmake time, so I have the 
> impression that it wouldn't work..
> I don't find anything useful in cmake -E however, that would allow me to 
> do something at make time.
> Any suggestions?

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(P NONE)
ADD_CUSTOM_TARGET(echo ${CMAKE_COMMAND} -E echo \${ECHO})

After initial configuration:

% make echo ECHO="Hello World"
Scanning dependencies of target echo
Hello World
Built target echo
% make echo ECHO="Goodbye World"
Goodbye World
Built target echo

% make echo ECHO="Regards, Michael"
Regards, Michael
Built target echo
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] passing arguments to the final make

2012-02-22 Thread Michael Hertling
On 02/22/2012 06:32 PM, Andrea Crotti wrote:
> On 02/22/2012 05:25 PM, Michael Hertling wrote:
>> On 02/22/2012 04:43 PM, Andrea Crotti wrote:
>>> I would like to be able to pass arguments to my generated Makefile.
>>>
>>> Suppose I use an environment variable like this:
>>>
>>> add_custom_target(run_dev_script
>>> COMMAND ${PYTHON_EXECUTABLE} ${PREREQUISITE}
>>> COMMAND ${PYTHON_EXECUTABLE} ${SCRIPT}
>>> )
>>>
>>> Would that actually work?
>>> In theory ${SCRIPT} is substituted at cmake time, so I have the
>>> impression that it wouldn't work..
>>> I don't find anything useful in cmake -E however, that would allow me to
>>> do something at make time.
>>> Any suggestions?
>> CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
>> PROJECT(P NONE)
>> ADD_CUSTOM_TARGET(echo ${CMAKE_COMMAND} -E echo \${ECHO})
>>
>> After initial configuration:
>>
>> % make echo ECHO="Hello World"
>> Scanning dependencies of target echo
>> Hello World
>> Built target echo
>> % make echo ECHO="Goodbye World"
>> Goodbye World
>> Built target echo
>>
>> % make echo ECHO="Regards, Michael"
>> Regards, Michael
>> Built target echo
> 
> Ah that's nice thanks, I'm not sure though that I can rely on being >= 
> 2.8 always,
> and that's probably a requirement, right?

It's sufficient that \$ makes it to the Makefile and becomes $ there.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] passing arguments to the final make

2012-02-22 Thread Michael Hertling
On 02/22/2012 06:56 PM, Andrea Crotti wrote:
> On 02/22/2012 05:32 PM, Andrea Crotti wrote:
>>
>> Ah that's nice thanks, I'm not sure though that I can rely on being >= 
>> 2.8 always,
>> and that's probably a requirement, right?
>>
> 
> I tried what you suggested and with this:
> add_custom_target(dev_no_run
>COMMAND ${PYTHON_EXECUTABLE} ${DEV_MAIN} -w ${WORKSPACE} 
> ${APPLICATION} --develop_only -l info
>COMMAND ${PYTHON_EXECUTABLE} \${SCRIPT}
>)
> 
> I get this in the Makefile:
> 
> CMakeFiles/dev_no_run:
>  /usr/bin/python 
> /home/andrea/git_projs/PSI_Hamburg/utils/utils/bin/dev_main.py -w 
> /home/andrea/git_projs 
> /home/andrea/git_projs/Minimum_Drag/airbus.application.minimum_drag 
> --develop_only -l info
>  /usr/bin/python ${SCRIPT}
> 
> which is probably not what I want, because for a Makefile it should be 
> $(SCRIPT), right?

In Makefiles, $(SCRIPT) and ${SCRIPT} are equivalent, see [1]. However,
parentheses can have a special meaning w.r.t. a library's object files,
and $() is primarily associated with the shell's command substitution.
Thus, I personally prefer ${} for dereferencing macros in Makefiles
since it's quite unambiguous.

Regards,

Michael

> [1] http://www.gnu.org/software/make/manual/html_node/Reference.html#Reference
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] delayed target

2012-02-22 Thread Michael Hertling
On 02/22/2012 07:21 PM, Andrea Crotti wrote:
> On 02/22/2012 05:14 PM, Michael Hertling wrote:
>> On 02/22/2012 05:02 PM, Andrea Crotti wrote:
>>> Again I'm having some troubles with the different building stages:
>>>
>>> I would like to have a target that simply unzips all the files contained
>>> in a directory,
>>> which can be found with a simple globbing.
>>>
>>>add_custom_target(unzip_all_eggs
>>>  file(GLOB eggs RELATIVE ${EGG_BUILD_DIRECTORY}/*egg)
>>>  COMMAND ${PYTHON_EXECUTABLE} ${UNZIP_SCRIPT} ${egg}
>>>  )
>>>
>>>
>>> The problem is that [...]
>> ...FILE(GLOB ...) is a CMake command executed by CMake, whereas the
>> custom target's COMMANDs are executed by the build tool at build
>> time, so this approach fails from the first.
>>
>>> A possible solution is to make my UNZIP_SCRIPT smarter and just do the
>>> globbing
>>> itself, is there any other more CMake-like solution?
>> ADD_CUSTOM_TARGET(unzip_all_eggs
>>  ${CMAKE_COMMAND}
>>  -DEGGDIR=${EGG_BUILD_DIRECTORY}
>>  -P ${CMAKE_SOURCE_DIR}/unzip_all_eggs.cmake)
>>
>> # ${CMAKE_SOURCE_DIR}/unzip_all_eggs.cmake:
>> SET(PYTHON_EXECUTABLE ...)
>> SET(UNZIP_SCRIPT ...)
>> FILE(GLOB eggs RELATIVE ${EGGDIR}/*egg)
>> EXECUTE_PROCESS(
>>  COMMAND ${PYTHON_EXECUTABLE} ${UNZIP_SCRIPT} ${eggs}
>>  WORKING_DIRECTORY ...
>> )
>>
>> You might want to provide an unzip_all_eggs.cmake.in template including
>>
>> SET(PYTHON_EXECUTABLE @PYTHON_EXECUTABLE@)
>> SET(UNZIP_SCRIPT @UNZIP_SCRIPT@)
>>
>> use CONFIGURE_FILE(unzip_all_eggs.cmake.in unzip_all_eggs.cmake @ONLY)
>> to generate the actual unzip_all_eggs.cmake after searching Python and
>> your script, and specify -P ${CMAKE_BINARY_DIR}/unzip_all_eggs.cmake.
>>
> 
> Thanks, this is really nice in general and I might use it in the future.
> The problem is that in this specific case it doesn't buy me much and 
> adds complexity, because
> I would still have only one target unzipping all the eggs.
> 
> It would be nice to be able to generate N target 1 for each egg.

In order to define one target per egg, you'd need to know the eggs at
configuration time since you cannot define targets at build time. So,
gathering the eggs with a custom target/command will not work. As an
alternative, you might gather the eggs at configuration time with a
FILE(GLOB ...) command, loop over the resulting list and define one
target per item. However, your Makefiles would not be aware of any
changes among the eggs - additions, removals, renamings - and you
would need to remember to reconfigure your project by hand if you
don't want to miss any changes. That's somewhat error-prone and
means relinquishing one of CMake's benefits.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Shared intermediary files

2012-02-22 Thread Michael Hertling
On 02/20/2012 10:07 PM, Kevin Schmidt wrote:
> Hello,
>   I'm in the process of converting over a large, monolithic tree with many 
> libraries from a custom build solution over to cmake.  So far, we've loved 
> it.  I am wondering about others' solutions to a problem we have encountered.
> 
> We have more than a few cases of generated source files - for example, Qt moc 
> files.   These all get dumped into CMAKE_CURRENT_BINARY_DIR.  Now, the 
> libraries we have build both static & shared, and have the same source files. 
>  In Visual Studio, this generates two projects in the solution.  It seems 
> that these do not share dependencies.  Occasionally, this means that both 
> libraries try to write to the generated source file at the same time, which 
> generates a (false) build failure.
> 
> What do others do?  Am I misunderstanding something?
> Kevin

How do you generate the source files? Supposedly, you're using custom
commands, right? At least, QT4_WRAP_CPP() does. If so, you probably
walk right into a quite common trap - from the documentation of
ADD_CUSTOM_COMMAND():

"Do not list the output in more than one independent target that
may build in parallel or the two instances of the rule may conflict
(instead use add_custom_target to drive the command and make the other
targets depend on that one)."

If your issue isn't related to custom commands, could you provide more
detailed information how you generate the source files in question?

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] delayed target

2012-02-22 Thread Michael Hertling
On 02/22/2012 11:55 PM, Andrea Crotti wrote:
> On 02/22/2012 09:37 PM, Michael Hertling wrote:
>>
>> In order to define one target per egg, you'd need to know the eggs at
>> configuration time since you cannot define targets at build time. So,
>> gathering the eggs with a custom target/command will not work. As an
>> alternative, you might gather the eggs at configuration time with a
>> FILE(GLOB ...) command, loop over the resulting list and define one
>> target per item. However, your Makefiles would not be aware of any
>> changes among the eggs - additions, removals, renamings - and you
>> would need to remember to reconfigure your project by hand if you
>> don't want to miss any changes. That's somewhat error-prone and
>> means relinquishing one of CMake's benefits.
>>
>> Regards,
>>
>> Michael
>> -
> Yes sure when there are changes in that sense we need to reconfigure,
> but it's really not a big deal in our case because it won't almost never 
> happen,
> and anyway I don't really have any other choice if I want to use the 
> parallelization
> provided by make -j.

There is a possibility to dynamically reconfigure/rebuild the project
without an intermediate manual step and in a way that you'll have one
target per egg, but that approach is disadvantageous in other regards
and possibly won't work with generators other than the Makefiles ones.

IMO, if you really need one target per egg, you should gather them at
configure time and accept the need to reconfigure the project by hand
when necessary. If one target per egg isn't a must-do, gather them at
build time and use a script - CMake, shell, whatever - to unzip them;
this can be done well in parallel also.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] passing arguments to the final make

2012-02-22 Thread Michael Hertling
On 02/23/2012 12:04 AM, John Drescher wrote:
>> And another thing, is it actually \${SCRIPT} a portable solution that works
>> on all the generators?
>>
> 
> This is not about generators but about what shell you are running
> cmake from. For example that would not work on windows since the
> command prompt has a different syntax for variables.

The point is that ${SCRIPT} is substituted in the Makefile by

(1) a macro specified on the command line
(2) a macro specified in the Makefile
(3) an environment variable

in that order, or with (2) and (3) reversed if Make is invoked with the
"-e" switch. When the Makefile's command lines are passed to the shell,
the substitution has already taken place, so it should also work with
the Windows command prompt. However, one needs a Make program, i.e. a
parameterization of this kind probably doesn't work with non-Makefile
generators. Even with Makefiles, there are subtle pitfalls: If a line
"SCRIPT = ..." happens to appear somewhere in the Makefiles, invoking
Make as "make SCRIPT=..." will overwrite it, most certainly resulting
in surprising and undesired behaviour. Personally, I'd advise against
using this method without explicit support by the Makefile generator.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] passing arguments to the final make

2012-02-23 Thread Michael Hertling
On 02/23/2012 11:11 AM, Andrea Crotti wrote:
> On 02/23/2012 06:20 AM, Michael Hertling wrote:
>>
>> The point is that ${SCRIPT} is substituted in the Makefile by
>>
>> (1) a macro specified on the command line
>> (2) a macro specified in the Makefile
>> (3) an environment variable
>>
>> in that order, or with (2) and (3) reversed if Make is invoked with the
>> "-e" switch. When the Makefile's command lines are passed to the shell,
>> the substitution has already taken place, so it should also work with
>> the Windows command prompt. However, one needs a Make program, i.e. a
>> parameterization of this kind probably doesn't work with non-Makefile
>> generators. Even with Makefiles, there are subtle pitfalls: If a line
>> "SCRIPT = ..." happens to appear somewhere in the Makefiles, invoking
>> Make as "make SCRIPT=..." will overwrite it, most certainly resulting
>> in surprising and undesired behaviour. Personally, I'd advise against
>> using this method without explicit support by the Makefile generator.
>>
>> Regards,
>>
>> Michael
>>
> Yes well the problem is that it should work on Windows, and at least
> with MinGW and with Gnu Makefiles.
> I tried and I failed with this approach so I'll just drop the idea...

If you want to revive it, please come up with a minimal hand-written
Makefile that exhibits this behaviour for further investigation, but
like I said, I'd recommend against that approach for CMake-generated
Makefiles.

> Also because typing
> 
> make do_this
> ./test.py
> 
> is not much different than "SCRIPT=test.py make do_this"

Note that

SCRIPT=test.py make do_this

and

make do_this SCRIPT=test.py

aren't equivalent, see (1) and (3) above. They might differ right
w.r.t. the SCRIPT macro's value while the Makefile is processed.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Code and API review request for Qt5 CMake files

2012-02-24 Thread Michael Hertling
On 02/24/2012 03:34 PM, Stephen Kelly wrote:
> 
> Just forwarding to the cmake users list.
> 
> 
> 
> Stephen Kelly wrote:
> 
>>
>> Hi there,
>>
>> Qt5 generates its own CMake files, which you will be able to use to find
>> Qt5 and build with it.
>>
>> That is, you will port from, eg
>>
>> find_package(Qt4 REQUIRED Core Gui Xml)
>>
>> to
>>
>> find_package(Qt5Widgets REQUIRED)
>> find_package(Qt5Xml REQUIRED)
>>
>> find_package(Qt5Core) is also possible but is not needed because it is a
>> dependency of at least one of the other requirements already in this case.
>>
>> find_package(Qt5) will not work currently (though it can be made to work
>> now or after Qt 5.0).
>>
>> You will then port
>>
>> target_link_libraries(foo ${QT_QTCORE_LIBRARIES})
>>
>> to
>>
>> target_link_libraries(foo ${Qt5Core_LIBRARIES})
>>
>> etc.
>>
>> Or you might use qt5_use_package:
>> http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/3083
>>
>> qt5_use_package(foo Core)
>> # That's it! Nothing more to do.
>>
>> The variables all map fairly well. There is also a Qt5Transitional package
>> which might help with that (If it gets released, which I'm not certain it
>> will be): https://projects.kde.org/projects/kdesupport/extra-cmake-
>>
> modules/repository/revisions/master/entry/modules/FindQt5Transitional.cmake
>>
>> The Qt5Config.cmake files are generated and installed by Qt
>> itself.
>>
>> I'd like a review of them by people familiar enough with how CMake works
>> and an API review from people familiar with how it is used.
>>
>> The generation of them is platform specific, and configure options
>> specific, eg whether you use -framework on mac, whether you use MinGW or
>> MSVC, whether building with an infix or a namespace. The easiest way for
>> you to generate the config files is:
>>
>> # Note: Don't bother cloning qt5.git unless you already have it.
>> # That takes forever.
>> git clone git://gitorious.org/qt/qtbase.git
>> cd qtbase
>> ./configure
>> ls lib/cmake
>>
>> Make sure you have at least commit
>> c470999329ee576038c50573314699f972f48909.
>>
>> You can go on to build and test them if you wish. The ctest unit tests are
>> in qtbase/tests/manual/cmake. These tests are not part of any
>> multi-platform CI system.
>>
>> Compared to the last time I emailed about this, the generated Config files
>> have become more simple. I discovered that qmake can have conditionals in
>> its configure_file equivalent.
>>
>> Things that work:
>> * Finding Qt with an infix.
>>
>> * Building against Qt with a namespace.
>>
>> * Finding statically built Qt (though when linking you have to list the
>> dependencies yourself currently)
>>
>> * Finding a particular version should work as ConfigVersion files are
>> installed, but I have not tested it.
>>
>> Things to review:
>>
>> * Are the Config files created correctly for your platform and
>> configuration?
>>
>> * Do the unit tests pass on your platform?
>>
>> * Currently there is no Qt5Config.cmake.
>> Such a thing could probably exist and use the FIND_COMPONENTS to find what
>> was requested. [...]

Absolutely, I would greatly appreciate a well-designed and component-
aware Qt5Config.cmake. In general, there might be reasons why a multi-
component package's components that are to be used together should not
be requested in separate FIND_PACKAGE() invocations, see [1] and look
for package X with components A and B. However, I don't know if Qt5
will be the first example of that kind.

>> [...] However, because there is no way to signal from a Config
>> file that a component was not found [...]

No: See [2] and look for the XXX_YY_FOUND variables. They fit perfectly
to indicate if component YY of package XXX has been found or not, and
they can be set conveniently by FPHSA(XXX_YY ...), see [3].

>> [...] (that is, find_package(Qt5 REQUIRED
>> Gui Xml) might not find QtXml, but Qt5_FOUND would still be true if the
>> Qt5Config file is found, whether the component is or not), [...]

No: FIND_PACKAGE(Qt5 REQUIRED ...) is expected to bail out if any of
the required components aren't found, so the value of the Qt5_FOUND
variable doesn't matter in this case. BTW, note that FIND_PACKAGE()
must not bail out if a component which the user hasn't requested is
not found, regardless of the REQUIRED flag, unless the component is
an immediate or mediate prerequisite of a required one.

Regarding Qt5_FOUND, FIND_PACKAGE(Qt5 COMPONENTS ...), i.e. without
REQUIRED, is more interesting, see [4]. In short: Qt5_FOUND indicates
if Qt5 is basically present but says nothing about any component; the
user must refer to the component-specific FOUND variables, and those
must even be protected by the package-specific one:

FIND_PACKAGE(Qt5 COMPONENTS XYZ)
IF(Qt5_FOUND AND Qt5_XYZ_FOUND)
...
ENDIF()

Referring to Qt5_XYZ_FOUND alone is not reliable because this variable
wouldn't have received a definite value if Qt5Config.cmake hasn't been
found by FIND_PACKAGE(). I.e., the user would refer to this variabl

Re: [CMake] add_executable and extension of source file

2012-02-24 Thread Michael Hertling
On 02/24/2012 06:16 PM, Kris Thielemans wrote:
> Hi
> 
> I have a project where I have C++ and C source files. I'm adding executables
> for this (via macros) like this
> 
> foreach(executable ${SOURCES})
>add_executable(${executable} ${executable} )
>target_link_libraries(${executable} ${STIR_LIBRARIES})
> endforeach()
> 
> where ${SOURCES} is a list of sources WITHOUT extension, e.g.
> 
>   set( SOURCES abs_image  src2)  
> 
> This relies on the fact that cmake should find .cxx and .c etc source files
> for add_executable. At least, I think it should (I found this some tutorial,
> e.g.
> http://www-flc.desy.de/ldcoptimization/documents/talks/CMake_Tutorial.pdf),
> but the doc for add_executable does not seem to mention this behaviour. 
> 
> My current CMake files work fine on Windows and Linux, but I now have a
> MacOSX user who says that it fails. He's running cmake 2.8.7 and when I
> inspect that linking command, it looks like (slightly edited for brevity)
> 
>   /usr/bin/c++   -O3 -DNDEBUG -ffast-math -Wl,-search_paths_first
> -Wl,-headerpad_max_install_names   
>  -o abs_image  a ../buildblock/libbuildblock.a
> 
> That is, clearly the abs_image.o file is missing on this command line.
> 
> Maybe this "adding a list of known extensions" feature is no longer
> supported? Or is the list of known extensions platform specific? (that would
> be bad)

The gcc manpage states:


For any given input file, the file name suffix determines what kind of
compilation is done:

file.c
C source code which must be preprocessed.
...
other
An object file to be fed straight into linking.  Any file name with
no recognized suffix is treated this way.
...
-c  Compile or assemble the source files, but do not link. [...]

Unrecognized input files, not requiring compilation or assembly,
are ignored.


Thus, AFAICS, CMake handles the extension-less sources correctly, but
gcc freaks out: No extension --> ignore when compiling --> no object
file. IMO, it's a quite bad idea to provide source files without a
proper suffix. However, see gcc's -x switch.

> I guess I will have to set my SOURCE files with the extension, and then
> strip the extension for the executable-name. maybe with something like
> 
> foreach(src ${SOURCES})
>   STRING(REPLACE \(.*\)\..* \1 executable ${src})
>  add_executable(${executable} ${src} )
>  ...
> endforeach()

SET(SOURCES abs_image.cxx src2.c)
...
FOREACH(i IN LISTS SOURCES)
GET_FILENAME_COMPONENT(j ${i} NAME_WE)
ADD_EXECUTABLE(${j} ${i})
ENDFOREACH()

> or alternatively find the source file
> 
> foreach(executable ${SOURCES})
>FILE(GLOB src "*.cxx" "*.c")
>   add_executable(${executable} ${src} )
>target_link_libraries(${executable} ${STIR_LIBRARIES})
> endforeach()

Do not use FILE(GLOB ...) in a CMakeLists.txt since this makes the
latter unaware of additions/removals/renamings among your sources.
You will most certainly miss a necessary reconfiguration one day.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] How to recursively copy directories and subdirectories...

2012-02-24 Thread Michael Hertling
On 02/25/2012 03:16 AM, Sumit Kumar wrote:
> Hello 
> 
> I would like to recursively copy folders/subfolders when I do a make install. 
> In addition, I would like to copy certain file patterns (typically *.h) files 
> that may be in these folders. I can do this for individual files (by doing a  
> glob / glob recurse). However, in doing this I lose the directory structure. 
> Any help will be appreciated.
> 
>  
> Thanks and Regards
> Sumit

INSTALL(DIRECTORY ...) with FILES_MATCHING/PATTERN/REGEX/EXCLUDE options.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Code and API review request for Qt5 CMake files

2012-02-25 Thread Michael Hertling
On 02/25/2012 09:43 AM, Alexander Neundorf wrote:
> On Friday 24 February 2012, Michael Hertling wrote:
>> On 02/24/2012 03:34 PM, Stephen Kelly wrote:
> ...
>>>> [...] (that is, find_package(Qt5 REQUIRED
>>>> Gui Xml) might not find QtXml, but Qt5_FOUND would still be true if the
>>>> Qt5Config file is found, whether the component is or not), [...]
>>
>> No: FIND_PACKAGE(Qt5 REQUIRED ...) is expected to bail out if any of
>> the required components aren't found, so the value of the Qt5_FOUND
>> variable doesn't matter in this case. BTW, note that FIND_PACKAGE()
>> must not bail out if a component which the user hasn't requested is
>> not found, regardless of the REQUIRED flag, unless the component is
>> an immediate or mediate prerequisite of a required one.
>>
>> Regarding Qt5_FOUND, FIND_PACKAGE(Qt5 COMPONENTS ...), i.e. without
>> REQUIRED, is more interesting, see [4]. In short: Qt5_FOUND indicates
>> if Qt5 is basically present but says nothing about any component; the
>> user must refer to the component-specific FOUND variables, and those
>> must even be protected by the package-specific one:
> 
> Ah, yes, I remember this discussion.
> I'd sum up the results as follows:
> 
> * Config-mode should behave the same way as Module-mode with regard to 
> COMPONENTS (I think this still needs changes in the find_package() 
> implementation)

Which changes do you have in mind? AFAIK, config files and find modules
can perfectly behave the same - provided they're implemented correctly.

> * if REQUIRED is used, find_package(Foo COMPONENTS A B C) must only succeed 
> if 
> all listed components have been found

Perhaps, we can also include components which are immediate or mediate
prerequisites of the listed ones. The REQUIRED flag should ensure that
anything necessary to use the listed components is actually available.

> * if REQUIRED is not used, we still have two opinions:
> 
> 1.) FOO_FOUND should be the major sign whether everything I wanted has been 
> found or not. I.e. it is only set to TRUE if all listed components have been 
> found. To check whether some of the components have been found, i.e. if 
> FOO_FOUND==FALSE, I can check the per-component _FOUND variables.
> The reasoning here is "I want to use some parts of a big package, if they all 
> are found, then I can use it, otherwise I can't use the package at all"

If FOO_FOUND==FALSE and FIND_PACKAGE() did load a config file, none of
the per-component _FOUND variables has received a definite value, i.e.
you'd refer to the values they already had before the invocation of
FIND_PACKAGE().

> 2.) FOO_FOUND should only indicate that at least something of Foo has been 
> found. To check which modules have been found, i.e. if FOO_FOUND==TRUE, I 
> must 
> check the per-component _FOUND variables.
> The logic here is "I want to use some parts of a big package, and I can use 
> them independently from each other".
> 
> Both make sense.
> I'd prefer the first one.

Presumably, you're not surprised that I move for the second. ;-)
One of my favorite points for the latter is the following use case:

Suppose there's a multi-component package FOO which provides some
required components and some optional ones. The user has three
distinct possibilities how those components can be requested:

(A) Request all of them with the REQUIRED flag: Bad, a missing optional
component would terminate the configuration although all is well.

(B) Request all of them without the REQUIRED flag: With your preference
(1), a missing optional component would result in FOO_FOUND==FALSE
although all is well. As for me, that's not what I'd expect if the
findings are certainly acceptable.

(C) Request the required components with REQUIRED and the optional ones
without this flag via a separate FIND_PACKAGE() invocation: If all
required components are found but an optional component is missing,
your preference (1) would result in FOO_FOUND==TRUE for the formers
and FOO_FOUND==FALSE for the latters. That's even more inconsistent
than (B), although the findings are likewise acceptable. Moreover,
there might be reasons why one doesn't want to use more than one
FIND_PACKAGE() call to request components which are going to be
used together; recall the example of package X with components
A and B and a possibly necessary -DX_WITH_B definition for A.

As a fourth possibility, one might drop the optional components from
the FIND_PACKAGE() call and rely on the assumption that unrequested
components are searched unaskedly by the config file / find module.
This should not be forced on the latter, and what should happen if
an optional component isn't

Re: [CMake] Code and API review request for Qt5 CMake files

2012-02-27 Thread Michael Hertling
On 02/26/2012 11:24 AM, Alexander Neundorf wrote:
> On Sunday 26 February 2012, Michael Hertling wrote:
>> On 02/25/2012 09:43 AM, Alexander Neundorf wrote:
>>> On Friday 24 February 2012, Michael Hertling wrote:
>>>> On 02/24/2012 03:34 PM, Stephen Kelly wrote:
>>> ...
>>>
>>>>>> [...] (that is, find_package(Qt5 REQUIRED
>>>>>> Gui Xml) might not find QtXml, but Qt5_FOUND would still be true if
>>>>>> the Qt5Config file is found, whether the component is or not), [...]
>>>>
>>>> No: FIND_PACKAGE(Qt5 REQUIRED ...) is expected to bail out if any of
>>>> the required components aren't found, so the value of the Qt5_FOUND
>>>> variable doesn't matter in this case. BTW, note that FIND_PACKAGE()
>>>> must not bail out if a component which the user hasn't requested is
>>>> not found, regardless of the REQUIRED flag, unless the component is
>>>> an immediate or mediate prerequisite of a required one.
>>>>
>>>> Regarding Qt5_FOUND, FIND_PACKAGE(Qt5 COMPONENTS ...), i.e. without
>>>> REQUIRED, is more interesting, see [4]. In short: Qt5_FOUND indicates
>>>> if Qt5 is basically present but says nothing about any component; the
>>>> user must refer to the component-specific FOUND variables, and those
>>>
>>>> must even be protected by the package-specific one:
>>> Ah, yes, I remember this discussion.
>>> I'd sum up the results as follows:
>>>
>>> * Config-mode should behave the same way as Module-mode with regard to
>>> COMPONENTS (I think this still needs changes in the find_package()
>>> implementation)
>>
>> Which changes do you have in mind? AFAIK, config files and find modules
>> can perfectly behave the same - provided they're implemented correctly.
> 
> I think currently cmFindPackage.cxx in Config mode doesn't evaluate the per 
> component variables at all to decide whether the package has been found or 
> not, which may be required for the next point:
>  
>>> * if REQUIRED is used, find_package(Foo COMPONENTS A B C) must only
>>> succeed if all listed components have been found
>>
>> Perhaps, we can also include components which are immediate or mediate
>> prerequisites of the listed ones. The REQUIRED flag should ensure that
>> anything necessary to use the listed components is actually available.
> 
> Yes.
> 
>>> * if REQUIRED is not used, we still have two opinions:
>>>
>>> 1.) FOO_FOUND should be the major sign whether everything I wanted has
>>> been found or not. I.e. it is only set to TRUE if all listed components
>>> have been found. To check whether some of the components have been
>>> found, i.e. if FOO_FOUND==FALSE, I can check the per-component _FOUND
>>> variables. The reasoning here is "I want to use some parts of a big
>>> package, if they all are found, then I can use it, otherwise I can't use
>>> the package at all"
>>
>> If FOO_FOUND==FALSE and FIND_PACKAGE() did load a config file, none of
>> the per-component _FOUND variables has received a definite value, i.e.
>> you'd refer to the values they already had before the invocation of
>> FIND_PACKAGE().
> 
> Yes. But other resulting variables are also not reset by find_package() in 
> case of failure. So I wouldn't see this a problem.

The fact that other variables remain untouched as well in this case
doesn't make things better; you'd still query variables which are to
be provided by the config file but have not been assigned a definite
value by the latter. IMO, that's bad style, makes the configuration
unneccessarily vulnerable and means asking for trouble in the long
term.

BTW, if FOO was a single-component package, one wouldn't use any of
its typical variables for any purpose after FIND_PACKAGE() returned
with FOO_FOUND==FALSE. Multi- and single-component packages should
behave the same in this regard, as well as find modules and config
files. FOO_FOUND's only consistent interpretation w.r.t. this is:
FOO_FOUND==FALSE --> Hands off, don't use the package in any way;
in particular, don't refer to any of the package's variables.

>>> 2.) FOO_FOUND should only indicate that at least something of Foo has
>>> been found. To check which modules have been found, i.e. if
>>> FOO_FOUND==TRUE, I must check the per-component _FOUND variables.
>>> The logic here is "I want to use some parts of a big package, and I can
>>> use them independently from each other".
>>>
>>

Re: [CMake] Code and API review request for Qt5 CMake files

2012-02-29 Thread Michael Hertling
On 02/28/2012 10:03 PM, Alexander Neundorf wrote:
> ...will reply later in detail.
> 
> Could you please go through the existing find-modules shipped with cmake 
> which 
> support COMPONENTS and make a summary of how they handle them ?
> 
> At least FindQt4.cmake be default searches all components.
> 
> Thanks
> Alex

The following CMakeLists.txt can be used to systematically investigate
the results of the component-aware find modules currently shipped with
CMake, these are Find{Boost,GTK2,HDF5,ImageMagick,Java,OpenSceneGraph,
Qt4,wxWidgets,XMLRPC}:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(FINDRESULTVARIABLES C CXX)
SET(CMAKE_VERBOSE_MAKEFILE ON)

FUNCTION(FindResultVariables pkg)
SET(prefix ${pkg})
IF(DEFINED ARGV1)
SET(prefix ${ARGV1})
ENDIF()
UNSET(REQUIRED)
IF(${pkg}_REQUIRED)
SET(REQUIRED REQUIRED)
ENDIF()
FIND_PACKAGE(${pkg} COMPONENTS ${${pkg}_COMPONENTS} ${REQUIRED})
MESSAGE("Begin: ${pkg} result variables")
GET_DIRECTORY_PROPERTY(v VARIABLES)
FOREACH(i IN LISTS v)
IF(i MATCHES "^${prefix}.*_FOUND$")
MESSAGE("${i}=${${i}}")
ENDIF()
ENDFOREACH()
MESSAGE("${prefix}_LIBRARIES: ${${prefix}_LIBRARIES}")
MESSAGE("End: ${pkg} result variables")
ENDFUNCTION()

FindResultVariables(Boost)
FindResultVariables(GTK2)
FindResultVariables(HDF5)
FindResultVariables(ImageMagick)
FindResultVariables(Java)
FindResultVariables(OpenSceneGraph)
FindResultVariables(Qt4 QT)
FindResultVariables(wxWidgets)
FindResultVariables(XMLRPC)

HDF5, OpenSceneGraph and XMLRPC aren't installed on my system; my
preliminary findings for the remaining packages are as follows:

(1) Searching unrequested components:

Qt4: Yes.
GTK2,ImageMagick: Partially.
wxWidgets: All components if none are requested.

The remaining modules don't search unrequested components.

(2) Assigning *_*_FOUND variables:

Qt4: Only for modules which are known and found.
ImageMagick: Also for requested but unknown components.
wxWidgets: No *_*_FOUND variables at all but forwards unknown
   components to *_LIBRARIES variable without an error.

The remaining modules assign only to *_*_FOUND variables for
components which they know and which have been requested.

(3) Respecting the REQUIRED flag:

wxWidgets: REQUIRED ignored completely.
Boost: SEND_ERROR instead of FATAL_ERROR.
GTK2,Java: Bail out on unknown components even if not REQUIRED.

The remaining modules bail out on unavailable requested components.

(4) Assinging the package-related *_FOUND variable:

Java: No *_FOUND variable at all although it's documented.
wxWidgets: TRUE even if requested components aren't found, see above.

The remaining modules return FALSE if a requested component isn't found.

My comments on these, say, multifarious findings are:

Ad.(1): In general, automatically searching unrequested components
does not mean a harm, but it is also not beneficial at all events:

- No guarantee to catch all components - consider a component added
  later to the package - so no guarantee that all later *_*_FOUND
  variables have been assigned a definite value by FIND_PACKAGE().
- Complicates find modules / config files due to REQUIRED/QUIET.
- Potentially higher costs due to unneeded search operations.

For the latter loint, there is a not-so-uncommon use case: Suppose
a find module wants to check whether a library matches its header.
Putting away cross-compiling issues for the moment, this requires
building and running a test program. If it is to be performed for
each Qt4 module, e.g., a FIND_PACKAGE(Qt4) invocation would most
certainly be quite expensive. For these reasons, I usually advice
to search only requested components, request all components going
to be used and refer only to components having been requested.

Ad.(2): Due to my guiding principle - refer only to FOUND variables
which have been assigned a definite value by FIND_PACKAGE() - I do
consider as important that a *_*_FOUND variable is assigned to for
each requested component. FindImageMagick.cmake does it right, but
the other modules - except for FindwxWidgets.cmake - have me check
*_*_FOUND variables without a definite value for requested but un-
known components. Again: The latters might become known one day.

Ad.(3): After FIND_PACKAGE(... REQUIRED), I definitely do not want
to check if all requested components including their prerequisites
are actually present. OTOH, the user must have the oppurtunity to
handle a package's or a component's absence by h(is|er)self. Thus,
FIND_PACKAGE() without REQUIRED should never bail out because of
something being not found, but with REQUIRED, it must bail out.

Ad.(4): None of the modules returning *_FOUND==FALSE just because
a component is missing could be turned into a config file at the
moment without changing its behavior. In order to address this
issue in the future, one has to decide if either

- a find module should behave like a config file in this regard and
  retu

Re: [CMake] Functions inherit parent variables?

2012-02-29 Thread Michael Hertling
On 03/01/2012 01:38 AM, Robert Dailey wrote:
> I ran a quick test:
> 
> 
> function( test )
> message( "SOME_TEST: ${SOME_TEST}" )
> endfunction()
> 
> function( start )
> set( SOME_TEST "HELLO WORLD" )
> test()
> endfunction()
> 
> start()
> 
> 
> Seems like a function has access to the calling scope's defined variables.
> I thought because functions created a new scope, that excluded access to
> variables defined in the outer scope (i.e. calling scope)
> 
> Can someone explain?

The line "SOME_TEST: HELLO WORLD" is missing, I guess?

As usual with scoping mechanisms, there is access to the outer scope
from within the inner scope: Read access via ordinary dereferencing
and write access via PARENT_SCOPE. It's quite the same as in C/C++
with the { and } tokens; see also the C++ "::" operator.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Code and API review request for Qt5 CMake files

2012-03-01 Thread Michael Hertling
On 03/01/2012 10:08 PM, Alexander Neundorf wrote:
> On Thursday 01 March 2012, Michael Hertling wrote:
>> On 02/28/2012 10:03 PM, Alexander Neundorf wrote:
>>> ...will reply later in detail.
>>>
>>> Could you please go through the existing find-modules shipped with cmake
>>> which support COMPONENTS and make a summary of how they handle them ?
>>>
>>> At least FindQt4.cmake be default searches all components.
>>>
>>> Thanks
>>> Alex
>>
>> The following CMakeLists.txt can be used to systematically investigate
>> the results of the component-aware find modules currently shipped with
>> CMake, these are Find{Boost,GTK2,HDF5,ImageMagick,Java,OpenSceneGraph,
>> Qt4,wxWidgets,XMLRPC}:
>>
>> CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
>> PROJECT(FINDRESULTVARIABLES C CXX)
>> SET(CMAKE_VERBOSE_MAKEFILE ON)
>>
>> FUNCTION(FindResultVariables pkg)
>> SET(prefix ${pkg})
>> IF(DEFINED ARGV1)
>> SET(prefix ${ARGV1})
>> ENDIF()
>> UNSET(REQUIRED)
>> IF(${pkg}_REQUIRED)
>> SET(REQUIRED REQUIRED)
>> ENDIF()
>> FIND_PACKAGE(${pkg} COMPONENTS ${${pkg}_COMPONENTS} ${REQUIRED})
>> MESSAGE("Begin: ${pkg} result variables")
>> GET_DIRECTORY_PROPERTY(v VARIABLES)
>> FOREACH(i IN LISTS v)
>> IF(i MATCHES "^${prefix}.*_FOUND$")
>> MESSAGE("${i}=${${i}}")
>> ENDIF()
>> ENDFOREACH()
>> MESSAGE("${prefix}_LIBRARIES: ${${prefix}_LIBRARIES}")
>> MESSAGE("End: ${pkg} result variables")
>> ENDFUNCTION()
>>
>> FindResultVariables(Boost)
>> FindResultVariables(GTK2)
>> FindResultVariables(HDF5)
>> FindResultVariables(ImageMagick)
>> FindResultVariables(Java)
>> FindResultVariables(OpenSceneGraph)
>> FindResultVariables(Qt4 QT)
>> FindResultVariables(wxWidgets)
>> FindResultVariables(XMLRPC)
> 
> Thanks :-)
>  
>> HDF5, OpenSceneGraph and XMLRPC aren't installed on my system; my
>> preliminary findings for the remaining packages are as follows:
> 
> Maybe you can have a look at the code of those ?

Perhaps, someone who has these packages already installed can take a
look at them in the meantime and run the above-noted CMakeLists.txt.
Probably, this will provide for faster results.

>> (1) Searching unrequested components:
>>
>> Qt4: Yes.
>> GTK2,ImageMagick: Partially.
>> wxWidgets: All components if none are requested.
>>
>> The remaining modules don't search unrequested components.
>>
>> (2) Assigning *_*_FOUND variables:
>>
>> Qt4: Only for modules which are known and found.
>> ImageMagick: Also for requested but unknown components.
>> wxWidgets: No *_*_FOUND variables at all but forwards unknown
>>components to *_LIBRARIES variable without an error.
>>
>> The remaining modules assign only to *_*_FOUND variables for
>> components which they know and which have been requested.
>>
>> (3) Respecting the REQUIRED flag:
>>
>> wxWidgets: REQUIRED ignored completely.
> 
> This is clearly a bug.
> 
>> Boost: SEND_ERROR instead of FATAL_ERROR.
> 
> This is somewhere between acceptable and bug.
> 
>> GTK2,Java: Bail out on unknown components even if not REQUIRED.
> 
> Depending on how unknown components should be handled, this is either ok or 
> not.
> I'm leaning towards supporting only known components, so the find-module or 
> config file knows what it is doing.
> In this case this would be correct behaviour, the programmer would see this 
> error, not the user.

Please recall the use case of Qt5 with config file and a module XYZ
added in a later release. A FIND_PACKAGE(Qt5 COMPONENTS XYZ) against
a later Qt5 installation works flawlessly, but against an early one,
it faces Qt5Config.cmake with an unknown component XYZ, and this is
perfectly legal. How should one use the XYZ module optionally - i.e.
if available - given that Qt5Config.cmake bails out on a missing XYZ
although REQUIRED isn't flagged? IMO, without REQUIRED, config files
/ find modules should handle requested but unknown components grace-
fully by just assigning FALSE to the respective *_*_FOUND variable.

What's your opinion about the above-mentioned use case?

>> The remaining modules bail out on unavailable requested components.
>>
>> (4) Assinging the package-related *_FOUND variable:
>>
>> Java: No *_FOUND variable at all although it's documented.
> 
> Bug.
> 
>> wxWidgets: TRUE even if requested components a

Re: [CMake] Functions inherit parent variables?

2012-03-02 Thread Michael Hertling
On 03/01/2012 06:01 PM, Robert Dailey wrote:
> No, the print statement is not missing. In fact it prints just fine
> (function test() is able to obtain the value for variable SOME_TEST).

I meant the output "SOME_TEST: HELLO WORLD" was missing in your report.

> This isn't exactly the same as C++. In C++, a function does not have access
> to the calling function's local declarations. In order for the function to
> get access to these, they must be passed in as parameters.

There wasn't talk of functions but of the "{" and "}" tokens:

#include 

int main(void)
{
int outer = 1;
{
int inner = 2;
printf("outer=%d, inner=%d\n",outer,inner);
}
return 0;
}

As you will see, there's access to the outer scope from the inner one.

However, to be more precise, C/C++'s scoping is static, i.e. it's in
effect at compilation time only, and - in contrast to Pascal, e.g. -
the ISO dialects don't allow a nested definition of functions, so a
function's scope isn't part of another function's one. Therefore, a
called function can't see the variables of the calling function as
their scopes aren't descendants but siblings.

Interpreted languages like CMake's one often have dynamic scoping,
i.e. an invocation of a function creates a new scope - capable to
hold variables - and pushes it on a stack from where it is popped
and destroyed when the function terminates. When dereferencing a
variable, it is searched by traversing the stacked scopes from
inner to outer until it is found. Therefore, a called function
can see the calling function's variables since the latter's
scope is accessible from the former's one.

Maybe, it was a rather bad idea to compare C/C++'s static
block scoping with CMake's dynamic function scoping.
Sorry about that.

Regards,

Michael

> On Wed, Feb 29, 2012 at 9:54 PM, Michael Hertling wrote:
> 
>> On 03/01/2012 01:38 AM, Robert Dailey wrote:
>>> I ran a quick test:
>>>
>>>
>>> function( test )
>>> message( "SOME_TEST: ${SOME_TEST}" )
>>> endfunction()
>>>
>>> function( start )
>>> set( SOME_TEST "HELLO WORLD" )
>>> test()
>>> endfunction()
>>>
>>> start()
>>>
>>>
>>> Seems like a function has access to the calling scope's defined
>> variables.
>>> I thought because functions created a new scope, that excluded access to
>>> variables defined in the outer scope (i.e. calling scope)
>>>
>>> Can someone explain?
>>
>> The line "SOME_TEST: HELLO WORLD" is missing, I guess?
>>
>> As usual with scoping mechanisms, there is access to the outer scope
>> from within the inner scope: Read access via ordinary dereferencing
>> and write access via PARENT_SCOPE. It's quite the same as in C/C++
>> with the { and } tokens; see also the C++ "::" operator.
>>
>> Regards,
>>
>> Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Functions inherit parent variables?

2012-03-02 Thread Michael Hertling
On 03/03/2012 02:29 AM, Robert Dailey wrote:
> Well you're really comparing apples to oranges. C++ nested scoping rules
> really have nothing to do with two separate functions sharing scoped
> variables. It doesn't even really serve as a good analogy, so I can't be
> 100% certain what you were trying to tell me ;-)

What I actually intended to express is that

(1) C/C++'s static block scoping has the same effect as CMake's dynamic
function scoping *insofar* that the inner scope has access to the
outer scope - as usual - and

(2) in C/C++, a function can't see a calling function's variables for
the reason alone that they don't have nested scopes, but the fact
that caller and callee don't have nested static scopes in C/C++
doesn't mean that they don't have nested dynamic ones in CMake.

Probably, as I said before, a quite silly idea...

> However I appreciate your response. I really just wanted to make sure this
> isn't a bug, because the way the called function inherits the calling
> function's local variables is an unusual behavior for a language, at least
> in my experience. So I had to think twice about it ;)

AFAIK, it's unusual for languages knowing nested functions, but
CMake doesn't know them. Among the nested-knowing ones, e.g.,
Python can do

def outer():
value = 123
print "outer:",value
def inner(): print "inner:",value
inner()
value = 321
outer()
outer()

whereas Perl 5 can do it only once ("will not stay shared")

use warnings;
use strict;
sub outer {
my $value;
$value = 123;
print "outer: $value\n";
sub inner { print "inner: $value\n"; }
inner();
$value = 321;
}
outer();
outer();

but Perl 6, in turn, is said to do it like Python.

We're getting off-topic, I guess.

Regards,

Michael

> On Fri, Mar 2, 2012 at 6:53 PM, Michael Hertling wrote:
> 
>> On 03/01/2012 06:01 PM, Robert Dailey wrote:
>>> No, the print statement is not missing. In fact it prints just fine
>>> (function test() is able to obtain the value for variable SOME_TEST).
>>
>> I meant the output "SOME_TEST: HELLO WORLD" was missing in your report.
>>
>>> This isn't exactly the same as C++. In C++, a function does not have
>> access
>>> to the calling function's local declarations. In order for the function
>> to
>>> get access to these, they must be passed in as parameters.
>>
>> There wasn't talk of functions but of the "{" and "}" tokens:
>>
>> #include 
>>
>> int main(void)
>> {
>>int outer = 1;
>>{
>>int inner = 2;
>>printf("outer=%d, inner=%d\n",outer,inner);
>>}
>>return 0;
>> }
>>
>> As you will see, there's access to the outer scope from the inner one.
>>
>> However, to be more precise, C/C++'s scoping is static, i.e. it's in
>> effect at compilation time only, and - in contrast to Pascal, e.g. -
>> the ISO dialects don't allow a nested definition of functions, so a
>> function's scope isn't part of another function's one. Therefore, a
>> called function can't see the variables of the calling function as
>> their scopes aren't descendants but siblings.
>>
>> Interpreted languages like CMake's one often have dynamic scoping,
>> i.e. an invocation of a function creates a new scope - capable to
>> hold variables - and pushes it on a stack from where it is popped
>> and destroyed when the function terminates. When dereferencing a
>> variable, it is searched by traversing the stacked scopes from
>> inner to outer until it is found. Therefore, a called function
>> can see the calling function's variables since the latter's
>> scope is accessible from the former's one.
>>
>> Maybe, it was a rather bad idea to compare C/C++'s static
>> block scoping with CMake's dynamic function scoping.
>> Sorry about that.
>>
>> Regards,
>>
>> Michael
>>
>>> On Wed, Feb 29, 2012 at 9:54 PM, Michael Hertling >> wrote:
>>>
>>>> On 03/01/2012 01:38 AM, Robert Dailey wrote:
>>>>> I ran a quick test:
>>>>>
>>>>>
>>>>> function( test )
>>>>> message( "SOME_TEST: ${SOME_TEST}" )
>>>>> endfunction()
>>>>>
>>>>> function( start )
>>>>> set( SOME_TEST "HELLO WORLD" )
>>>>> test()
>>>>> endfunction()
>>>>>
>>>>&

Re: [CMake] avoid rebuilding targets depending on generated source files

2012-03-03 Thread Michael Hertling
On 03/03/2012 10:36 PM, Ajay Panyala wrote:
> Try "cmake -E copy_if_different ..."
> 
> cmake -E copy_if_different build/test1.c build/tests/test1.c
> 
> That would work when make is run atleast once.
> When running make for the 1st time test1.c was never
> copied to build/tests before. So I would be comparing a file with
> another non-existant file and that would result in an error halting
> the make process.

No, it wouldn't; check it out:

% touch a
% rm -f b
% ls b
ls: cannot access b: No such file or directory
% cmake -E copy_if_different a b
% ls b
b
% cksum a b
4294967295 0 a
4294967295 0 b

Regards,

Michael

> On Sat, Mar 3, 2012 at 1:20 PM, Hendrik Sattler 
> wrote:
> 
>> Am Samstag, 3. März 2012, 21:41:49 schrieb Ajay Panyala:
>>> I have a custom target which runs a command to generate
>>> a C source file say test1.c
>>>
>>> ADD_CUSTOM_TARGET(TestGen ALL
>>> COMMAND genExec ${PROJECT_SOURCE_DIR}/Main.java
>>> DEPENDS ${PROJECT_SOURCE_DIR}/Main.java
>>> )
>>>
>>> And I have a custom command that moves the generated *test1.c *
>>> to a new directory inside the build directory.
>>>
>>> ADD_CUSTOM_COMMAND(
>>> TARGET TestGen
>>> POST_BUILD
>>> COMMAND mv
>>> ARGS ${PROJECT_BINARY_DIR}/test1.c ${PROJECT_BINARY_DIR}/tests/
>>> )
>>>
>>> Each time I run make, the custom target is run (since custom targets are
>>> always
>>> out-of-date). But I want to avoid moving the new test1.c generated each
>>> time if build/test1.c is the same as build/tests/test1.c since there are
>>> other targets
>>> like add_executable and add_library later in the CMakelists file that are
>>>  re-built
>>> each time since they depend on test1.c
>>
>> Try "cmake -E copy_if_different ..."
>>
>> HS
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Problems with CMake and static Qt plugins

2012-03-03 Thread Michael Hertling
On 03/02/2012 02:48 PM, NoRulez wrote:
> Hello,
> 
> I use Qt 4.8.0 from the QtSDK and Iwant to generate a static qt plugin.
> In my main.cpp I have the following:
> 
> 
> #include
> #include
> 
> Q_IMPORT_PLUGIN(Local)
> 
> intmain(intargc,char*argv[]){
> QApplicationapp(argc,argv);
> 
>  .
>  .
>  .
> return  app.exec();
> 
> }
> 
> The corresponding CMakeLists.txt for the LocalPlugin looks like the following:
> 
> SET(LOCALPLUGIN_HEADERS
> 
>  LocalPlugin.h
> 
> )
> 
> SET(LOCALPLUGIN_SOURCES
> 
>  LocalPlugin.cpp
> 
> )
> 
> 
> SET(QT_USE_QTGUITRUE)
> SET(QT_USE_QTPLUGINTRUE)
> 
> QT4_AUTOMOC(${LOCALPLUGIN_SOURCES})
> QT4_WRAP_CPP(LOCALPLUGIN_MOC${LOCALPLUGIN_HEADERS})
> 
> ADD_LIBRARY(Local  STATIC  ${LOCALPLUGIN_HEADERS}  ${LOCALPLUGIN_SOURCES}  
> ${LOCALPLUGIN_MOC})
> 
> TARGET_LINK_LIBRARIES(Local  ${QT_LIBRARIES})
> 
> 
> The corresponding CMakeLists.txt for the main app looks like the following:
> 
> SET(QT_USE_QTMAINTRUE)
> 
> SET(QT_USE_QTGUI  TRUE)
> 
> ADD_EXECUTABLE(MyApp WIN32  ${APP_SOURCES}  ${APP_RCC}  MyApp.rc)
> TARGET_LINK_LIBRARIES(MyAppLocal  ${QT_LIBRARIES})
> 
> When I compile it I get the following error:
> In function `StaticLocalPluginInstance': undefined reference to 
> `qt_plugin_instance_Local()'
> 
> Please, could anybody help me to get it working?

Did you INCLUDE(${QT_USE_FILE}) in the correct place, i.e. after
setting the QT_USE_QT* variables? QT_LIBRARIES is populated in
that file.

Moreover, the lines

SET(QT_USE_QTGUITRUE)
SET(QT_USE_QTMAINTRUE)
SET(QT_USE_QTPLUGINTRUE)
QT4_WRAP_CPP(LOCALPLUGIN_MOC${LOCALPLUGIN_HEADERS})

are obviously missing blanks - just typos in your report?

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] avoid rebuilding targets depending on generated source files

2012-03-03 Thread Michael Hertling
On 03/04/2012 12:14 AM, Ajay Panyala wrote:
> No, it wouldn't; check it out:
> 
> % touch a
> % rm -f b
> % ls b
> ls: cannot access b: No such file or directory
> % cmake -E copy_if_different a b
> % ls b
> b
> % cksum a b
> 4294967295 0 a
> 4294967295 0 b
> 
> It works with one file, but I have 4 files that are generated.
> I have 4 cmake -E copy_if_different commands, one for each file.
> Only the last file is not copied (if similar). The others are copied
> even if they are the same.
> 
> I verfied that they are the same with a diff.
> 
> Any idea what might be happening here ?

Please provide a minimal but complete example for this issue.

Regards,

Michael

> On Sat, Mar 3, 2012 at 2:47 PM, Michael Hertling wrote:
> 
>> On 03/03/2012 10:36 PM, Ajay Panyala wrote:
>>> Try "cmake -E copy_if_different ..."
>>>
>>> cmake -E copy_if_different build/test1.c build/tests/test1.c
>>>
>>> That would work when make is run atleast once.
>>> When running make for the 1st time test1.c was never
>>> copied to build/tests before. So I would be comparing a file with
>>> another non-existant file and that would result in an error halting
>>> the make process.
>>
>> No, it wouldn't; check it out:
>>
>> % touch a
>> % rm -f b
>> % ls b
>> ls: cannot access b: No such file or directory
>> % cmake -E copy_if_different a b
>> % ls b
>> b
>> % cksum a b
>> 4294967295 0 a
>> 4294967295 0 b
>>
>> Regards,
>>
>> Michael
>>
>>> On Sat, Mar 3, 2012 at 1:20 PM, Hendrik Sattler >> wrote:
>>>
>>>> Am Samstag, 3. März 2012, 21:41:49 schrieb Ajay Panyala:
>>>>> I have a custom target which runs a command to generate
>>>>> a C source file say test1.c
>>>>>
>>>>> ADD_CUSTOM_TARGET(TestGen ALL
>>>>> COMMAND genExec ${PROJECT_SOURCE_DIR}/Main.java
>>>>> DEPENDS ${PROJECT_SOURCE_DIR}/Main.java
>>>>> )
>>>>>
>>>>> And I have a custom command that moves the generated *test1.c *
>>>>> to a new directory inside the build directory.
>>>>>
>>>>> ADD_CUSTOM_COMMAND(
>>>>> TARGET TestGen
>>>>> POST_BUILD
>>>>> COMMAND mv
>>>>> ARGS ${PROJECT_BINARY_DIR}/test1.c ${PROJECT_BINARY_DIR}/tests/
>>>>> )
>>>>>
>>>>> Each time I run make, the custom target is run (since custom targets
>> are
>>>>> always
>>>>> out-of-date). But I want to avoid moving the new test1.c generated each
>>>>> time if build/test1.c is the same as build/tests/test1.c since there
>> are
>>>>> other targets
>>>>> like add_executable and add_library later in the CMakelists file that
>> are
>>>>>  re-built
>>>>> each time since they depend on test1.c
>>>>
>>>> Try "cmake -E copy_if_different ..."
>>>>
>>>> HS
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Transitive library dependencies with parallel builds

2012-03-03 Thread Michael Hertling
On 02/29/2012 05:35 PM, Number Cruncher wrote:
> Do transitive dependencies reduce number of jobs that can be compiled in 
> parallel?
> 
> If I have two libraries A and B, with an executable C, whose 
> dependencies are described by:
> 
>add_library(A ${A_SRC})
> 
>add_library(B ${B_SRC})
>target_link_libraries(B A)
> 
>add_executable(C ${C_SRC})
>target_link_libraries(C B)
> 
> I understand that when *linking* C, the transitive dependency A will be 
> added. However, if I build C in parallel "make -j N", will CMake build 
> libraries A and B simultaneously, or fully compile and link A before 
> starting compilation of B? I.e. just because the link steps are serial 
> dependencies, are the compilation steps? Would it be faster to do:
> 
>add_library(A ${A_SRC})
> 
>add_library(B ${B_SRC})
> 
>add_executable(C ${C_SRC})
>target_link_libraries(C B A)
> 
> Thanks.

Look at the following exemplary project:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(P C)
FILE(WRITE ${CMAKE_BINARY_DIR}/a.c "void a(void){}\n")
FILE(WRITE ${CMAKE_BINARY_DIR}/b.c "void b(void){a();}\n")
FILE(WRITE ${CMAKE_BINARY_DIR}/c.c "int main(void){b(); return 0;}\n")
ADD_LIBRARY(A SHARED a.c)
ADD_LIBRARY(B SHARED b.c)
ADD_EXECUTABLE(C c.c)
IF(TRANSITIVE)
TARGET_LINK_LIBRARIES(B A)
TARGET_LINK_LIBRARIES(C B)
ELSE()
TARGET_LINK_LIBRARIES(C B A)
ENDIF()

Configure with -DTRANSITIVE=ON and inspect CMakeFiles/Makefile2:

CMakeFiles/A.dir/all:
CMakeFiles/B.dir/all: CMakeFiles/A.dir/all
CMakeFiles/C.dir/all: CMakeFiles/B.dir/all

With -DTRANSITIVE=OFF, these lines read:

CMakeFiles/A.dir/all:
CMakeFiles/B.dir/all:
CMakeFiles/C.dir/all: CMakeFiles/A.dir/all
CMakeFiles/C.dir/all: CMakeFiles/B.dir/all

The CMakeFiles/.dir/all targets do:

$(MAKE) -f CMakeFiles/.dir/build.make CMakeFiles/.dir/build

Finally, CMakeFiles/.dir/build in CMakeFiles/.dir/build.make
does build target  completely, i.e. including the linking step.

Thus, the two-part transitive linking with -DTRANSITIVE=ON indeed
completes A before addressing B, so A and B can not be compiled in
parallel. In contrast, the one-part non-transitive linking with -D
TRANSITIVE=OFF allows for A and B to be compiled and even linked in
parallel since they haven't any interdependencies. So, with -j, the
latter is potentially faster than the former, but...

...reconsider what you're about to do: If B actually references A,
you might possibly not want to drop the TARGET_LINK_LIBRARIES(B A)
command. Run "readelf -d libB.so" on both results for -DTRANSITIVE
and you will see the difference. If A and B were static libraries,
CMake would lose the awareness that B must pull in A in the linker
command line.

In short, the answers to your questions are: N/Y, Y and Y.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] avoid rebuilding targets depending on generated source files

2012-03-04 Thread Michael Hertling
On 03/04/2012 01:06 AM, Ajay Panyala wrote:
> Please provide a minimal but complete example for this issue.
> 
> Please find it in the following link
> http://pastie.org/private/pd13u33s9xpfihf2dbzc1q

The following project is a boiled-down version of yours but doesn't
need any programs except for CMake - that's what I actually meant
with "minimal but complete" as I don't have the org.antlr.Tool
Java program:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(P NONE)
SET(CMAKE_VERBOSE_MAKEFILE ON)

SET(GrammarSource ${PROJECT_BINARY_DIR}/src)
FILE(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/src)

ADD_CUSTOM_TARGET(GrammarBuild ALL
COMMAND ${CMAKE_COMMAND} -E echo "\${X}"
> ${GrammarSource}/testLexer.h
COMMAND ${CMAKE_COMMAND} -E echo "\${X}"
> ${GrammarSource}/testLexer.c
COMMAND ${CMAKE_COMMAND} -E echo "\${X}"
> ${GrammarSource}/testParser.h
COMMAND ${CMAKE_COMMAND} -E echo "\${X}"
> ${GrammarSource}/testParser.c
COMMAND ${CMAKE_COMMAND} -E echo "\${X}"
> ${PROJECT_BINARY_DIR}/test.tokens
)

ADD_CUSTOM_COMMAND(TARGET GrammarBuild POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${GrammarSource}/testLexer.h
${PROJECT_BINARY_DIR}/parser/testLexer.h
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${GrammarSource}/testLexer.c
${PROJECT_BINARY_DIR}/parser/testLexer.c
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${GrammarSource}/testParser.h
${PROJECT_BINARY_DIR}/parser/testParser.h
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${GrammarSource}/testParser.c
${PROJECT_BINARY_DIR}/parser/testParser.c
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${PROJECT_BINARY_DIR}/test.tokens
${PROJECT_BINARY_DIR}/parser/test.tokens
)

After configuration, you can run the target by "make X=0" and check the
timestamps by "ls -l --full-time test.tokens parser src". Issuing "make
X=0" again reveals that the copied files aren't rewritten as it happens
after "make X=1". Thus, AFAICS, everything works as expected. Could you
check if the above-noted example also works on your system?

What exactly does not work with your example? You wrote:

>>> I have 4 cmake -E copy_if_different commands, one for each file.
>>> Only the last file is not copied (if similar). [...]

Does this mean that the last file out of four - in fact, your example
handles five files - is not copied *although* the source file and the
destination file are different, i.e. similar but not equal?

You wrote further:

>>> [...] The others are copied
>>> even if they are the same.
>>>
>>> I verfied that they are the same with a diff.

Does this mean that source files are copied *although* they are equal
to their respective destination file? How do you determine that they
have been copied? Do you check the timestamps? With --full-time?

Regards,

Michael

PS: Does org.antlr.Tool write to the source tree? If so: Don't do that.

> On Sat, Mar 3, 2012 at 3:54 PM, Michael Hertling wrote:
> 
>> On 03/04/2012 12:14 AM, Ajay Panyala wrote:
>>> No, it wouldn't; check it out:
>>>
>>> % touch a
>>> % rm -f b
>>> % ls b
>>> ls: cannot access b: No such file or directory
>>> % cmake -E copy_if_different a b
>>> % ls b
>>> b
>>> % cksum a b
>>> 4294967295 0 a
>>> 4294967295 0 b
>>>
>>> It works with one file, but I have 4 files that are generated.
>>> I have 4 cmake -E copy_if_different commands, one for each file.
>>> Only the last file is not copied (if similar). The others are copied
>>> even if they are the same.
>>>
>>> I verfied that they are the same with a diff.
>>>
>>> Any idea what might be happening here ?
>>
>> Please provide a minimal but complete example for this issue.
>>
>> Regards,
>>
>> Michael
>>
>>> On Sat, Mar 3, 2012 at 2:47 PM, Michael Hertling >> wrote:
>>>
>>>> On 03/03/2012 10:36 PM, Ajay Panyala wrote:
>>>>> Try "cmake -E copy_if_different ..."
>>>>>
>>>>> cmake -E copy_if_different build/test1.c build/tests/test1.c
>>>>>
>>>>> That would work when make is run atleast once.
>>>>> When running make for the 1st time test1.c was never
>>>>> copied to build/tests before. So I would be comparing a file with
>>>>> another non-existant file and that would result in an error halting
>>>>> the make process.
>>>>
>>>> No, it wouldn't; check it 

Re: [CMake] avoid rebuilding targets depending on generated source files

2012-03-04 Thread Michael Hertling
On 03/04/2012 08:02 PM, Ajay Panyala wrote:
> The following project is a boiled-down version of yours but doesn't
> need any programs except for CMake - that's what I actually meant
> with "minimal but complete" as I don't have the org.antlr.Tool
> Java program:
> 
> I am sorry. I was mainly trying to cleanup the big CMakeLists file
> I had and removed about 10 different targets - all of which were
> rebuilt because the 5 files (test*.*) were overwritten.
> 
> If you want to try running the test project on your system
> 
> test.g is at http://pastie.org/private/agzor3ibzoa5pom6q31qq
> 
> org.antlr.Tool is at www.antlr.org/download/antlr-3.4-complete.jar
> 
> After configuration, you can run the target by "make X=0" and check the
> timestamps by "ls -l --full-time test.tokens parser src". Issuing "make
> X=0" again reveals that the copied files aren't rewritten as it happens
> after "make X=1". Thus, AFAICS, everything works as expected. Could you
> check if the above-noted example also works on your system?
> 
> It does not work. The files are still overwritten.

Could you run the following shell script in a build tree configured
with the CMakeLists.txt from my previous reply and post the output?

# check.sh:
make X=0 2>&1 > /dev/null
echo "After make X=0 (1):"
echo "---"
echo ""
ls --full-time test.tokens src parser
echo -ne "\n\n"
sleep 3
make X=0 2>&1 > /dev/null
echo "After make X=0 (2):"
echo "---"
echo ""
ls --full-time test.tokens src parser
echo -ne "\n\n"
sleep 3
make X=1 2>&1 > /dev/null
echo "After make X=1:"
echo "---"
echo ""
ls --full-time test.tokens src parser
# End of check.sh

BTW, which CMake version do you use?

Regards,

Michael

PS: Could you set up your e-mail client so that it marks quoted
text in some way? Currently, one can't distinguish between
the lines you are writing and the lines written by others.

> What exactly does not work with your example? You wrote:
> 
>>>> I have 4 cmake -E copy_if_different commands, one for each file.
>>>> Only the last file is not copied (if similar). [...]
> 
> Does this mean that the last file out of four - in fact, your example
> handles five files - is not copied *although* the source file and the
> destination file are different, i.e. similar but not equal?
> 
> Yes the file test.tokens is not copied overwritten since they are
> exactly (diff) similar files. This is the case with the other 4 files as
> well,
> but they are still copied over and rewritten.
> 
> 
> You wrote further:
> 
>>>> [...] The others are copied
>>>> even if they are the same.
>>>>
>>>> I verfied that they are the same with a diff.
> 
> Does this mean that source files are copied *although* they are equal
> to their respective destination file? How do you determine that they
> have been copied? Do you check the timestamps? With --full-time?
> 
> Yes, I do check with ls -l --full-time. Except test.tokens, all the other
> files
> are copied over (rewritten) even though they are exactly the same (diff
> same I mean).
> 
> This is what is confusing me about the behavior of copy_if_different.
> that is why it works only with test.tokens and not others.
> 
> PS: Does org.antlr.Tool write to the source tree? If so: Don't do that.
> 
> Yes, it generates the files in the source dir itself (where test.g is
> present)
> I now modified CMakeLists to copy test.g to the project build folder and
> run it there. The new CMakeLists is at
> 
> http://pastie.org/private/p1yi0l8so9cqimqlywfmhw
> 
> 
> Thank You
> Ajay
> 
> On Sun, Mar 4, 2012 at 12:52 AM, Michael Hertling wrote:
> 
>> On 03/04/2012 01:06 AM, Ajay Panyala wrote:
>>> Please provide a minimal but complete example for this issue.
>>>
>>> Please find it in the following link
>>> http://pastie.org/private/pd13u33s9xpfihf2dbzc1q
>>
>>
> 
> 
>> The following project is a boiled-down version of yours but doesn't
>> need any programs except for CMake - that's what I actually meant
>> with "minimal but complete" as I don't have the org.antlr.Tool
>> Java program:
>>
>> CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
>> PROJECT(P NONE)
>> SET(CMAKE_VERBOSE_MAKEFILE ON)
>>
>> SET(GrammarSource ${PROJECT_BINARY_DIR}/src)
>> FILE(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/src)
>>
>> ADD_CUSTOM_TARGET(GrammarBuild ALL
>>COMMAND ${CMAKE_COMMA

Re: [CMake] avoid rebuilding targets depending on generated source files

2012-03-04 Thread Michael Hertling
On 03/05/2012 01:59 AM, Ajay Panyala wrote:
> I use cmake version 2.8.3.
> 
> If I use CMakeLists from your previous reply, it avoids overwriting files
> when X=0.
> I have attached the output of your script.

Actually, this is exactly what I was talking about: The second "make
X=0" invocation rewrites the source files - i.e., they receive a new
timestamp - but their contents do not change. Thus, the destination
files in the parser directory are *not* touched by the second "make
X=0", and this can be seen clearly by reference to the timestamps.
It's the subsequent "make X=1" which provides for a new content of
the source files and makes "cmake -E copy_if_different" copy the
sources to the destinations. That's why I said everything works
as expected, but you wrote:

>>> It does not work. The files are still overwritten.

So, my question again: What exactly does not work?

I.e., does "cmake -E copy_if_different"

- copy a file although the destination exists
  and has the same content as the source, or

- not copy a file although the destination does not
  exist or does not have the same content as the source?

> It works for my CMakeLists as well now. What I did now is
> 
> if(${GrammarSource}/test.g IS_NEWER_THAN ${PROJECT_BINARY_DIR}/test.g)
> ADD_CUSTOM_TARGET(...)
> ADD_CUSTOM_COMMAND(...)
> 
> i.e I am totally avoiding the process of rebuilding the test.g file and
> copying the generated files to build/parser
> *IF* test.g has not been modified.

...and if test.g is once modified, you won't have a custom target which
regenerates the source files and copies them to the parser directory -
I'm pretty sure this is not what you intend. Recall the difference
between configuration time and build time in CMakified projects.

> PS: Could you set up your e-mail client so that it marks quoted
>text in some way? Currently, one can't distinguish between
>the lines you are writing and the lines written by others.
> 
> Sorry. I did not realize that. I use gmail and when I checked my sent
> emails,
> quoted text appears to be clearly marked. Is the quoted text in this email
> marked properly.

Yes, it is.

Regards,

Michael

> On Sun, Mar 4, 2012 at 4:05 PM, Michael Hertling wrote:
> 
>> On 03/04/2012 08:02 PM, Ajay Panyala wrote:
>>> The following project is a boiled-down version of yours but doesn't
>>> need any programs except for CMake - that's what I actually meant
>>> with "minimal but complete" as I don't have the org.antlr.Tool
>>> Java program:
>>>
>>> I am sorry. I was mainly trying to cleanup the big CMakeLists file
>>> I had and removed about 10 different targets - all of which were
>>> rebuilt because the 5 files (test*.*) were overwritten.
>>>
>>> If you want to try running the test project on your system
>>>
>>> test.g is at http://pastie.org/private/agzor3ibzoa5pom6q31qq
>>>
>>> org.antlr.Tool is at www.antlr.org/download/antlr-3.4-complete.jar
>>>
>>> After configuration, you can run the target by "make X=0" and check the
>>> timestamps by "ls -l --full-time test.tokens parser src". Issuing "make
>>> X=0" again reveals that the copied files aren't rewritten as it happens
>>> after "make X=1". Thus, AFAICS, everything works as expected. Could you
>>> check if the above-noted example also works on your system?
>>>
>>> It does not work. The files are still overwritten.
>>
>> Could you run the following shell script in a build tree configured
>> with the CMakeLists.txt from my previous reply and post the output?
>>
>> # check.sh:
>> make X=0 2>&1 > /dev/null
>> echo "After make X=0 (1):"
>> echo "---"
>> echo ""
>> ls --full-time test.tokens src parser
>> echo -ne "\n\n"
>> sleep 3
>> make X=0 2>&1 > /dev/null
>> echo "After make X=0 (2):"
>> echo "---"
>> echo ""
>> ls --full-time test.tokens src parser
>> echo -ne "\n\n"
>> sleep 3
>> make X=1 2>&1 > /dev/null
>> echo "After make X=1:"
>> echo "---"
>> echo ""
>> ls --full-time test.tokens src parser
>> # End of check.sh
>>
>> BTW, which CMake version do you use?
>>
>> Regards,
>>
>> Michael
>>
>> PS: Could you set up your e-mail client so that it marks quoted
>>text in some way? Currently, one can't distinguish between
&g

Re: [CMake] Question regarding source tree structure and how to find libraries easily within that structure

2012-03-05 Thread Michael Hertling
On 03/04/2012 11:01 AM, Andreas Guther wrote:
> Hello,
> 
> thanks for the responses. The problem I have is, that we have more than one 
> application in the directory. So if I put an CMakeLists.txt in the Src 
> directory I do not have the choice (only by options). I would prefer a 
> solution where I change into the application directory I want to build and 
> create workspace etc. from there. The created workspace should then also 
> build all necessary libraries for the application.
> 
> Any ideas on this?

In Application_1/CMakeLists.txt, e.g., do:

SET(Library_1_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../Library_1
CACHE PATH "Library_1 source directory")
...
ADD_SUBDIRECTORY(${Library_1_SOURCE_DIR} Library_1)

Do the same for Library_2 and every other prerequisite project which

- has a source tree external to Application_1
- you want to be built along with the latter

and finally: TARGET_LINK_LIBRARIES(Application_1 Library_1 ...)

If the fallback value of Library_1_SOURCE_DIR once doesn't suit, you
can set it on the command line or in the GUI before (re)configuring.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Functions inherit parent variables?

2012-03-05 Thread Michael Hertling
On 03/05/2012 10:43 AM, Johannes Zarl wrote:
> On Saturday 03 March 2012, 02:29:05, Robert Dailey wrote:
>> Well you're really comparing apples to oranges. C++ nested scoping rules
>> really have nothing to do with two separate functions sharing scoped
>> variables. It doesn't even really serve as a good analogy, so I can't be
>> 100% certain what you were trying to tell me ;-)
>>
>> However I appreciate your response. I really just wanted to make sure this
>> isn't a bug, because the way the called function inherits the calling
>> function's local variables is an unusual behavior for a language, at least
>> in my experience. So I had to think twice about it ;)
> 
> As Michael said: This behaviour is not at all unusual for scripting 
> languages, 
> but there is not really a One True Way: In Tcl you have to import variables 
> explicitly, in bourne shell you overwrite values in the parent scope, ...
> It's just a property of the language that you have to know about.
> 
> So in the CMake language you should be aware that the parent scope is visible 
> inside a function, but the function does not affect the parent scope unless 
> explicitly stated:
> 
> function( test1 )
>   set( var_a "var_a inner1" )
>   message( "test1(): var_a: ${var_a}" )
> endfunction()
> 
> function( test2 )
>   set( var_a "var_a inner2" PARENT_SCOPE )
>   message( "test2(): var_a: ${var_a}" )
> endfunction()
> 
> set( var_a "var_a outer" )
> test1()
> message( "var_a: ${var_a}" )
> test2()
> message( "var_a: ${var_a}" )
> 
> --- Output:
> test1(): var_a: var_a inner1  
>   
>   
>  
> var_a: var_a outer
>   
>   
>  
> test2(): var_a: var_a outer
> var_a: var_a inner2
> 
> Disclaimer:  Actually, this was surprising to me. I was thinking that 
> PARENT_SCOPE sets the value in the current scope plus the parent scope, not 
> in 
> the parent scope only. I guess this could be stated in the documentation more 
> clearly...

IMO, the documentation of the PARENT_SCOPE flag is sufficiently clear:

"If PARENT_SCOPE is present, the variable will be set in the scope
*above* the current scope. Each new directory or function creates
a new scope. This command will set the value of a variable into
the *parent* directory or *calling* function (whichever is
applicable to the case at hand)."

Not a word about setting anything in the current scope, and as for
me, the explanation of CACHE/INTERNAL/FORCE, e.g., is rather vague.

Anyway, an additional remark on this thread's topic: CMake's functions
know neither return values nor pointers or references to variables, so
this kind of access from the callee to the caller's scope is the only
mechanism to transfer data from the the former to the latter, except
for properties and global variables which are often less convenient.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] failing target

2012-03-05 Thread Michael Hertling
On 03/05/2012 05:59 PM, Andrea Crotti wrote:
> I'm having the following behaviour, and I can't quite understand the 
> error message:
> 
> ..
> Built target psi.utility_install
> ..
> make[3]: *** No rule to make target `psi.utility_install', needed by 
> `CMakeFiles/install_all_eggs'.  Stop.
> make[2]: *** [CMakeFiles/install_all_eggs.dir/all] Error 2
> make[1]: *** [CMakeFiles/unzip_all_eggs.dir/rule] Error 2
> make: *** [unzip_all_eggs] Error 2
> 
> 
> So first it builds successfully psi.utility_install and then it 
> complains that there are no rules to make it.
> Who is right then and what could cause such a problem?
> 
> This is happening on a strange Linux machine, on Windows with MinGW it's 
> working (strangely)..

Could you boil down your project to a minimal and self-sufficient
example which exhibits this behavior for further investigations?

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] How to make package depend on tests?

2012-03-06 Thread Michael Hertling
On 03/06/2012 12:36 AM, Oliver kfsone Smith wrote:
> I have test and package configurations on my project, I want:
> 
>  cmake .
>  make package
> 
> to run force injection of the "test" target prior to building the 
> package target.
> 
> Can it be done? How? :)

By filing a solution to [1]. ;-)

In the meantime, you might provide a target on your own:

ADD_CUSTOM_TARGET(test_and_pack
  COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target test
  COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target package
)

Regards,

Michael

[1] http://public.kitware.com/Bug/view.php?id=8438
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] POST_BUILD & ALL_BUILD

2012-03-06 Thread Michael Hertling
On 03/06/2012 02:34 AM, Christopher Piekarski wrote:
> Hello All,
> 
> I am trying to attach a custom POST_BUILD command to the ALL_BUILD target.
> I've tried adding the following at the bottom of my root CMakeLists.txt
> file but the Post Event never shows up in Visual Studio. I have been able
> to get it to work for sub projects, just not ALL_BUILD. Has anyone gotten
> this to work?
> 
> add_custom_command(TARGET ALL_BUILD
> POST_BUILD
> COMMAND "python27.exe brand.py"
> COMMENT "Branding VS debug build"
> )

AFAIK, that's not possible ATM, see also [1].

Instead, you could use a custom target

ADD_CUSTOM_TARGET(brand ALL
   COMMAND python27.exe brand.py
   COMMENT "Branding VS debug build"
)
ADD_DEPENDENCIES(brand target<1> ... target)

and list your project's targets as prerequisites in order to ensure
that "brand" is built last. For convenience, you might consider to
provide wrappers for ADD_LIBRARY() and ADD_EXECUTABLE() which add
the respective target to a global property, and use the latter's
value for the above-noted ADD_DEPENDENCIES() at the end of your
top-level CMakeLists.txt.

Regards,

Michael

[1] http://public.kitware.com/Bug/view.php?id=8438
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] failing target

2012-03-06 Thread Michael Hertling
On 03/06/2012 12:21 PM, Andrea Crotti wrote:
> On 03/06/2012 07:23 AM, Michael Hertling wrote:
>> On 03/05/2012 05:59 PM, Andrea Crotti wrote:
>>> I'm having the following behaviour, and I can't quite understand the
>>> error message:
>>>
>>> ..
>>> Built target psi.utility_install
>>> ..
>>> make[3]: *** No rule to make target `psi.utility_install', needed by
>>> `CMakeFiles/install_all_eggs'.  Stop.
>>> make[2]: *** [CMakeFiles/install_all_eggs.dir/all] Error 2
>>> make[1]: *** [CMakeFiles/unzip_all_eggs.dir/rule] Error 2
>>> make: *** [unzip_all_eggs] Error 2
>>>
>>>
>>> So first it builds successfully psi.utility_install and then it
>>> complains that there are no rules to make it.
>>> Who is right then and what could cause such a problem?
>>>
>>> This is happening on a strange Linux machine, on Windows with MinGW it's
>>> working (strangely)..
>> Could you boil down your project to a minimal and self-sufficient
>> example which exhibits this behavior for further investigations?
>>
>> Regards,
>>
>> Michael
>> --
>>
> 
> That's quite tricky unfortunately, I hoped that someone saw something 
> similar already and
> could give me a hint..
> Anyway that machine is not a priority at the moment I'll just see later 
> when it's more stable.

Could you post the lines which define those targets psi.utility_install
and install_all_eggs, or is this quite tricky, too? Do these lines stem
from the same CMakeLists.txt? IIRC, the "no rule to make... needed by"
error occurs when there's something wrong with the DEPENDS clause of
ADD_CUSTOM_COMMAND/TARGET().

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] failing target

2012-03-06 Thread Michael Hertling
On 03/06/2012 02:47 PM, Andrea Crotti wrote:
> On 03/06/2012 01:45 PM, Michael Hertling wrote:
>>
>> Could you post the lines which define those targets psi.utility_install
>> and install_all_eggs, or is this quite tricky, too? Do these lines stem
>> from the same CMakeLists.txt? IIRC, the "no rule to make... needed by"
>> error occurs when there's something wrong with the DEPENDS clause of
>> ADD_CUSTOM_COMMAND/TARGET().
>>
>> Regards,
>>
>> Michael
> 
> Well I think it's something related to the platform, because both on my 
> Linux
> box and windows it works perfectly.
> 
> This is the interesting part anyway:
> 
> foreach(egg ${egg_list})
>#TODO: now I need to replace the name with only the last part of the path
>get_filename_component(egg_name ${egg} NAME)
>set(egg_install ${egg_name}_install)
># generate the list of targets to create more easily dependencies
>list(APPEND egg_install_list ${egg_install})
> 
>add_custom_target(${egg_install}
>  COMMAND ${PYTHON_EXECUTABLE} setup.py -q bdist_egg -d 
> ${EGG_BUILD_DIRECTORY}
>  WORKING_DIRECTORY ${egg}
>)
> 
> endforeach()
> 
> add_custom_target(install_all_eggs
>DEPENDS ${egg_install_list}
> )
> 
> #TODO: add this target to the dependencies of run and packing if it works
> add_custom_target(unzip_all_eggs
># unzip the eggs and clean up the zips
>COMMAND ${PYTHON_EXECUTABLE} ${UNZIP_SCRIPT} ${EGG_BUILD_DIRECTORY} 
> ${EGG_UNZIPPED_DIRECTORY}
># copy the two run files in the final destination
>COMMAND ${CMAKE_COMMAND} -E copy ${EGG_BUILD_DIRECTORY}/${RUNNER} 
> ${EGG_UNZIPPED_DIRECTORY}/${RUNNER}
>COMMAND ${CMAKE_COMMAND} -E copy ${EGG_BUILD_DIRECTORY}/${C_RUNNER} 
> ${EGG_UNZIPPED_DIRECTORY}/${C_RUNNER}
> 
>DEPENDS install_all_eggs
> )
> 
> 
> sdo the targets are generated at cmake-time reading from a file and then 
> there are few more targets that depend on
> all of them.
> 
> Is there anything wrong in this part?

Yes, the DEPENDS clause of ADD_CUSTOM_TARGET() is only for *file*
dependencies, but you use it for *target* dependencies. According
to the documentation of ADD_CUSTOM_TARGET():

"Dependencies listed with the DEPENDS argument may reference files
and outputs of custom commands created with add_custom_command()
in the same directory (CMakeLists.txt file)."

"Use ADD_DEPENDENCIES to add dependencies to or from other targets."

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] transitive linking with separate projects

2012-03-06 Thread Michael Hertling
On 03/06/2012 02:47 PM, Alexander Dahl wrote:
> Hei hei, 
> 
> we faced a build problem with transitive linking of separate projects
> where I can't find the right solution on my own. I hope someone can give
> me a hint. I prepared a test case with two libraries libfoo and libbar
> and an application baz. libfoo is on his own, libbar calls a function
> from libfoo and baz calls the function from libbar calling libfoo. So
> the dependencies are like this:
> 
> baz -> libbar -> libfoo
> 
> baz doesn't need to know of libfoo because it just calls libbar, so I
> thought.
> 
> Now the projects are separated and both libraries come with cmake
> package configuration files. For linking libfoo in libbar I do the
> following:
> 
> find_package(FOO)
> target_link_libraries(BAR_SRC foo-shared)
> 
> foo-shared is the target libfoo exports via cmake package
> configuration. This works and ldd shows libbar is correctly linked
> against libfoo.
> 
> Now when compiling baz I more or less do the same:
> 
> find_package(BAR)
> target_link_libraries(BAZ_SRC bar-shared)
> 
> However building baz fails with the following error:
> 
> % make
> [100%] Building C object src/CMakeFiles/baz.dir/baz.c.o
> Linking C executable baz
> /usr/bin/ld: cannot find -lfoo-shared
> collect2: ld returned 1 exit status
> make[2]: *** [src/baz] Fehler 1
> make[1]: *** [src/CMakeFiles/baz.dir/all] Fehler 2
> make: *** [all] Fehler 2
> 
> It seems like cmake tries to link against libfoo here but does not know
> anything about it. If I add find_package(FOO) to baz obviously the
> target is imported from libfoo cmake package files. The question is, if
> I know nothing about the requirements of libbar and want to avoid adding
> find_package statements for those requirements to baz, how would I do
> this?
> 
> I put all the code on GitHub, so if someone maybe could have a look?
> 
> https://github.com/LeSpocky/libfoo
> https://github.com/LeSpocky/libbar
> https://github.com/LeSpocky/baz
> 
> Greets
> Alex

If you run "grep foo -r /lib/cmake/bar", you will
see only one line which informs the user of bar-config.cmake that the
bar-shared target has a prerequisite name foo-shared, but there is no
more information. For this reason, it's passed as -lfoo-shared to the
linker. You need to include foo-targets.cmake in bar-config.cmake in
order to make the necessary information available, e.g. by

# libbar/bar-config.cmake.in:
INCLUDE(@FOO_CONFIG@)
get_filename_component(_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_prefix "${_dir}/../../.." ABSOLUTE)
include("${_dir}/@PROJECT_NAME@-targets.cmake")
set(BAR_INCLUDE_DIRS "${_prefix}/include/@PROJECT_NAME@")

or possibly better:

# libbar/bar-config.cmake.in:
FIND_PACKAGE(FOO PATHS @FOO_DIR@ NO_DEFAULT_PATH)
get_filename_component(_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_prefix "${_dir}/../../.." ABSOLUTE)
include("${_dir}/@PROJECT_NAME@-targets.cmake")
set(BAR_INCLUDE_DIRS "${_prefix}/include/@PROJECT_NAME@")

This will make the user of bar-config.cmake include the same foo-
config.cmake and, thus, foo-targets.cmake that bar's CMakeLists.txt
has included, too. See also FIND_PACKAGE()'s NAMES / CONFIGS clauses.

BTW, find modules / config files should provide a *_LIBRARIES variable
even if they use imported targets, e.g.: SET(FOO_LIBRARIES foo-shared)

Regards,

Michael

PS: The baz project on GitHub only contains a README.
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] transitive linking with separate projects

2012-03-07 Thread Michael Hertling
On 03/07/2012 11:29 AM, Alexander Dahl wrote:
> Hello Michael, 
> 
> Am 2012-03-06 16:46, schrieb Michael Hertling:
>> or possibly better:
>>
>> # libbar/bar-config.cmake.in:
>> FIND_PACKAGE(FOO PATHS @FOO_DIR@ NO_DEFAULT_PATH)
> 
> I used
> 
> FIND_PACKAGE(FOO 0.1.0 REQUIRED)
> 
> in the package config file now, which works, too.

Actually, FIND_PACKAGE(FOO PATHS @FOO_DIR@ NO_DEFAULT_PATH) is meant
to ensure that bar-config.cmake loads the *same* foo-config.cmake as
bar's CMakeLists.txt has before. Possibly, it's even the best to use
exactly the same parameters - apart from PATHS and NO_DEFAULT_PATH -
i.e., version, components, external variables etc., in order to
guarantee that really the same foo-targets.cmake is included.

>> BTW, find modules / config files should provide a *_LIBRARIES variable
>> even if they use imported targets, e.g.: SET(FOO_LIBRARIES foo-shared)
> 
> I added this. Let me guess, this is for convenience with find rules
> using the same variables?

Yes, in this way, it works with imported targets as well as full paths.

>> PS: The baz project on GitHub only contains a README.
> 
> I forgot to push this one.
> 
> Thanks very much, I guess this solves this kind of problem with my
> packages. :-)

See also [1].

Regards,

Michael

[1] http://public.kitware.com/Bug/view.php?id=12588
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Forcibly run 'moc' on Qt files that are NOT part of the build

2012-03-07 Thread Michael Hertling
On 03/07/2012 04:10 PM, Michael Jackson wrote:
> In an effort to speed up the build of a project that uses Qt (and moc) I 
> tried an alternate approach with the moc files. Normally I use the basic idea 
> of gathering the headers that need to be "moc'ed" and feed those to moc with 
> this type of CMake Code:
> 
> QT4_WRAP_CPP( FilterWidgets_Generated_MOC_SRCS ${QFilterWidget_HDRS} 
> ${FilterWidget_GEN_HDRS}) 
> 
> The in the Add_Executable(...) call include the 
> ${FilterWidgets_Generated_MOC_SRCS} variable to the list of sources. In my 
> project I have at least 30 auto-generated files which all get moc'ed. That 
> gives me an additional 60 compiled files. So I tried the idea of #include 
> "moc_[some_file.cxx]" in each of the auto-generated .cpp files for each 
> Widget. This would cut the number of files compiled in half. The issue is 
> that since they are being #include'ed in the .cpp files then they do NOT need 
> to be compiled themselves so I took the ${FilterWidgets_Generated_MOC_SRCS} 
> out of the list of sources in the add_executable() call. What happened is 
> that CMake did NOT run moc on those headers because there were now NOT 
> included in the build.
> 
>  So for that version of the cmake code I have something like this:
> 
> QT4_WRAP_CPP( FilterWidgets_Generated_MOC_SRCS ${FilterWidget_GEN_HDRS}) 
> QT4_WRAP_CPP( FilterWidgets_MOC_SRCS ${QFilterWidget_HDRS} )
> 
> Is there a way to forcibly run the moc step even if the resulting source 
> files are NOT directly included in the add_executable? Custom_Command? 
> Add_Depends?

AFAIK, the QT4_WRAP_CPP() macro is essentially a wrapper around ADD_
CUSTOM_COMMAND() which accumulates the latter's OUTPUT files in the
former's first parameter. Thus, you might try

QT4_WRAP_CPP(not2compile ...)
ADD_CUSTOM_TARGET(mocem DEPENDS ${not2compile})
ADD_DEPENDENCIES(... mocem)

but I haven't tested this.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Code and API review request for Qt5 CMake files

2012-03-09 Thread Michael Hertling
On 03/05/2012 02:04 AM, Stephen Kelly wrote:
> 
> Michael Hertling wrote:
> 
>>>> * Currently there is no Qt5Config.cmake.
>>>> Such a thing could probably exist and use the FIND_COMPONENTS to find
>>>> what was requested. [...]
> 
> Hi there,
> 
> Thank you for your insights on this issue. Do you have any other insights 
> into other issues I raised in the original post?

No, I just picked out the Qt5Config.cmake ones. Perhaps later...

>> Absolutely, I would greatly appreciate a well-designed and component-
>> aware Qt5Config.cmake. 
> 
> Yes. This thread confirms though that it is not a simple issue as I wrote 
> before :)

Indeed, component-aware find modules / config files are significantly
more complicated than component-unaware ones. Typical questions are:

- Accumulation of result variables
- Handling of unknown components
- Searching unrequested components
- Interpretation of *_FOUND variable
- Untouched *_*_FOUND variables
- Impact of REQUIRED/QUIET

>> In general, there might be reasons why a multi-
>> component package's components that are to be used together should not
>> be requested in separate FIND_PACKAGE() invocations, see [1] and look
>> for package X with components A and B. However, I don't know if Qt5
>> will be the first example of that kind.
> 
> Your exact example is not covered by the Qt5 situation as far as I can tell. 
> However, similar issues already crop up (with Qt4 based systems). Can you 
> confirm whether you are aware of the issues around code like this regarding 
> the use of -DQT_GUI_LIB with the foo target so I know if I need to explain 
> it and whether we are on the same page? :
> 
> find_package(Qt4 REQUIRED Gui Test)
> include(${QT_USE_FILE})
> add_executable(bar ${QT_QTCORE_LIBRARIES} ${QT_QTGUI_LIBRARIES})
> add_executable(foo ${QT_QTCORE_LIBRARIES} ${QT_QTTEST_LIBRARIES})

Do you mean the appearance of -DQT_GUI_LIB during foo's compilation
although the latter doesn't need it? If so, this is a, say, inverse
version of what I had in mind: An unnecessary -D, possibly enabling
undesired code in headers during the compilation. If not, could you
explain it once more in another way? ;-)

Actually, my general consideration in this regard is: There might be
quite subtle relations among a package's components, beyond the usual
B-needs-A one. Find modules and config files suit perfectly to handle
such relations, but in order to do this, they must be supplied with
sufficient information. So, all components going to be used together
should be requested together, and if one wants to use a different set
of components, one should request them with a separate FIND_PACKAGE()
call. In this way, a find module / config file is equipped to provide
optimal results, i.e. the exact settings to enable the requested set
of components - no more, no less. In fact, settings like QT_GUI_LIB
made me reason about this issue for the first time, though I still
do not know a real-life example for a -D which is related solely
to a combination of components, or anything else of that kind.

>> Referring to Qt5_XYZ_FOUND alone is not reliable because this variable
>> wouldn't have received a definite value if Qt5Config.cmake hasn't been
>> found by FIND_PACKAGE(). 
> 
> I don't actually see the problem with checking Qt5_XYZ_FOUND. Unset 
> variables are well defined as false in the if() command. Maybe I 
> misunderstand you?

Maybe. ;-) What ensures the variables had already been unset before
FIND_PACKAGE() was invoked? If they had evaluated as TRUE - for what-
ever reason - and FIND_PACKAGE() fails to load Qt5Config.cmake, they
will still be TRUE afterwards although Qt5 has not been found at all.

IMO, if FIND_PACKAGE() fails to locate a package, one shouldn't rely
on the assumption that any variable except *_FOUND has a reasonable
value. Thus, in order to play safe, one should access the variables
only after checking the package's successful detection, e.g. like:

IF(Qt5_FOUND AND Qt5_Xml_FOUND)

This consideration is one of my major objections against the proposal
w.r.t. permitting config files to set *_FOUND by themselves. As it is
suggested, it would result in *_FOUND set to FALSE if just a component
is missing, so one can not use *_FOUND anymore to detect the package's
presence. Instead, one would need to apply other means, e.g. the *_DIR
variable set by FIND_PACKAGE() in config mode, but that doesn't work in
module mode, AFAIK. Anyway, I am afraid this will complicate the usage
of FIND_PACKAGE() and promote the inconsistencies among find modules
and config files.

>> I.e., the user would refer to this variable's
>> value before the FIND_PACKAGE() call; probably, that's not expected.
> 
> Why would the user refer to Qt5_Xml_FOUND b

Re: [CMake] top level make

2012-03-11 Thread Michael Hertling
On 03/11/2012 10:27 PM, Totte Karlsson wrote:
> Hi,
> My project depends on several third party libraries, e.g. vtk. I wonder, if 
> it 
> is possible to setup using CMake so that when building my project, necessary 
> third party libs are built as well.
> 
> Or is it advisable to keep it separate?
> 
> My src folder structure is
> top\
> -\mySource
> -\ThirdParty\vtk
> -\ThirdParty\SomeOther libs
> 
> Cheers,
> Totte

See the ExternalProject module [1].

Regards,

Michael

> [1] http://www.cmake.org/cmake/help/cmake-2-8-docs.html#module:ExternalProject
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Operator Precedence

2012-03-12 Thread Michael Hertling
On 03/12/2012 07:32 PM, Robert Dailey wrote:
> What is the precedence for logical operators (specifically in IF
> conditions)?
> 
> Consider: STREQUAL, AND, OR (plus any others)

Documentation of IF():

"...there is a traditional order of precedence. Parenthetical
expressions are evaluated first followed by unary operators such as
EXISTS, COMMAND, and DEFINED. Then any EQUAL, LESS, GREATER, STRLESS,
STRGREATER, STREQUAL, MATCHES will be evaluated. Then NOT operators and
finally AND, OR operators will be evaluated."

Documentation of WHILE():

"The condition is evaluated using the same logic as the if command."

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] CMake Linking Error

2012-03-12 Thread Michael Hertling
On 03/08/2012 05:40 PM, buzz clay wrote:
> Hi,
> 
> I have not been able to find the answer to my current problem so I thought
> I'd try a new post. Before diving into the details, please be aware that
> the code I am writing compiles/runs perfectly with a personal Makefile I
> wrote.
> 
> My code is written in C++ and has many different class definitions. To run
> different simulations some classes may or may not have actual objects
> created. However, there are other portions of the code that specifically
> reference functions from nearly all classes (although this code might not
> actually be used because the object was never created). The linking errors
> that I am facing arise when I do not make an object of a given class. Other
> parts of the code need to be aware that the class exists, even if an object
> was never made. Although this seems like it would be a result of not
> including the appropriate header files, I assure you they are correct! For
> some reason, if I do not make an object of a given class cmake "ignores"
> the class and when it comes time to link everything together I get the
> following error:
> 
> Linking CXX executable collision
> Output/libOutput.a(Output.cpp.o): In function
> `Output::Output(std::vector >*,
> std::vector >*)':
> Output.cpp:(.text+0x379): undefined reference to `SWall::getY2()'
> Output.cpp:(.text+0x391): undefined reference to `SWall::getX2()'
> Output.cpp:(.text+0x3a9): undefined reference to `SWall::getY1()'
> Output.cpp:(.text+0x3c1): undefined reference to `SWall::getX1()'
> collect2: ld returned 1 exit status
> make[2]: *** [collision] Error 1
> make[1]: *** [CMakeFiles/collision.dir/all] Error 2
> make: *** [all] Error 2
> 
> PLEASE NOTE: If in my main.cpp file I simply create an SWall object and
> never use it, the errors go away and everything works perfectly. I simply
> do not understand why cmake would care whether or not I actually make an
> object of a given class!
> 
> The following is my CMakeLists.txt file in the highest level directory:
> 
> cmake_minimum_required(VERSION 2.8)
> 
> project(collision CXX)
> 
> add_subdirectory(Extraneous)
> add_subdirectory(Output)
> add_subdirectory(Simulation)
> add_subdirectory(CollisionObject)
> 
> add_definitions(-ansi -Wall -O2)
> 
> add_executable(collision test.cpp)
> 
> target_link_libraries(collision Simulation)
> target_link_libraries(collision PriorityQueue)
> target_link_libraries(collision Event)
> target_link_libraries(collision Ball)
> target_link_libraries(collision SWall)
> target_link_libraries(collision Circle)
> target_link_libraries(collision Output)
> target_link_libraries(collision SimpleMath)
> 
> INSTALL(PROGRAMS ${CMAKE_BINARY_DIR}/collision DESTINATION
> ${CMAKE_SOURCE_DIR})
> 
> All of the lower level directories simply had add_library(
> ) in the CMakeLists.txt file. [...]

I.e., they don't have TARGET_LINK_LIBRARIES() commands? If so, CMake
can't know that "Output" must be linked against "SWall", and in your
final link command line, the former appears behind the latter --> un-
defined references. Express all your targets' immediate dependencies
via TARGET_LINK_LIBRARIES(), and drop the mediate ones if there are
any; CMake figures them out by itself.

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Using cmake to build & link to autotools based project

2012-03-13 Thread Michael Hertling
On 03/13/2012 10:10 AM, Kurien Mathew wrote:
> Hello,
> 
> I have a solution (collection of projects) that is built using cmake. In this 
> solution some projects depend on 3rd party projects that use gnu autotools. I 
> would like to build and link to these autotools based projects from the cmake 
> build.
> 
> Where can I find additional information on this topic?
> 
> Thanks
> Kurien

http://www.cmake.org/cmake/help/cmake-2-8-docs.html#module:ExternalProject

http://www.kitware.com/products/html/BuildingExternalProjectsWithCMake2.8.html

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Code and API review request for Qt5 CMake files

2012-03-13 Thread Michael Hertling
On 03/10/2012 02:25 PM, Alexander Neundorf wrote:
> On Friday 09 March 2012, Michael Hertling wrote:
>> On 03/05/2012 02:04 AM, Stephen Kelly wrote:
> ...
>>> I don't actually see the problem with checking Qt5_XYZ_FOUND. Unset
>>> variables are well defined as false in the if() command. Maybe I
>>> misunderstand you?
>>
>> Maybe. ;-) What ensures the variables had already been unset before
>> FIND_PACKAGE() was invoked? If they had evaluated as TRUE - for what-
>> ever reason - and FIND_PACKAGE() fails to load Qt5Config.cmake, they
>> will still be TRUE afterwards although Qt5 has not been found at all.
>>
>> IMO, if FIND_PACKAGE() fails to locate a package, one shouldn't rely
>> on the assumption that any variable except *_FOUND has a reasonable
>> value. Thus, in order to play safe, one should access the variables
>> only after checking the package's successful detection, 
> 
> Yes, exactly :-)

It's very good there's a consensus in this respect. ;-)

> (...which would be the case with the "set _FOUND only TRUE if all components 
> have been found).

Only in the successful case; in the failing case, *_FOUND would not
provide any information about the package's presence. Anyway, your
proposal stated below is capable to address this issue, AFAICS.

>> e.g. like:
>>
>> IF(Qt5_FOUND AND Qt5_Xml_FOUND)
> 
> See the other thread
> With a potential OPTIONAL_COMPONENTS parameters you could do:
> 
> find_package(Qt5 COMPONENTS QtXml)
> and checking Qt5_FOUND would be enough.
> 
> If you do 
> find_package(Qt5 COMPONENTS QtXml OPTIONAL_COMPONENTS QtFoo)
> you would have to check both Qt5_FOUND and Qt5_QtFoo_FOUND.

This sounds quite attractive; I'll answer to it on the other thread.

>> This consideration is one of my major objections against the proposal
>> w.r.t. permitting config files to set *_FOUND by themselves. 
> 
> Here I object.
> This is necessary.
> Let's say one Config file depends on another one and does
> find_package(TheOtherPackage NO_MODULE)
> 
> If TheOtherPackage is not found, it must be possible for the calling Config 
> file to indicate that, although the Config file has been found, the package 
> is 
> not usable. because its dependencies have not been found.

This is a very good point. Until now, I presumed that a config file
contains the necessary information about its package's prerequisites
in a hard-coded manner, so it does not need to invoke FIND_PACKAGE().
Usually, that's possible since the information is available already
at configuration time. Allowing config files to call FIND_PACKAGE()
would surely add a certain flexibility, but it also bears a risk: A
successfully configured/built/installed package might fail at deploy
time because of an unavailable prerequisite that has been available
once before. If one is generally aware of this risk and willing to
accept it, I'm fine with it, too.

One or two thoughts and another cup of coffee later, I think that
allowing a config file to set *_FOUND by itself can actually be a
benefit, so my concerns about that are pretty much dispelled. :-)

Regards,

Michael
--

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://www.cmake.org/mailman/listinfo/cmake


Re: [CMake] Code and API review request for Qt5 CMake files

2012-03-13 Thread Michael Hertling
On 03/05/2012 01:35 AM, Stephen Kelly wrote:
> Michael Hertling wrote:
> 
>> Suppose the Qt folks decide that Qt5's core module doesn't need to
>> be explicitly requested because it is prerequisite for everything
>> else.
> 
> Just to disseminate information here, this is already the case.
> 
> You can currently do this:
> 
> find_package(Qt5Declarative)
> include_directories(${Qt5Declarative_INCLUDE_DIRS})
> add_definitions(${Qt5Declarative_DEFINITONS})
> target_link_libraries(foo ${Qt5Declarative_LIBRARIES})
> 
> Each find_package finds its dependencies and adds its dependencies values to 
> its own variables. So already, the core module (and in the above example, 
> the gui module) don't need to be explicitly mentioned.

That's not what I had in mind. AFAICS, the Qt5 modules' config files
are all single-component, and of course, they are expected to enable
all prerequisites necessary to enable their respective module.

What I thought of is: Suppose there's a comprehensive multi-component
Qt5Config.cmake which does not provide a Qt5Core component explicitly
because the latter is silently enabled anyway. So, FIND_PACKAGE(Qt5)
would yield solely Qt5Core, and FIND_PACKAGE(Qt5 COMPONENTS Qt5Gui)
would yield Qt5Gui and Qt5Core, e.g. Now, if Qt5_FOUND is allowed to
be FALSE just because Qt5Gui is missing, one can't use this variable
anymore to determine Qt5Core's availability; a totally unavailabe Qt5
would yield the same result. For a project that does need Qt5Core and
can use Qt5Gui - if available - this is crucial, but a reliable check
for the presence of Qt5Core would require further measures. However,
Alex recently came up with a proposal to distinguish mandatory from
optional components already in the FIND_PACKAGE() invocation, and
this seems capable to address that issue.

> This is one of the things I'd like feedback on, and on of the reasons I'm 
> asking people to try this out, or to read the generated Config files.
> 
> Can anyone say they've read the generated files? Has anyone confirm they 
> have run this or something like it? :
> 
> git clone git://gitorious.org/qt/qtbase.git
> cd qtbase
> ./configure
> ls lib/cmake

Yes. :)

> To see the input files for the generated config files see:
> 
> https://qt.gitorious.org/qt/qtbase/blobs/master/mkspecs/cmake/Qt5BasicConfig.cmake.in

Some remarks, though I haven't dissected each and every detail:

(1) Protecting imported targets: I suppose lines like

if (NOT _Qt5Gui_target)
set(_Qt5Gui_target 1)
add_library(Qt5::Gui SHARED IMPORTED)
endif()

serve to protect the Qt5::Gui imported target against redefinition
within the same scope? If so, look at the end of [1]. An inherited
directory property might be a cleaner and slightly more robust
alternative to a - rather fragile - variable:

DEFINE_PROPERTY(DIRECTORY PROPERTY Qt5Gui INHERITED ...)
GET_PROPERTY(p DIRECTORY PROPERTY Qt5Gui SET)
IF(NOT p)
SET_PROPERTY(DIRECTORY PROPERTY Qt5Gui TRUE)
ADD_LIBRARY(Qt5::Gui SHARED IMPORTED)
ENDIF()

Anyway, a minor issue and possibly not worth the effort.

(2) Enabling prerequisite Qt5 modules:

foreach(_module_dep ${_Qt5_MODULE_DEPENDENCIES})
if (NOT Qt5${_module_dep}_FOUND)
find_package(Qt5${_module_dep} REQUIRED)
endif()

endforeach()

Basically, the information provided by FIND_PACKAGE() here is already
available at configuration time, so there's no actual need to query it
at, say, deploy time. Instead, it could be weaved immediately into the
config file. However, doing it in the above-noted manner might be very
well intended, e.g. to keep the config files compact and regular and
to straightly express the modules' dependencies. If one decides to
do so, one should consider to use:

FIND_PACKAGE(Qt5${_module_dep} REQUIRED PATHS ... NO_DEFAULT_PATH)

Otherwise, FIND_PACKAGE() might load a config file from another Qt5
installation due to its fine-grained parameterization by variables
like CMAKE_PREFIX_PATH, in the cache as well as the environment.

(3) Enabling prerequisite external packages:

!!IF contains(QT_CONFIG, system-png)
find_package(PNG REQUIRED)
list(APPEND Qt5Gui_LIB_DEPENDENCIES ${PNG_LIBRARIES})
!!ENDIF

A similar consideration as in (2), but note that PNG does not have a
config file, so the PATHS/NO_DEFAULT_PATH interception will not work.
Is it permissible that a binary using Qt5Gui might be built against
a different PNG library than Qt5Gui has been built against? If so,
you could perhaps think about REQUIRED: IMO, FIND_PACKAGE() called
without that flag must not bail out because of anything not being
found. Instead, the user must have the chance to handle this by him/
herself. Note that Qt5 might be optional for the user's project. So,
REQUIRED should be passed to the internal FIND_PACKAGE() invocations
only if Qt5*_FIND_REQUIRED is set,

<    3   4   5   6   7   8