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

Bill Hoffman bill . hoffman at kitware . com
Tue, 15 Jul 2003 11:16:51 -0400


At 10:45 AM 7/15/2003, Nitin Gupta wrote:
>Hi Bill,
>        Thanks for your help.
>        Yes it works, I have tested with my projects
>        on windows. I'll revert back my code for Linux
>        too and would test with Linux makefiles too.
>
>        There are a few more things I'm looking for. I think
>        its better to seek you advise whether these can be done
>        by rewriting CMakeLists.txt rather then hacking the code:
>
>        1.) Overriding compilation flags for one or more
>        source files of a project. The COMPILE_FLAGS source file
>        property helps in appending extra flags to default flags.
>        I'm looking for some mechanism of passing special
>        compilation flags to a few files in a project.

I suppose you could do this by using the COMPILE_FLAGS on each source file.
You could save the regular flags into a variable:
SET(CMAKE_CXX_FLAGS_SAVE ${CMAKE_CXX_FLAGS})
# now set the one used by default to nothing
SET(CMAKE_CXX_FLAGS )

# set all the files to have the default ones
FOREACH(SRC ${SOURCES})
     SET_SOURCE_FILE_PROPERTIES(${SRC} COMPILE_FLAGS ${CMAKE_CXX_FLAGS_SAVE})
ENDFOREACH(SRC)

# now override any of the files you want to with other flags

>        2.) Post linking command execution over the binary.
>        Both for Linux and windows.

This is already done in cvs cmake with the ADD_CUSTOM_COMMAND:

  "  ADD_CUSTOM_COMMAND(TARGET target\n"
      "                     PRE_BUILD | PRE_LINK | POST_BUILD\n"
      "                     COMMAND command\n"
      "                     [ARGS [args...]]\n"
      "                     [COMMENT comment])\n"
      "This defines a new command that will be associated with "
      "building the specified target. When the command will "
      "happen is determined by whether you specify\n"
      "PRE_BUILD - run before all other dependencies\n"
      "PRE_LINK - run after other dependencies\n"
      "POST_BUILD - run after the target has been built\n";

It should be in the next major release of cmake.


-Bill

>Thanks and Regards,
>Nitin
>
>
>
>
>
>
>
>> -----Original Message-----
>> From: Bill Hoffman [mailto:bill . hoffman at kitware . com]
>> Sent: Monday, July 14, 2003 7:32 PM
>> To: Nitin Gupta; cmake at public . kitware . com
>> Subject: Re: [Cmake] [PATCH] Custom LIB/EXE output path for each
>> CMakeList.txt
>>
>>
>> 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(),fullLibpat
>> h.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
>>
>>
>>
>
>_______________________________________________
>Cmake mailing list
>Cmake at cmake . org
>http://www . cmake . org/mailman/listinfo/cmake