0

I'm trying to build my project statically using cMake. Yet cMake always tries to link to shared libraries instead. I will get errors such as this:

/usr/bin/ld: attempted static link of dynamic object /usr/lib/x86_64-linux-gnu/libjpeg.so

I just can't seem to get cMake to use staic libraries eg libjpeg.a and not libjpeg.so I'm using cLion IDE if that makes any difference.

Below is my cmake file, I have removed some source_files just to shorten the length for this question.

# Declare the minimum required CMake version
cmake_minimum_required(VERSION 3.20)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/Modules/")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

# Name the project
project(MyProject)

# Project Version
set(MyProject_VERSION_MAJOR 0)
set(MyProject_VERSION_MINOR 0.1)

# cpp version
set(CMAKE_CXX_STANDARD 17)

if(WIN32)
    set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} /std:c11")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17")
elseif()
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -Wall")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall")
endif()

# first use static libraries
set(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib)

##########################
# Libraries look up
##########################
find_package(wxWidgets 3.2 CONFIG REQUIRED)
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost COMPONENTS filesystem system iostreams locale serialization chrono program_options REQUIRED)
find_package(OpenSSL 3.0 REQUIRED)
find_package(cpprestsdk REQUIRED NAMES cpprestsdk cpprest)
find_package(Botan REQUIRED)
find_library(PQXX_LIB pqxx)
find_package(PostgreSQL REQUIRED)

##########################
# Includes and Linkage
##########################

include_directories(${Boost_INCLUDE_DIR})
include_directories(${OPENSSL_INCLUDE_DIR})
include_directories(${BOTAN_INCLUDE_DIRS})
include_directories(${PostgreSQL_LIBRARY_DIRS})
include_directories(${PQXX_INCLUDE_DIR})
link_directories(${Boost_LIBRARY_DIRS})
add_library(tiny-aes encryption/aes.c)
##########################
# Targets
##########################
# Define a variable containing a list of source files for the project
set(SRC_FILES
        appStart.h
        appStart.cpp
        )

if(WIN32)
    # Include a RC file for windows
    list(APPEND SRC_FILES resources.rc)
elseif(APPLE)
    # Add an icon for the apple .app file
    list(APPEND SRC_FILES src/osx/carbon/wxmac.icns)
endif()

# Define the build target for the executable
add_executable(${PROJECT_NAME} WIN32 MACOSX_BUNDLE ${SRC_FILES})

# force static library usage
link_libraries("-static")

# Link required libraries to the executable
target_link_libraries(${PROJECT_NAME} wx::core wx::base wx::richtext)
target_link_libraries(${PROJECT_NAME} ${BOTAN_LIBRARIES})
target_link_libraries(${PROJECT_NAME} ${OPENSSL_LIBRARIES})
target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES})
target_link_libraries(${PROJECT_NAME} cpprestsdk::cpprest)
target_include_directories(${PROJECT_NAME} PRIVATE tiny-AES-c/)
target_link_libraries(${PROJECT_NAME} ${PQXX_LIB} -static)
target_link_libraries(${PROJECT_NAME} ${PostgreSQL_LIBRARIES})

I have tried adding:

set(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib) to tell cMake to first search for .a files but it doesn't seem to do so. It still tries to link to for example - libjpeg.so and not libjpeg.a which are in the same location.

I have tried adding:

-static at the end of every target_link_libraries example:

target_link_libraries(${PROJECT_NAME} ${PQXX_LIB} -static) That doesn't work

I have tried adding:

link_libraries("-static") before all the target_link_libraries. But that also doesn't work

Can someone help me understand why on linux system, cMake keeps linking to the shared libraries and not the static ones.

Edit (Progress):

rebuilding wxWidgets and using the builtin libraries as follows helped solved the linking dynamic issues:

cmake -G "Unix Makefiles" /home/datahdd/SDKs/wxWidgets-3.2.1 -DwxBUILD_SHARED=OFF -DwxUSE_WEBVIEW=true -DwxUSE_LIBJPEG=builtin -DwxUSE_LIBPNG=builtin -DwxUSE_ZLIB=builtin -DwxUSE_LIBTIFF=builtin -DwxUSE_REGEX=builtin -DwxUSE_EXPAT=builtin -DwxBUILD_MONOLITHIC=OFF

But now I get the following errors:

/usr/bin/ld: cannot find -lgtk-3: No such file or directory
/usr/bin/ld: cannot find -lgdk-3: No such file or directory
/usr/bin/ld: cannot find -lpangocairo-1.0: No such file or directory
/usr/bin/ld: cannot find -lpango-1.0: No such file or directory
/usr/bin/ld: cannot find -latk-1.0: No such file or directory
/usr/bin/ld: cannot find -lgdk_pixbuf-2.0: No such file or directory

I'm guessing I am missing something with the cMake version of wxWidgets. The configuration is showing that it is using GTK3 and building the static version. So why can't it find gtk-3?

-- Configured wxWidgets 3.2.1 for Linux-6.0.6-76060006-generic
    Min OS Version required at runtime:                Linux x86_64
    Which GUI toolkit should wxWidgets use?            gtk3 3.24.33 with support for: GTK+ printing
    Should wxWidgets be compiled into single library?  OFF
    Should wxWidgets be linked as a shared library?    OFF
    Should wxWidgets support Unicode?                  ON
    What wxWidgets compatibility level should be used? 3.0
-- Configuring done
Jono M
  • 91
  • 2
  • 9
  • 1
    Variable `CMAKE_FIND_LIBRARY_SUFFIXES` affects only on libraries searched by `find_library`. Since you code doesn't explicitly use libjpeg, this library is probably linked by some of your dependent libraries (which in turn are used via `find_package`). For find out which dependent library uses libjpeg, you could look into **complete command line**, used for linking. (If you use `make` for build the project, then with `VERBOSE=1` it will shows complete command lines). – Tsyvarev Nov 30 '22 at 08:58
  • @Tsyvarev Thank you very much. I will give that a try and see what I can find. – Jono M Nov 30 '22 at 09:36
  • @JonoM, why do you need to build statically on Linux? Just curious... – Igor Nov 30 '22 at 13:15
  • @Igor I'm wanting to have a very portable application. Something that can just be downloaded / copied and run. I have it working great on windows, I'm just struggling a lot with linux builds. But I am still new to the wold of c++ and compiled based programming. So if it is better or suggested to rather build it using shared libraries, then I will look into how to do that though cMake. I just couldn't figure out how to properly have cMake automatically add the needed shared libraries to to the build, so I was manually having to find libraries and copy them to the executable. It wasn't fun. – Jono M Nov 30 '22 at 15:31
  • 1
    @JonoM, it is strongly suggested/preferred to build using dynamic configuration on all *nix-based platforms, including big UNIX and OSX. There are multiple reasons for it including fat binaries, a possibility of license change and, most importantly, a conflict with existing dynamic libraries, because of the way linker works in *nix-based OSes. Also, it will be easier to provide updates to the software. – Igor Nov 30 '22 at 16:31
  • 1
    On Windows it is preferred to use static linking as the linker there designed differently and it will not conflict with anything else on the system as system itself only contains Windows. – Igor Nov 30 '22 at 16:33
  • @Igor Thank you very much for your help. I really do appreciate it. I will defiantly rather go that way then. Static on windows and shared on UNIX / OSX. Thank you again for your time and help. – Jono M Nov 30 '22 at 17:01
  • Does the hint of `add_library( STATIC ... )` and [this](https://stackoverflow.com/questions/24648357/compiling-a-static-executable-with-cmake) answer your question? – DevSolar Nov 30 '22 at 19:36
  • @DevSolar I have tried those but I still run into the same problems. – Jono M Dec 01 '22 at 07:52
  • Well, I don't *see* that you did those modifications, and I don't *see* the problems you're having, in part because I don't have all those third-party libs on my system to test-run your configuration. I guess what I'm trying to say here is, it would be helpful if you could reduce your example to a [mcve] that doesn't require wxWidgets, Boost, OpenSSL, cpprestsdk, Botan, PQXX_LIB, PostgreSQL, and your undisclosed project sources to reproduce... – DevSolar Dec 01 '22 at 08:04

0 Answers0