[Cmake] [PATCH] Custom LIB/EXE output path for each CMakeList.txt

Bill Hoffman bill . hoffman at kitware . com
Mon, 14 Jul 2003 10:01:32 -0400


There is no need for a patch.  This can already be done from the CMakeLists.txt files
with a SET command.   A common technique for overriding global cache variables is
to create a project specific variable, and then to use SET to override the global
one in the local directory.


So, the following is an example:

PROJECT(foo)
SET(FOO_EXE_PATH CACHE...)
SET(EXECUTABLE_OUTPUT_PATH ${FOO_EXE_PATH})


SUBDIR(BAR)


---BAR---
PROJECT(BAR)
SET(BAR_EXE_PATH CACHE...)
SET(EXECUTABLE_OUTPUT_PATH ${BAR_EXE_PATH})


EXECUTABLE_OUTPUT_PATH and LIBRARY_OUTPUT_PATH should remain global,
as many times you really do want one directory for a combined project.
For example ParaViewComplete which is a combination of VTK and ParaView
needs to have one.   The main reason for wanting one directory is so
that dll builds on windows can run without having to set the PATH.
There is no rpath on windows, however exes will look in the current directory
for dll's.

-Bill

At 05:50 AM 7/14/2003, Nitin Gupta wrote:
>Hi,
>        If a TARGET in the top level CMakeLists.txt depends
>        upon another target in a SUBDIR CMakeList.txt then
>        the EXECUTABLE_OUTPUT_PATH and LIBRARY_OUTPUT_PATH
>        of SUBDIR CMakeLists.txt is same as toplevel CMakeLists.txt.
>        If a different EXE.../LIBRAR.. path is specified then
>        the Makefiles genereted for top level CMakeList.txt
>        does not contain the correct path of dependent libraries
>        and hence the build breaks.
>
>        While   porting our projects to CMake(Linux/VC++) I
>        realized a need of such feature. The following patch
>        allows the CMakeLists.txt in SUBDIR to have different
>        EXECUTABLE_OUTPUT_PATH and LIBRARY_OUTPUT_PATH. Please
>        feel free to use the patch if it is of help to you.
>        I have taken the "diff" with 1.6.7 sources I downloaded
>        as tar.gz. If required I may post a diff with current CVS.
>
>        The patch does not mandate EXECUTABLE_OUTPUT
>        and LIBRARY_OUTPUT_PATH in every SUBDIR CMakeLitst.txt.
>        Hence the existing projects being build using CMake
>        won't break. The change is enabled for linux builds
>        only. I may extend it to VC++ if it is accepted.
>
>        I think the change is inline with the philosophy
>        of CMake and it does not break anything else. Since
>        I have a little exposure to CMake any comments related
>        to correctness and completeness (or anything other aspect)
>        of the patch would be valuable.
>
>Thanks and Regards
>Nitin
>
>
>Change Log Entry
>--------------
>2003-07-14      Nitin
>        * Source/cmMakefile.cxx, cmLocalUnixMakefileGenerator.cxx:
>        Changes fot Custom LIBRARY_OUTPUT_PATH and EXECUTABLE_OUTPUT_PATH
>        for each CMakeLists.txt. New CMake variable
>        <target>_CMAKE_OUTPUT_PATH added for each target.
>
>
>The Patch
>-------------
>*** cmLocalUnixMakefileGenerator.cxx.org        Mon Jul 14 09:21:58 2003
>--- cmLocalUnixMakefileGenerator.cxx.mod        Mon Jul 14 10:43:34 2003
>*************** void cmLocalUnixMakefileGenerator::Outpu
>*** 1235,1240 ****
>--- 1235,1255 ----
>              {
>              // Output this dependency.
>              this->OutputLibDepend(fout, lib->first.c_str());
>+           std::string libOutputPathVar = lib->first.c_str();
>+           libOutputPathVar += "_CMAKE_OUTPUT_PATH";
>+           std::string libPathVar = lib->first.c_str();
>+           libPathVar += "_CMAKE_PATH";
>+           const char * libOutputPath =
>m_Makefile->GetDefinition(libOutputPathVar.c_str());
>+           const char * libPath = m_Makefile->GetDefinition(libPathVar.c_str());
>+           std::string fullLibpath = libOutputPath;
>+           if(!cmSystemTools::FileIsFullPath(libOutputPath))
>+             {
>+             fullLibpath = libPath;
>+             if((libPath[strlen(libPath) -1] != '/') ||
>(libPath[strlen(libPath) -1] != '\\') )
>+               fullLibpath += "/";
>+               fullLibpath += libOutputPath;
>+             }
>+
>m_Makefile->AddLinkDirectoryForTarget(l->first.c_str(),fullLibpath.c_str());
>              }
>            }
>          }
>*************** void cmLocalUnixMakefileGenerator::Outpu
>*** 1310,1316 ****
>            cmSystemTools::Error("Unknown library type!");
>            return;
>            }
>!         if(m_LibraryOutputPath.size())
>            {
>            libpath = m_LibraryOutputPath;
>            }
>--- 1325,1337 ----
>            cmSystemTools::Error("Unknown library type!");
>            return;
>            }
>!         std::string dependLibPathVar = *lib + "_CMAKE_OUTPUT_PATH";
>!         if(m_Makefile->GetDefinition(dependLibPathVar.c_str()))
>!           {
>!           libpath = m_Makefile->GetDefinition(dependLibPathVar.c_str());
>!           libpath += "/";
>!           }
>!         else if(m_LibraryOutputPath.size())
>            {
>            libpath = m_LibraryOutputPath;
>            }
>*************** void cmLocalUnixMakefileGenerator::Outpu
>*** 1332,1338 ****
>        else
>          {
>          std::string exepath = cacheValue;
>!         if(m_ExecutableOutputPath.size())
>            {
>            exepath = m_ExecutableOutputPath;
>            }
>--- 1353,1365 ----
>        else
>          {
>          std::string exepath = cacheValue;
>!         std::string dependExePathVar = *lib + "_CMAKE_OUTPUT_PATH";
>!         if(m_Makefile->GetDefinition(dependExePathVar.c_str()))
>!           {
>!           exepath = m_Makefile->GetDefinition(dependExePathVar.c_str());
>!           exepath += "/";
>!           }
>!         else if(m_ExecutableOutputPath.size())
>            {
>            exepath = m_ExecutableOutputPath;
>            }
>*************** void cmLocalUnixMakefileGenerator::Outpu
>*** 1435,1441 ****
>        {
>        // if the library is not in the current directory, then get the full
>        // path to it
>!       if(m_LibraryOutputPath.size())
>          {
>          libpath = m_LibraryOutputPath;
>          }
>--- 1462,1477 ----
>        {
>        // if the library is not in the current directory, then get the full
>        // path to it
>!       libPath = name;
>!       libPath += "_CMAKE_OUTPUT_PATH";
>!       const char * libOutputPath =
>m_Makefile->GetDefinition(libPath.c_str());
>!       if(libOutputPath)
>!         {
>!         libpath = libOutputPath;
>!       if(libOutputPath[strlen(libOutputPath) - 1] != '/')
>!         libpath += "/";
>!         }
>!       else if(m_LibraryOutputPath.size())
>          {
>          libpath = m_LibraryOutputPath;
>          }
>*************** void cmLocalUnixMakefileGenerator::Outpu
>*** 1492,1498 ****
>        {
>        // if the exe/utility is not in the current directory, then get the
>full
>        // path to it
>!       if(m_ExecutableOutputPath.size())
>          {
>          exepath = m_ExecutableOutputPath;
>          }
>--- 1528,1543 ----
>        {
>        // if the exe/utility is not in the current directory, then get the
>full
>        // path to it
>!       exepath = name;
>!       exepath += "_CMAKE_OUTPUT_PATH";
>!       const char * exeOutputPath =
>m_Makefile->GetDefinition(exepath.c_str());
>!       if(exeOutputPath)
>!         {
>!         exepath = exeOutputPath;
>!       if(libOutputPath[strlen(exeOutputPath) - 1] != '/')
>!         exepath += "/";
>!         }
>!       else if(m_ExecutableOutputPath.size())
>          {
>          exepath = m_ExecutableOutputPath;
>          }
>*** cmMakefile.cxx.org  Fri Mar 14 10:38:01 2003
>--- cmMakefile.cxx.mod  Mon Jul 14 10:48:38 2003
>*************** void cmMakefile::AddLibrary(const char*
>*** 694,699 ****
>--- 694,710 ----
>                    this->GetCurrentOutputDirectory(),
>                    "Path to a library", cmCacheManager::INTERNAL);
>
>+   if(this->GetDefinition("LIBRARY_OUTPUT_PATH"))
>+   {
>+     libPath = lname;
>+     libPath += "_CMAKE_OUTPUT_PATH";
>+     this->GetCacheManager()->
>+       AddCacheEntry(libPath.c_str(),
>+                     this->GetDefinition("LIBRARY_OUTPUT_PATH"),
>+                     "Library output path", cmCacheManager::INTERNAL);
>+   }
>+
>+
>    // Add an entry into the cache
>    std::string ltname = lname;
>    ltname += "_LIBRARY_TYPE";
>*************** void cmMakefile::AddExecutable(const cha
>*** 759,764 ****
>--- 770,788 ----
>      AddCacheEntry(exePath.c_str(),
>                    this->GetCurrentOutputDirectory(),
>                    "Path to an executable", cmCacheManager::INTERNAL);
>+
>+    if(this->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
>+    {
>+      exePath = exeName;
>+      exePath += "_CMAKE_OUTPUT_PATH";
>+      this->GetCacheManager()->
>+       AddCacheEntry(exePath.c_str(),
>+                     this->GetDefinition("EXECUTABLE_OUTPUT_PATH"),
>+                     "Executable output path", cmCacheManager::INTERNAL);
>+    }
>+
>+
>+
>  }
>
>
>
>_______________________________________________
>Cmake mailing list
>Cmake at cmake . org
>http://www . cmake . org/mailman/listinfo/cmake