On Tue, Mar 31, 2009 at 3:27 PM, BRM <bm_witn...@yahoo.com> wrote:

Notice my original API suggestion - the project controls its own header - just 
not the list of available items.

So essentially:

1) Cmake runs, finds packages, builds list
2) user add extra items to list
3) header generated

Noting from my original API example:

cmake_autoheader(C, path/to/cmake/autoheader_output1.h some_other_package )
cmake_autoheader(C, path/to/cmake/autoheader_output2.h some_other_package )
cmake_autoheader(C, path/to/cmake/autoheader_output3.h some_other_package )

Adding in the filtering as I suggested:

cmake_autoheader(C, path/to/cmake/autoheader_output1.h some_other_package 
[filter 1])
cmake_autoheader(C, path/to/cmake/autoheader_output2.h some_other_package 
[filter 2])
cmake_autoheader(C, path/to/cmake/autoheader_output3.h some_other_package 
[filter 3])

Each project could easily define its own header (or headers) - there would be 
no limit. And it should probably generate the header immediately based on when 
the cmake_autoheader() is called, based on the state of the list at that point. 
(I think it would be too complex to push it until the end of the file; but that 
might be possible too.)

As to resolving between sub-projects, it would likely be good to internally 
register a scope for the variables - the scope being the path from the root 
CMakeLists.txt to the present one. If a parent, sibling, or child node wanted 
to access a different node's variables, it would have to do so using the 
filters and explicitly name the path. This would be easy to do in the filters 
as the project designer would know the paths between the projects. The output 
in the header would be no different - just the #define HAS_VARIABLE no matter 
what node it was in.

So take the following:

src/CMakeLists.txt
src/subdir1/CMakeLists.txt
src/subdir1/subdir1a/CMakeLists.txt
src/subdir2/CMakeLists.txt

src/subdir1/CMakeLists.txt would be able to access its variables with no 
scoping whatsoever. But to access a variable in src/CMakeLists.txt, it would 
have to provide explicit scoping to it via a filter when generating the 
autoheader via cmake_autoheader(). It would need to do the same to access 
variables in either src/subdir1/subdir1a/CMakeLists.txt and 
src/subdir2/CMakeLists.txt.

However, I would only guarantee that the cmake_autoheader() would be able to 
get what is in the global list at the time it is run. So 
src/subdir1/CMakeLists.txt would likely not be able to see 
src/subdir2/CMakeLists.txt's variables, or all of the variables in 
src/CMakeLists.txt (as some may be defined after src/subdir1/CMakeLists.txt is 
run). It could control what it or its child nodes know though - based on when 
it makes the call, but that can be left to the project designer.

Quote Philip Lowman <phi...@yhbt.com>:
===============================
Why not simply make cmake_autoheader() reentrant (and I assume a command) and 
have it process last?  This would solve one of your critiques of not having to 
pass lists around.  You could also eliminate the need to specify the filename 
everywhere and a logical name could be used.  It would presumably call the 
functionality provided by configure_file() internally per logical name.

cmake_autoheader(INIT myconfig ${CMAKE_CURRENT_BINARY_DIR}/config.h)
cmake_autoheader(CONFIG myconfig
      ... stuff like we already have ...)

add_subdirectory(foo)
     foo/ =>  cmake_autoheader(CONFIG myconfig
                ... add additional stuff)

Ben's Reply:
=========

Only issue I can see with it being re-entrant (good idea overall) is that you 
would be limited to having one file. Otherwise love it.

Quote Philip Lowman <phi...@yhbt.com>:
===============================
I hear you on trying to automatically add #cmakedefine variables to a list.  
Ultimately I think Bill and co. are right that trying to retrofit 
find_package() and any other place where you may (or may not) want to add a 
#cmakedefine like check_function_exists, etc. is simply going to be too 
complex.  Also as for find_package() someone out there will certainly want 
HAVE_OPENSCENEGRAPH to work instead of HAVE_OSG or HAVE_OSG2 or whatever.  You 
seem to like HAS_FOO, others probably prefer USE_FOO or HAVE_FOO_H.  Clearly 
we're never all going to agree.

Even if it was easy to do this there is another risk.  Users won't care to 
really define which variables they want #cmakedefined or not so they'll simply 
define everything.  Then you'll end up with what GNU autotools seems to do now 
which is to create a ginormous config.h.in file for pretty much anything you 
type in configure.ac.  Trying to wade through which of these #defines are 
actually necessary or not is an annoying exercise in the use of grep.  Also 
many of these #defines are superfluous on modern compilers/platforms.

Ben's Reply:
=========

If you noticed my original API example, I had the Find function use its own 
variable for defining the variable. I honestly could care less what it is 
actually called. There is already precedence (I think) for FOO_FOUND. I quoted 
'HAS_FOO' only to keep the discussion simple as someone quoted that from the 
Autotools equivalent functionality. But what it is called in the end makes no 
difference to me. All I care about is that there is consistency between 
projects so developer's don't have to either (a) figure out what something is 
called, or (b) figure out what to call something. Simplicity.

I proposed having it done by the Find functions as that would provide a unified 
area for any given library, and thus minimize overlapping defines. It would be 
easier to move between projects, and re-use would be better. Simplicity.

As to whether a user wants to call something else by the same name - well, I'd 
have to say "tough luck", and the precedences seems to already be set by the 
Find functions - they already define a series of variables that the user cannot 
change and if they conflict with variables the user wants, then its "touch 
luck, use something else". So I don't think that either is or will be an issue 
- it certainly doesn't seem to have been already. Precedence is already there 
to what I can tell. 
(http://www.cmake.org/Wiki/CMake_HowToFindInstalledSoftware, 
http://www.cmake.org/cmake/help/cmake2.6docs.html#command:find_package)

I also don't think that would be overly complex - it's just updating the 
various Find functions to add a call to the correct API.

So would you rather that a project designer have to bloat their CMakeFiles.txt 
with something like:

if (FOUND_FOO)
   cmake_autoheader(CONFIG myconfig HAS_FOO)

for every package they want found? (So if you have 30 packages, you'd have 60 
lines added)

Or would it be better to only have to define it once (like a project), and then 
have everything add to that and only have one other line required to generate 
the header?

Simplicity is best, and I think the simplest solution means not having user's 
bloat their CMakeFiles.txt - it should be part of the system provided by CMake.

As another POV, suppose you are working on 10 projects. You started 5 of them, 
and at different times joined 5 others. If you relied on user's to define the 
variables for the header, then you could theoretically have 10 different 
variables. Or if you were smart about your own projects, you'd have 4 - 1 for 1 
project + your 5, and 3 others. If were absolutely lucky against all odds, 
you'd have 1 - but that would likely only occur if you had a common participant 
on all projects OR if someone reviewed all the projects and said "Let's make 
these all the same". Imagine having to move between those projects? If they had 
different variables (which is more likely than not), then you'd have to 
remember which variable was for which project.

Now consider the POV where the system predefines what the variable format would 
be, and what the variable names are for non-project-specific variables - e.g. 
stuff that CMake finds FOR your project via the Find Functions. In that same 
scenario, you'd have 1 variable for the same package on all projects.

Ultimately there are three choices to make:

1) Do we want to have a reliable naming convention for variables in the API?
2) Do we want to have reliable, cross-project names for the same project in the 
API?
3) Do we want to make it easy for users to use the API?

I think all the answer to all the above should be "YES". And I think the 
user-visible syntax/work to support using it should be absolutely minimal.

Perhaps there is a middle ground, somewhat, but it would require more work on 
the part of the CMake developers I think:
1) Have the scope limited to a project/module. When the user creates a project, 
they can optionally have it register itself for Autoheader support.
2) Whenever a variable is added, the supporting API function checks with the 
internals and registers the variables with all registered modules that are in 
scope. (I think the scoping here is probably already well defined.)

This would really eliminate much of any user-visible API - other than to do two 
things:
1) When the project/module is defined:
          PROJECT(name C)
          CMAKE_AUTOHEADER(name file [optional filter])
2) A generic API to add/remove variables - the user would not necessarily have 
to use it; but it would be used for the CMake provided back-end (e.g. in the 
Find functions) for the same purpose
          CMAKE_AUTOHEADER_ADD_VAR(myvar)
          CMAKE_AUTOHEADER_REMOVE_VAR(myvar)

When CMake generates the project, it would also generate the autoheader - e.g. 
it could be among the last steps.

Ben
_______________________________________________
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

Reply via email to