Merge topic 'output-compile-lines'
cdc2b41 Fix CompileCommandOutput test build on Windows 7039d1f Fix CompileCommandOutput test for Make tools not supporting spaces 4268e3d run_compile_commands: Cast istream::get() result to char c45c60b run_compile_commands: Avoid extra stl vector conversion 7c5be51 run_compile_commands: Avoid shadow in std::map<>::at workaround 169bb05 Provide std::map<>::at for use in run_compile_commands 4e2185c Make std::map usage more portable in language=>flags/defines maps a7e7a04 Fix run_compile_commands build on Apple GCC 3.3 c9174c0 Fix signed/unsigned comparison in EscapeJSON 8346a28 Only offer the compile command output feature on unix systems 0e6b05f Adds a test for the compile command line output. 5674844 make compile command output optional fe07b05 implement cxx command output 65c0c24 cache flags and defines 3f064ef refactor flags and defines
This commit is contained in:
commit
e51bbc14f6
@ -50,6 +50,12 @@ IF(CMAKE_GENERATOR MATCHES "Makefiles")
|
||||
IF(DEFINED CMAKE_RULE_MESSAGES)
|
||||
SET_PROPERTY(GLOBAL PROPERTY RULE_MESSAGES ${CMAKE_RULE_MESSAGES})
|
||||
ENDIF(DEFINED CMAKE_RULE_MESSAGES)
|
||||
IF(CMAKE_GENERATOR MATCHES "Unix Makefiles")
|
||||
SET(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL
|
||||
"Enable/Disable output of compile commands during generation."
|
||||
)
|
||||
MARK_AS_ADVANCED(CMAKE_EXPORT_COMPILE_COMMANDS)
|
||||
ENDIF(CMAKE_GENERATOR MATCHES "Unix Makefiles")
|
||||
ENDIF(CMAKE_GENERATOR MATCHES "Makefiles")
|
||||
|
||||
|
||||
|
@ -30,6 +30,7 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3()
|
||||
#else
|
||||
this->UseLinkScript = true;
|
||||
#endif
|
||||
this->CommandDatabase = NULL;
|
||||
}
|
||||
|
||||
void cmGlobalUnixMakefileGenerator3
|
||||
@ -138,6 +139,17 @@ void cmGlobalUnixMakefileGenerator3
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::string EscapeJSON(const std::string& s) {
|
||||
std::string result;
|
||||
for (std::string::size_type i = 0; i < s.size(); ++i) {
|
||||
if (s[i] == '"' || s[i] == '\\') {
|
||||
result += '\\';
|
||||
}
|
||||
result += s[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void cmGlobalUnixMakefileGenerator3::Generate()
|
||||
{
|
||||
// first do superclass method
|
||||
@ -179,6 +191,35 @@ void cmGlobalUnixMakefileGenerator3::Generate()
|
||||
// write the main makefile
|
||||
this->WriteMainMakefile2();
|
||||
this->WriteMainCMakefile();
|
||||
|
||||
if (this->CommandDatabase != NULL) {
|
||||
*this->CommandDatabase << std::endl << "]";
|
||||
delete this->CommandDatabase;
|
||||
this->CommandDatabase = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand(
|
||||
const std::string &sourceFile, const std::string &workingDirectory,
|
||||
const std::string &compileCommand) {
|
||||
if (this->CommandDatabase == NULL)
|
||||
{
|
||||
std::string commandDatabaseName =
|
||||
std::string(this->GetCMakeInstance()->GetHomeOutputDirectory())
|
||||
+ "/compile_commands.json";
|
||||
this->CommandDatabase =
|
||||
new cmGeneratedFileStream(commandDatabaseName.c_str());
|
||||
*this->CommandDatabase << "[" << std::endl;
|
||||
} else {
|
||||
*this->CommandDatabase << "," << std::endl;
|
||||
}
|
||||
*this->CommandDatabase << "{" << std::endl
|
||||
<< " \"directory\": \"" << EscapeJSON(workingDirectory) << "\","
|
||||
<< std::endl
|
||||
<< " \"command\": \"" << EscapeJSON(compileCommand) << "\","
|
||||
<< std::endl
|
||||
<< " \"file\": \"" << EscapeJSON(sourceFile) << "\""
|
||||
<< std::endl << "}";
|
||||
}
|
||||
|
||||
void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
|
||||
|
@ -112,6 +112,10 @@ public:
|
||||
/** Record per-target progress information. */
|
||||
void RecordTargetProgress(cmMakefileTargetGenerator* tg);
|
||||
|
||||
void AddCXXCompileCommand(const std::string &sourceFile,
|
||||
const std::string &workingDirectory,
|
||||
const std::string &compileCommand);
|
||||
|
||||
protected:
|
||||
void WriteMainMakefile2();
|
||||
void WriteMainCMakefile();
|
||||
@ -176,6 +180,8 @@ protected:
|
||||
size_t CountProgressMarksInTarget(cmTarget* target,
|
||||
std::set<cmTarget*>& emitted);
|
||||
size_t CountProgressMarksInAll(cmLocalUnixMakefileGenerator3* lg);
|
||||
|
||||
cmGeneratedFileStream *CommandDatabase;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -249,32 +249,56 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
|
||||
std::string cmMakefileTargetGenerator::GetFlags(const std::string &l)
|
||||
{
|
||||
// write language flags for target
|
||||
std::set<cmStdString> languages;
|
||||
this->Target->GetLanguages(languages);
|
||||
// put the compiler in the rules.make file so that if it changes
|
||||
// things rebuild
|
||||
for(std::set<cmStdString>::const_iterator l = languages.begin();
|
||||
l != languages.end(); ++l)
|
||||
ByLanguageMap::iterator i = this->FlagsByLanguage.find(l);
|
||||
if (i == this->FlagsByLanguage.end())
|
||||
{
|
||||
cmStdString compiler = "CMAKE_";
|
||||
compiler += *l;
|
||||
compiler += "_COMPILER";
|
||||
*this->FlagFileStream << "# compile " << l->c_str() << " with " <<
|
||||
this->Makefile->GetSafeDefinition(compiler.c_str()) << "\n";
|
||||
}
|
||||
|
||||
for(std::set<cmStdString>::const_iterator l = languages.begin();
|
||||
l != languages.end(); ++l)
|
||||
{
|
||||
const char *lang = l->c_str();
|
||||
std::string flags;
|
||||
std::string defines;
|
||||
const char *lang = l.c_str();
|
||||
|
||||
bool shared = ((this->Target->GetType() == cmTarget::SHARED_LIBRARY) ||
|
||||
(this->Target->GetType() == cmTarget::MODULE_LIBRARY));
|
||||
|
||||
// Add language feature flags.
|
||||
this->AddFeatureFlags(flags, lang);
|
||||
|
||||
this->LocalGenerator->AddArchitectureFlags(flags, this->Target,
|
||||
lang, this->ConfigName);
|
||||
|
||||
// Fortran-specific flags computed for this target.
|
||||
if(l == "Fortran")
|
||||
{
|
||||
this->AddFortranFlags(flags);
|
||||
}
|
||||
|
||||
// Add shared-library flags if needed.
|
||||
this->LocalGenerator->AddSharedFlags(flags, lang, shared);
|
||||
|
||||
// Add include directory flags.
|
||||
this->AddIncludeFlags(flags, lang);
|
||||
|
||||
// Append old-style preprocessor definition flags.
|
||||
this->LocalGenerator->
|
||||
AppendFlags(flags, this->Makefile->GetDefineFlags());
|
||||
|
||||
// Add include directory flags.
|
||||
this->LocalGenerator->
|
||||
AppendFlags(flags,this->GetFrameworkFlags().c_str());
|
||||
|
||||
ByLanguageMap::value_type entry(l, flags);
|
||||
i = this->FlagsByLanguage.insert(entry).first;
|
||||
}
|
||||
return i->second;
|
||||
}
|
||||
|
||||
std::string cmMakefileTargetGenerator::GetDefines(const std::string &l)
|
||||
{
|
||||
ByLanguageMap::iterator i = this->DefinesByLanguage.find(l);
|
||||
if (i == this->DefinesByLanguage.end())
|
||||
{
|
||||
std::string defines;
|
||||
const char *lang = l.c_str();
|
||||
// Add the export symbol definition for shared library objects.
|
||||
if(const char* exportMacro = this->Target->GetExportMacro())
|
||||
{
|
||||
@ -294,40 +318,41 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
|
||||
this->LocalGenerator->AppendDefines
|
||||
(defines, this->Target->GetProperty(defPropName.c_str()), lang);
|
||||
|
||||
// Add language feature flags.
|
||||
this->AddFeatureFlags(flags, lang);
|
||||
ByLanguageMap::value_type entry(l, defines);
|
||||
i = this->DefinesByLanguage.insert(entry).first;
|
||||
}
|
||||
return i->second;
|
||||
}
|
||||
|
||||
this->LocalGenerator->AddArchitectureFlags(flags, this->Target,
|
||||
lang, this->ConfigName);
|
||||
void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
|
||||
{
|
||||
// write language flags for target
|
||||
std::set<cmStdString> languages;
|
||||
this->Target->GetLanguages(languages);
|
||||
// put the compiler in the rules.make file so that if it changes
|
||||
// things rebuild
|
||||
for(std::set<cmStdString>::const_iterator l = languages.begin();
|
||||
l != languages.end(); ++l)
|
||||
{
|
||||
cmStdString compiler = "CMAKE_";
|
||||
compiler += *l;
|
||||
compiler += "_COMPILER";
|
||||
*this->FlagFileStream << "# compile " << l->c_str() << " with " <<
|
||||
this->Makefile->GetSafeDefinition(compiler.c_str()) << "\n";
|
||||
}
|
||||
|
||||
// Fortran-specific flags computed for this target.
|
||||
if(*l == "Fortran")
|
||||
{
|
||||
this->AddFortranFlags(flags);
|
||||
}
|
||||
|
||||
// Add shared-library flags if needed.
|
||||
this->LocalGenerator->AddSharedFlags(flags, lang, shared);
|
||||
|
||||
// Add include directory flags.
|
||||
this->AddIncludeFlags(flags, lang);
|
||||
|
||||
// Append old-style preprocessor definition flags.
|
||||
this->LocalGenerator->
|
||||
AppendFlags(flags, this->Makefile->GetDefineFlags());
|
||||
|
||||
// Add include directory flags.
|
||||
this->LocalGenerator->
|
||||
AppendFlags(flags,this->GetFrameworkFlags().c_str());
|
||||
|
||||
*this->FlagFileStream << lang << "_FLAGS = " << flags << "\n\n";
|
||||
*this->FlagFileStream << lang << "_DEFINES = " << defines << "\n\n";
|
||||
for(std::set<cmStdString>::const_iterator l = languages.begin();
|
||||
l != languages.end(); ++l)
|
||||
{
|
||||
*this->FlagFileStream << *l << "_FLAGS = " << this->GetFlags(*l) << "\n\n";
|
||||
*this->FlagFileStream << *l << "_DEFINES = " << this->GetDefines(*l) <<
|
||||
"\n\n";
|
||||
}
|
||||
|
||||
// Add target-specific flags.
|
||||
if(this->Target->GetProperty("COMPILE_FLAGS"))
|
||||
{
|
||||
std::string flags;
|
||||
std::string flags;
|
||||
this->LocalGenerator->AppendFlags
|
||||
(flags, this->Target->GetProperty("COMPILE_FLAGS"));
|
||||
*this->FlagFileStream << "# TARGET_FLAGS = " << flags << "\n\n";
|
||||
@ -641,6 +666,9 @@ cmMakefileTargetGenerator
|
||||
vars.Flags = flags.c_str();
|
||||
vars.Defines = defines.c_str();
|
||||
|
||||
bool lang_is_c_or_cxx = ((strcmp(lang, "C") == 0) ||
|
||||
(strcmp(lang, "CXX") == 0));
|
||||
|
||||
// Construct the compile rules.
|
||||
{
|
||||
std::string compileRuleVar = "CMAKE_";
|
||||
@ -651,6 +679,23 @@ cmMakefileTargetGenerator
|
||||
std::vector<std::string> compileCommands;
|
||||
cmSystemTools::ExpandListArgument(compileRule, compileCommands);
|
||||
|
||||
if (this->Makefile->IsOn("CMAKE_EXPORT_COMPILE_COMMANDS") &&
|
||||
lang_is_c_or_cxx && compileCommands.size() == 1)
|
||||
{
|
||||
std::string compileCommand = compileCommands[0];
|
||||
this->LocalGenerator->ExpandRuleVariables(compileCommand, vars);
|
||||
std::string workingDirectory =
|
||||
this->LocalGenerator->Convert(
|
||||
this->Makefile->GetStartOutputDirectory(), cmLocalGenerator::FULL);
|
||||
compileCommand.replace(compileCommand.find(langFlags),
|
||||
langFlags.size(), this->GetFlags(lang));
|
||||
std::string langDefines = std::string("$(") + lang + "_DEFINES)";
|
||||
compileCommand.replace(compileCommand.find(langDefines),
|
||||
langDefines.size(), this->GetDefines(lang));
|
||||
this->GlobalGenerator->AddCXXCompileCommand(
|
||||
source.GetFullPath(), workingDirectory, compileCommand);
|
||||
}
|
||||
|
||||
// Expand placeholders in the commands.
|
||||
for(std::vector<std::string>::iterator i = compileCommands.begin();
|
||||
i != compileCommands.end(); ++i)
|
||||
@ -691,8 +736,6 @@ cmMakefileTargetGenerator
|
||||
}
|
||||
}
|
||||
|
||||
bool lang_is_c_or_cxx = ((strcmp(lang, "C") == 0) ||
|
||||
(strcmp(lang, "CXX") == 0));
|
||||
bool do_preprocess_rules = lang_is_c_or_cxx &&
|
||||
this->LocalGenerator->GetCreatePreprocessedSourceRules();
|
||||
bool do_assembly_rules = lang_is_c_or_cxx &&
|
||||
|
@ -216,6 +216,12 @@ protected:
|
||||
std::string MacContentDirectory;
|
||||
std::set<cmStdString> MacContentFolders;
|
||||
|
||||
typedef std::map<cmStdString, cmStdString> ByLanguageMap;
|
||||
std::string GetFlags(const std::string &l);
|
||||
ByLanguageMap FlagsByLanguage;
|
||||
std::string GetDefines(const std::string &l);
|
||||
ByLanguageMap DefinesByLanguage;
|
||||
|
||||
// Target-wide Fortran module output directory.
|
||||
bool FortranModuleDirectoryComputed;
|
||||
std::string FortranModuleDirectory;
|
||||
|
@ -445,6 +445,13 @@ public:
|
||||
args.push_back(*arg);
|
||||
}
|
||||
}
|
||||
void Store(std::vector<cmStdString>& args) const
|
||||
{
|
||||
for(char** arg = this->ArgV; arg && *arg; ++arg)
|
||||
{
|
||||
args.push_back(*arg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@ -456,6 +463,15 @@ void cmSystemTools::ParseUnixCommandLine(const char* command,
|
||||
argv.Store(args);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmSystemTools::ParseUnixCommandLine(const char* command,
|
||||
std::vector<cmStdString>& args)
|
||||
{
|
||||
// Invoke the underlying parser.
|
||||
cmSystemToolsArgV argv = cmsysSystem_Parse_CommandForUnix(command, 0);
|
||||
argv.Store(args);
|
||||
}
|
||||
|
||||
std::string cmSystemTools::EscapeWindowsShellArgument(const char* arg,
|
||||
int shell_flags)
|
||||
{
|
||||
|
@ -237,6 +237,8 @@ public:
|
||||
/** Parse arguments out of a unix command line string. */
|
||||
static void ParseUnixCommandLine(const char* command,
|
||||
std::vector<std::string>& args);
|
||||
static void ParseUnixCommandLine(const char* command,
|
||||
std::vector<cmStdString>& args);
|
||||
|
||||
/** Compute an escaped version of the given argument for use in a
|
||||
windows shell. See kwsys/System.h.in for details. */
|
||||
|
@ -30,3 +30,8 @@ endif()
|
||||
foreach(test ${CMakeLib_TESTS})
|
||||
add_test(CMakeLib.${test} CMakeLibTests ${test})
|
||||
endforeach()
|
||||
|
||||
if(TEST_CompileCommandOutput)
|
||||
add_executable(runcompilecommands run_compile_commands.cxx)
|
||||
target_link_libraries(runcompilecommands CMakeLib)
|
||||
endif()
|
||||
|
141
Tests/CMakeLib/run_compile_commands.cxx
Normal file
141
Tests/CMakeLib/run_compile_commands.cxx
Normal file
@ -0,0 +1,141 @@
|
||||
#include "cmSystemTools.h"
|
||||
|
||||
class CompileCommandParser {
|
||||
public:
|
||||
class CommandType: public std::map<cmStdString, cmStdString>
|
||||
{
|
||||
public:
|
||||
cmStdString const& at(cmStdString const& k) const
|
||||
{
|
||||
const_iterator i = this->find(k);
|
||||
if(i != this->end()) { return i->second; }
|
||||
static cmStdString emptyString;
|
||||
return emptyString;
|
||||
}
|
||||
};
|
||||
typedef std::vector<CommandType> TranslationUnitsType;
|
||||
|
||||
CompileCommandParser(std::ifstream *input)
|
||||
{
|
||||
this->Input = input;
|
||||
}
|
||||
|
||||
void Parse()
|
||||
{
|
||||
NextNonWhitespace();
|
||||
ParseTranslationUnits();
|
||||
}
|
||||
|
||||
const TranslationUnitsType& GetTranslationUnits()
|
||||
{
|
||||
return this->TranslationUnits;
|
||||
}
|
||||
|
||||
private:
|
||||
void ParseTranslationUnits()
|
||||
{
|
||||
this->TranslationUnits = TranslationUnitsType();
|
||||
ExpectOrDie('[', "at start of compile command file");
|
||||
do
|
||||
{
|
||||
ParseTranslationUnit();
|
||||
this->TranslationUnits.push_back(this->Command);
|
||||
} while(Expect(','));
|
||||
ExpectOrDie(']', "at end of array");
|
||||
}
|
||||
|
||||
void ParseTranslationUnit()
|
||||
{
|
||||
this->Command = CommandType();
|
||||
if(!Expect('{')) return;
|
||||
if(Expect('}')) return;
|
||||
do
|
||||
{
|
||||
ParseString();
|
||||
std::string name = this->String;
|
||||
ExpectOrDie(':', "between name and value");
|
||||
ParseString();
|
||||
std::string value = this->String;
|
||||
this->Command[name] = value;
|
||||
} while(Expect(','));
|
||||
ExpectOrDie('}', "at end of object");
|
||||
}
|
||||
|
||||
void ParseString()
|
||||
{
|
||||
this->String.clear();
|
||||
if(!Expect('"')) return;
|
||||
while (!Expect('"'))
|
||||
{
|
||||
Expect('\\');
|
||||
this->String.push_back(C);
|
||||
Next();
|
||||
}
|
||||
}
|
||||
|
||||
bool Expect(char c)
|
||||
{
|
||||
if(this->C == c)
|
||||
{
|
||||
NextNonWhitespace();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ExpectOrDie(char c, const std::string & message)
|
||||
{
|
||||
if (!Expect(c))
|
||||
ErrorExit(std::string("'") + c + "' expected " + message + ".");
|
||||
}
|
||||
|
||||
void NextNonWhitespace()
|
||||
{
|
||||
do { Next(); } while (IsWhitespace());
|
||||
}
|
||||
|
||||
void Next()
|
||||
{
|
||||
this->C = char(Input->get());
|
||||
if (this->Input->bad()) ErrorExit("Unexpected end of file.");
|
||||
}
|
||||
|
||||
void ErrorExit(const std::string &message) {
|
||||
std::cout << "ERROR: " << message;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bool IsWhitespace()
|
||||
{
|
||||
return (this->C == ' ' || this->C == '\t' ||
|
||||
this->C == '\n' || this->C == '\r');
|
||||
}
|
||||
|
||||
char C;
|
||||
TranslationUnitsType TranslationUnits;
|
||||
CommandType Command;
|
||||
std::string String;
|
||||
std::ifstream *Input;
|
||||
};
|
||||
|
||||
int main ()
|
||||
{
|
||||
std::ifstream file("compile_commands.json");
|
||||
CompileCommandParser parser(&file);
|
||||
parser.Parse();
|
||||
for(CompileCommandParser::TranslationUnitsType::const_iterator
|
||||
it = parser.GetTranslationUnits().begin(),
|
||||
end = parser.GetTranslationUnits().end(); it != end; ++it)
|
||||
{
|
||||
std::vector<cmStdString> command;
|
||||
cmSystemTools::ParseUnixCommandLine(it->at("command").c_str(), command);
|
||||
if (!cmSystemTools::RunSingleCommand(
|
||||
command, 0, 0, it->at("directory").c_str()))
|
||||
{
|
||||
std::cout << "ERROR: Failed to run command \""
|
||||
<< command[0] << "\"" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -11,6 +11,7 @@ MACRO(ADD_TEST_MACRO NAME COMMAND)
|
||||
--build-generator ${CMAKE_TEST_GENERATOR}
|
||||
--build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
|
||||
--build-project ${proj}
|
||||
${${NAME}_EXTRA_OPTIONS}
|
||||
--test-command ${COMMAND} ${ARGN})
|
||||
LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${dir}")
|
||||
ENDMACRO(ADD_TEST_MACRO)
|
||||
@ -39,6 +40,10 @@ CONFIGURE_FILE(${CMake_SOURCE_DIR}/Tests/EnforceConfig.cmake.in
|
||||
|
||||
# Testing
|
||||
IF(BUILD_TESTING)
|
||||
IF("${CMAKE_TEST_GENERATOR}" MATCHES "Unix Makefiles")
|
||||
SET(TEST_CompileCommandOutput 1)
|
||||
ENDIF()
|
||||
|
||||
ADD_SUBDIRECTORY(CMakeLib)
|
||||
|
||||
# Collect a list of all test build directories.
|
||||
@ -2031,6 +2036,13 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
|
||||
ENDIF()
|
||||
SET_TESTS_PROPERTIES(Contracts.${project} PROPERTIES TIMEOUT ${timeout})
|
||||
ENDFOREACH()
|
||||
|
||||
IF(TEST_CompileCommandOutput)
|
||||
SET(CompileCommandOutput_EXTRA_OPTIONS
|
||||
--build-options -DMAKE_SUPPORTS_SPACES=${MAKE_IS_GNU})
|
||||
ADD_TEST_MACRO(CompileCommandOutput
|
||||
"${CMake_BINARY_DIR}/Tests/CMakeLib/runcompilecommands")
|
||||
ENDIF()
|
||||
ENDIF(BUILD_TESTING)
|
||||
|
||||
SUBDIRS(CMakeTests)
|
||||
|
16
Tests/CompileCommandOutput/CMakeLists.txt
Normal file
16
Tests/CompileCommandOutput/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
||||
# a simple C only test case
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
project (CompileCommandOutput CXX)
|
||||
|
||||
SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
set(CMAKE_DEBUG_POSTFIX "_test_debug_postfix")
|
||||
IF(MAKE_SUPPORTS_SPACES)
|
||||
SET(test1_srcs "file with spaces.cxx")
|
||||
ELSE()
|
||||
SET(test1_srcs "file_with_underscores.cxx")
|
||||
ENDIF()
|
||||
ADD_LIBRARY(test1 STATIC ${test1_srcs})
|
||||
ADD_LIBRARY(test2 SHARED "../CompileCommandOutput/relative.cxx")
|
||||
INCLUDE_DIRECTORIES(${CompileCommandOutput_SOURCE_DIR}/../../Source)
|
||||
ADD_EXECUTABLE(CompileCommandOutput compile_command_output.cxx)
|
||||
TARGET_LINK_LIBRARIES(CompileCommandOutput test1 test2)
|
9
Tests/CompileCommandOutput/compile_command_output.cxx
Normal file
9
Tests/CompileCommandOutput/compile_command_output.cxx
Normal file
@ -0,0 +1,9 @@
|
||||
#include "file_with_underscores.h"
|
||||
#include "relative.h"
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
file_with_underscores();
|
||||
relative();
|
||||
return 0;
|
||||
}
|
1
Tests/CompileCommandOutput/file with spaces.cxx
Normal file
1
Tests/CompileCommandOutput/file with spaces.cxx
Normal file
@ -0,0 +1 @@
|
||||
#include "file_with_underscores.cxx"
|
3
Tests/CompileCommandOutput/file_with_underscores.cxx
Normal file
3
Tests/CompileCommandOutput/file_with_underscores.cxx
Normal file
@ -0,0 +1,3 @@
|
||||
#include "file_with_underscores.h"
|
||||
|
||||
void file_with_underscores() {}
|
1
Tests/CompileCommandOutput/file_with_underscores.h
Normal file
1
Tests/CompileCommandOutput/file_with_underscores.h
Normal file
@ -0,0 +1 @@
|
||||
void file_with_underscores();
|
3
Tests/CompileCommandOutput/relative.cxx
Normal file
3
Tests/CompileCommandOutput/relative.cxx
Normal file
@ -0,0 +1,3 @@
|
||||
#include "relative.h"
|
||||
|
||||
void relative() {}
|
11
Tests/CompileCommandOutput/relative.h
Normal file
11
Tests/CompileCommandOutput/relative.h
Normal file
@ -0,0 +1,11 @@
|
||||
#if defined(_WIN32)
|
||||
# ifdef test2_EXPORTS
|
||||
# define TEST2_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define TEST2_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
#else
|
||||
# define TEST2_EXPORT
|
||||
#endif
|
||||
|
||||
TEST2_EXPORT void relative();
|
Loading…
x
Reference in New Issue
Block a user