Commit f2dc04ab authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

Compiling, Windows . Avoid unnecessary rebuilds with MSVC.

To export symbols from the mysqld.exe, use lib.exe with /DEF, rather than
pre-link step when building mysqld.exe.

This helps to avoid relinking all plugins, if mysqld.exe was recompiled
but the list of its exports has not changed.

Also removed unnecessary DEPENDS in some ADD_CUSTOM_COMMAND (gen_lex_token,
gen_lex_hash etc). They confuse VS generator which tends to
recreate headers and do unnecessary recompilations.
parent ff6f4d7d
...@@ -179,8 +179,15 @@ MACRO(MYSQL_ADD_PLUGIN) ...@@ -179,8 +179,15 @@ MACRO(MYSQL_ADD_PLUGIN)
# executable to the linker command line (it would result into link error). # executable to the linker command line (it would result into link error).
# Thus we skip TARGET_LINK_LIBRARIES on Linux, as it would only generate # Thus we skip TARGET_LINK_LIBRARIES on Linux, as it would only generate
# an additional dependency. # an additional dependency.
IF(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") IF(MSVC)
TARGET_LINK_LIBRARIES (${target} mysqld ${ARG_LINK_LIBRARIES}) ADD_DEPENDENCIES(${target} gen_mysqld_lib)
TARGET_LINK_LIBRARIES(${target} mysqld_import_lib)
ELSEIF(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
TARGET_LINK_LIBRARIES (${target} mysqld)
ENDIF()
IF(ARG_LINK_LIBRARIES)
TARGET_LINK_LIBRARIES (${target} ${ARG_LINK_LIBRARIES})
ENDIF() ENDIF()
ADD_DEPENDENCIES(${target} GenError ${ARG_DEPENDENCIES}) ADD_DEPENDENCIES(${target} GenError ${ARG_DEPENDENCIES})
......
...@@ -46,7 +46,6 @@ ENDIF() ...@@ -46,7 +46,6 @@ ENDIF()
ADD_CUSTOM_COMMAND( ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lex_token.h OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lex_token.h
COMMAND gen_lex_token > lex_token.h COMMAND gen_lex_token > lex_token.h
DEPENDS gen_lex_token
) )
ADD_DEFINITIONS(-DMYSQL_SERVER -DHAVE_EVENT_SCHEDULER) ADD_DEFINITIONS(-DMYSQL_SERVER -DHAVE_EVENT_SCHEDULER)
...@@ -150,6 +149,63 @@ ELSE() ...@@ -150,6 +149,63 @@ ELSE()
SET(MYSQLD_SOURCE main.cc ${DTRACE_PROBES_ALL}) SET(MYSQLD_SOURCE main.cc ${DTRACE_PROBES_ALL})
ENDIF() ENDIF()
IF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS)
# mysqld.exe must to export symbols from some specific libs.
# These symbols are used by dynamic plugins, that "link" to mysqld.
#
# To do that, we
#
# 1. Generate mysqld_lib.def text file with all symbols from static
# libraries mysys, dbug, strings, sql.
# 2. Then we call
# lib.exe /DEF:mysqld_lib.def ...
# to create import library mysqld_lib.lib and export library mysqld_lib.exp
# 3. mysqld.exe links with mysqld_lib.exp (exporting symbols)
# 4. plugins link with mysqld_lib.lib (importing symbols)
#
# We do not not regenerate .def, .lib and .exp
# without necessity.E.g source modifications, that do not
# change list of exported symbols, will not result in a relink for plugins.
SET(MYSQLD_DEF ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib.def)
SET(MYSQLD_EXP ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib.exp)
SET(MYSQLD_LIB ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib.lib)
SET(MYSQLD_CORELIBS sql mysys mysys_ssl dbug strings)
FOREACH (CORELIB ${MYSQLD_CORELIBS})
GET_TARGET_PROPERTY(LOC ${CORELIB} LOCATION)
FILE(TO_NATIVE_PATH ${LOC} LOC)
SET (LIB_LOCATIONS ${LIB_LOCATIONS} ${LOC})
ENDFOREACH (CORELIB)
SET(_PLATFORM x86)
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
SET(_PLATFORM x64)
ENDIF()
ADD_CUSTOM_COMMAND(
OUTPUT ${MYSQLD_DEF}
COMMAND cscript ARGS //nologo ${PROJECT_SOURCE_DIR}/win/create_def_file.js
${_PLATFORM} /forLib ${LIB_LOCATIONS} > mysqld_lib.def.tmp
COMMAND ${CMAKE_COMMAND} -E copy_if_different mysqld_lib.def.tmp mysqld_lib.def
COMMAND ${CMAKE_COMMAND} -E remove mysqld_lib.def.tmp
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${MYSQLD_CORELIBS}
)
ADD_CUSTOM_COMMAND(
OUTPUT ${MYSQLD_LIB}
COMMAND lib
ARGS /NAME:mysqld.exe "/DEF:${MYSQLD_DEF}" "/MACHINE:${_PLATFORM}"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${MYSQLD_DEF}
)
ADD_CUSTOM_TARGET(gen_mysqld_lib DEPENDS ${MYSQLD_LIB})
ADD_LIBRARY(mysqld_import_lib UNKNOWN IMPORTED GLOBAL)
SET_TARGET_PROPERTIES(mysqld_import_lib PROPERTIES IMPORTED_LOCATION ${MYSQLD_LIB})
ENDIF()
MYSQL_ADD_EXECUTABLE(mysqld ${MYSQLD_SOURCE} DESTINATION ${INSTALL_SBINDIR} COMPONENT Server) MYSQL_ADD_EXECUTABLE(mysqld ${MYSQLD_SOURCE} DESTINATION ${INSTALL_SBINDIR} COMPONENT Server)
IF(APPLE) IF(APPLE)
...@@ -170,25 +226,9 @@ IF(NOT WITHOUT_DYNAMIC_PLUGINS) ...@@ -170,25 +226,9 @@ IF(NOT WITHOUT_DYNAMIC_PLUGINS)
SET_TARGET_PROPERTIES(mysqld PROPERTIES LINK_FLAGS "${mysqld_link_flags} -Wl,--export-all-symbols") SET_TARGET_PROPERTIES(mysqld PROPERTIES LINK_FLAGS "${mysqld_link_flags} -Wl,--export-all-symbols")
ENDIF() ENDIF()
IF(MSVC) IF(MSVC)
# Set module definition file. Also use non-incremental linker, SET_TARGET_PROPERTIES(mysqld PROPERTIES LINK_FLAGS "${mysqld_link_flags} \"${MYSQLD_EXP}\"")
# incremental appears to crash from time to time,if used with /DEF option ADD_DEPENDENCIES(mysqld gen_mysqld_lib)
SET_TARGET_PROPERTIES(mysqld PROPERTIES LINK_FLAGS "${mysqld_link_flags} /DEF:mysqld.def /INCREMENTAL:NO") ENDIF()
FOREACH (CORELIB sql mysys mysys_ssl dbug strings)
GET_TARGET_PROPERTY(LOC ${CORELIB} LOCATION)
FILE(TO_NATIVE_PATH ${LOC} LOC)
SET (LIB_LOCATIONS ${LIB_LOCATIONS} ${LOC})
ENDFOREACH (CORELIB ${MYSQLD_CORE_LIBS})
SET(_PLATFORM x86)
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
SET(_PLATFORM x64)
ENDIF()
ADD_CUSTOM_COMMAND(TARGET mysqld PRE_LINK
COMMAND echo ${_PLATFORM} && cscript ARGS //nologo ${PROJECT_SOURCE_DIR}/win/create_def_file.js
${_PLATFORM} ${LIB_LOCATIONS} > mysqld.def
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
ADD_DEPENDENCIES(sql GenError)
ENDIF(MSVC)
ENDIF(NOT WITHOUT_DYNAMIC_PLUGINS) ENDIF(NOT WITHOUT_DYNAMIC_PLUGINS)
SET_TARGET_PROPERTIES(mysqld PROPERTIES ENABLE_EXPORTS TRUE) SET_TARGET_PROPERTIES(mysqld PROPERTIES ENABLE_EXPORTS TRUE)
...@@ -254,7 +294,6 @@ ENDIF() ...@@ -254,7 +294,6 @@ ENDIF()
ADD_CUSTOM_COMMAND( ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h
COMMAND gen_lex_hash > lex_hash.h COMMAND gen_lex_hash > lex_hash.h
DEPENDS gen_lex_hash
) )
MYSQL_ADD_EXECUTABLE(mysql_tzinfo_to_sql tztime.cc COMPONENT Server) MYSQL_ADD_EXECUTABLE(mysql_tzinfo_to_sql tztime.cc COMPONENT Server)
...@@ -379,7 +418,7 @@ IF(WIN32) ...@@ -379,7 +418,7 @@ IF(WIN32)
${CMAKE_CURRENT_BINARY_DIR}/my_bootstrap.sql ${CMAKE_CURRENT_BINARY_DIR}/my_bootstrap.sql
mysql_bootstrap_sql.c mysql_bootstrap_sql.c
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS comp_sql ${my_bootstrap_sql} DEPENDS ${my_bootstrap_sql}
) )
MYSQL_ADD_EXECUTABLE(mysql_install_db MYSQL_ADD_EXECUTABLE(mysql_install_db
......
...@@ -54,6 +54,22 @@ var is64 = args.Item(0).toLowerCase() == "x64"; ...@@ -54,6 +54,22 @@ var is64 = args.Item(0).toLowerCase() == "x64";
var shell = new ActiveXObject("WScript.Shell"); var shell = new ActiveXObject("WScript.Shell");
var fso = new ActiveXObject("Scripting.FileSystemObject"); var fso = new ActiveXObject("Scripting.FileSystemObject");
/*
If .def file is used with together with lib.exe
the name mangling for stdcall is slightly different.
Undescore prefix for stdcall function name must be removed for
lib.exe but not link.exe (see ScrubSymbol())
This difference is not documented anywhere and could
be a bug in compiler tools.
We use a parameter /forLib, if the resulting .def file is used
with lib.exe .
*/
var forLib = false;
OutputSymbols(CollectSymbols()); OutputSymbols(CollectSymbols());
...@@ -62,8 +78,8 @@ function OutputSymbols(symbols) ...@@ -62,8 +78,8 @@ function OutputSymbols(symbols)
{ {
var out = WScript.StdOut; var out = WScript.StdOut;
out.WriteLine("EXPORTS"); out.WriteLine("EXPORTS");
for (var sym in symbols) for (var i= 0; i < symbols.length; i++)
out.WriteLine(sym); out.WriteLine(symbols[i]);
} }
function echo(message) function echo(message)
...@@ -72,9 +88,10 @@ function echo(message) ...@@ -72,9 +88,10 @@ function echo(message)
} }
// Extract global symbol names and type from objects // Extract global symbol names and type from objects
// Returns string array with symbol names
function CollectSymbols() function CollectSymbols()
{ {
var uniqueSymbols = new Array(); var uniqueSymbols = new Object();
try try
{ {
...@@ -146,7 +163,19 @@ function CollectSymbols() ...@@ -146,7 +163,19 @@ function CollectSymbols()
uniqueSymbols[symbol] = 1; uniqueSymbols[symbol] = 1;
} }
fso.DeleteFile(rspfilename); fso.DeleteFile(rspfilename);
return uniqueSymbols; // Sort symbols names
var keys=[];
var sorted = {};
for (key in uniqueSymbols)
{
if (uniqueSymbols.hasOwnProperty(key))
{
keys.push(key);
}
}
keys.sort();
return keys;
} }
// performs necessary cleanup on the symbol name // performs necessary cleanup on the symbol name
...@@ -156,6 +185,9 @@ function ScrubSymbol(symbol) ...@@ -156,6 +185,9 @@ function ScrubSymbol(symbol)
if (symbol.charAt(0) != "_") if (symbol.charAt(0) != "_")
return symbol; return symbol;
if (forLib)
return symbol.substring(1, symbol.length);
var atSign = symbol.indexOf("@"); var atSign = symbol.indexOf("@");
if (atSign != -1) if (atSign != -1)
{ {
...@@ -189,7 +221,11 @@ function CreateResponseFile(filename) ...@@ -189,7 +221,11 @@ function CreateResponseFile(filename)
var index = 1; var index = 1;
for (; index < args.length; index++) for (; index < args.length; index++)
{ {
addToResponseFile(args.Item(index),responseFile); var param = args.Item(index);
if (param == "/forLib")
forLib = true;
else
addToResponseFile(args.Item(index),responseFile);
} }
responseFile.Close(); responseFile.Close();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment