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

Building with CMARK_SHARED=OFF fails #247

Closed
ericpruitt opened this issue Nov 12, 2017 · 10 comments
Closed

Building with CMARK_SHARED=OFF fails #247

ericpruitt opened this issue Nov 12, 2017 · 10 comments

Comments

@ericpruitt
Copy link
Contributor

I'm attempting to build a static cmark binary by setting the cmake option "CMARK_SHARED" to "OFF", but the cmark binary fails to build. This is the script I'm using:

rm -rf CMakeFiles/ CMakeCache.txt build/ &&
(
    mkdir -p build &&
    cd build/ &&
    cmake -G "Unix Makefiles" \
        -DCMAKE_BUILD_TYPE= \
        -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
        -DCMARK_TESTS=OFF -DCMARK_SHARED=OFF .. &&
    make
)

The build fails because the compiler is unable to locate some source files. All failed builds show the exact same error:

In file included from /home/ericpruitt/projects/mdlint/cmark/src/node.h:11:0,
                 from /home/ericpruitt/projects/mdlint/cmark/src/node.c:5:
/home/ericpruitt/projects/mdlint/cmark/src/cmark.h:5:26: fatal error: cmark_export.h: No such file or directory
 #include <cmark_export.h>
                          ^
compilation terminated.

Here's the diff of the generated Makefiles with CMAKE_SHARED=ON/OFF:

--- CMAKE_SHARED=ON      2017-11-11 19:01:31.807657734 -0800
+++ CMAKE_SHARED=OFF      2017-11-11 19:08:02.069241357 -0800
@@ -168,19 +168,6 @@
 .PHONY : cmark/fast

 #=============================================================================
-# Target rules for targets named libcmark
-
-# Build rule for target.
-libcmark: cmake_check_build_system
-       $(MAKE) -f CMakeFiles/Makefile2 libcmark
-.PHONY : libcmark
-
-# fast build rule for target.
-libcmark/fast:
-       $(MAKE) -f src/CMakeFiles/libcmark.dir/build.make src/CMakeFiles/libcmark.dir/build
-.PHONY : libcmark/fast
-
-#=============================================================================
 # Target rules for targets named libcmark_static

 # Build rule for target.
@@ -206,7 +193,6 @@
        @echo "... list_install_components"
        @echo "... install"
        @echo "... cmark"
-       @echo "... libcmark"
        @echo "... libcmark_static"
 .PHONY : help

A year and a half ago, I opened #129 , and I was able to build just a static cmark binary by modifying CMakeFiles.txt at your recommendation, but that no longer works either:

cmark [1]$ git diff src/CMakeLists.txt | cat
diff --git src/CMakeLists.txt src/CMakeLists.txt
index d5a1936..7014bd5 100644
--- src/CMakeLists.txt
+++ src/CMakeLists.txt
@@ -80,7 +80,7 @@ elseif(CMAKE_COMPILER_IS_GNUCC OR ${CMAKE_C_COMPILER_ID} STREQUAL "Clang")
 endif ()

 if (CMARK_SHARED)
-  add_library(${LIBRARY} SHARED ${LIBRARY_SOURCES})
+  #add_library(${LIBRARY} SHARED ${LIBRARY_SOURCES})
   # Include minor version and patch level in soname for now.
   set_target_properties(${LIBRARY} PROPERTIES
     OUTPUT_NAME "cmark"
cmark$ make clean
rm -rf build build-mingw windows
cmark$ make
mkdir -p build; \
cd build; \
cmake .. \
        -G "Unix Makefiles" \
        -DCMAKE_BUILD_TYPE= \
        -DCMAKE_INSTALL_PREFIX=/usr/local \
        -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
-- The C compiler identification is GNU 6.3.0
-- The CXX compiler identification is GNU 6.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test HAVE_FLAG_ADDRESS_SANITIZER
-- Performing Test HAVE_FLAG_ADDRESS_SANITIZER - Failed
-- Performing Test HAVE_FLAG_SANITIZE_ADDRESS
-- Performing Test HAVE_FLAG_SANITIZE_ADDRESS - Success
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
CMake Error at src/CMakeLists.txt:85 (set_target_properties):
  set_target_properties Can not find target to add properties to: libcmark


CMake Error at src/CMakeLists.txt:90 (set_property):
  set_property could not find TARGET libcmark.  Perhaps it has not yet been
  created.


CMake Error at src/CMakeLists.txt:94 (set_target_properties):
  set_target_properties Can not find target to add properties to: libcmark


CMake Error at /usr/share/cmake-3.7/Modules/GenerateExportHeader.cmake:370 (get_property):
  get_property could not find TARGET libcmark.  Perhaps it has not yet been
  created.
Call Stack (most recent call first):
  src/CMakeLists.txt:96 (generate_export_header)


CMake Error at src/CMakeLists.txt:131 (install):
  install TARGETS given target "libcmark" which does not exist in this
  directory.


-- Looking for stdbool.h
-- Looking for stdbool.h - found
-- Performing Test HAVE___BUILTIN_EXPECT
-- Performing Test HAVE___BUILTIN_EXPECT - Success
-- Performing Test HAVE___ATTRIBUTE__
-- Performing Test HAVE___ATTRIBUTE__ - Success
-- Found PythonInterp: /usr/bin/python3 (found suitable version "3.5.3", minimum required is "3")
-- Configuring incomplete, errors occurred!
See also "/home/ericpruitt/projects/mdlint/cmark/build/CMakeFiles/CMakeOutput.log".
See also "/home/ericpruitt/projects/mdlint/cmark/build/CMakeFiles/CMakeError.log".
Makefile:37: recipe for target 'build' failed
make: *** [build] Error 1
(2)

How should I go about build a static cmark binary now?

@nwellnhof
Copy link
Contributor

The problem is that the generate_export_header command in CMakeLists.txt is only part of the CMARK_SHARED block, although it is required by both the shared and static build. For a quick workaround, move the command outside of the shared block.

@kivikakk
Copy link
Contributor

I've looked into a fix for this — I'm fairly sure trying to build shared and static at the same time is a bug? They generate different export headers.

@nwellnhof Pulling the command outside of the shared block doesn't work because there's no LIBRARY target when not building the shared library (it's STATICLIBRARY). Just copying the generate_export_header command into the static block (and changing LIBRARY to STATICLIBRARY) means building the static library only works, but building both (the default) fails because the static library's export header overwrites the shared one, and trying to link against the shared library while including the static export header fails.

We either only permit building static or shared at one point in time, or generate separate export headers (which will require source-level tinkering, as we currently just always #include <cmark_export.h>).

@jgm
Copy link
Member

jgm commented Nov 16, 2017

I believe this was fixed by #249, so closing.

@jgm jgm closed this as completed Nov 16, 2017
@ericpruitt
Copy link
Contributor Author

ericpruitt commented Nov 16, 2017

@jgm: Building with CMARK_SHARED=OFF works now, but the end result is a statically linked cmark binary:

cmark$ ldd build/src/cmark
        linux-vdso.so.1 (0x00007fffb4ce5000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f62d7d83000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f62d8373000)

If I want the binary to be statically linked, what options should I set? The CMARK_STATIC and CMARK_SHARED options only mention the library.

@kivikakk
Copy link
Contributor

Currently the binary is always just compiled as a separate target with all the library sources included. (i.e. you can turn both CMARK_STATIC and CMARK_SHARED off, since they don't come into it.)

@ericpruitt
Copy link
Contributor Author

(i.e. you can turn both CMARK_STATIC and CMARK_SHARED off, since they don't come into it.)

Trying to build with both of those set to OFF causes the build to fail with the same error from before:

compilation terminated.
In file included from /home/ericpruitt/projects/mdlint/cmark/src/node.h:11:0,
                 from /home/ericpruitt/projects/mdlint/cmark/src/inlines.c:7:
/home/ericpruitt/projects/mdlint/cmark/src/cmark.h:5:26: fatal error: cmark_export.h: No such file or directory
 #include <cmark_export.h>

My question of how do I compile a static binary still hasn't be answered. I'm not terribly familiar with cmake, and I would like to build a static cmark binary without having to modify files in the repository if possible.

@nwellnhof
Copy link
Contributor

My question of how do I compile a static binary still hasn't be answered.

As @kivikakk said, the cmark executable is always built as a separate target with all the library sources included. This produces exactly the same result as linking with a static cmark library.

@ericpruitt
Copy link
Contributor Author

ericpruitt commented Nov 22, 2018

This produces exactly the same result as linking with a static cmark library.

I'm attempting to work building cmark in a static manner again, and I would like clarification on this comment. Unless I'm missing something, this doesn't appear to be the case because the generated executable depends on linux-vdso.so.1, libc.so.6 and /lib64/ld-linux-x86-64.so.2 as shown by the ldd output above. Just because it's not dynamically linked to the cmark library doesn't mean it isn't dynamically linked to other libraries. I'm trying to make an entirely hermetic binary that doesn't depend on any shared libraries.

@nwellnhof
Copy link
Contributor

nwellnhof commented Nov 22, 2018

You can build a completely static executable like this:

mkdir build
cd build
LDFLAGS=-static cmake -DCMARK_SHARED=OFF ..
make

On my Linux system, this results in:

$ ldd src/cmark
        not a dynamic executable
$ file src/cmark
src/cmark: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=18f8f44fa0e10dc2fc839ae16352dd38b4fb0c15, not stripped

@ericpruitt
Copy link
Contributor Author

Perfect; thank you!

talum referenced this issue in github/cmark-gfm Sep 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants