summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Modules/Automoc.cmake158
-rw-r--r--Modules/AutomocInfo.cmake.in13
-rw-r--r--Source/cmAddExecutableCommand.cxx30
-rw-r--r--Source/cmQtAutomoc.cxx126
-rw-r--r--Source/cmQtAutomoc.h6
-rw-r--r--Source/cmake.cxx7
-rw-r--r--Source/cmake.h1
7 files changed, 340 insertions, 1 deletions
diff --git a/Modules/Automoc.cmake b/Modules/Automoc.cmake
new file mode 100644
index 0000000..1e77c96
--- /dev/null
+++ b/Modules/Automoc.cmake
@@ -0,0 +1,158 @@
+
+# AUTOMOC4_MOC_HEADERS(<target> header1.h header2.h ...)
+# Use this to add more header files to be processed with automoc4.
+#
+# AUTOMOC4_ADD_EXECUTABLE(<target_NAME> src1 src2 ...)
+# This macro does the same as ADD_EXECUTABLE, but additionally
+# adds automoc4 handling for all source files.
+#
+# AUTOMOC4_ADD_LIBRARY(<target_NAME> src1 src2 ...)
+# This macro does the same as ADD_LIBRARY, but additionally
+# adds automoc4 handling for all source files.
+
+# Internal helper macro, may change or be removed anytime:
+# _ADD_AUTOMOC4_TARGET(<target_NAME> <SRCS_VAR>)
+#
+# Since version 0.9.88:
+# The following two macros are only to be used for KDE4 projects
+# and do something which makes sure automoc4 works for KDE. Don't
+# use them anywhere else. See kdelibs/cmake/modules/KDE4Macros.cmake.
+# _AUTOMOC4_KDE4_PRE_TARGET_HANDLING(<target_NAME> <SRCS_VAR>)
+# _AUTOMOC4_KDE4_POST_TARGET_HANDLING(<target_NAME>)
+
+# Copyright (C) 2007 Matthias Kretz <kretz@kde.org>
+# Copyright (C) 2008-2009 Alexander Neundorf <neundorf@kde.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+macro (AUTOMOC4_MOC_HEADERS _target_NAME)
+ set (_headers_to_moc)
+ foreach (_current_FILE ${ARGN})
+ get_filename_component(_suffix "${_current_FILE}" EXT)
+ if (".h" STREQUAL "${_suffix}" OR ".hpp" STREQUAL "${_suffix}" OR ".hxx" STREQUAL "${_suffix}" OR ".H" STREQUAL "${_suffix}")
+ list(APPEND _headers_to_moc ${_current_FILE})
+ else (".h" STREQUAL "${_suffix}" OR ".hpp" STREQUAL "${_suffix}" OR ".hxx" STREQUAL "${_suffix}" OR ".H" STREQUAL "${_suffix}")
+ message(STATUS "AUTOMOC4_MOC_HEADERS: ignoring non-header file ${_current_FILE}")
+ endif (".h" STREQUAL "${_suffix}" OR ".hpp" STREQUAL "${_suffix}" OR ".hxx" STREQUAL "${_suffix}" OR ".H" STREQUAL "${_suffix}")
+ endforeach (_current_FILE)
+ # need to create moc_<filename>.cpp file using automoc4
+ # and add it to the target
+ if(_headers_to_moc)
+ set(_automoc4_headers_${_target_NAME} "${_headers_to_moc}")
+ endif(_headers_to_moc)
+endmacro (AUTOMOC4_MOC_HEADERS)
+
+
+macro(_ADD_AUTOMOC4_TARGET _target_NAME _SRCS)
+ set(_moc_files)
+ set(_moc_headers)
+
+ # first list all explicitly set headers
+ foreach(_header_to_moc ${_automoc4_headers_${_target_NAME}} )
+ get_filename_component(_abs_header ${_header_to_moc} ABSOLUTE)
+ list(APPEND _moc_headers ${_abs_header})
+ endforeach(_header_to_moc)
+
+ # now add all the sources for the automoc
+ foreach (_current_FILE ${${_SRCS}})
+ get_filename_component(_abs_current_FILE "${_current_FILE}" ABSOLUTE)
+ get_source_file_property(_skip "${_abs_current_FILE}" SKIP_AUTOMOC)
+ get_source_file_property(_generated "${_abs_current_FILE}" GENERATED)
+
+ if(NOT _generated AND NOT _skip)
+ get_filename_component(_suffix "${_current_FILE}" EXT)
+ # skip every source file that's not C++
+ if(_suffix STREQUAL ".cpp" OR _suffix STREQUAL ".cc" OR _suffix STREQUAL ".cxx" OR _suffix STREQUAL ".C" OR _suffix STREQUAL ".mm")
+ list(APPEND _moc_files ${_abs_current_FILE})
+ endif(_suffix STREQUAL ".cpp" OR _suffix STREQUAL ".cc" OR _suffix STREQUAL ".cxx" OR _suffix STREQUAL ".C" OR _suffix STREQUAL ".mm")
+ endif(NOT _generated AND NOT _skip)
+ endforeach (_current_FILE)
+
+ if(_moc_files OR _moc_headers)
+ set(_automoc_source "${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}.cpp")
+ get_directory_property(_moc_incs INCLUDE_DIRECTORIES)
+ get_directory_property(_moc_defs DEFINITIONS)
+ get_directory_property(_moc_cdefs COMPILE_DEFINITIONS)
+
+ # configure_file replaces _moc_files, _moc_incs, _moc_cdefs and _moc_defs
+ set(_automocTargetDir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_target_NAME}.dir/" )
+ set(AM_TARGET_NAME ${_target_NAME})
+ configure_file(${CMAKE_ROOT}/Modules/AutomocInfo.cmake.in ${_automocTargetDir}/AutomocInfo.cmake @ONLY)
+
+ add_custom_target(${_target_NAME}
+ COMMAND ${CMAKE_COMMAND} -E cmake_automoc "${_automocTargetDir}" )
+
+ set_source_files_properties(${_automoc_source} PROPERTIES GENERATED TRUE)
+ get_directory_property(_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
+ list(APPEND _extra_clean_files "${_automoc_source}")
+ set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${_extra_clean_files}")
+ set(${_SRCS} ${_automoc_source} ${${_SRCS}})
+ endif(_moc_files OR _moc_headers)
+endmacro(_ADD_AUTOMOC4_TARGET)
+
+
+macro(AUTOMOC4_ADD_EXECUTABLE _target_NAME)
+ set(_SRCS ${ARGN})
+
+ set(_add_executable_param)
+ foreach(_argName "WIN32" "MACOSX_BUNDLE" "EXCLUDE_FROM_ALL")
+ list(FIND _SRCS ${_argName} _index)
+ if(_index GREATER -1)
+ list(APPEND _add_executable_param ${_argName})
+ list(REMOVE_AT _SRCS ${_index})
+ endif(_index GREATER -1)
+ endforeach(_argName)
+
+ _add_automoc4_target("${_target_NAME}_automoc" _SRCS)
+ add_executable(${_target_NAME} ${_add_executable_param} ${_SRCS})
+ add_dependencies(${_target_NAME} "${_target_NAME}_automoc")
+
+endmacro(AUTOMOC4_ADD_EXECUTABLE)
+
+
+macro(AUTOMOC4_ADD_LIBRARY _target_NAME)
+ set(_SRCS ${ARGN})
+
+ set(_add_executable_param)
+ foreach(_argName "STATIC" "SHARED" "MODULE" "EXCLUDE_FROM_ALL")
+ list(FIND _SRCS ${_argName} _index)
+ if(_index GREATER -1)
+ list(APPEND _add_executable_param ${_argName})
+ list(REMOVE_AT _SRCS ${_index})
+ endif(_index GREATER -1)
+ endforeach(_argName)
+
+ _add_automoc4_target("${_target_NAME}_automoc" _SRCS)
+ add_library(${_target_NAME} ${_add_executable_param} ${_SRCS})
+ add_dependencies(${_target_NAME} "${_target_NAME}_automoc")
+endmacro(AUTOMOC4_ADD_LIBRARY)
+
+
+macro(_AUTOMOC4_KDE4_PRE_TARGET_HANDLING _target _srcs)
+ _add_automoc4_target("${_target}_automoc" ${_srcs})
+endmacro(_AUTOMOC4_KDE4_PRE_TARGET_HANDLING)
+
+
+macro(_AUTOMOC4_KDE4_POST_TARGET_HANDLING _target)
+ add_dependencies(${_target} "${_target}_automoc")
+endmacro(_AUTOMOC4_KDE4_POST_TARGET_HANDLING)
diff --git a/Modules/AutomocInfo.cmake.in b/Modules/AutomocInfo.cmake.in
new file mode 100644
index 0000000..2dc3aa2
--- /dev/null
+++ b/Modules/AutomocInfo.cmake.in
@@ -0,0 +1,13 @@
+set(AM_SOURCES "@_moc_files@" )
+set(AM_HEADERS "@_moc_headers@" )
+set(AM_MOC_COMPILE_DEFINITIONS "@_moc_compile_defs@")
+set(AM_MOC_DEFINITIONS "@_moc_defs@")
+set(AM_MOC_INCLUDES "@_moc_incs@")
+set(AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE "@CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE@")
+set(AM_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@/")
+set(AM_CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@/")
+set(AM_QT_MOC_EXECUTABLE "@QT_MOC_EXECUTABLE@")
+set(AM_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/")
+set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/")
+set(AM_QT_VERSION_MAJOR "@QT_VERSION_MAJOR@" )
+set(AM_TARGET_NAME "@_moc_target_name@")
diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
index a625c47..9710d20 100644
--- a/Source/cmAddExecutableCommand.cxx
+++ b/Source/cmAddExecutableCommand.cxx
@@ -10,6 +10,7 @@
See the License for more information.
============================================================================*/
#include "cmAddExecutableCommand.h"
+#include "cmQtAutomoc.h"
// cmExecutableCommand
bool cmAddExecutableCommand
@@ -29,6 +30,7 @@ bool cmAddExecutableCommand
bool use_macbundle = false;
bool excludeFromAll = false;
bool importTarget = false;
+ bool doAutomoc = false;
while ( s != args.end() )
{
if (*s == "WIN32")
@@ -41,6 +43,11 @@ bool cmAddExecutableCommand
++s;
use_macbundle = true;
}
+ else if ( *s == "AUTOMOC" )
+ {
+ ++s;
+ doAutomoc = true;
+ }
else if(*s == "EXCLUDE_FROM_ALL")
{
++s;
@@ -58,12 +65,18 @@ bool cmAddExecutableCommand
}
// Special modifiers are not allowed with IMPORTED signature.
- if(importTarget && (use_win32 || use_macbundle || excludeFromAll))
+ if(importTarget
+ && (use_win32 || use_macbundle || excludeFromAll || doAutomoc))
{
if(use_win32)
{
this->SetError("may not be given WIN32 for an IMPORTED target.");
}
+ else if(doAutomoc)
+ {
+ this->SetError(
+ "may not be given AUTOMOC for an IMPORTED target.");
+ }
else if(use_macbundle)
{
this->SetError(
@@ -113,6 +126,14 @@ bool cmAddExecutableCommand
}
std::vector<std::string> srclists(s, args.end());
+ cmQtAutomoc* automoc = 0;
+ if ( doAutomoc )
+ {
+ automoc = new cmQtAutomoc;
+ automoc->SetupAutomocTarget(this->Makefile, exename.c_str(), srclists);
+ }
+
+
cmTarget* tgt = this->Makefile->AddExecutable(exename.c_str(), srclists,
excludeFromAll);
if ( use_win32 )
@@ -124,5 +145,12 @@ bool cmAddExecutableCommand
tgt->SetProperty("MACOSX_BUNDLE", "ON");
}
+ if ( automoc )
+ {
+ automoc->AddTargetDependency(this->Makefile, tgt);
+ delete automoc;
+ automoc = 0;
+ }
+
return true;
}
diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
index 5494b2a..1431551 100644
--- a/Source/cmQtAutomoc.cxx
+++ b/Source/cmQtAutomoc.cxx
@@ -1,6 +1,7 @@
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmSourceFile.h"
#include "cmSystemTools.h"
#include "cmQtAutomoc.h"
@@ -16,6 +17,131 @@ cmQtAutomoc::cmQtAutomoc()
}
+void cmQtAutomoc::SetupAutomocTarget(cmMakefile* makefile,
+ const char* targetName,
+ std::vector<std::string>& srcs)
+{
+ // don't do anything if there is no Qt4:
+ std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
+ if (qtMajorVersion != "4")
+ {
+ return;
+ }
+
+ std::string automocTargetName = targetName;
+ automocTargetName += "_automoc";
+
+ std::string targetDir = makefile->GetCurrentOutputDirectory();
+ targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory();
+ targetDir += "/";
+ targetDir += automocTargetName;
+ targetDir += ".dir/";
+
+ cmCustomCommandLine currentLine;
+ currentLine.push_back(makefile->GetCMakeInstance()->GetCMakeCommand());
+ currentLine.push_back("-E");
+ currentLine.push_back("cmake_automoc");
+ currentLine.push_back(targetDir);
+
+ cmCustomCommandLines commandLines;
+ commandLines.push_back(currentLine);
+
+ std::string workingDirectory = cmSystemTools::CollapseFullPath(
+ "", makefile->GetCurrentOutputDirectory());
+
+ std::vector<std::string> depends;
+
+ cmTarget* target = makefile->AddUtilityCommand(automocTargetName.c_str(),
+ true,
+ workingDirectory.c_str(), depends,
+ commandLines, false, "Automoc target");
+
+ std::string _moc_files;
+ std::string _moc_headers;
+ const char* sepFiles = "";
+ const char* sepHeaders = "";
+ for(std::vector<std::string>::const_iterator fileIt = srcs.begin();
+ fileIt != srcs.end();
+ ++fileIt)
+ {
+ std::string absFile = cmSystemTools::CollapseFullPath(
+ fileIt->c_str(), makefile->GetCurrentDirectory());
+
+ bool skip = false;
+ bool generated = false;
+ cmSourceFile* sf = makefile->GetSource(absFile.c_str());
+ if (sf)
+ {
+ skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC"));
+ generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"));
+ }
+
+ if ((skip==false) && (generated == false))
+ {
+ std::string ext = cmSystemTools::GetFilenameExtension(fileIt->c_str());
+ cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(ext.c_str());
+ if (fileType == cmSystemTools::CXX_FILE_FORMAT)
+ {
+ _moc_files += sepFiles;
+ _moc_files += absFile;
+ sepFiles = ";";
+ }
+ else if (fileType == cmSystemTools::HEADER_FILE_FORMAT)
+ {
+ _moc_headers += sepHeaders;
+ _moc_headers += absFile;
+ sepHeaders = ";";
+ }
+ }
+ }
+
+ std::string _moc_incs = makefile->GetProperty("INCLUDE_DIRECTORIES");
+ std::string _moc_defs = makefile->GetProperty("DEFINITIONS");
+ std::string _moc_compile_defs = makefile->GetProperty("COMPILE_DEFINITIONS");
+ // forget the variables added here afterwards again:
+ cmMakefile::ScopePushPop varScope(makefile);
+ static_cast<void>(varScope);
+
+ makefile->AddDefinition("_moc_target_name", automocTargetName.c_str());
+ makefile->AddDefinition("_moc_incs", _moc_incs.c_str());
+ makefile->AddDefinition("_moc_defs", _moc_defs.c_str());
+ makefile->AddDefinition("_moc_compile_defs", _moc_compile_defs.c_str());
+ makefile->AddDefinition("_moc_files", _moc_files.c_str());
+ makefile->AddDefinition("_moc_headers", _moc_headers.c_str());
+
+ const char* cmakeRoot = makefile->GetDefinition("CMAKE_ROOT");
+ std::string inputFile = cmakeRoot;
+ inputFile += "/Modules/AutomocInfo.cmake.in";
+ std::string outputFile = targetDir;
+ outputFile += "/AutomocInfo.cmake";
+ makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(),
+ false, true, false);
+
+ std::string mocCppFile = makefile->GetCurrentOutputDirectory();
+ mocCppFile += "/";
+ mocCppFile += automocTargetName;
+ mocCppFile += ".cpp";
+ makefile->GetOrCreateSource(mocCppFile.c_str(), true);
+ srcs.push_back(mocCppFile);
+
+}
+
+
+void cmQtAutomoc::AddTargetDependency(cmMakefile* makefile, cmTarget* target)
+{
+ // don't do anything if there is no Qt4:
+ std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
+ if (qtMajorVersion != "4")
+ {
+ return;
+ }
+
+ std::string automocTargetName = target->GetName();
+ automocTargetName += "_automoc";
+ target->AddUtility(automocTargetName.c_str());
+}
+
+
bool cmQtAutomoc::Run(const char* targetDirectory)
{
cmake cm;
diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h
index 891b47a..e573610 100644
--- a/Source/cmQtAutomoc.h
+++ b/Source/cmQtAutomoc.h
@@ -10,6 +10,12 @@ public:
cmQtAutomoc();
bool Run(const char* targetDirectory);
+ void SetupAutomocTarget(cmMakefile* makefile,
+ const char* targetName,
+ std::vector<std::string>& srcs);
+
+ void AddTargetDependency(cmMakefile* makefile, cmTarget* target);
+
private:
cmGlobalGenerator* CreateGlobalGenerator(cmake* cm,
const char* targetDirectory);
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 06229e0..c5eff1c 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -2927,6 +2927,13 @@ const char* cmake::GetCPackCommand()
return this->CPackCommand.c_str();
}
+
+const char* cmake::GetCMakeCommand()
+{
+ return this->CMakeCommand.c_str();
+}
+
+
void cmake::MarkCliAsUsed(const std::string& variable)
{
this->UsedCliVariables[variable] = true;
diff --git a/Source/cmake.h b/Source/cmake.h
index f2a2ae3..09f6c37 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -301,6 +301,7 @@ class cmake
*/
const char* GetCTestCommand();
const char* GetCPackCommand();
+ const char* GetCMakeCommand();
// Do we want debug output during the cmake run.
bool GetDebugOutput() { return this->DebugOutput; }