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

Nitin Gupta ngupta at GlobespanVirata . com
Mon, 14 Jul 2003 15:20:07 +0530


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);
+    }
+
+
+
  }