xlnt-community / xlnt

:bar_chart: Cross-platform user-friendly xlsx library for C++11+
https://xlnt-community.github.io/xlnt/
Other
10 stars 2 forks source link

Linking xlnt in my CMake project #21

Closed Egesa18 closed 1 month ago

Egesa18 commented 2 months ago

Hello Guys, I'm having trouble trying to link xlnt in my CMake Project. Is this currently possible? I installed xlnt via vcpkg according to the readme in this repository. However, it seems that these instructions are not updated for this fork? Could I get some help with this?

doomlaur commented 2 months ago

The version from vcpkg is currently @tfussell's XLNT 1.5.0 released in March 2020. That version is ancient, and also @tfussell's master branch contained very important fixes not present in version 1.5.0. Due to the fact that we are trying to fix a few issues before releasing our first stable version (see #4), we have not released a new stable version yet, thus the version on vcpkg is still the very old one, for now.

I recommend you to clone the master branch of this repository and build XLNT from it - it should be much more stable than version 1.5.0. Let us know if it works well for you! :wink:

m7913d commented 2 months ago

You should be able to add xlnt to your CMake project using the following lines:

find_package(Xlnt)
target_link_libraries(<target> PRIVATE xlnt::xlnt)

If CMake does not find it by default, you may need to first specify the location where xlnt is installed:

list(APPEND CMAKE_PREFIX_PATH "/path/to/xlnt/install/prefix")
Egesa18 commented 1 month ago

Hi Guys, thanks for your answers! I was able to clone this master branch and installed XLNT. I have linked it in my cmake project following @m7913d 'suggestion. However, using this instruction target_link_libraries(<target> PRIVATE xlnt::xlnt) I ran into another problem: When I run my program for the first time it makes a copy of the xlnt.dll file in the same folder as my executable, But with subsequent builds the .dll file disappears from that folder and I don't get any expected output in the terminal anymore. This seemed to be resolved when I tried the following configuration: target_link_libraries( <target> PRIVATE "/path/to/xlnt/lib/xlnt.lib) ButI am not sure this is a correct soIution here. Is there anyway how I can link xlnt as a static version in my project?

doomlaur commented 1 month ago

Just to understand your environment a bit better: as far as I understand, you're using Windows. Are you using the Visual C++ compiler or some other compiler? Are you only trying to compile XLNT once and then use it as a binary, or do you want to always compile it together with some external project?

I'm not sure this is what you actually want, but if you would prefer to link XLNT statically, you can use the STATIC option in CMake. However, try to avoid the issues explained in #13.

We can help you more easily if you provide us with a few more details :slightly_smiling_face:

Egesa18 commented 1 month ago

That's correct I am using Windows and Visual C++ compiler. I want to compile XLNT once and then use it as a binary. So I would be interested to know if there is a static version of the library, so that I avoid the missing .dll file problem that occurs when I run my own project in VS Code. The following lines in CMake:

get_target_property(TARGET_TYPE xlnt::xlnt TYPE)
message(STATUS "xlnt::xlnt is a ${TARGET_TYPE} library")

output: [cmake] -- xlnt::xlnt is a SHARED_LIBRARY library so I was wondering if the library provides a static version in addition to the shared version.


Also, another question is: How can I apply a protection object like this one: xlnt::sheet_protection protection; protection.password("1234"); to a worksheet? Is there something similiar to worksheet.protection(protection) currently implemented?

Thanks for your help!

doomlaur commented 1 month ago

First of all, if you really want to link XLNT statically, you can enable the STATIC option in CMake, which is turned off by default. The image attached to issue #13 shows the CMake options that you can easily change according to your preferences.

Secondly, if you prefer to link XLNT dynamically, you can compile XLNT once as a DLL and always copy it using a post-build script. I'll give you an example for doing this using Visual Studio and MSBuild, but you can also achieve something similar with CMake. Here is a simple example of a .bat file that you can use to copy your xlnt.dll to the output directory (of course, you'll need to adapt the paths and either set the environment variables, or remove them and use relative paths):

REM %1 Platform Name
REM %2 Configuration Name

robocopy "%SOURCE_DIR%\Dependencies\xlnt\%1\Release" "%SOURCE_DIR%\%1\%2\bin" /s /ns /nc /nfl /ndl /njh /njs

Or, if necessary, you can even differentiate between Debug and Release builds, or any other builds:

REM %1 Platform Name
REM %2 Configuration Name

if "%2"=="Debug" ( set use_debug_libs=1 )

if defined use_debug_libs (
    ECHO  - xlnt [debug]...
    robocopy "%SOURCE_DIR%\Dependencies\xlnt\%1\Debug" "%SOURCE_DIR%\%1\%2\bin" /s /ns /nc /nfl /ndl /njh /njs
) else (
    ECHO  - xlnt [release]...
    robocopy "%SOURCE_DIR%\Dependencies\xlnt\%1\Release" "%SOURCE_DIR%\%1\%2\bin" /s /ns /nc /nfl /ndl /njh /njs
)

You can then run this after the build process by either editing the .vcxproj file...

<ItemDefinitionGroup>
    <!-- Add the following to the existing "ItemDefinitionGroup". -->
    <PostBuildEvent>
      <Command>post_events.bat $(Platform) $(Configuration)</Command>
    </PostBuildEvent>
</ItemDefinitionGroup>

... or by setting it under "Build Events --> Post-Build Event" in Visual Studio. If you have a very simple use case to only copy XLNT and nothing else, you can even simply write the robocopy command above directly, without using an aditional .bat file.

Note: for even simpler use cases, you can find further examples for configuring post-build scripts on the internet.

To your last question: would the solution described in #19 help? If not, I can look into it :wink:

georgeef commented 1 month ago

Hello,

first of all thank you for your efforts to bring xlnt back to life. I try to use xlnt from another CMake/C++ project on macOS. I need only basic functionality (read: text, numbers; write: text, numbers, font selection, header freeze, group/outline).

v1.5.0 does not compile (it fails at libstudxml). The current master branch (ac1ce21) compiles with minor warnings. Is it usable at least for basic functionality, or is it still unstable?

If it is partially stable, I could work with this, however the master branch is a moving target. Could you add a tag and probably also a short description in REAMDE of what functionality is OK or not OK?

If the master branch is still not usable, could you add a milestone with an estimated release date?

m7913d commented 1 month ago

@georgeef The master branch should be fairly "stable": what currently works, should continue to work when the master branch is updated. We have CI in place containing many unit tests on multiple compiler versions (gcc on unix and msvc on windows, currently not on mac) to ensure backwards compatibility before a PR is merged with the master branch. All changes are reviewed before merging with master branch.

The idea is to release a v1.6.0 in the future, but I can't give you an estimated release date at the moment.

Using the latest master branch should be definitely better than using v1.5.0 as it contains many bug fixes. Just live at head (at least for now).

The best overview of the currently supported features is mentioned in the documentation. You can also have a look at the API documentation (especially the worksheet and workbook classes may be a good starting point): this should give you the most detailed view of what is currently implemented.

georgeef commented 1 month ago

@m7913d Thank you for your quick reply and for the information.

I can definitely work with the master head, but I prefer to give a fixed version in the "build from source" instructions in my project (just to avoid unpredictable surprises). At the moment I give instructions to clone and switch to a specific commit, which is a bit weird.

EDIT: Maybe a submodule would be better instead of separate download and build.

m7913d commented 1 month ago

@georgeef I understand. Currently, I see two options:

m7913d commented 1 month ago

@Egesa18 I'm going to close this issue, as I think the issue is resolved. Feel free to reopen the issue if needed.

Note that I also added some more information to the installation documentation.