Add support for WINDOWS_EXPORT_ALL_SYMBOLS when cross-compiling to Windows

Implement `__create_def` using `llvm-nm` (when given as `CMAKE_NM`).
This commit is contained in:
Isuru Fernando
2019-11-23 04:04:52 +00:00
committed by Brad King
parent 07226324eb
commit 5ff1d7bd90
4 changed files with 42 additions and 33 deletions

View File

@@ -693,6 +693,8 @@ set(SRCS
cmDuration.h cmDuration.h
cmDuration.cxx cmDuration.cxx
bindexplib.cxx
) )
SET_PROPERTY(SOURCE cmProcessOutput.cxx APPEND PROPERTY COMPILE_DEFINITIONS SET_PROPERTY(SOURCE cmProcessOutput.cxx APPEND PROPERTY COMPILE_DEFINITIONS
@@ -715,7 +717,6 @@ if (WIN32)
set(SRCS ${SRCS} set(SRCS ${SRCS}
cmCallVisualStudioMacro.cxx cmCallVisualStudioMacro.cxx
cmCallVisualStudioMacro.h cmCallVisualStudioMacro.h
bindexplib.cxx
) )
if(NOT UNIX) if(NOT UNIX)

View File

@@ -64,32 +64,36 @@
*/ */
#include "bindexplib.h" #include "bindexplib.h"
#include <iostream> #include <cstddef>
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#include <windows.h> #ifdef _WIN32
# include <windows.h>
# include "cmsys/Encoding.hxx"
#endif
#include "cmsys/Encoding.hxx"
#include "cmsys/FStream.hxx" #include "cmsys/FStream.hxx"
#include "cmSystemTools.h" #include "cmSystemTools.h"
#ifndef IMAGE_FILE_MACHINE_ARM #ifdef _WIN32
# define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian # ifndef IMAGE_FILE_MACHINE_ARM
#endif # define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
# endif
#ifndef IMAGE_FILE_MACHINE_THUMB # ifndef IMAGE_FILE_MACHINE_THUMB
# define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian # define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian
#endif # endif
#ifndef IMAGE_FILE_MACHINE_ARMNT # ifndef IMAGE_FILE_MACHINE_ARMNT
# define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian # define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian
#endif # endif
#ifndef IMAGE_FILE_MACHINE_ARM64 # ifndef IMAGE_FILE_MACHINE_ARM64
# define IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARM64 Little-Endian # define IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARM64 Little-Endian
#endif # endif
typedef struct cmANON_OBJECT_HEADER_BIGOBJ typedef struct cmANON_OBJECT_HEADER_BIGOBJ
{ {
@@ -306,6 +310,7 @@ private:
SymbolTableType* SymbolTable; SymbolTableType* SymbolTable;
bool IsI386; bool IsI386;
}; };
#endif
bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename, bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename,
std::set<std::string>& symbols, std::set<std::string>& symbols,
@@ -315,15 +320,15 @@ bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename,
// break up command line into a vector // break up command line into a vector
std::vector<std::string> command; std::vector<std::string> command;
command.push_back(nmPath); command.push_back(nmPath);
command.push_back("--no-weak"); command.emplace_back("--no-weak");
command.push_back("--defined-only"); command.emplace_back("--defined-only");
command.push_back("--format=posix"); command.emplace_back("--format=posix");
command.push_back(filename); command.emplace_back(filename);
// run the command // run the command
int exit_code = 0; int exit_code = 0;
cmSystemTools::RunSingleCommand(command, &output, &output, &exit_code, "", cmSystemTools::RunSingleCommand(command, &output, &output, &exit_code,
cmSystemTools::OUTPUT_NONE); nullptr, cmSystemTools::OUTPUT_NONE);
if (exit_code != 0) { if (exit_code != 0) {
fprintf(stderr, "llvm-nm returned an error: %s\n", output.c_str()); fprintf(stderr, "llvm-nm returned an error: %s\n", output.c_str());
@@ -336,7 +341,7 @@ bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename,
if (line.empty()) { // last line if (line.empty()) { // last line
continue; continue;
} }
size_t sym_end = line.find(" "); size_t sym_end = line.find(' ');
if (sym_end == std::string::npos) { if (sym_end == std::string::npos) {
fprintf(stderr, "Couldn't parse llvm-nm output line: %s\n", fprintf(stderr, "Couldn't parse llvm-nm output line: %s\n",
line.c_str()); line.c_str());
@@ -366,6 +371,9 @@ bool DumpFile(std::string const& nmPath, const char* filename,
std::set<std::string>& symbols, std::set<std::string>& symbols,
std::set<std::string>& dataSymbols) std::set<std::string>& dataSymbols)
{ {
#ifndef _WIN32
return DumpFileWithLlvmNm(nmPath, filename, symbols, dataSymbols);
#else
HANDLE hFile; HANDLE hFile;
HANDLE hFileMapping; HANDLE hFileMapping;
LPVOID lpFileBase; LPVOID lpFileBase;
@@ -446,6 +454,7 @@ bool DumpFile(std::string const& nmPath, const char* filename,
CloseHandle(hFileMapping); CloseHandle(hFileMapping);
CloseHandle(hFile); CloseHandle(hFile);
return true; return true;
#endif
} }
bool bindexplib::AddObjectFile(const char* filename) bool bindexplib::AddObjectFile(const char* filename)

View File

@@ -2508,11 +2508,11 @@ void cmGeneratorTarget::ComputeModuleDefinitionInfo(
info.WindowsExportAllSymbols = info.WindowsExportAllSymbols =
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") && this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") &&
this->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS"); this->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS");
#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) #if !defined(CMAKE_BOOTSTRAP)
info.DefFileGenerated = info.DefFileGenerated =
info.WindowsExportAllSymbols || info.Sources.size() > 1; info.WindowsExportAllSymbols || info.Sources.size() > 1;
#else #else
// Our __create_def helper is only available on Windows. // Our __create_def helper is not available during CMake bootstrap.
info.DefFileGenerated = false; info.DefFileGenerated = false;
#endif #endif
if (info.DefFileGenerated) { if (info.DefFileGenerated) {

View File

@@ -21,16 +21,15 @@
#if !defined(CMAKE_BOOTSTRAP) #if !defined(CMAKE_BOOTSTRAP)
# include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback. # include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
# include "cmFileTime.h"
# include "cmServer.h" # include "cmServer.h"
# include "cmServerConnection.h" # include "cmServerConnection.h"
# include "bindexplib.h"
#endif #endif
#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) #if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32)
# include "cmsys/ConsoleBuf.hxx" # include "cmsys/ConsoleBuf.hxx"
# include "cmFileTime.h"
# include "bindexplib.h"
#endif #endif
#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__) #if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__)
@@ -581,11 +580,11 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return 0; return 0;
} }
#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP) #if !defined(CMAKE_BOOTSTRAP)
else if (args[1] == "__create_def") { if (args[1] == "__create_def") {
if (args.size() < 4) { if (args.size() < 4) {
std::cerr << "__create_def Usage: -E __create_def outfile.def " std::cerr << "__create_def Usage: -E __create_def outfile.def "
"objlistfile [-nm=nm-path]\n"; "objlistfile [--nm=nm-path]\n";
return 1; return 1;
} }
cmsys::ifstream fin(args[3].c_str(), std::ios::in | std::ios::binary); cmsys::ifstream fin(args[3].c_str(), std::ios::in | std::ios::binary);
@@ -612,7 +611,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return 0; return 0;
} }
} }
FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+"); FILE* fout = cmsys::SystemTools::Fopen(args[2], "w+");
if (!fout) { if (!fout) {
std::cerr << "could not open output .def file: " << args[2].c_str() std::cerr << "could not open output .def file: " << args[2].c_str()
<< "\n"; << "\n";