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

Build freeorioncommon as shared library on Windows with CMake #1416

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 17 additions & 19 deletions BUILD.md
Expand Up @@ -106,33 +106,32 @@ maintained Visual Studio Project is used for building.
Step by step procedure:

* Enter the _source directory_.
* Create a `build` directory, which will contain all compile FreeOrion
build artifacs.
* Change into the `build` directory on the command line.
* Execute cmake to generate the native build system:

```
cmake -G "GENERATOR" ..
```

Where `GENERATOR` should be:

* on Windows: "Visual Studio 2015"
* on Mac OS X: "Xcode"
* on Linux and other other Operating Systems: "Unix Makefiles"

* On Windows:
* Open `msvc2015\FreeOrion.sln` with Visual Studio.
* Open `FreeOrion.sln` with Visual Studio.
* Compile the whole project by selecting the `Build` -> `Build Solution`
menu entry.

* On Mac OS X:
* Create a `build` directory, which will contain all compile FreeOrion
build artifacs.
* Change into the `build` directory on the command line.
* Execute cmake to generate a Xcode project file:

```
cmake -GXcode ..
```
* Open `FreeOrion.xcodeproj` with Xcode.
* Compile the whole project by selecting the `ALL_BUILD` scheme and
pressing 'Command' + 'B'.

* On Linux and other Operating Systems
* Create a `build` directory, which will contain all compile FreeOrion
build artifacs.
* Change into the `build` directory on the command line.
* Execute cmake to generate Makefiles:

```
cmake ..
```
* Compile the whole project by calling `make` within the build directory.
In case you want to utilize multiple CPU cores by running parallel compile
jobs check out the the [make jobs](`--jobs`) parameter of `make`.
Expand All @@ -145,8 +144,7 @@ Step by step procedure:

This will leave you with a build of FreeOrion executables.

* `freeorion-project/FreeOrion` on Windows.
* `freeorion-project/build/Release` on Mac OS X.
* `freeorion-project/build/Release` on Windows and Mac OS X.
* `freeorion-project/freeorion/build` on Linux and other Operating Systems.


Expand Down
58 changes: 8 additions & 50 deletions CMakeLists.txt
Expand Up @@ -321,13 +321,6 @@ target_compile_options(freeorioncommon
$<$<CXX_COMPILER_ID:AppleClang>:-ftemplate-depth=512>
)

if(APPLE)
set_target_properties(freeorioncommon
PROPERTIES
LINK_FLAGS "-undefined dynamic_lookup"
)
endif()

target_compile_definitions(freeorioncommon
PRIVATE
-DFREEORION_BUILD_COMMON
Expand Down Expand Up @@ -360,27 +353,20 @@ target_link_libraries(freeorioncommon
add_dependencies(freeorioncommon freeorionversion)


add_library(freeorionparseobj OBJECT "")
add_library(freeorionparse OBJECT "")

target_include_directories(freeorionparseobj SYSTEM
target_include_directories(freeorionparse SYSTEM
PRIVATE
${Boost_INCLUDE_DIRS}
${PROJECT_SOURCE_DIR}/GG
)

set_property(TARGET freeorionparseobj
set_property(TARGET freeorionparse
PROPERTY
POSITION_INDEPENDENT_CODE ON
)

if(WIN32)
set_property(TARGET freeorionparse
PROPERTY
OUTPUT_NAME Parsers
)
endif()

target_compile_options(freeorionparseobj
target_compile_options(freeorionparse
PRIVATE
$<$<CXX_COMPILER_ID:GNU>:-fvisibility=hidden>
$<$<CXX_COMPILER_ID:Clang>:-fvisibility=hidden>
Expand All @@ -390,39 +376,17 @@ target_compile_options(freeorionparseobj
$<$<AND:$<NOT:$<BOOL:${BUILD_TESTING}>>,$<CXX_COMPILER_ID:GNU>>:-O3>
)

target_compile_definitions(freeorionparseobj
target_compile_definitions(freeorionparse
PRIVATE
-DNDEBUG
-DFREEORION_BUILD_PARSE
-DFREEORION_BUILD_COMMON
)


add_library(freeorionparse $<TARGET_OBJECTS:freeorionparseobj>)

target_compile_options(freeorionparse
target_sources(freeorioncommon
PRIVATE
$<$<CXX_COMPILER_ID:GNU>:-fvisibility=hidden>
$<$<CXX_COMPILER_ID:Clang>:-fvisibility=hidden>
$<$<CXX_COMPILER_ID:AppleClang>:-fvisibility=hidden>
$<TARGET_OBJECTS:freeorionparse>
)

if(APPLE)
# Xcode doesn't build freeorionparse because it doesn't have any
# source code files associated and only links the freeorionparselib
# objects into a shared library. Adding an empty file fixes this.
# https://cmake.org/cmake/help/v3.0/command/add_library.html
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/xcode_dummy.cpp" "")
target_sources(freeorionparse
PRIVATE
"${CMAKE_CURRENT_BINARY_DIR}/xcode_dummy.cpp"
)

set_target_properties(freeorionparse
PROPERTIES
LINK_FLAGS "-undefined dynamic_lookup"
)
endif()


add_executable(freeoriond "")

Expand Down Expand Up @@ -455,7 +419,6 @@ target_include_directories(freeoriond SYSTEM

target_link_libraries(freeoriond
freeorioncommon
freeorionparse
${PYTHON_LIBRARIES}
${Boost_PYTHON_LIBRARY}
${Boost_LOG_LIBRARY}
Expand Down Expand Up @@ -498,7 +461,6 @@ target_include_directories(freeorionca SYSTEM

target_link_libraries(freeorionca
freeorioncommon
freeorionparse
${PYTHON_LIBRARIES}
${Boost_PYTHON_LIBRARY}
${Boost_LOG_LIBRARY}
Expand Down Expand Up @@ -600,7 +562,6 @@ if(NOT BUILD_HEADLESS)

target_link_libraries(freeorion
freeorioncommon
freeorionparse
GiGi
GiGiSDL
${OPENGL_gl_LIBRARY}
Expand Down Expand Up @@ -633,8 +594,6 @@ if(APPLE)
${CMAKE_COMMAND} -E make_directory "$<TARGET_FILE_DIR:freeorion>/../SharedSupport"
COMMAND
${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:freeorioncommon>" "$<TARGET_FILE_DIR:freeorion>/../SharedSupport"
COMMAND
${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:freeorionparse>" "$<TARGET_FILE_DIR:freeorion>/../SharedSupport"
COMMAND
${CMAKE_COMMAND} -E copy_if_different "$<TARGET_FILE:GiGi>" "$<TARGET_FILE_DIR:freeorion>/../SharedSupport"
COMMAND
Expand Down Expand Up @@ -714,7 +673,6 @@ if(UNIX AND NOT APPLE)
install(
TARGETS
freeorioncommon
freeorionparse
LIBRARY DESTINATION ${FreeOrion_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
Expand Down
22 changes: 20 additions & 2 deletions appveyor.yml
Expand Up @@ -2,6 +2,11 @@ os: Visual Studio 2017

version: ci-{build}

environment:
matrix:
- BUILD_SYSTEM: CMAKE
- BUILD_SYSTEM: MSVC

init:
- git config --global core.eol native
- git config --global core.autocrlf true
Expand All @@ -24,9 +29,22 @@ install:
- cd freeorion

before_build:
- cd msvc2017
- if "%BUILD_SYSTEM%" == "MSVC" (
cd msvc2017
)
- if "%BUILD_SYSTEM%" == "CMAKE" (
mkdir build
)

build_script:
- msbuild FreeOrion.sln /maxcpucount /property:BuildInParallel=true /property:CL_MPCount=2 /property:PlatformToolset=v140_xp /property:Configuration=Release-XP /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" /verbosity:minimal
- if "%BUILD_SYSTEM%" == "MSVC" (
msbuild FreeOrion.sln /maxcpucount /property:BuildInParallel=true /property:CL_MPCount=2 /property:PlatformToolset=v140_xp /property:Configuration=Release-XP /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" /verbosity:minimal
)
- if "%BUILD_SYSTEM%" == "CMAKE" (
pushd build &&
cmake -G "Visual Studio 15 2017" -T v140_xp .. &&
cmake --build . --config "Release" -- /maxcpucount /property:BuildInParallel=true /property:CL_MPCount=2 /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" &&
popd
)

test: off
2 changes: 1 addition & 1 deletion parse/CMakeLists.txt
@@ -1,4 +1,4 @@
target_sources(freeorionparseobj
target_sources(freeorionparse
PUBLIC
${CMAKE_CURRENT_LIST_DIR}/Parse.h
PRIVATE
Expand Down
48 changes: 22 additions & 26 deletions parse/Parse.h
@@ -1,12 +1,8 @@
#ifndef _Parse_h_
#define _Parse_h_

#if FREEORION_BUILD_PARSE && __GNUC__
# define FO_PARSE_API __attribute__((__visibility__("default")))
#else
# define FO_PARSE_API
#endif

#include "../util/Export.h"
#include "../universe/Tech.h"
#include "../universe/ValueRefFwd.h"

#include <boost/filesystem/path.hpp>
Expand All @@ -30,9 +26,9 @@ class GameRules;
struct ItemSpec;

namespace parse {
FO_PARSE_API std::map<std::string, std::unique_ptr<BuildingType>> buildings(const boost::filesystem::path& path);
FO_PARSE_API std::map<std::string, std::unique_ptr<FieldType>> fields(const boost::filesystem::path& path);
FO_PARSE_API std::map<std::string, std::unique_ptr<Special>> specials(const boost::filesystem::path& path);
FO_COMMON_API std::map<std::string, std::unique_ptr<BuildingType>> buildings(const boost::filesystem::path& path);
FO_COMMON_API std::map<std::string, std::unique_ptr<FieldType>> fields(const boost::filesystem::path& path);
FO_COMMON_API std::map<std::string, std::unique_ptr<Special>> specials(const boost::filesystem::path& path);

/** Parse all species in directory \p path, store them with their name in \p
species_by_name. If a file exists called SpeciesCensusOrdering.focs.txt, parse it and
Expand All @@ -41,17 +37,17 @@ namespace parse {
std::map<std::string, std::unique_ptr<Species>>, // species_by_name,
std::vector<std::string> // ordering
>;
FO_PARSE_API species_type species(const boost::filesystem::path& path);
FO_COMMON_API species_type species(const boost::filesystem::path& path);

/* T in techs<T> can only be TechManager::TechParseTuple. This decouples
Parse.h from Tech.h so that all parsers are not recompiled when Tech.h changes.*/
template <typename T>
FO_PARSE_API T techs(const boost::filesystem::path& path);
FO_COMMON_API T techs(const boost::filesystem::path& path);

FO_PARSE_API std::vector<ItemSpec> items(const boost::filesystem::path& path);
FO_PARSE_API std::vector<ItemSpec> starting_buildings(const boost::filesystem::path& path);
FO_PARSE_API std::map<std::string, std::unique_ptr<PartType>> ship_parts(const boost::filesystem::path& path);
FO_PARSE_API std::map<std::string, std::unique_ptr<HullType>> ship_hulls(const boost::filesystem::path& path);
FO_COMMON_API std::vector<ItemSpec> items(const boost::filesystem::path& path);
FO_COMMON_API std::vector<ItemSpec> starting_buildings(const boost::filesystem::path& path);
FO_COMMON_API std::map<std::string, std::unique_ptr<PartType>> ship_parts(const boost::filesystem::path& path);
FO_COMMON_API std::map<std::string, std::unique_ptr<HullType>> ship_hulls(const boost::filesystem::path& path);

/** Parse all ship designs in directory \p path, store them with their filename in \p
design_and_path. If a file exists called ShipDesignOrdering.focs.txt, parse it and
Expand All @@ -60,22 +56,22 @@ namespace parse {
std::vector<std::pair<std::unique_ptr<ParsedShipDesign>, boost::filesystem::path>>, // designs_and_paths,
std::vector<boost::uuids::uuid> // ordering
>;
FO_PARSE_API ship_designs_type ship_designs(const boost::filesystem::path& path);
FO_COMMON_API ship_designs_type ship_designs(const boost::filesystem::path& path);

FO_PARSE_API std::vector<std::unique_ptr<FleetPlan>> fleet_plans(const boost::filesystem::path& path);
FO_PARSE_API std::vector<std::unique_ptr<MonsterFleetPlan>> monster_fleet_plans(const boost::filesystem::path& path);
FO_PARSE_API std::map<std::string, std::unique_ptr<ValueRef::ValueRefBase<double>>> statistics(const boost::filesystem::path& path);
FO_PARSE_API std::map<std::string, std::vector<EncyclopediaArticle>> encyclopedia_articles(const boost::filesystem::path& path);
FO_PARSE_API std::map<std::string, std::map<int, int>> keymaps(const boost::filesystem::path& path);
FO_PARSE_API GameRules game_rules(const boost::filesystem::path& path);
FO_PARSE_API bool read_file(const boost::filesystem::path& path, std::string& file_contents);
FO_COMMON_API std::vector<std::unique_ptr<FleetPlan>> fleet_plans(const boost::filesystem::path& path);
FO_COMMON_API std::vector<std::unique_ptr<MonsterFleetPlan>> monster_fleet_plans(const boost::filesystem::path& path);
FO_COMMON_API std::map<std::string, std::unique_ptr<ValueRef::ValueRefBase<double>>> statistics(const boost::filesystem::path& path);
FO_COMMON_API std::map<std::string, std::vector<EncyclopediaArticle>> encyclopedia_articles(const boost::filesystem::path& path);
FO_COMMON_API std::map<std::string, std::map<int, int>> keymaps(const boost::filesystem::path& path);
FO_COMMON_API GameRules game_rules(const boost::filesystem::path& path);
FO_COMMON_API bool read_file(const boost::filesystem::path& path, std::string& file_contents);

/** Find all FOCS scripts (files with .focs.txt suffix) in \p path. If \p allow_permissive =
true then if \p path is not empty and there are no .focs.txt files allow all files to qualify.*/
FO_PARSE_API std::vector< boost::filesystem::path > ListScripts(const boost::filesystem::path& path, bool permissive = false);
FO_COMMON_API std::vector< boost::filesystem::path > ListScripts(const boost::filesystem::path& path, bool permissive = false);

FO_PARSE_API void file_substitution(std::string& text, const boost::filesystem::path& file_search_path);
FO_PARSE_API void process_include_substitutions(std::string& text,
FO_COMMON_API void file_substitution(std::string& text, const boost::filesystem::path& file_search_path);
FO_COMMON_API void process_include_substitutions(std::string& text,
const boost::filesystem::path& file_search_path,
std::set<boost::filesystem::path>& files_included);
}
Expand Down
2 changes: 1 addition & 1 deletion parse/TechsParser.cpp
Expand Up @@ -254,4 +254,4 @@ namespace parse {
// explicitly instantiate techs.
// This allows Tech.h to only be included in this .cpp file and not Parse.h
// which recompiles all parsers if Tech.h changes.
template FO_PARSE_API TechManager::TechParseTuple parse::techs<TechManager::TechParseTuple>(const boost::filesystem::path& path);
template FO_COMMON_API TechManager::TechParseTuple parse::techs<TechManager::TechParseTuple>(const boost::filesystem::path& path);
2 changes: 1 addition & 1 deletion test/parse/CMakeLists.txt
Expand Up @@ -3,7 +3,7 @@ find_package(Boost ${MINIMUM_BOOST_VERSION} COMPONENTS unit_test_framework REQUI
add_executable(fo_unittest_parse
main.cpp
CommonTest.cpp
$<TARGET_OBJECTS:freeorionparseobj>
$<TARGET_OBJECTS:freeorionparse>
)

target_compile_definitions(fo_unittest_parse
Expand Down
4 changes: 2 additions & 2 deletions universe/Encyclopedia.h
Expand Up @@ -43,9 +43,9 @@ class FO_COMMON_API Encyclopedia {
unsigned int GetCheckSum() const;

/** Sets articles to the value of \p future. */
FO_COMMON_API void SetArticles(Pending::Pending<ArticleMap>&& future);
void SetArticles(Pending::Pending<ArticleMap>&& future);

FO_COMMON_API const ArticleMap& Articles() const;
const ArticleMap& Articles() const;

const EncyclopediaArticle empty_article;
private:
Expand Down
8 changes: 4 additions & 4 deletions universe/ShipDesign.h
Expand Up @@ -193,7 +193,7 @@ class FO_COMMON_API PartTypeManager {
//@}

/** Sets part types to the future value of \p pending_part_types. */
FO_COMMON_API void SetPartTypes(Pending::Pending<PartTypeMap>&& pending_part_types);
void SetPartTypes(Pending::Pending<PartTypeMap>&& pending_part_types);

private:
PartTypeManager();
Expand Down Expand Up @@ -388,7 +388,7 @@ class FO_COMMON_API HullTypeManager {
//@}

/** Sets hull types to the future value of \p pending_hull_types. */
FO_COMMON_API void SetHullTypes(Pending::Pending<HullTypeMap>&& pending_hull_types);
void SetHullTypes(Pending::Pending<HullTypeMap>&& pending_hull_types);

private:
HullTypeManager();
Expand Down Expand Up @@ -687,11 +687,11 @@ class FO_COMMON_API PredefinedShipDesignManager {

/** Sets ship design types to the future value of \p pending_designs
found in \p subdir. */
FO_COMMON_API void SetShipDesignTypes(Pending::Pending<ParsedShipDesignsType>&& pending_designs);
void SetShipDesignTypes(Pending::Pending<ParsedShipDesignsType>&& pending_designs);

/** Sets monster design types to the future value of \p
pending_design_types found in \p subdir. */
FO_COMMON_API void SetMonsterDesignTypes(Pending::Pending<ParsedShipDesignsType>&& pending_designs);
void SetMonsterDesignTypes(Pending::Pending<ParsedShipDesignsType>&& pending_designs);

private:
PredefinedShipDesignManager();
Expand Down
2 changes: 1 addition & 1 deletion universe/Species.h
Expand Up @@ -328,7 +328,7 @@ class FO_COMMON_API SpeciesManager {
std::map<std::string, std::map<std::string, int>>& SpeciesShipsDestroyed(int encoding_empire = ALL_EMPIRES);

/** Sets species types to the value of \p future. */
FO_COMMON_API void SetSpeciesTypes(Pending::Pending<std::pair<SpeciesTypeMap, CensusOrder>>&& future);
void SetSpeciesTypes(Pending::Pending<std::pair<SpeciesTypeMap, CensusOrder>>&& future);

//@}

Expand Down
2 changes: 1 addition & 1 deletion universe/Tech.h
Expand Up @@ -269,7 +269,7 @@ class FO_COMMON_API TechManager {
std::set<std::string> // categories_seen
>;
/** Sets types to the value of \p future. */
FO_COMMON_API void SetTechs(Pending::Pending<TechParseTuple>&& future);
void SetTechs(Pending::Pending<TechParseTuple>&& future);


/** returns the instance of this singleton class; you should use the free function GetTechManager() instead */
Expand Down