BUG: Create an exe's implib output dir for VS

If an executable marks symbols with __declspec(dllexport) then VS
creates an import library for it.  However, it forgets to create the
directory that will contain the import library if it is different from
the location of the executable.  We work around this VS bug by creating
a pre-build event on the executable target to make the directory.
This commit is contained in:
Brad King 2009-06-15 10:55:21 -04:00
parent d30923d631
commit f4b3bdc6be
3 changed files with 32 additions and 0 deletions

View File

@ -1674,6 +1674,33 @@ void cmLocalVisualStudio7Generator::WriteVCProjEndGroup(std::ostream& fout)
fout << "\t\t</Filter>\n"; fout << "\t\t</Filter>\n";
} }
void cmLocalVisualStudio7Generator::MaybeCreateImplibDir(cmTarget& target,
const char* config,
EventWriter& event)
{
// If an executable exports symbols then VS wants to create an
// import library but forgets to create the output directory.
if(target.GetType() != cmTarget::EXECUTABLE) { return; }
std::string outDir = target.GetDirectory(config, false);
std::string impDir = target.GetDirectory(config, true);
if(impDir == outDir) { return; }
// Add a pre-build event to create the directory.
cmCustomCommandLine command;
command.push_back(this->Makefile->GetRequiredDefinition("CMAKE_COMMAND"));
command.push_back("-E");
command.push_back("make_directory");
command.push_back(impDir);
std::vector<std::string> no_output;
std::vector<std::string> no_depends;
cmCustomCommandLines commands;
commands.push_back(command);
cmCustomCommand cc(no_output, no_depends, commands, 0, 0);
cc.SetEscapeOldStyle(false);
cc.SetEscapeAllowMakeVars(true);
event.Write(cc);
}
// look for custom rules on a target and collect them together // look for custom rules on a target and collect them together
void cmLocalVisualStudio7Generator void cmLocalVisualStudio7Generator
@ -1693,6 +1720,7 @@ void cmLocalVisualStudio7Generator
this->FortranProject? "VFPreBuildEventTool":"VCPreBuildEventTool"; this->FortranProject? "VFPreBuildEventTool":"VCPreBuildEventTool";
event.Start(tool); event.Start(tool);
event.Write(target.GetPreBuildCommands()); event.Write(target.GetPreBuildCommands());
this->MaybeCreateImplibDir(target, configName, event);
event.Finish(); event.Finish();
// Add pre-link event. // Add pre-link event.

View File

@ -125,6 +125,8 @@ private:
class EventWriter; class EventWriter;
friend class EventWriter; friend class EventWriter;
void MaybeCreateImplibDir(cmTarget& target, const char* config,
EventWriter& event);
cmVS7FlagTable const* ExtraFlagTable; cmVS7FlagTable const* ExtraFlagTable;
std::string ModuleDefinitionFile; std::string ModuleDefinitionFile;

View File

@ -34,6 +34,8 @@ ADD_EXECUTABLE(example_exe src/example_exe.cxx)
SET_TARGET_PROPERTIES(example_exe PROPERTIES SET_TARGET_PROPERTIES(example_exe PROPERTIES
ENABLE_EXPORTS 1 ENABLE_EXPORTS 1
OUTPUT_NAME example OUTPUT_NAME example
# Test placing exe import library in unique directory.
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/exe
) )
TARGET_LINK_LIBRARIES(example_exe kwsys) TARGET_LINK_LIBRARIES(example_exe kwsys)