mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00

LD is stupid and doesn't handle stdcall decoration as proper as dlltool does (after we provided a patch). Passing --kill-at, also kills C++ mangled names and exports with stdcall decoration are imposible. In trunk we use dlltool to generate an exp file that we link with LD, but in the cmake branch we pass the def file to LD directly. Luckily we have a tool called spec2def that can handle these things. We now generate 2 different .def files, one for LD, containing the undecorated export name forwarded to the decorated symbol name (FooFunc=FooFunc@12), while the 2nd def file which is passed to dlltool for exportlib generation has full stdcall decorations. --kill-at is now passed to dlltool only. This commit might break msvc, but should be pretty easy to fix. svn path=/branches/cmake-bringup/; revision=50217
279 lines
11 KiB
CMake
279 lines
11 KiB
CMake
|
|
if(NOT CMAKE_CROSSCOMPILING)
|
|
|
|
add_definitions(-fshort-wchar)
|
|
|
|
else()
|
|
|
|
# Linking
|
|
link_directories("${REACTOS_SOURCE_DIR}/importlibs" ${REACTOS_BINARY_DIR}/lib/3rdparty/mingw)
|
|
set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
|
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
|
set(CMAKE_EXE_LINKER_FLAGS "-nodefaultlibs -nostdlib -Wl,--enable-auto-image-base -Wl,--disable-auto-import")
|
|
# -Wl,-T,${REACTOS_SOURCE_DIR}/global.lds
|
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS_INIT} -Wl,--disable-stdcall-fixup")
|
|
|
|
# Compiler Core
|
|
add_definitions(-pipe -fms-extensions)
|
|
|
|
set(CMAKE_C_CREATE_SHARED_LIBRARY "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_C_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
|
|
set(CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
|
|
set(CMAKE_RC_CREATE_SHARED_LIBRARY "<CMAKE_C_COMPILER> <CMAKE_SHARED_LIBRARY_C_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
|
|
|
|
# Debugging (Note: DWARF-4 on 4.5.1 when we ship)
|
|
add_definitions(-gdwarf-2 -g2 -femit-struct-debug-detailed=none -feliminate-unused-debug-types)
|
|
|
|
# Tuning
|
|
if(ARCH MATCHES i386)
|
|
add_definitions(-march=${OARCH} -mtune=${TUNE})
|
|
elseif(ARCH MATCHES amd64)
|
|
add_definitions(-march=${OARCH})
|
|
endif()
|
|
|
|
# Warnings
|
|
add_definitions(-Wall -Wno-char-subscripts -Wpointer-arith -Wno-multichar -Wno-error=uninitialized -Wno-unused-value -Winvalid-pch)
|
|
|
|
# Optimizations
|
|
if(ARCH MATCHES i386)
|
|
add_definitions(-Os -fno-strict-aliasing -ftracer -momit-leaf-frame-pointer -mpreferred-stack-boundary=2 -fno-set-stack-executable -fno-optimize-sibling-calls)
|
|
elseif(ARCH MATCHES amd64)
|
|
add_definitions(-Os -fno-strict-aliasing -ftracer -momit-leaf-frame-pointer -mpreferred-stack-boundary=4)
|
|
endif()
|
|
|
|
# Other
|
|
if(ARCH MATCHES amd64)
|
|
add_definitions(-U_X86_ -UWIN32)
|
|
endif()
|
|
|
|
# alternative arch name
|
|
if(ARCH MATCHES amd64)
|
|
set(ARCH2 x86_64)
|
|
else()
|
|
set(ARCH2 ${ARCH})
|
|
endif()
|
|
|
|
# Macros
|
|
macro(_PCH_GET_COMPILE_FLAGS _target_name _out_compile_flags _header_filename)
|
|
# Add the precompiled header to the build
|
|
get_filename_component(FILE ${_header_filename} NAME)
|
|
set(_gch_filename "${_target_name}_${FILE}.gch")
|
|
list(APPEND ${_out_compile_flags} -c ${_header_filename} -o ${_gch_filename})
|
|
|
|
# This gets us our includes
|
|
get_directory_property(DIRINC INCLUDE_DIRECTORIES)
|
|
foreach(item ${DIRINC})
|
|
list(APPEND ${_out_compile_flags} -I${item})
|
|
endforeach()
|
|
|
|
# This is a particular bit of undocumented/hacky magic I'm quite proud of
|
|
get_directory_property(_compiler_flags DEFINITIONS)
|
|
string(REPLACE "\ " "\t" _compiler_flags ${_compiler_flags})
|
|
list(APPEND ${_out_compile_flags} ${_compiler_flags})
|
|
|
|
# This gets any specific definitions that were added with set-target-property
|
|
get_target_property(_target_defs ${_target_name} COMPILE_DEFINITIONS)
|
|
if (_target_defs)
|
|
foreach(item ${_target_defs})
|
|
list(APPEND ${_out_compile_flags} -D${item})
|
|
endforeach()
|
|
endif()
|
|
endmacro()
|
|
|
|
macro(add_pch _target_name _header_filename _src_list)
|
|
get_filename_component(FILE ${_header_filename} NAME)
|
|
set(_gch_filename "${_target_name}_${FILE}.gch")
|
|
list(APPEND ${_src_list} ${_gch_filename})
|
|
_PCH_GET_COMPILE_FLAGS(${_target_name} _args ${_header_filename})
|
|
file(REMOVE ${_gch_filename})
|
|
add_custom_command(
|
|
OUTPUT ${_gch_filename}
|
|
COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1} ${_args}
|
|
DEPENDS ${_header_filename})
|
|
endmacro()
|
|
|
|
macro(add_linkerflag MODULE _flag)
|
|
set(NEW_LINKER_FLAGS ${_flag})
|
|
get_target_property(LINKER_FLAGS ${MODULE} LINK_FLAGS)
|
|
if(LINKER_FLAGS)
|
|
set(NEW_LINKER_FLAGS "${LINKER_FLAGS} ${NEW_LINKER_FLAGS}")
|
|
endif()
|
|
set_target_properties(${MODULE} PROPERTIES LINK_FLAGS ${NEW_LINKER_FLAGS})
|
|
endmacro()
|
|
|
|
# Optional 3rd parameter: stdcall stack bytes
|
|
macro(set_entrypoint MODULE ENTRYPOINT)
|
|
if(${ENTRYPOINT} STREQUAL "0")
|
|
add_linkerflag(${MODULE} "-Wl,-entry,0")
|
|
elseif(ARCH MATCHES i386)
|
|
set(_entrysymbol _${ENTRYPOINT})
|
|
if (${ARGC} GREATER 2)
|
|
set(_entrysymbol ${_entrysymbol}@${ARGV2})
|
|
endif()
|
|
add_linkerflag(${MODULE} "-Wl,-entry,${_entrysymbol}")
|
|
else()
|
|
add_linkerflag(${MODULE} "-Wl,-entry,${ENTRYPOINT}")
|
|
endif()
|
|
endmacro()
|
|
|
|
macro(set_subsystem MODULE SUBSYSTEM)
|
|
add_linkerflag(${MODULE} "-Wl,--subsystem,${SUBSYSTEM}")
|
|
endmacro()
|
|
|
|
macro(set_image_base MODULE IMAGE_BASE)
|
|
add_linkerflag(${MODULE} "-Wl,--image-base,${IMAGE_BASE}")
|
|
endmacro()
|
|
|
|
macro(set_module_type MODULE TYPE)
|
|
|
|
add_dependencies(${MODULE} psdk buildno_header)
|
|
if(${IS_CPP})
|
|
target_link_libraries(${MODULE} stlport -lsupc++ -lgcc)
|
|
endif()
|
|
|
|
if(${TYPE} MATCHES nativecui)
|
|
set_subsystem(${MODULE} native)
|
|
set_entrypoint(${MODULE} NtProcessStartup 4)
|
|
elseif(${TYPE} MATCHES win32gui)
|
|
set_subsystem(${MODULE} windows)
|
|
set_entrypoint(${MODULE} WinMainCRTStartup)
|
|
if(NOT IS_UNICODE)
|
|
target_link_libraries(${MODULE} mingw_main)
|
|
else()
|
|
target_link_libraries(${MODULE} mingw_wmain)
|
|
endif(NOT IS_UNICODE)
|
|
target_link_libraries(${MODULE} mingw_common)
|
|
elseif(${TYPE} MATCHES win32cui)
|
|
set_subsystem(${MODULE} console)
|
|
set_entrypoint(${MODULE} mainCRTStartup)
|
|
if(NOT IS_UNICODE)
|
|
target_link_libraries(${MODULE} mingw_main)
|
|
else()
|
|
target_link_libraries(${MODULE} mingw_wmain)
|
|
endif(NOT IS_UNICODE)
|
|
target_link_libraries(${MODULE} mingw_common)
|
|
elseif(${TYPE} MATCHES win32dll)
|
|
set_entrypoint(${MODULE} DllMainCRTStartup 12)
|
|
target_link_libraries(${MODULE} mingw_dllmain mingw_common)
|
|
if(DEFINED baseaddress_${MODULE})
|
|
set_image_base(${MODULE} ${baseaddress_${MODULE}})
|
|
else()
|
|
message(STATUS "${MODULE} has no base address")
|
|
endif()
|
|
elseif(${TYPE} MATCHES win32ocx)
|
|
set_entrypoint(${MODULE} DllMainCRTStartup 12)
|
|
target_link_libraries(${MODULE} mingw_dllmain mingw_common)
|
|
set_target_properties(${MODULE} PROPERTIES SUFFIX ".ocx")
|
|
elseif(${TYPE} MATCHES cpl)
|
|
set_entrypoint(${MODULE} DllMainCRTStartup 12)
|
|
target_link_libraries(${MODULE} mingw_dllmain mingw_common)
|
|
set_target_properties(${MODULE} PROPERTIES SUFFIX ".cpl")
|
|
elseif(${TYPE} MATCHES kernelmodedriver)
|
|
set_target_properties(${MODULE} PROPERTIES LINK_FLAGS "-Wl,--exclude-all-symbols -Wl,-file-alignment=0x1000 -Wl,-section-alignment=0x1000" SUFFIX ".sys")
|
|
set_entrypoint(${MODULE} DriverEntry 8)
|
|
set_subsystem(${MODULE} native)
|
|
set_image_base(${MODULE} 0x00010000)
|
|
add_dependencies(${MODULE} bugcodes)
|
|
elseif(${TYPE} MATCHES nativedll)
|
|
set_subsystem(${MODULE} native)
|
|
else()
|
|
message(FATAL_ERROR "Unknown module type : ${TYPE}")
|
|
endif()
|
|
endmacro()
|
|
|
|
macro(set_unicode)
|
|
add_definitions(-DUNICODE -D_UNICODE)
|
|
set(IS_UNICODE 1)
|
|
endmacro()
|
|
|
|
# Workaround lack of mingw RC support in cmake
|
|
macro(set_rc_compiler)
|
|
get_directory_property(defines COMPILE_DEFINITIONS)
|
|
get_directory_property(includes INCLUDE_DIRECTORIES)
|
|
|
|
foreach(arg ${defines})
|
|
set(rc_result_defs "${rc_result_defs} -D${arg}")
|
|
endforeach()
|
|
|
|
foreach(arg ${includes})
|
|
set(rc_result_incs "-I${arg} ${rc_result_incs}")
|
|
endforeach()
|
|
|
|
set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> ${rc_result_defs} ${rc_result_incs} -i <SOURCE> -O coff -o <OBJECT>")
|
|
endmacro()
|
|
|
|
#idl files support
|
|
set(IDL_COMPILER native-widl)
|
|
|
|
if(ARCH MATCHES i386)
|
|
set(IDL_FLAGS -m32 --win32)
|
|
elseif(ARCH MATCHES amd64)
|
|
set(IDL_FLAGS -m64 --win64)
|
|
endif()
|
|
|
|
set(IDL_HEADER_ARG -h -H) #.h
|
|
set(IDL_TYPELIB_ARG -t -T) #.tlb
|
|
set(IDL_SERVER_ARG -s -S) #.c for server library
|
|
set(IDL_CLIENT_ARG -c -C) #.c for stub client library
|
|
set(IDL_PROXY_ARG -p -P)
|
|
set(IDL_DLLDATA_ARG --dlldata-only --dlldata=)
|
|
|
|
macro(add_importlibs MODULE)
|
|
foreach(LIB ${ARGN})
|
|
target_link_libraries(${MODULE} ${CMAKE_BINARY_DIR}/importlibs/lib${LIB}.a)
|
|
add_dependencies(${MODULE} lib${LIB})
|
|
endforeach()
|
|
endmacro()
|
|
|
|
if(NOT ARCH MATCHES i386)
|
|
set(DECO_OPTION "-@")
|
|
endif()
|
|
|
|
macro(add_importlib_target _exports_file)
|
|
|
|
get_filename_component(_name ${_exports_file} NAME_WE)
|
|
get_filename_component(_extension ${_exports_file} EXT)
|
|
|
|
if (${_extension} STREQUAL ".spec")
|
|
if (${ARGC} GREATER 1)
|
|
set(DLLNAME_OPTION "-n=${ARGV1}")
|
|
else()
|
|
set(DLLNAME_OPTION "")
|
|
endif()
|
|
|
|
add_custom_command(
|
|
OUTPUT ${CMAKE_BINARY_DIR}/importlibs/lib${_name}.a
|
|
COMMAND native-spec2def ${DLLNAME_OPTION} -a=${ARCH2} -d=${CMAKE_CURRENT_BINARY_DIR}/${_name}_implib.def ${CMAKE_CURRENT_SOURCE_DIR}/${_exports_file}
|
|
COMMAND ${MINGW_PREFIX}dlltool --def ${CMAKE_CURRENT_BINARY_DIR}/${_name}_implib.def --kill-at --output-lib=${CMAKE_BINARY_DIR}/importlibs/lib${_name}.a
|
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_exports_file})
|
|
|
|
elseif(${_extension} STREQUAL ".def")
|
|
add_custom_command(
|
|
OUTPUT ${CMAKE_BINARY_DIR}/importlibs/lib${_name}.a
|
|
COMMAND ${MINGW_PREFIX}dlltool --def ${CMAKE_CURRENT_SOURCE_DIR}/${_exports_file} --kill-at --output-lib=${CMAKE_BINARY_DIR}/importlibs/lib${_name}.a
|
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_exports_file})
|
|
else()
|
|
message(FATAL_ERROR "Unsupported exports file extension: ${_extension}")
|
|
endif()
|
|
|
|
add_custom_target(
|
|
lib${_name}
|
|
DEPENDS ${CMAKE_BINARY_DIR}/importlibs/lib${_name}.a)
|
|
|
|
endmacro()
|
|
|
|
macro(spec2def _dllname _spec_file)
|
|
get_filename_component(_file ${_spec_file} NAME_WE)
|
|
add_custom_command(
|
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_file}.def ${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c
|
|
COMMAND native-spec2def -n=${_dllname} --kill-at -a=${ARCH2} -d=${CMAKE_CURRENT_BINARY_DIR}/${_file}.def -s=${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file}
|
|
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_spec_file})
|
|
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${_file}.def
|
|
PROPERTIES GENERATED TRUE EXTERNAL_OBJECT TRUE)
|
|
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c PROPERTIES GENERATED TRUE)
|
|
list(APPEND SOURCE ${CMAKE_CURRENT_BINARY_DIR}/${_file}_stubs.c)
|
|
endmacro()
|
|
|
|
#pseh lib, needed with mingw
|
|
set(PSEH_LIB "pseh")
|
|
|
|
endif()
|