Windows: Honor WINDOWS_EXPORT_ALL_SYMBOLS for executables with exports

For executables with ENABLE_EXPORTS set, export all symbols when
instructed to do so by WINDOWS_EXPORT_ALL_SYMBOLS.
This commit is contained in:
Yury Zhuravlev 2016-07-10 20:24:43 +03:00 committed by Brad King
parent 2005b96067
commit 9da725cb00
10 changed files with 50 additions and 9 deletions

View File

@ -5,8 +5,9 @@ This property is implemented only for MS-compatible tools on Windows.
Enable this boolean property to automatically create a module definition
(``.def``) file with all global symbols found in the input ``.obj`` files
for a ``SHARED`` library on Windows. The module definition file will be
passed to the linker causing all symbols to be exported from the ``.dll``.
for a ``SHARED`` library (or executable with :prop_tgt:`ENABLE_EXPORTS`)
on Windows. The module definition file will be passed to the linker
causing all symbols to be exported from the ``.dll``.
For global *data* symbols, ``__declspec(dllimport)`` must still be used when
compiling against the code in the ``.dll``. All other function symbols will
be automatically exported and imported by callers. This simplifies porting

View File

@ -0,0 +1,5 @@
windows-export-all-from-exe
---------------------------
* The :prop_tgt:`WINDOWS_EXPORT_ALL_SYMBOLS` target property now applies
to executable targets with the :prop_tgt:`ENABLE_EXPORTS` property set.

View File

@ -1013,7 +1013,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
linkOptions.AddFlag("ModuleDefinitionFile", defFile.c_str());
}
if (target->GetType() == cmState::SHARED_LIBRARY &&
if ((target->GetType() == cmState::SHARED_LIBRARY ||
target->IsExecutableWithExports()) &&
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
if (target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) {
linkOptions.AddFlag("ModuleDefinitionFile", "$(IntDir)/exportall.def");
@ -1836,7 +1837,8 @@ void cmLocalVisualStudio7Generator::OutputTargetRules(
tool = this->FortranProject ? "VFPreLinkEventTool" : "VCPreLinkEventTool";
event.Start(tool);
bool addedPrelink = false;
if (target->GetType() == cmState::SHARED_LIBRARY &&
if ((target->GetType() == cmState::SHARED_LIBRARY ||
target->IsExecutableWithExports()) &&
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
if (target->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) {
addedPrelink = true;

View File

@ -318,6 +318,12 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->CreateObjectLists(useLinkScript, false, useResponseFileForObjects,
buildObjs, depends, useWatcomQuote);
// maybe create .def file from list of objects
if (this->GeneratorTarget->IsExecutableWithExports() &&
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
this->GenDefFile(real_link_commands, linkFlags);
}
std::string manifests = this->GetManifests();
cmLocalGenerator::RuleVariables vars;

View File

@ -472,7 +472,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
vars["FLAGS"], vars["LINK_FLAGS"], frameworkPath,
linkPath, &genTarget, useWatcomQuote);
if (this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") &&
gt.GetType() == cmState::SHARED_LIBRARY) {
(gt.GetType() == cmState::SHARED_LIBRARY ||
gt.IsExecutableWithExports())) {
if (gt.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) {
std::string name_of_def_file = gt.GetSupportDirectory();
name_of_def_file += "/" + gt.GetName();
@ -599,7 +600,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
}
// maybe create .def file from list of objects
if (gt.GetType() == cmState::SHARED_LIBRARY &&
if ((gt.GetType() == cmState::SHARED_LIBRARY ||
gt.IsExecutableWithExports()) &&
this->GetMakefile()->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
if (gt.GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS")) {
std::string cmakeCommand =

View File

@ -253,7 +253,8 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->TargetTypeValue == cmState::MODULE_LIBRARY) {
this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
}
if (this->TargetTypeValue == cmState::SHARED_LIBRARY) {
if (this->TargetTypeValue == cmState::SHARED_LIBRARY ||
this->TargetTypeValue == cmState::EXECUTABLE) {
this->SetPropertyDefault("WINDOWS_EXPORT_ALL_SYMBOLS", CM_NULLPTR);
}

View File

@ -2343,7 +2343,8 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
"%(IgnoreSpecificDefaultLibraries)");
}
if (this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY &&
if ((this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY ||
this->GeneratorTarget->IsExecutableWithExports()) &&
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
if (this->GeneratorTarget->GetPropertyAsBool(
"WINDOWS_EXPORT_ALL_SYMBOLS")) {
@ -2506,7 +2507,8 @@ void cmVisualStudio10TargetGenerator::WriteEvents(
std::string const& configName)
{
bool addedPrelink = false;
if (this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY &&
if ((this->GeneratorTarget->GetType() == cmState::SHARED_LIBRARY ||
this->GeneratorTarget->IsExecutableWithExports()) &&
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS")) {
if (this->GeneratorTarget->GetPropertyAsBool(
"WINDOWS_EXPORT_ALL_SYMBOLS")) {

View File

@ -3,5 +3,11 @@ set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${autoexport_BINARY_DIR}/bin)
add_subdirectory(sub)
add_library(autoexport SHARED hello.cxx world.cxx foo.c)
add_executable(say say.cxx)
if(MSVC)
set_target_properties(say PROPERTIES ENABLE_EXPORTS ON)
add_library(autoexport_for_exec SHARED hello2.c)
target_link_libraries(autoexport_for_exec say)
endif()
target_link_libraries(say autoexport autoexport2)

View File

@ -0,0 +1,8 @@
#include <stdio.h>
extern int own_auto_export_function(int i);
void hello2()
{
printf("hello exec:%i", own_auto_export_function(41));
}

View File

@ -18,6 +18,14 @@ int bar();
void hello();
void world();
// test exports for executable target
extern "C" {
int own_auto_export_function(int i)
{
return i + 1;
}
}
int main()
{
// test static data (needs declspec to work)