<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Aug 23, 2017 at 2:07 AM, Clément Gregoire <span dir="ltr"><<a href="mailto:lectem@gmail.com" target="_blank">lectem@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><p dir="ltr">I can't argue too much why paths or absolute on cmake as I don't know the rationale behind it is. While your point about command line limit makes sense, I feel like a system limiting command line size to this extent is dumb if it doesn't allow reading more arguments through a file. (again, I don't know the system at all). <br></p></blockquote><div>My command line problem experience stems from two problems:<br><br></div><div>1) building ITK as a superproject/superbuild within my project and from within VMTK which also used ITK in a superbuild.. well and building VMTK superbuild inside my superbuild project.  Yes it's a Russian dolls/onion of superbuilds.  Boy I would also like to comment on those problems, but that will be for a different post.<br></div><div><br>2) My somewhat successful (I say somewhat as appose to ideal) ExternalProject_Add build of boost from git repo where setting boost build command at the cmd prompt vs within VS studio.  I had to resort to CMD prompt to eak out those last bits-o-chars.<br></div><div> <br>Ahh yes here it is from my CMake files:<br><br>    # Does not work as command path length is too long.<br>    #    add_custom_target( <br>    #       boost_build_target<br>    #       "echo ${BUILD_BOOST_CMD}; ${BUILD_BOOST_CMD}"<br>    #       WORKING_DIRECTORY ${BOOST_SOURCE_DIR} )<br><br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><p dir="ltr">
I kinda understand your point about not being able to set the libdir per target but (might have missed it in your previous mails) I don't know what kind of project would need that. At best I would need one version of the library per configuration, which is supported. </p></blockquote><div>Ok here goes as I would really like people to understand my problems with the current CMake impl then possibly I could be awed by the logic of CMake and stand corrected .... or possibly ... just possibly I am correct and CMake could change course.<br></div><div><br></div><div>First off there is some inconsistencies in the logic of the design / impl of CMake from my perspective if we look at the new target/properties and statements from 3rd parties (pdf mentioned earlier) as to the direction /logic of CMake.  <br><br></div><div>1) find_library forces user down a path of abs paths and does not allow the return of the path in the event the user wants to pass the path to LINK_DIRECTORIES.  Which coupled with my path problems I chose/forced not to use find_library.  Ok so like I said I could build of off C:\ so I'll give CMake that.  CMake forces full abs paths for every lib specified even for those of us who don't want it / can't use it in find_library.  Why not have find_library return two (2) VARS one for lib and other for path and provide option to user and state the WHY the user should choose abs paths.  Then I could argue the WHY problem directly, but still have an out for LINK_DIRECTORIES/LIBPATH use.  However CMake forced the abs full  path on every lib issue and has not provide a *good* mechanism to the alternative.  <br><br></div><div>2) find_library is as I am sure CMake would agree is not under the target/property new design.  Say the target is targ and the property is the library path, but find_library is all or nothing and a CMake variable.  Where CMake variables if pdf is to be believed is not under the new CMake "don't use variables" design philosophy.  Not that I know what the actual Design of CMake is or should be and I would certainly like to hear that and have CMake resolve this discrepancy.<br></div><div><br>3) In VS (well in Linux for that matter) can set include paths and I can set LIBPATH(s) on targets.   In CMake I can set include_directories on targets but not lib paths.  However I can get around this and do by using LIBRARY_PATH which is at the directory level.  CMake should expose always the underlying abilities of the tools to the user and guide to the best use for sure, but never force... and I am seemingly forced to do an illogical end-around (go to directory scope to set what should be a target property).<br></div><div><br></div><div>As to:<br><br>"I kinda understand your point about not being able to set the libdir per
 target but (might have missed it in your previous mails) I don't know 
what kind of project would need that"<br><br></div><div></div>How about projects for which boost and find_package(Boost) (<- Beware of caps when using boost and find_package yes it's case sensitive)  is used?<br><br></div><div class="gmail_quote">#+-----------------------------------------------------------------------------<br>set( <br>        BOOST_LIBS<br>        Boost::boost<br>        Boost::system<br>        Boost::date_time<br>        Boost::filesystem<br>        Boost::serialization<br>        )<br><br>add_library( boost_interface INTERFACE )<br>target_include_directories( <br>    boost_interface <br>    INTERFACE<br>        ${BOOST_INCLUDE_DIR}<br>) <br><br>target_link_libraries(<br>    boost_interface<br>    INTERFACE<br>        ${BOOST_LIBS}<br>)<br><br>#+-----------------------------------------------------------------------------<br><br></div><div class="gmail_quote">And yes all my boost use needs at least those libs other opts to create another interface for inheritance based on other lib use is certainly possible.<br></div><div class="gmail_quote"><br><div>I have a mixed mode CMake generated vsprojs and existing vsprojs files where include_external_msproject is used for some projects:<br><br>#------------------------------------------------------------------------------<br>add_library( 4duiplugin_interface INTERFACE )<br><br>target_include_directories( <br>    4duiplugin_interface<br>    INTERFACE<br>         ${4DUI_PLUGIN_DIR}<br>)<br><br><br><br>add_library( utilities_interface INTERFACE )<br><br>target_link_libraries( <br>    utilities_interface<br>    INTERFACE<br>    optimized ${TOP}/build/x64/Release/Libraries/Utilities.lib<br>    debug ${TOP}/build/x64/Debug/Libraries/Utilities.lib<br>)<br><br>target_include_directories( <br>    utilities_interface<br>    INTERFACE<br>     ${4DFUTILITIES_INCLUDE_DIR}<br>)<br><br><br>add_library( dicomreader_interface INTERFACE )<br><br>target_link_libraries( <br>   dicomreader_interface<br>    INTERFACE<br>    optimized ${TOP}/build/x64/Release/Libraries/DicomReader.lib<br>    debug ${TOP}/build/x64/Debug/Libraries/DicomReader.lib<br>)<br>#------------------------------------------------------------------------------<br><br></div><div>Why cannot I set say:<br><br></div><div>target_library_directories(    <br>    utilities_interface<br>    INTERFACE<br>    optimized ${TOP}/build/x64/Release/Libraries<br>    debug ${TOP}/build/x64/Debug/Libraries<br>)<br></div><div><br></div><div>Note use of only directories above and use of unavailable target_library_directory to set LIBPATH where it could search out duplicate paths before chucking at the linker.  find_library certainly can't do it as is uses abs paths.  While abs paths are used above and certainly could by target/property'izing LIB_DR this could give CMake an "out" to the command line length problem by filtering for unique before setting LIBPATH.  Hey CMake could even provide an ABSOLUTE command in target_link_directories and state some gibberish as to how/why absolute long paths for every library is better... not that I buy it now and will not then either.<br></div><div><br><br></div><div>Then used sometime later:<br></div><div><br>target_link_libraries(<br>    ${SOME_LIB}<br>    4dfutilities_interface<br>    4dfdicomreader_interface<br>    cuda_sdk_interface<br>    boost_interface<br>    shaderslib_interface<br>#    vtk_interface<br>    vmtk_interface<br>)<br><br><br></div><div>Also cmake 3.7/3.8//3.9 started to support CUDA as a first class language.  Now the question: do I use:<br><br></div><div>project( prjname CXX CUDA)<br><br></div><div>or <br><br></div><div>find_package(CUDA 9.0)<br><br></div><div>or both?<br><br></div><div>well I in the spirit of new CMake I chose project.<br></div><div><br></div><div>But now the question... how does CMake 3.9 support finding the cudart.lib (or cudafft) or say libs in the SDK( such as gluts or glews or FreeImage).  Well the answer as far as I can tell ... it does not.  It's not documented and so I checked out the 3.9 source and I am reverse engineering it to figure out how it works or what works and does not and what is impled/not impled.  So what's a CMake 3.+'er (me) to do?  (well after crying as to the state of things)  I could:<br><br># -----------------------------------------------------------------------------<br>add_library( cuda_toolkit_interface INTERFACE )<br>target_include_directories( <br>    cuda_toolkit_interface <br>    INTERFACE<br>         ${CUDA_TOOLKIT_LIB_DIR}<br>)<br><br>target_link_libraries( <br>    cuda_toolkit_interface <br>    INTERFACE<br>        cuda_rt_static    <br>)<br><br>add_library( cuda_sdk_interface INTERFACE )<br>target_include_directories( <br>    cuda_sdk_interface <br>    INTERFACE<br>        ${CUDA_SDK_INCLUDE_DIR} <br>) <br># -----------------------------------------------------------------------------<br></div><div><br></div><div>then when linking a target that needs said inherited build properties I could:<br></div><div><br>target_link_libraries(<br>    rendertest<br>    PRIVATE<br>    cuda_toolkit_interface<br>    cuda_sdk_interface<br>    boost_interface<br>    opengl_interface<br>    shaderslib<br>)<br><br></div><div>say for any target needing cuda.<br></div><div><br><br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><p dir="ltr">I entirely agree with for the rest. CMake badly documenting good practices or even giving tutorials is an issue. Probably the biggest issue I found. I myself still fight after years of using and experimenting with it. This lead to a plethora of badly written cmakelists.txt or module scripts, that even people in this list still advocates without understanding the problems behind it. Even some tutorial series found on <a href="http://github.com" target="_blank">github.com</a> or used by coverage websites do it wrong. </p></blockquote><div>Yes glad and at the same time sorry to hear someone has had some of the same experience I have had and I say these things in hopes CMake will get fixed/better, but hey again maybe I am wrong.   <br><br>I have been rewriting my CMake files to support new target/properties and for the most part I no longer have to use my parameterized variables and custom project macros (add_project_config, add_project_executable, and add_project_library - which sadly had to use LINK_DIRECTORIES)  with VAR ARGS parsing to get the concept of "inherited build properties" based on my jam experience from Boost.Build... so kudos to CMake for that if only for LIBPATH an hence the post.  <br><br>Sadly I knew the answer even before I asked the question based on using CMake since 2009 and even giving a teaching lecture on it to promote it's use where I also promoted inherited build properties even though CMake at at the time did not support it directly.<br></div><div><br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<p dir="ltr">At the moment the only reference I trust is Daniel's presentation and some of the internal cmake scripts. </p>
<p dir="ltr">While not solving your problem, I documented most of my findings in this small template /reference <a href="https://github.com/Lectem/cpp-boilerplate" target="_blank">https://github.com/Lectem/cpp-<wbr>boilerplate</a> (which might still do things the wrong way) <br></p></blockquote><div><br></div><div>Yes just at line 22 I already have a problem.... that did not take long.<br><br></div><div>1) project does not specify VERSION and project name  <span class="gmail-pl-s">"CPP-BoilerPlate"<span class="gmail-"> </span>does not incorporate ver string such as <br><br></span></div><div><br><span class="gmail-pl-s">SET(MAJOR_VERSION 1)</span><br><span class="gmail-pl-s">SET(</span><span class="gmail-pl-s"><span class="gmail-pl-s"><span class="gmail-pl-s">MINOR_VERSION</span></span> 2)</span><br><span class="gmail-pl-s">SET(</span><span class="gmail-pl-s"><span class="gmail-pl-s"><span class="gmail-pl-s"><span class="gmail-pl-s">MAINTENANCE</span>_VERSION</span></span> 3)<br></span></div><div><span class="gmail-pl-s"><br></span></div><div><span class="gmail-pl-s">and then<br></span></div><div><span class="gmail-pl-s"><br></span><span class="gmail-pl-s">project( "CPP-BoilerPlate-${MAJOR_VERSION}</span><span class="gmail-pl-s">.</span><span class="gmail-pl-s"><span class="gmail-pl-s">${MINOR_VERSION}</span></span><span class="gmail-pl-s">.</span><span class="gmail-pl-s"><span class="gmail-pl-s">${</span></span><span class="gmail-pl-s"><span class="gmail-pl-s"><span class="gmail-pl-s">MAINTENANCE</span>_VERSION}</span></span><span class="gmail-pl-s">" VERSION </span><span class="gmail-pl-s">${MAJOR_VERSION}</span><span class="gmail-pl-s">.</span><span class="gmail-pl-s"><span class="gmail-pl-s">${MINOR_VERSION}</span></span><span class="gmail-pl-s">.</span><span class="gmail-pl-s"><span class="gmail-pl-s">${</span></span><span class="gmail-pl-s"><span class="gmail-pl-s"><span class="gmail-pl-s">MAINTENANCE</span>_VERSION}</span></span><span class="gmail-pl-s"></span><br><span class="gmail-pl-s"><span class="gmail-pl-s"></span> C CXX)<br><br></span></div><div><span class="gmail-pl-s">as what is CMAKE_INSTALL_PREFIX by default across versions?  What does VERSION do in project?  Well I know what it does not affect... yep </span><span class="gmail-pl-s">CMAKE_INSTALL_PREFIX.  Try compiling and installing on Windows multiple versions of this project see what you get.<br><br></span></div><div><span class="gmail-pl-s">3rd party package developers end up blasting away prior versions... maybe by design but who knows in my experience (IME).<br><br></span></div><div><span class="gmail-pl-s">Again though not as though CMake discusses "best practices" here or make VERSION actually do something useful as say append to CMAKE_INSTALL_PREFIX </span><br><span class="gmail-pl-s">${MAJOR_VERSION}</span><span class="gmail-pl-s">.</span><span class="gmail-pl-s"><span class="gmail-pl-s">${MINOR_VERSION}</span></span><span class="gmail-pl-s">.</span><span class="gmail-pl-s"><span class="gmail-pl-s">${</span></span><span class="gmail-pl-s"><span class="gmail-pl-s"><span class="gmail-pl-s">MAINTENANCE</span>_VERSION}.<br><br></span></span></div><div><span class="gmail-pl-s"><span class="gmail-pl-s">Thanks for the link/resource I take form it any good bits I can use at 157 lines it is not all that realistic of a full blown project with multiple dependencies mixed mode VS projs and CMake gen projs and other real world shenanigans.<br></span></span></div></div><br></div></div>