Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not export internal symbols in shared object files #1307

Merged
6 changes: 6 additions & 0 deletions bindings/libdnf5/shared.i
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@
// be renamed to Perl_get_context
#undef get_context
%}


// Define empty macros. They are used to define the visibility of symbols.
#define LIBDNF_API
#define LIBDNF_LOCAL
#define LIBDNF_PLUGIN_API
1 change: 1 addition & 0 deletions bindings/libdnf5_cli/progressbar.i
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#define CV __perl_CV

#define LIBDNF_CLI_API

%include "libdnf5-cli/progressbar/progress_bar.hpp"
%include "libdnf5-cli/progressbar/download_progress_bar.hpp"
Expand Down
1 change: 1 addition & 0 deletions common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ include_directories(.)

add_library(common OBJECT ${COMMON_SOURCES})
set_property(TARGET common PROPERTY POSITION_INDEPENDENT_CODE ON)
set_target_properties(common PROPERTIES C_VISIBILITY_PRESET hidden CXX_VISIBILITY_PRESET hidden)

# required by clang
target_link_libraries(common PUBLIC stdc++)
3 changes: 3 additions & 0 deletions dnf5-plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ if(NOT WITH_DNF5_PLUGINS)
return()
endif()

set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_C_VISIBILITY_PRESET hidden)

include_directories("${PROJECT_SOURCE_DIR}/dnf5/include/")
# These plugins use symbols from dnf5 program, hence the symbold are undefined
# at link time and cannot pass "-z defs" linker check. Disable the check.
Expand Down
4 changes: 4 additions & 0 deletions dnf5/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ endif()

find_package(Threads)

add_definitions(-DDNF_BUILD_APPLICATION)

# set gettext domain for translations
set(GETTEXT_DOMAIN dnf5)
add_definitions(-DGETTEXT_DOMAIN=\"${GETTEXT_DOMAIN}\")
Expand All @@ -28,6 +30,8 @@ add_executable(dnf5 ${DNF5_SOURCES})

# Enable symbol export. Needed for loadable modules (dnf5 plugins).
set_property(TARGET dnf5 PROPERTY ENABLE_EXPORTS 1)
# Export only explicitly marked symbols.
set_target_properties(dnf5 PROPERTIES C_VISIBILITY_PRESET hidden CXX_VISIBILITY_PRESET hidden)

target_link_libraries(dnf5 PRIVATE common libdnf5 libdnf5-cli Threads::Threads)
install(TARGETS dnf5 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
Expand Down
19 changes: 10 additions & 9 deletions dnf5/include/dnf5/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
#ifndef DNF5_CONTEXT_HPP
#define DNF5_CONTEXT_HPP

#include "defs.h"
#include "version.hpp"

#include <libdnf5-cli/argument_parser.hpp>
Expand All @@ -44,7 +45,7 @@ namespace dnf5 {

class Plugins;

class Context : public libdnf5::cli::session::Session {
class DNF_API Context : public libdnf5::cli::session::Session {
public:
enum class LoadAvailableRepos { NONE, ENABLED, ALL };

Expand Down Expand Up @@ -164,12 +165,12 @@ class Context : public libdnf5::cli::session::Session {
const std::vector<std::pair<std::vector<std::string>, bool>> & get_libdnf_plugins_enablement() const;

private:
class Impl;
class DNF_LOCAL Impl;
std::unique_ptr<Impl> p_impl;
};


class Command : public libdnf5::cli::session::Command {
class DNF_API Command : public libdnf5::cli::session::Command {
public:
using libdnf5::cli::session::Command::Command;

Expand All @@ -183,7 +184,7 @@ class Command : public libdnf5::cli::session::Command {
};


class RpmTransCB : public libdnf5::rpm::TransactionCallbacks {
class DNF_API RpmTransCB : public libdnf5::rpm::TransactionCallbacks {
public:
RpmTransCB(Context & context);
~RpmTransCB();
Expand Down Expand Up @@ -252,25 +253,25 @@ class RpmTransCB : public libdnf5::rpm::TransactionCallbacks {
void verify_stop([[maybe_unused]] uint64_t total) override;

private:
void new_progress_bar(int64_t total, const std::string & descr);
DNF_LOCAL void new_progress_bar(int64_t total, const std::string & descr);
jan-kolarik marked this conversation as resolved.
Show resolved Hide resolved

static bool is_time_to_print();
DNF_LOCAL static bool is_time_to_print();

static std::chrono::time_point<std::chrono::steady_clock> prev_print_time;
DNF_LOCAL static std::chrono::time_point<std::chrono::steady_clock> prev_print_time;

libdnf5::cli::progressbar::MultiProgressBar multi_progress_bar;
libdnf5::cli::progressbar::DownloadProgressBar * active_progress_bar{nullptr};
Context & context;
};

void run_transaction(libdnf5::rpm::Transaction & transaction);
DNF_API void run_transaction(libdnf5::rpm::Transaction & transaction);

/// Returns the names of matching packages and paths of matching package file names and directories.
/// If `nevra_for_same_name` is true, it returns a full nevra for packages with the same name.
/// Only files whose names match `file_name_regex` are returned.
/// NOTE: This function is intended to be used only for autocompletion purposes as the argument parser's
/// complete hook argument. It does the base setup and repos loading inside.
std::vector<std::string> match_specs(
DNF_API std::vector<std::string> match_specs(
Context & ctx,
const std::string & pattern,
bool installed,
Expand Down
59 changes: 59 additions & 0 deletions dnf5/include/dnf5/defs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
Copyright Contributors to the libdnf project.

This file is part of libdnf: https://github.com/rpm-software-management/libdnf/

Libdnf is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2.1 of the License, or
(at your option) any later version.

Libdnf 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
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with libdnf. If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef DNF5_DEFS_H
#define DNF5_DEFS_H

// Generic helper definitions for shared library support
#if defined _WIN32 || defined __CYGWIN__
#define DNF_SYMBOL_IMPORT __declspec(dllimport)
#define DNF_SYMBOL_EXPORT __declspec(dllexport)
#define DNF_SYMBOL_LOCAL
#else
#if __GNUC__ >= 4
#define DNF_SYMBOL_IMPORT __attribute__((visibility("default")))
#define DNF_SYMBOL_EXPORT __attribute__((visibility("default")))
#define DNF_SYMBOL_LOCAL __attribute__((visibility("hidden")))
#else
#define DNF_SYMBOL_IMPORT
#define DNF_SYMBOL_EXPORT
#define DNF_SYMBOL_LOCAL
#endif
#endif

// Now define DNF_API, DNF_LOCAL and DNF_PLUGIN_API.
// DNF_API and DNF_PLUGIN_API are used for public API symbols. It either imports or exports the symbol.
// DNF_LOCAL is used for non-api symbols.

#ifdef DNF_BUILD_APPLICATION // defined if we are building the dnf application
#define DNF_API DNF_SYMBOL_EXPORT
#else
#define DNF_API DNF_SYMBOL_IMPORT
#endif

#define DNF_LOCAL DNF_SYMBOL_LOCAL

// DNF exports its symbols but imports plugin symbols.
#ifdef DNF_BUILD_APPLICATION // defined if we are building the dnf application
#define DNF_PLUGIN_API DNF_SYMBOL_IMPORT
#else
#define DNF_PLUGIN_API DNF_SYMBOL_EXPORT
#endif

#endif
14 changes: 8 additions & 6 deletions dnf5/include/dnf5/iplugin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
#define DNF5_PLUGIN_IPLUGIN_HPP

#include "context.hpp"
#include "defs.h"

#include <cstdint>
#include <vector>
Expand All @@ -35,7 +36,7 @@ struct PluginVersion {
};

/// @brief A base class for implementing DNF5 plugins that provide one or more commands to users.
class IPlugin {
class DNF_PLUGIN_API IPlugin {
public:
explicit IPlugin(Context & context);
virtual ~IPlugin();
Expand Down Expand Up @@ -83,21 +84,22 @@ extern "C" {

/// Returns the version of the API required by the plugin.
/// Same result as IPlugin::get_api_version(), but can be called without creating an IPlugin instance.
dnf5::PluginAPIVersion dnf5_plugin_get_api_version(void);
DNF_PLUGIN_API dnf5::PluginAPIVersion dnf5_plugin_get_api_version(void);

/// Returns the name of the plugin. It can be called at any time.
/// Same result as IPlugin::get_name(), but can be called without creating an IPlugin instance.
const char * dnf5_plugin_get_name(void);
DNF_PLUGIN_API const char * dnf5_plugin_get_name(void);

/// Returns the version of the plugin. It can be called at any time.
/// Same result as IPlugin::get_version(), but can be called without creating an IPlugin instance.
dnf5::PluginVersion dnf5_plugin_get_version(void);
DNF_PLUGIN_API dnf5::PluginVersion dnf5_plugin_get_version(void);

/// Creates a new plugin instance. Passes the API version to the plugin.
dnf5::IPlugin * dnf5_plugin_new_instance(dnf5::ApplicationVersion application_version, dnf5::Context & context);
DNF_PLUGIN_API dnf5::IPlugin * dnf5_plugin_new_instance(
dnf5::ApplicationVersion application_version, dnf5::Context & context);

/// Deletes plugin instance.
void dnf5_plugin_delete_instance(dnf5::IPlugin * plugin_instance);
DNF_PLUGIN_API void dnf5_plugin_delete_instance(dnf5::IPlugin * plugin_instance);
}

#endif
5 changes: 3 additions & 2 deletions dnf5/include/dnf5/offline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
#ifndef DNF5_OFFLINE_HPP
#define DNF5_OFFLINE_HPP

#include <dnf5/context.hpp>
#include "context.hpp"
#include "defs.h"

#include <string>

namespace dnf5::offline {

void log_status(
DNF_API void log_status(
Context & context,
const std::string & message,
const std::string & message_id,
Expand Down
20 changes: 11 additions & 9 deletions dnf5/include/dnf5/shared_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,29 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
#ifndef DNF5_COMMANDS_SHARED_OPTIONS_HPP
#define DNF5_COMMANDS_SHARED_OPTIONS_HPP

#include "defs.h"

#include <dnf5/context.hpp>
#include <libdnf5-cli/session.hpp>
#include <libdnf5/utils/bgettext/bgettext-lib.h>

namespace dnf5 {

class AllowErasingOption : public libdnf5::cli::session::BoolOption {
class DNF_API AllowErasingOption : public libdnf5::cli::session::BoolOption {
public:
explicit AllowErasingOption(libdnf5::cli::session::Command & command);
~AllowErasingOption();
};


class SkipBrokenOption : public libdnf5::cli::session::BoolOption {
class DNF_API SkipBrokenOption : public libdnf5::cli::session::BoolOption {
public:
explicit SkipBrokenOption(dnf5::Command & command);
~SkipBrokenOption();
};


class SkipUnavailableOption : public libdnf5::cli::session::BoolOption {
class DNF_API SkipUnavailableOption : public libdnf5::cli::session::BoolOption {
public:
explicit SkipUnavailableOption(dnf5::Command & command);
~SkipUnavailableOption();
Expand All @@ -49,25 +51,25 @@ class SkipUnavailableOption : public libdnf5::cli::session::BoolOption {

/// Create two options (`--allow-downgrade` and `--no-allow-downgrade`) for a command provided as an argument command.
/// The values are stored in the `allow_downgrade` configuration option
void create_allow_downgrade_options(dnf5::Command & command);
DNF_API void create_allow_downgrade_options(dnf5::Command & command);

/// Create the `--destdir` option for a command provided as an argument.
/// The values are stored in the `destdir` configuration option
void create_destdir_option(dnf5::Command & command);
DNF_API void create_destdir_option(dnf5::Command & command);

/// Create the `--downloadonly` option for a command provided as an argument.
/// The values are stored in the `downloadonly` configuration option
void create_downloadonly_option(dnf5::Command & command);
DNF_API void create_downloadonly_option(dnf5::Command & command);

/// Create the `--store` option for a command provided as an argument.
/// The value is stored in Context::transaction_store_path.
void create_store_option(dnf5::Command & command);
DNF_API void create_store_option(dnf5::Command & command);

/// Create the `--offline` option for a command provided as an argument.
void create_offline_option(dnf5::Command & command);
DNF_API void create_offline_option(dnf5::Command & command);

/// Create the `--json` option for a command provided as an argument.
void create_json_option(dnf5::Command & command);
DNF_API void create_json_option(dnf5::Command & command);

} // namespace dnf5

Expand Down
6 changes: 4 additions & 2 deletions dnf5/include/dnf5/version.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ along with libdnf. If not, see <https://www.gnu.org/licenses/>.
#ifndef DNF5_CONFIG_HPP
#define DNF5_CONFIG_HPP

#include "defs.h"

#include <cstdint>

namespace dnf5 {
Expand Down Expand Up @@ -49,11 +51,11 @@ static constexpr PluginAPIVersion PLUGIN_API_VERSION{.major = 2, .minor = 0};

/// @return Application version
/// @since 5.0
ApplicationVersion get_application_version() noexcept;
DNF_API ApplicationVersion get_application_version() noexcept;

/// @return API version implemented in the application
/// @since 5.0
PluginAPIVersion get_plugin_api_version() noexcept;
DNF_API PluginAPIVersion get_plugin_api_version() noexcept;

} // namespace dnf5

Expand Down
Loading
Loading