Iterating over a generator expression list, specifically $<TARGET_OBJECTS:objlib> of an OBJECT library

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Iterating over a generator expression list, specifically $<TARGET_OBJECTS:objlib> of an OBJECT library

George PF
Hello,

how can e.g. $<TARGET_OBJECTS:objlib> be iterated over in cmake?

This builds the lib, but the loop is never run:

    add_library(objlib12 OBJECT lib1.c lib2.c)
    foreach(o IN LISTS $<TARGET_OBJECTS:objlib12>)
        message("obj ${o}")
    endforeach()

But the $<TARGET_OBJECTS:objlib12> variable is set correctly, as this builds a shared library:

    add_library(lib12 SHARED $<TARGET_OBJECTS:objlib12>)

And the ;-separated list is visible when running this custom command via the 'test12' target:

    add_custom_command(OUTPUT libtest.cc
        COMMAND bash -c "echo '$<TARGET_OBJECTS:objlib12>'; echo > libtest.cc"
        VERBATIM)
    add_library(test12 SHARED libtest.cc)


Why does the for loop completely ignore this variable?


Regards

GPF
--

Powered by www.kitware.com

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

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

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

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Iterating over a generator expression list, specifically $<TARGET_OBJECTS:objlib> of an OBJECT library

Eric Noulard


Le mar. 28 août 2018 à 15:39, George PF <[hidden email]> a écrit :
Hello,

how can e.g. $<TARGET_OBJECTS:objlib> be iterated over in cmake?

This builds the lib, but the loop is never run:

    add_library(objlib12 OBJECT lib1.c lib2.c)
    foreach(o IN LISTS $<TARGET_OBJECTS:objlib12>)
        message("obj ${o}")
    endforeach()

But the $<TARGET_OBJECTS:objlib12> variable is set correctly, as this builds a shared library:

    add_library(lib12 SHARED $<TARGET_OBJECTS:objlib12>)

And the ;-separated list is visible when running this custom command via the 'test12' target:

    add_custom_command(OUTPUT libtest.cc
        COMMAND bash -c "echo '$<TARGET_OBJECTS:objlib12>'; echo > libtest.cc"
        VERBATIM)
    add_library(test12 SHARED libtest.cc)


Why does the for loop completely ignore this variable?

Because generator expressions are not handled in every cmake construct:

genex is probably not handled in foreach.


--
Eric

--

Powered by www.kitware.com

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

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

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

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Iterating over a generator expression list, specifically $<TARGET_OBJECTS:objlib> of an OBJECT library

Eric Noulard
I cc the list because I think you drop it inadvertently.

Le mar. 28 août 2018 à 16:18, George PF <[hidden email]> a écrit :
> Because generator expressions are not handled in every cmake construct:
https://cmake.org/cmake/help/v3.12/manual/cmake-generator-expressions.7.html

> genex is probably not handled in foreach.

That is a harsh limitation, set() or list() also does not expand this expression.

genex are evaluated during "Generation time" i.e. when CMake produces/generates the specific build system
files (makefile, [build|rules].ninja, MSVC solution etc...). This is convenient because some (most of) genex informations
may be generator specific (library file name, build artefact location, etc...)


set() , list(), foreach() are "running" at "CMake time" i.e. when cmake runs and processes CMakeLists.txt and other cmake scripts
that is before "Generation time".
 

And the variable XYZ, when set via this indirection to TARGET_OBJECTS,

    add_library(lib12 SHARED $<TARGET_OBJECTS:objlib12>)
    get_property(XYZ TARGET lib12 PROPERTY SOURCES)

is also not expanded yet. Is there a workaround regarding the generator expressions, or
another way to get the TARGET_OBJECTS of an object library (and why is this hidden
behind a generator and not available as a property)?

My opinion (but I may be proven wrong by others) is that genex contains generator specific bits that cannot be **evaluated**
until the build system is generated.  Properties (on target, or directory, or files) contains informations that is available as soon
as the corresponding CMakeLists.txt part defining the object has been processed.  


--
Eric

--

Powered by www.kitware.com

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

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

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

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Iterating over a generator expression list, specifically $<TARGET_OBJECTS:objlib> of an OBJECT library

George PF
> I cc the list because I think you drop it inadvertently.

Ah, thanks. I'll pay more attention to that now.

> Le mar. 28 août 2018 à 16:18, George PF <george.p.f at mail.com> a écrit :
>
> > > Because generator expressions are not handled in every cmake construct:
> > >
> > https://cmake.org/cmake/help/v3.12/manual/cmake-generator-expressions.7.html
> > >
> > > genex is probably not handled in foreach.
> >
> > That is a harsh limitation, set() or list() also does not expand this
> > expression.
> >
>
> genex are evaluated during "Generation time" i.e. when CMake
> produces/generates the specific build system
> files (makefile, [build|rules].ninja, MSVC solution etc...). This is
> convenient because some (most of) genex informations
> may be generator specific (library file name, build artefact location,
> etc...)
>
> https://stackoverflow.com/questions/46206495/cmake-generator-expressions
>
> set() , list(), foreach() are "running" at "CMake time" i.e. when cmake
> runs and processes CMakeLists.txt and other cmake scripts
> that is before "Generation time".
>
>
> And the variable XYZ, when set via this indirection to TARGET_OBJECTS,
> >
> >     add_library(lib12 SHARED $<TARGET_OBJECTS:objlib12>)
> >     get_property(XYZ TARGET lib12 PROPERTY SOURCES)
> >
> > is also not expanded yet. Is there a workaround regarding the generator
> > expressions, or
> > another way to get the TARGET_OBJECTS of an object library (and why is
> > this hidden
> > behind a generator and not available as a property)?
> >
>
> My opinion (but I may be proven wrong by others) is that genex contains
> generator specific bits that cannot be **evaluated**
> until the build system is generated.  Properties (on target, or directory,
> or files) contains informations that is available as soon
> as the corresponding CMakeLists.txt part defining the object has been
> processed.

That seems more like an internal cmake limitation. Though maybe on purpose so
the scripts can not be tailored for just one backend.
 
And the documentation says quite optimistically: "Generator expressions are allowed
in the context of many target properties", a more restrictive phrasing - "only works
with X / Y for reasons Z" would help there.
--

Powered by www.kitware.com

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

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

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

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Iterating over a generator expression list, specifically $<TARGET_OBJECTS:objlib> of an OBJECT library

Eric Noulard


Le mer. 29 août 2018 à 14:44, George PF <[hidden email]> a écrit :

>
> My opinion (but I may be proven wrong by others) is that genex contains
> generator specific bits that cannot be **evaluated**
> until the build system is generated.  Properties (on target, or directory,
> or files) contains informations that is available as soon
> as the corresponding CMakeLists.txt part defining the object has been
> processed.

That seems more like an internal cmake limitation. Though maybe on purpose so
the scripts can not be tailored for just one backend.

I think this was a design choice thus the name "Generator" expression they are evaluated at generation time
not configuration time and I don't think it's an internal cmake limitation, I think (but I may be wrong) that this
"generation step" would happen for any generative build system.

And there is more than that about "when" you'll know some var values.
Some generators are supporting "multiple build configuration" like MSVC and Xcode so that
the build output dir is "mangled" with a prefix **at build time** (since you can switch configuration after you have generated your project files).
see e.g. 

And the documentation says quite optimistically: "Generator expressions are allowed
in the context of many target properties", a more restrictive phrasing - "only works
with X / Y for reasons Z" would help there.

I agree this could be clearer.
Having a possibly exhaustive description of where genex may be used would be nice.
May be it's worth a bug report with a proposal doc update?

Genex support is added in places where it is useful (and possible I guess):

And concerning having them "at configure time", there is open issue
about "configuration expression":


--
Eric

--

Powered by www.kitware.com

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

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

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

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake