From a7498adc03b5a8d0e4c120de039aa97fe32efc7a Mon Sep 17 00:00:00 2001 From: redfish Date: Mon, 29 Aug 2016 09:34:58 -0400 Subject: [PATCH 1/2] cmake: comply with the new policy CMP0026 Access to LOCATION property at config time was disallowed by this policy. This patch updates the offending code to comply with the policy and thereby gets rid of the warning printed by cmake. The fix is to use generator expressions instead of that property. NOTE: Had to remove support for multiconfig (only affects MSVC which is not supported anyway; and mutliconf is an IDE thing in any case), because could not see how to support it with generator expressions. --- cmake/MergeStaticLibs.cmake | 149 ++++++++++++------------------------ 1 file changed, 47 insertions(+), 102 deletions(-) diff --git a/cmake/MergeStaticLibs.cmake b/cmake/MergeStaticLibs.cmake index 858a026a3..1f0cee11a 100644 --- a/cmake/MergeStaticLibs.cmake +++ b/cmake/MergeStaticLibs.cmake @@ -16,114 +16,59 @@ function(merge_static_libs outlib ) set(libs ${ARGV}) list(REMOVE_AT libs 0) -# Create a dummy file that the target will depend on - set(dummyfile ${CMAKE_CURRENT_BINARY_DIR}/${outlib}_dummy.c) - file(WRITE ${dummyfile} "const char * dummy = \"${dummyfile}\";") - - add_library(${outlib} STATIC ${dummyfile}) + list(REMOVE_DUPLICATES libs) # just in case - if("${CMAKE_CFG_INTDIR}" STREQUAL ".") - set(multiconfig FALSE) - else() - set(multiconfig TRUE) - endif() - -# First get the file names of the libraries to be merged + # First get the file names of the libraries to be merged foreach(lib ${libs}) get_target_property(libtype ${lib} TYPE) if(NOT libtype STREQUAL "STATIC_LIBRARY") - message(FATAL_ERROR "Merge_static_libs can only process static libraries") + message(FATAL_ERROR "merge_static_libs can only process static libraries") endif() - if(multiconfig) - foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES}) - get_target_property("libfile_${CONFIG_TYPE}" ${lib} "LOCATION_${CONFIG_TYPE}") - list(APPEND libfiles_${CONFIG_TYPE} ${libfile_${CONFIG_TYPE}}) - endforeach() - else() - get_target_property(libfile ${lib} LOCATION) - list(APPEND libfiles "${libfile}") - endif(multiconfig) + set(libfiles "${libfiles} $") endforeach() - message(STATUS "will be merging ${libfiles}") -# Just to be sure: cleanup from duplicates - if(multiconfig) - foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES}) - list(REMOVE_DUPLICATES libfiles_${CONFIG_TYPE}) - set(libfiles ${libfiles} ${libfiles_${CONFIG_TYPE}}) - endforeach() - endif() - list(REMOVE_DUPLICATES libfiles) -# Now the easy part for MSVC and for MAC - if(MSVC) - # lib.exe does the merging of libraries just need to conver the list into string - foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES}) - set(flags "") - foreach(lib ${libfiles_${CONFIG_TYPE}}) - set(flags "${flags} ${lib}") - endforeach() - string(TOUPPER "STATIC_LIBRARY_FLAGS_${CONFIG_TYPE}" PROPNAME) - set_target_properties(${outlib} PROPERTIES ${PROPNAME} "${flags}") - endforeach() - - elseif(APPLE) - # Use OSX's libtool to merge archives - if(multiconfig) - message(FATAL_ERROR "Multiple configurations are not supported") - endif() - get_target_property(outfile ${outlib} LOCATION) - add_custom_command(TARGET ${outlib} POST_BUILD - COMMAND rm ${outfile} - COMMAND /usr/bin/libtool -static -o ${outfile} - ${libfiles} - ) - else() - # general UNIX - need to "ar -x" and then "ar -ru" - if(multiconfig) - message(FATAL_ERROR "Multiple configurations are not supported") - endif() - get_target_property(outfile ${outlib} LOCATION) - message(STATUS "outfile location is ${outfile}") - foreach(lib ${libfiles}) -# objlistfile will contain the list of object files for the library - set(objlistfile ${lib}.objlist) - set(objdir ${lib}.objdir) - set(objlistcmake ${objlistfile}.cmake) -# we only need to extract files once - if(${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/cmake.check_cache IS_NEWER_THAN ${objlistcmake}) -#--------------------------------- - FILE(WRITE ${objlistcmake} -"# Extract object files from the library -message(STATUS \"Extracting object files from ${lib}\") -EXECUTE_PROCESS(COMMAND ${CMAKE_AR} -x ${lib} - WORKING_DIRECTORY ${objdir}) -# save the list of object files -EXECUTE_PROCESS(COMMAND ls . - OUTPUT_FILE ${objlistfile} - WORKING_DIRECTORY ${objdir})") -#--------------------------------- - file(MAKE_DIRECTORY ${objdir}) - add_custom_command( - OUTPUT ${objlistfile} - COMMAND ${CMAKE_COMMAND} -P ${objlistcmake} - DEPENDS ${lib}) - endif() - list(APPEND extrafiles "${objlistfile}") - # relative path is needed by ar under MSYS - file(RELATIVE_PATH objlistfilerpath ${objdir} ${objlistfile}) + if(MSVC) # lib.exe does the merging of given a list + set_target_properties(${outlib} PROPERTIES STATIC_LIBRARY_FLAGS "${libfiles}") + + elseif(APPLE) # Use OSX's libtool to merge archives add_custom_command(TARGET ${outlib} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E echo "Running: ${CMAKE_AR} ru ${outfile} @${objlistfilerpath}" - COMMAND ${CMAKE_AR} ru "${outfile}" @"${objlistfilerpath}" - WORKING_DIRECTORY ${objdir}) - endforeach() - add_custom_command(TARGET ${outlib} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E echo "Running: ${CMAKE_RANLIB} ${outfile}" - COMMAND ${CMAKE_RANLIB} ${outfile}) - endif() - file(WRITE ${dummyfile}.base "const char* ${outlib}_sublibs=\"${libs}\";") - add_custom_command( - OUTPUT ${dummyfile} - COMMAND ${CMAKE_COMMAND} -E copy ${dummyfile}.base ${dummyfile} - DEPENDS ${libs} ${extrafiles}) + COMMAND rm "$" + COMMAND /usr/bin/libtool -static -o "$" ${libfiles}) - endfunction() \ No newline at end of file + else() # general UNIX: use "ar" to extract objects and re-add to a common lib + foreach(lib ${libs}) + set(objlistfile ${lib}.objlist) # list of objects in the input library + set(objdir ${lib}.objdir) + + add_custom_command(OUTPUT ${objdir} + COMMAND ${CMAKE_COMMAND} -E make_directory ${objdir}) + + add_custom_command(OUTPUT ${objlistfile} + COMMAND ${CMAKE_AR} -x "$" + COMMAND ${CMAKE_AR} -t "$" > ../${objlistfile} + DEPENDS ${lib} ${objdir} + WORKING_DIRECTORY ${objdir}) + + # Empty dummy source file that goes into merged library + set(mergebase ${lib}.mergebase.c) + add_custom_command(OUTPUT ${mergebase} + COMMAND ${CMAKE_COMMAND} -E touch ${mergebase} + DEPENDS ${objlistfile}) + + list(APPEND mergebases "${mergebase}") + endforeach() + + # We need a target for the output merged library + add_library(${outlib} STATIC ${mergebases}) + set(outlibfile "$") + + foreach(lib ${libs}) + add_custom_command(TARGET ${outlib} POST_BUILD + COMMAND ${CMAKE_AR} ru ${outlibfile} @"../${objlistfile}" + WORKING_DIRECTORY ${objdir}) + endforeach() + + add_custom_command(TARGET ${outlib} POST_BUILD + COMMAND ${CMAKE_RANLIB} ${outlibfile}) + endif() +endfunction() From 1de812a92a1f0b6c9080044e04cb77bc34a2ebe7 Mon Sep 17 00:00:00 2001 From: redfish Date: Mon, 29 Aug 2016 10:58:52 -0400 Subject: [PATCH 2/2] cmake: merge libs via virtual object libraries CMake issued a warming about policy CMP0026: access of LOCATION target property at config time was disallowed. Offending code was the code that merged static libraries to generate libwallet_merged.a. This patch does that same merge task in a much simpler way. And, since it doesn't violate the policy, the warning went away. --- cmake/MergeStaticLibs.cmake | 74 ------------------------------------- src/CMakeLists.txt | 9 ++++- src/wallet/CMakeLists.txt | 7 +++- 3 files changed, 12 insertions(+), 78 deletions(-) delete mode 100644 cmake/MergeStaticLibs.cmake diff --git a/cmake/MergeStaticLibs.cmake b/cmake/MergeStaticLibs.cmake deleted file mode 100644 index 1f0cee11a..000000000 --- a/cmake/MergeStaticLibs.cmake +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright (C) 2012 Modelon AB - -# This program is free software: you can redistribute it and/or modify -# it under the terms of the BSD style license. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# FMILIB_License.txt file for more details. - -# You should have received a copy of the FMILIB_License.txt file -# along with this program. If not, contact Modelon AB . - -# Merge_static_libs(outlib lib1 lib2 ... libn) merges a number of static -# libs into a single static library -function(merge_static_libs outlib ) - set(libs ${ARGV}) - list(REMOVE_AT libs 0) - list(REMOVE_DUPLICATES libs) # just in case - - # First get the file names of the libraries to be merged - foreach(lib ${libs}) - get_target_property(libtype ${lib} TYPE) - if(NOT libtype STREQUAL "STATIC_LIBRARY") - message(FATAL_ERROR "merge_static_libs can only process static libraries") - endif() - set(libfiles "${libfiles} $") - endforeach() - - if(MSVC) # lib.exe does the merging of given a list - set_target_properties(${outlib} PROPERTIES STATIC_LIBRARY_FLAGS "${libfiles}") - - elseif(APPLE) # Use OSX's libtool to merge archives - add_custom_command(TARGET ${outlib} POST_BUILD - COMMAND rm "$" - COMMAND /usr/bin/libtool -static -o "$" ${libfiles}) - - else() # general UNIX: use "ar" to extract objects and re-add to a common lib - foreach(lib ${libs}) - set(objlistfile ${lib}.objlist) # list of objects in the input library - set(objdir ${lib}.objdir) - - add_custom_command(OUTPUT ${objdir} - COMMAND ${CMAKE_COMMAND} -E make_directory ${objdir}) - - add_custom_command(OUTPUT ${objlistfile} - COMMAND ${CMAKE_AR} -x "$" - COMMAND ${CMAKE_AR} -t "$" > ../${objlistfile} - DEPENDS ${lib} ${objdir} - WORKING_DIRECTORY ${objdir}) - - # Empty dummy source file that goes into merged library - set(mergebase ${lib}.mergebase.c) - add_custom_command(OUTPUT ${mergebase} - COMMAND ${CMAKE_COMMAND} -E touch ${mergebase} - DEPENDS ${objlistfile}) - - list(APPEND mergebases "${mergebase}") - endforeach() - - # We need a target for the output merged library - add_library(${outlib} STATIC ${mergebases}) - set(outlibfile "$") - - foreach(lib ${libs}) - add_custom_command(TARGET ${outlib} POST_BUILD - COMMAND ${CMAKE_AR} ru ${outlibfile} @"../${objlistfile}" - WORKING_DIRECTORY ${objdir}) - endforeach() - - add_custom_command(TARGET ${outlib} POST_BUILD - COMMAND ${CMAKE_RANLIB} ${outlibfile}) - endif() -endfunction() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 70bb215d0..5a79325ef 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -82,8 +82,13 @@ function (bitmonero_add_library name) FILES ${ARGN}) - add_library("${name}" - ${ARGN}) + # Define a ("virtual") object library and an actual library that links those + # objects together. The virtual libraries can be arbitrarily combined to link + # any subset of objects into one library archive. This is used for releasing + # libwallet, which combines multiple components. + set(objlib obj_${name}) + add_library(${objlib} OBJECT ${ARGN}) + add_library("${name}" STATIC $) set_property(TARGET "${name}" PROPERTY FOLDER "libs") diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index c4585f9ee..48e4b0a23 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -27,7 +27,6 @@ # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # include (${PROJECT_SOURCE_DIR}/cmake/libutils.cmake) -include (${PROJECT_SOURCE_DIR}/cmake/MergeStaticLibs.cmake) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) @@ -76,7 +75,11 @@ target_link_libraries(wallet ${EXTRA_LIBRARIES}) set(libs_to_merge wallet cryptonote_core mnemonics common crypto) -merge_static_libs(wallet_merged "${libs_to_merge}") + +foreach(lib ${libs_to_merge}) + list(APPEND objlibs $) # matches naming convention in src/CMakeLists.txtA +endforeach() +add_library(wallet_merged STATIC ${objlibs}) install(TARGETS wallet_merged ARCHIVE DESTINATION lib)