Generator Expressions and FetchContent

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

Generator Expressions and FetchContent

Saad Khattak
Hi,

ExternalProject_Add builds, generates and installs and thus any generator expressions used will be expanded by the time another library uses it. 

For example, if I add a library LibA using ExternalProject_Add, I can then query the target property INTERFACE_INCLUDE_DIRECTORIES and get the include directory for the library:

get_target_property(LibA_INCLUDE_DIRECTORIES LibA
  INTERFACE_INCLUDE_DIRECTORIES
  )

This allows me to then use the variable LibA_INCLUDE_DIRECTORIES in my CMake include(...) statements. However, with FetchContent, this is no longer possible.

The reason I would like to query a variable is because at project generation time, I invoke FetchContent only if LibA is not found by find_package(LibA). 

Thus, the include directory for LibA may be in the current build directory (through FetchContent) OR it may be found in the folder where LibA is cloned by the user and generated/built OR an INSTALL of LibA.

Perhaps I should not be using `get_target_property` to get the a library's include directory? Either way, would like some guidance in solving this issue.

Thank you,
Saad


--

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: Generator Expressions and FetchContent

Craig Scott-3
Can you provide a small project example that can be used to demonstrate your problem? The specifics of how you are doing things may be important.


On Sun, Mar 18, 2018 at 8:12 AM, Saad Khattak <[hidden email]> wrote:
Hi,

ExternalProject_Add builds, generates and installs and thus any generator expressions used will be expanded by the time another library uses it. 

For example, if I add a library LibA using ExternalProject_Add, I can then query the target property INTERFACE_INCLUDE_DIRECTORIES and get the include directory for the library:

get_target_property(LibA_INCLUDE_DIRECTORIES LibA
  INTERFACE_INCLUDE_DIRECTORIES
  )

This allows me to then use the variable LibA_INCLUDE_DIRECTORIES in my CMake include(...) statements. However, with FetchContent, this is no longer possible.

The reason I would like to query a variable is because at project generation time, I invoke FetchContent only if LibA is not found by find_package(LibA). 

Thus, the include directory for LibA may be in the current build directory (through FetchContent) OR it may be found in the folder where LibA is cloned by the user and generated/built OR an INSTALL of LibA.

Perhaps I should not be using `get_target_property` to get the a library's include directory? Either way, would like some guidance in solving this issue.

Thank you,
Saad


--

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




--
Craig Scott
Melbourne, Australia

--

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: Generator Expressions and FetchContent

Saad Khattak
Absolutely. Please find the example project here: https://github.com/samaursa/cmake_fetch_content_and_generator_expressions 

The repository README also includes the output from running `./setup.sh`. 

On Sat, Mar 17, 2018 at 6:47 PM Craig Scott <[hidden email]> wrote:
Can you provide a small project example that can be used to demonstrate your problem? The specifics of how you are doing things may be important.


On Sun, Mar 18, 2018 at 8:12 AM, Saad Khattak <[hidden email]> wrote:
Hi,

ExternalProject_Add builds, generates and installs and thus any generator expressions used will be expanded by the time another library uses it. 

For example, if I add a library LibA using ExternalProject_Add, I can then query the target property INTERFACE_INCLUDE_DIRECTORIES and get the include directory for the library:

get_target_property(LibA_INCLUDE_DIRECTORIES LibA
  INTERFACE_INCLUDE_DIRECTORIES
  )

This allows me to then use the variable LibA_INCLUDE_DIRECTORIES in my CMake include(...) statements. However, with FetchContent, this is no longer possible.

The reason I would like to query a variable is because at project generation time, I invoke FetchContent only if LibA is not found by find_package(LibA). 

Thus, the include directory for LibA may be in the current build directory (through FetchContent) OR it may be found in the folder where LibA is cloned by the user and generated/built OR an INSTALL of LibA.

Perhaps I should not be using `get_target_property` to get the a library's include directory? Either way, would like some guidance in solving this issue.

Thank you,
Saad


--

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




--
Craig Scott
Melbourne, Australia

--

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: Generator Expressions and FetchContent

Craig Scott-3


On Mon, Mar 19, 2018 at 3:44 AM, Saad Khattak <[hidden email]> wrote:
Absolutely. Please find the example project here: https://github.com/samaursa/cmake_fetch_content_and_generator_expressions 

The repository README also includes the output from running `./setup.sh`. 


Okay that's much clearer, thanks. The example is doing what I'd expect and the generator expressions are also expected to be visible at the point your example is printing them. If you made your main target link against LibA, you'd see that CMake automatically expands out the generator expressions when it constructs the link command line for main, so the example as it stands doesn't actually have any error.

Generator expressions are not expanded when CMake is processing the files (called the configure stage), they are expanded only when writing out the Makefiles during the generation stage. When running cmake from the command line, one doesn't tend to think of these two phases as being distinct, but you can see it at the end of the cmake log with these two messages:

-- Configuring done
-- Generating done

It is clearer when using the CMake GUI application because you get two different buttons, one for Configure and another for Generate, so you have to trigger both phases manually. So if you look at the contents of various properties and variables with CMake commands like message(...), you are doing that during the configure stage and therefore will see unexpanded generator expressions.


 

On Sat, Mar 17, 2018 at 6:47 PM Craig Scott <[hidden email]> wrote:
Can you provide a small project example that can be used to demonstrate your problem? The specifics of how you are doing things may be important.


On Sun, Mar 18, 2018 at 8:12 AM, Saad Khattak <[hidden email]> wrote:
Hi,

ExternalProject_Add builds, generates and installs and thus any generator expressions used will be expanded by the time another library uses it. 

For example, if I add a library LibA using ExternalProject_Add, I can then query the target property INTERFACE_INCLUDE_DIRECTORIES and get the include directory for the library:

get_target_property(LibA_INCLUDE_DIRECTORIES LibA
  INTERFACE_INCLUDE_DIRECTORIES
  )

This allows me to then use the variable LibA_INCLUDE_DIRECTORIES in my CMake include(...) statements. However, with FetchContent, this is no longer possible.

The reason I would like to query a variable is because at project generation time, I invoke FetchContent only if LibA is not found by find_package(LibA). 

Thus, the include directory for LibA may be in the current build directory (through FetchContent) OR it may be found in the folder where LibA is cloned by the user and generated/built OR an INSTALL of LibA.

Perhaps I should not be using `get_target_property` to get the a library's include directory? Either way, would like some guidance in solving this issue.

Thank you,
Saad


--

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




--
Craig Scott
Melbourne, Australia



--
Craig Scott
Melbourne, Australia

--

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: Generator Expressions and FetchContent

Saad Khattak
Thank you for the clarification Craig.

>> If you made your main target link against LibA, you'd see that CMake automatically expands out the generator expressions when it constructs the link command line for main, so the example as it stands doesn't actually have any error.

In my actual project, a library like LibA has .cmake files that can be included by dependent projects to reuse. Of course, CMake `include` does not get affected by target_link_libraries. 

I would like dependent projects to have the ability to use an existing clone of LibA, if found (e.g. using find_package), otherwise clone locally for using ExternalProject_Add which I am now trying to refactor to FetchContent. Another option open to dependent projects is to force the FetchContent on all repositories regardless of what find_package returns (this is great for testing locally to ensure I have no uncommitted, unpushed changes).

Using existing clones is a way to ensure that every project dependent on LibA doesn't clone it's own copy (unless forced to do so).

To allow the possibility for any dependent project to include the .cmake files properly, I get the INTERFACE_INCLUDE_DIRECTORIES target property (using get_target_property) for LibA and then include the .cmake utility files like this:

include(${LibA_INCLUDE_DIRECTORY}/my_utility.cmake)

Perhaps I am approaching the problem incorrectly? Essentially, I would like a way to reliably include .cmake files found in LibA's include folder regardless of how LibA was acquired (e.g. cloned and built and/or installed separately or acquired using FetchContent). In my case, I could only think of the above as a reliable way to include the files.



On Sun, Mar 18, 2018 at 4:22 PM Craig Scott <[hidden email]> wrote:
On Mon, Mar 19, 2018 at 3:44 AM, Saad Khattak <[hidden email]> wrote:
Absolutely. Please find the example project here: https://github.com/samaursa/cmake_fetch_content_and_generator_expressions 

The repository README also includes the output from running `./setup.sh`. 


Okay that's much clearer, thanks. The example is doing what I'd expect and the generator expressions are also expected to be visible at the point your example is printing them. If you made your main target link against LibA, you'd see that CMake automatically expands out the generator expressions when it constructs the link command line for main, so the example as it stands doesn't actually have any error.

Generator expressions are not expanded when CMake is processing the files (called the configure stage), they are expanded only when writing out the Makefiles during the generation stage. When running cmake from the command line, one doesn't tend to think of these two phases as being distinct, but you can see it at the end of the cmake log with these two messages:

-- Configuring done
-- Generating done

It is clearer when using the CMake GUI application because you get two different buttons, one for Configure and another for Generate, so you have to trigger both phases manually. So if you look at the contents of various properties and variables with CMake commands like message(...), you are doing that during the configure stage and therefore will see unexpanded generator expressions.


 

On Sat, Mar 17, 2018 at 6:47 PM Craig Scott <[hidden email]> wrote:
Can you provide a small project example that can be used to demonstrate your problem? The specifics of how you are doing things may be important.


On Sun, Mar 18, 2018 at 8:12 AM, Saad Khattak <[hidden email]> wrote:
Hi,

ExternalProject_Add builds, generates and installs and thus any generator expressions used will be expanded by the time another library uses it. 

For example, if I add a library LibA using ExternalProject_Add, I can then query the target property INTERFACE_INCLUDE_DIRECTORIES and get the include directory for the library:

get_target_property(LibA_INCLUDE_DIRECTORIES LibA
  INTERFACE_INCLUDE_DIRECTORIES
  )

This allows me to then use the variable LibA_INCLUDE_DIRECTORIES in my CMake include(...) statements. However, with FetchContent, this is no longer possible.

The reason I would like to query a variable is because at project generation time, I invoke FetchContent only if LibA is not found by find_package(LibA). 

Thus, the include directory for LibA may be in the current build directory (through FetchContent) OR it may be found in the folder where LibA is cloned by the user and generated/built OR an INSTALL of LibA.

Perhaps I should not be using `get_target_property` to get the a library's include directory? Either way, would like some guidance in solving this issue.

Thank you,
Saad


--

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




--
Craig Scott
Melbourne, Australia



--
Craig Scott
Melbourne, Australia

--

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: Generator Expressions and FetchContent

Craig Scott-3

On Mon, Mar 19, 2018 at 8:25 AM, Saad Khattak <[hidden email]> wrote:
Thank you for the clarification Craig.

>> If you made your main target link against LibA, you'd see that CMake automatically expands out the generator expressions when it constructs the link command line for main, so the example as it stands doesn't actually have any error.

In my actual project, a library like LibA has .cmake files that can be included by dependent projects to reuse. Of course, CMake `include` does not get affected by target_link_libraries. 

I would like dependent projects to have the ability to use an existing clone of LibA, if found (e.g. using find_package), otherwise clone locally for using ExternalProject_Add which I am now trying to refactor to FetchContent. Another option open to dependent projects is to force the FetchContent on all repositories regardless of what find_package returns (this is great for testing locally to ensure I have no uncommitted, unpushed changes).

Using existing clones is a way to ensure that every project dependent on LibA doesn't clone it's own copy (unless forced to do so).

To allow the possibility for any dependent project to include the .cmake files properly, I get the INTERFACE_INCLUDE_DIRECTORIES target property (using get_target_property) for LibA and then include the .cmake utility files like this:

include(${LibA_INCLUDE_DIRECTORY}/my_utility.cmake)

Perhaps I am approaching the problem incorrectly? Essentially, I would like a way to reliably include .cmake files found in LibA's include folder regardless of how LibA was acquired (e.g. cloned and built and/or installed separately or acquired using FetchContent). In my case, I could only think of the above as a reliable way to include the files.

Rather than focusing on including files, I would choose to base things around targets. If the rest of your project simply links against the required target name, the target itself should bring with it any transitive dependencies such as required header search paths, dependent libraries that must also be linked, etc. These are the INTERFACE_... properties that can be set on a target, usually by commands such as target_include_directories(foo INTERFACE ...), target_link_libraries(foo INTERFACE ...), etc. When building directly from your source tree, the targets will be directly available. When using find_package(), the package should provide import targets. The rest of your project shouldn't really need to care which one of the two it is dealing with. This is the recommended way to structure a situation like this. You shouldn't need to also pull in a secondary .cmake file in most circumstances, but maybe I'm missing something about your particular situation.

 

On Sun, Mar 18, 2018 at 4:22 PM Craig Scott <[hidden email]> wrote:
On Mon, Mar 19, 2018 at 3:44 AM, Saad Khattak <[hidden email]> wrote:
Absolutely. Please find the example project here: https://github.com/samaursa/cmake_fetch_content_and_generator_expressions 

The repository README also includes the output from running `./setup.sh`. 


Okay that's much clearer, thanks. The example is doing what I'd expect and the generator expressions are also expected to be visible at the point your example is printing them. If you made your main target link against LibA, you'd see that CMake automatically expands out the generator expressions when it constructs the link command line for main, so the example as it stands doesn't actually have any error.

Generator expressions are not expanded when CMake is processing the files (called the configure stage), they are expanded only when writing out the Makefiles during the generation stage. When running cmake from the command line, one doesn't tend to think of these two phases as being distinct, but you can see it at the end of the cmake log with these two messages:

-- Configuring done
-- Generating done

It is clearer when using the CMake GUI application because you get two different buttons, one for Configure and another for Generate, so you have to trigger both phases manually. So if you look at the contents of various properties and variables with CMake commands like message(...), you are doing that during the configure stage and therefore will see unexpanded generator expressions.


 

On Sat, Mar 17, 2018 at 6:47 PM Craig Scott <[hidden email]> wrote:
Can you provide a small project example that can be used to demonstrate your problem? The specifics of how you are doing things may be important.


On Sun, Mar 18, 2018 at 8:12 AM, Saad Khattak <[hidden email]> wrote:
Hi,

ExternalProject_Add builds, generates and installs and thus any generator expressions used will be expanded by the time another library uses it. 

For example, if I add a library LibA using ExternalProject_Add, I can then query the target property INTERFACE_INCLUDE_DIRECTORIES and get the include directory for the library:

get_target_property(LibA_INCLUDE_DIRECTORIES LibA
  INTERFACE_INCLUDE_DIRECTORIES
  )

This allows me to then use the variable LibA_INCLUDE_DIRECTORIES in my CMake include(...) statements. However, with FetchContent, this is no longer possible.

The reason I would like to query a variable is because at project generation time, I invoke FetchContent only if LibA is not found by find_package(LibA). 

Thus, the include directory for LibA may be in the current build directory (through FetchContent) OR it may be found in the folder where LibA is cloned by the user and generated/built OR an INSTALL of LibA.

Perhaps I should not be using `get_target_property` to get the a library's include directory? Either way, would like some guidance in solving this issue.

Thank you,
Saad




--
Craig Scott
Melbourne, Australia

--

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: Generator Expressions and FetchContent

Saad Khattak
I do use target_link_libraries when it comes to C++ projects and it works wonderfully for them. However, in this case, my base project has a bunch of helper files with CMake functionality that help me work with and build my library of projects (which you can see here https://github.com/2LoC/tl_base_ci).

Of course, these helper .cmake files (with the functionality I want) are in the tl_base_ci project which can be either (1) cloned separately, built, (2) Installed without building, or (3) cloned through ExternalProject_Add (which I am trying to convert to FetchContent). In all cases, the include directories might differ, which is why I use rely on the generator expressions expanding.

In projects depending on tl_base_ci (e.g. https://github.com/2LoC/tl_proj_template), I have CMake includes like this:

include("${tl_base_ci_INCLUDE_DIRECTORY}/tl_base_ci/tl_common.cmake") # in the actual project, it's slightly different as it searches for the file in a list of directories returned by get_target_property(... INTERFACE_INCLUDE_DIRECTORIES)

Where the tl_base_ci_INCLUDE_DIRECTORY might differ. So ultimately I was hoping for a way to reliably include the helper .cmake files (i.e. figure out tl_base_ci's include directory path). I did that with get_target_property(...) which worked great for ExternalProject_Add, but did not work so well for FetchContent because the generator expressions did not expand.

Hopefully I was able to explain the problem well. If there is any confusion, please let me know.



On Mon, Mar 19, 2018 at 7:11 AM Craig Scott <[hidden email]> wrote:
On Mon, Mar 19, 2018 at 8:25 AM, Saad Khattak <[hidden email]> wrote:
Thank you for the clarification Craig.

>> If you made your main target link against LibA, you'd see that CMake automatically expands out the generator expressions when it constructs the link command line for main, so the example as it stands doesn't actually have any error.

In my actual project, a library like LibA has .cmake files that can be included by dependent projects to reuse. Of course, CMake `include` does not get affected by target_link_libraries. 

I would like dependent projects to have the ability to use an existing clone of LibA, if found (e.g. using find_package), otherwise clone locally for using ExternalProject_Add which I am now trying to refactor to FetchContent. Another option open to dependent projects is to force the FetchContent on all repositories regardless of what find_package returns (this is great for testing locally to ensure I have no uncommitted, unpushed changes).

Using existing clones is a way to ensure that every project dependent on LibA doesn't clone it's own copy (unless forced to do so).

To allow the possibility for any dependent project to include the .cmake files properly, I get the INTERFACE_INCLUDE_DIRECTORIES target property (using get_target_property) for LibA and then include the .cmake utility files like this:

include(${LibA_INCLUDE_DIRECTORY}/my_utility.cmake)

Perhaps I am approaching the problem incorrectly? Essentially, I would like a way to reliably include .cmake files found in LibA's include folder regardless of how LibA was acquired (e.g. cloned and built and/or installed separately or acquired using FetchContent). In my case, I could only think of the above as a reliable way to include the files.

Rather than focusing on including files, I would choose to base things around targets. If the rest of your project simply links against the required target name, the target itself should bring with it any transitive dependencies such as required header search paths, dependent libraries that must also be linked, etc. These are the INTERFACE_... properties that can be set on a target, usually by commands such as target_include_directories(foo INTERFACE ...), target_link_libraries(foo INTERFACE ...), etc. When building directly from your source tree, the targets will be directly available. When using find_package(), the package should provide import targets. The rest of your project shouldn't really need to care which one of the two it is dealing with. This is the recommended way to structure a situation like this. You shouldn't need to also pull in a secondary .cmake file in most circumstances, but maybe I'm missing something about your particular situation.

 

On Sun, Mar 18, 2018 at 4:22 PM Craig Scott <[hidden email]> wrote:
On Mon, Mar 19, 2018 at 3:44 AM, Saad Khattak <[hidden email]> wrote:
Absolutely. Please find the example project here: https://github.com/samaursa/cmake_fetch_content_and_generator_expressions 

The repository README also includes the output from running `./setup.sh`. 


Okay that's much clearer, thanks. The example is doing what I'd expect and the generator expressions are also expected to be visible at the point your example is printing them. If you made your main target link against LibA, you'd see that CMake automatically expands out the generator expressions when it constructs the link command line for main, so the example as it stands doesn't actually have any error.

Generator expressions are not expanded when CMake is processing the files (called the configure stage), they are expanded only when writing out the Makefiles during the generation stage. When running cmake from the command line, one doesn't tend to think of these two phases as being distinct, but you can see it at the end of the cmake log with these two messages:

-- Configuring done
-- Generating done

It is clearer when using the CMake GUI application because you get two different buttons, one for Configure and another for Generate, so you have to trigger both phases manually. So if you look at the contents of various properties and variables with CMake commands like message(...), you are doing that during the configure stage and therefore will see unexpanded generator expressions.


 

On Sat, Mar 17, 2018 at 6:47 PM Craig Scott <[hidden email]> wrote:
Can you provide a small project example that can be used to demonstrate your problem? The specifics of how you are doing things may be important.


On Sun, Mar 18, 2018 at 8:12 AM, Saad Khattak <[hidden email]> wrote:
Hi,

ExternalProject_Add builds, generates and installs and thus any generator expressions used will be expanded by the time another library uses it. 

For example, if I add a library LibA using ExternalProject_Add, I can then query the target property INTERFACE_INCLUDE_DIRECTORIES and get the include directory for the library:

get_target_property(LibA_INCLUDE_DIRECTORIES LibA
  INTERFACE_INCLUDE_DIRECTORIES
  )

This allows me to then use the variable LibA_INCLUDE_DIRECTORIES in my CMake include(...) statements. However, with FetchContent, this is no longer possible.

The reason I would like to query a variable is because at project generation time, I invoke FetchContent only if LibA is not found by find_package(LibA). 

Thus, the include directory for LibA may be in the current build directory (through FetchContent) OR it may be found in the folder where LibA is cloned by the user and generated/built OR an INSTALL of LibA.

Perhaps I should not be using `get_target_property` to get the a library's include directory? Either way, would like some guidance in solving this issue.

Thank you,
Saad




--
Craig Scott
Melbourne, Australia

--

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