Skip to content

Commit

Permalink
build: don't generate fake GNU libtool .la files
Browse files Browse the repository at this point in the history
When building on unix systems TigerVNC will build several static
archives (.a) and corresponding GNU libtool archive (.la) files within
cmake build files. However these .la files are specific to GNU libtool
and are not compatible with alternative libtool implementations such as
Slibtool which results in build issues.

Instead it is better to link directly with the static archives which
both GNU libtool and Slibtool can consume, but this requires the
dependency_libs variable from the fake libtool archives which are now
generated in automake (unix.mk) files and then included in Makefile.am.

Gentoo bug: https://bugs.gentoo.org/913581
  • Loading branch information
orbea committed Sep 4, 2023
1 parent c5ad3d6 commit 3f7ee61
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 80 deletions.
122 changes: 48 additions & 74 deletions cmake/Modules/CMakeMacroLibtoolFile.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -79,57 +79,53 @@ function(libtool_generate_control_file _target)
else()
# No shared library extension matched. Check whether target is a CMake
# target.
if(TARGET ${library})
# Target is a CMake target, so assume it is a static library and
# build a reference to it
get_target_property(library_path ${library} BINARY_DIR)
set(library ${library_path}/${CMAKE_STATIC_LIBRARY_PREFIX}${library}.la)
set(_target_dependency_libs "${_target_dependency_libs} ${library}")
elseif(${library} STREQUAL "-Wl,-Bstatic")
# All following libraries should be static
set(STATIC_MODE ON)
elseif(${library} STREQUAL "-Wl,-Bdynamic")
# All following libraries should be dynamic
set(STATIC_MODE OFF)
elseif(${library} MATCHES "^${CMAKE_LIBRARY_PATH_FLAG}")
# Library search path
string(REPLACE ${CMAKE_LIBRARY_PATH_FLAG} "" library ${library})
list(APPEND LIBRARY_PATHS ${library})
else()
# Normal library, so use find_library() to attempt to locate the
# library in a system directory.
if(NOT TARGET ${library})
if(${library} STREQUAL "-Wl,-Bstatic")
# All following libraries should be static
set(STATIC_MODE ON)
elseif(${library} STREQUAL "-Wl,-Bdynamic")
# All following libraries should be dynamic
set(STATIC_MODE OFF)
elseif(${library} MATCHES "^${CMAKE_LIBRARY_PATH_FLAG}")
# Library search path
string(REPLACE ${CMAKE_LIBRARY_PATH_FLAG} "" library ${library})
list(APPEND LIBRARY_PATHS ${library})
else()
# Normal library, so use find_library() to attempt to locate the
# library in a system directory.

# Need to remove -l prefix
if(${library} MATCHES "^${CMAKE_LINK_LIBRARY_FLAG}")
string(REPLACE ${CMAKE_LINK_LIBRARY_FLAG} "" library ${library})
endif()
# Need to remove -l prefix
if(${library} MATCHES "^${CMAKE_LINK_LIBRARY_FLAG}")
string(REPLACE ${CMAKE_LINK_LIBRARY_FLAG} "" library ${library})
endif()

if(STATIC_MODE)
set(_library ${CMAKE_STATIC_LIBRARY_PREFIX}${library}${CMAKE_STATIC_LIBRARY_SUFFIX})
find_library(FL ${_library} PATHS ${LIBRARY_PATHS})
endif()
if(STATIC_MODE)
set(_library ${CMAKE_STATIC_LIBRARY_PREFIX}${library}${CMAKE_STATIC_LIBRARY_SUFFIX})
find_library(FL ${_library} PATHS ${LIBRARY_PATHS})
endif()

if(NOT FL)
find_library(FL ${library} PATHS ${LIBRARY_PATHS})
endif()
if(NOT FL)
find_library(FL ${library} PATHS ${LIBRARY_PATHS})
endif()

if(FL)
# Found library. Depending on if it's static or not we might
# extract the path and library name, then add the
# result to the libtool dependency libs.
if("${FL}" MATCHES ".+${CMAKE_STATIC_LIBRARY_SUFFIX}$")
set(_target_dependency_libs "${_target_dependency_libs} ${FL}")
if(FL)
# Found library. Depending on if it's static or not we might
# extract the path and library name, then add the
# result to the libtool dependency libs.
if("${FL}" MATCHES ".+${CMAKE_STATIC_LIBRARY_SUFFIX}$")
set(_target_dependency_libs "${_target_dependency_libs} ${FL}")
else()
get_filename_component(_shared_lib ${FL} NAME_WE)
get_filename_component(_shared_lib_path ${FL} PATH)
string(REPLACE "lib" "" _shared_lib ${_shared_lib})
set(_target_dependency_libs "${_target_dependency_libs} -L${_shared_lib_path} -l${_shared_lib}")
endif()
else()
get_filename_component(_shared_lib ${FL} NAME_WE)
get_filename_component(_shared_lib_path ${FL} PATH)
string(REPLACE "lib" "" _shared_lib ${_shared_lib})
set(_target_dependency_libs "${_target_dependency_libs} -L${_shared_lib_path} -l${_shared_lib}")
message(FATAL_ERROR " - could not find library ${library}")
endif()
else()
message(FATAL_ERROR " - could not find library ${library}")
# Need to clear FL to get new results next loop
unset(FL CACHE)
endif()
# Need to clear FL to get new results next loop
unset(FL CACHE)
endif()
endif()
else()
Expand Down Expand Up @@ -160,38 +156,16 @@ function(libtool_generate_control_file _target)
get_target_property(_binary_dir ${_target} BINARY_DIR)

# Write the libtool control file for the static library
set(_lname ${CMAKE_STATIC_LIBRARY_PREFIX}${_target})
set(_laname ${_binary_dir}/${_lname}.la)

file(WRITE ${_laname} "# ${_lname}.la - a libtool library file\n# Generated by ltmain.sh (GNU libtool) 2.2.6b\n")
file(APPEND ${_laname} "dlname=''\n\n")
file(APPEND ${_laname} "library_names=''\n\n")
file(APPEND ${_laname} "old_library='${_lname}${CMAKE_STATIC_LIBRARY_SUFFIX}'\n\n")
file(APPEND ${_laname} "inherited_linker_flags=''\n\n")
file(APPEND ${_laname} "dependency_libs=' ${_target_dependency_libs}'\n\n")
file(APPEND ${_laname} "weak_library_names=''\n\n")
file(APPEND ${_laname} "current=\n")
file(APPEND ${_laname} "age=\n")
file(APPEND ${_laname} "revision=\n\n")
file(APPEND ${_laname} "installed=no\n\n")
file(APPEND ${_laname} "shouldnotlink=no\n\n")
file(APPEND ${_laname} "dlopen=''\n")
file(APPEND ${_laname} "dlpreopen=''\n\n")
file(APPEND ${_laname} "libdir='/usr/lib'\n\n")
set(_lname ${_target})
set(_mkname ${_binary_dir}/unix.mk)

file(WRITE ${_mkname} "${_target}_LIBS = ${_target_dependency_libs}\n")

# Make sure the timestamp is updated to trigger other make invocations
add_custom_command(OUTPUT "${_laname}" DEPENDS ${_target}
COMMENT "Updating timestamp on ${_lname}.la"
COMMAND "${CMAKE_COMMAND}" -E touch "${_laname}")

# Add custom command to symlink the static library so that autotools finds
# the library in .libs. These are executed after the specified target build.
set(_libname ${_binary_dir}/.libs/${_lname}${CMAKE_STATIC_LIBRARY_SUFFIX})
add_custom_command(OUTPUT "${_libname}" DEPENDS ${_target}
COMMENT "Creating symlink .libs/${_lname}${CMAKE_STATIC_LIBRARY_SUFFIX}"
COMMAND "${CMAKE_COMMAND}" -E make_directory "${_binary_dir}/.libs"
COMMAND "${CMAKE_COMMAND}" -E create_symlink ../${_lname}${CMAKE_STATIC_LIBRARY_SUFFIX} "${_libname}")
add_custom_command(OUTPUT "${_mkname}" DEPENDS ${_target}
COMMENT "Updating timestamp on ${_binary_dir}/unix.mk"
COMMAND "${CMAKE_COMMAND}" -E touch "${_mkname}")

add_custom_target(${_target}.la ALL
DEPENDS "${_laname}" "${_libname}")
DEPENDS "${_mkname}" "${_libname}")
endfunction()
19 changes: 13 additions & 6 deletions unix/xserver/hw/vnc/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
TIGERVNC_SRCDIR=${top_srcdir}/../..
TIGERVNC_BUILDDIR=${TIGERVNC_SRCDIR}

RFB_LIB=$(TIGERVNC_BUILDDIR)/common/rfb/librfb.la
RDR_LIB=$(TIGERVNC_BUILDDIR)/common/rdr/librdr.la
OS_LIB=$(TIGERVNC_BUILDDIR)/common/os/libos.la
NETWORK_LIB=$(TIGERVNC_BUILDDIR)/common/network/libnetwork.la
UNIXCOMMON_LIB=$(TIGERVNC_BUILDDIR)/unix/common/libunixcommon.la
COMMON_LIBS=$(NETWORK_LIB) $(RFB_LIB) $(RDR_LIB) $(OS_LIB) $(UNIXCOMMON_LIB)
include $(TIGERVNC_BUILDDIR)/common/network/unix.mk
include $(TIGERVNC_BUILDDIR)/common/os/unix.mk
include $(TIGERVNC_BUILDDIR)/common/rdr/unix.mk
include $(TIGERVNC_BUILDDIR)/common/rfb/unix.mk
include $(TIGERVNC_BUILDDIR)/unix/common/unix.mk

RFB_LIB=$(TIGERVNC_BUILDDIR)/common/rfb/librfb.a
RDR_LIB=$(TIGERVNC_BUILDDIR)/common/rdr/librdr.a
OS_LIB=$(TIGERVNC_BUILDDIR)/common/os/libos.a
NETWORK_LIB=$(TIGERVNC_BUILDDIR)/common/network/libnetwork.a
UNIXCOMMON_LIB=$(TIGERVNC_BUILDDIR)/unix/common/libunixcommon.a
STATIC_LIBS=$(network_LIBS) $(rfb_LIBS) $(rdr_LIBS) $(os_LIBS) $(unixcommon_LIBS)
COMMON_LIBS=$(NETWORK_LIB) $(RFB_LIB) $(RDR_LIB) $(OS_LIB) $(UNIXCOMMON_LIB) $(STATIC_LIBS)

noinst_LTLIBRARIES = libvnccommon.la

Expand Down

0 comments on commit 3f7ee61

Please sign in to comment.