docopt / docopt.cpp

C++11 port of docopt
Boost Software License 1.0
1.05k stars 146 forks source link

Document how to use CMake #93

Open tdegeus opened 6 years ago

tdegeus commented 6 years ago

I have installed doctopt.cpp as follows:

mkdir /some/tempdir
cd /some/tempdir
cmake /path/to/docopt.cpp
make install

Then I want to use it using CMake, but ${DOCOPT_LIBRARIES} is empty. Here is a simple CMakeLists.txt:

cmake_minimum_required(VERSION 3.1)

# define a project name
project(test)

# define empty list of libraries to link
set(PROJECT_LIBS "")

# set optimization level
set(CMAKE_BUILD_TYPE Release)

# set C++ standard
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# load DOCOPT
find_package(docopt REQUIRED)
include_directories(${DOCOPT_INCLUDE_DIRS})
set(PROJECT_LIBS ${PROJECT_LIBS} ${DOCOPT_LIBRARIES})

# create executable
add_executable(${PROJECT_NAME} main.cpp)

# link libraries
target_link_libraries(${PROJECT_NAME} ${PROJECT_LIBS})

The linker ultimately fails, main.cpp compiles successfully.

tdegeus commented 6 years ago

I have found the solution (see also below). But it would be great if this would be better documented (I edited the title accordingly).

cmake_minimum_required(VERSION 3.1)

# define a project name
project(test)

# define empty list of libraries to link
set(PROJECT_LIBS "")

# set optimization level
set(CMAKE_BUILD_TYPE Release)

# set C++ standard
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# load DOCOPT
find_package(docopt REQUIRED)
include_directories(${DOCOPT_INCLUDE_DIRS})

# create executable
add_executable(${PROJECT_NAME} main.cpp)

# link libraries
target_link_libraries(${PROJECT_NAME} ${PROJECT_LIBS} docopt)
tdegeus commented 6 years ago

I have just found of that this fails when I make using:

cmake /path/to/docopt.cpp -DCMAKE_INSTALL_PREFIX:PATH=$HOME/opt
make install

as ${DOCOPT_INCLUDE_DIRS} is then empty.

kunaltyagi commented 4 years ago

I have the following install structure:

$ tree
.
├── include
│   └── docopt
│       ├── docopt.h
│       ├── docopt_private.h
│       ├── docopt_util.h
│       └── docopt_value.h
├── lib
│   ├── cmake
│   │   └── docopt
│   │       ├── docopt-config-version.cmake
│   │       ├── docopt-config.cmake
│   │       ├── docopt-targets-debug.cmake
│   │       ├── docopt-targets-release.cmake
│   │       └── docopt-targets.cmake
│   ├── libdocopt.0.6.2.dylib
│   ├── libdocopt.0.dylib
│   ├── libdocopt.a
│   ├── libdocopt.dylib
│   ├── libdocoptd.0.6.2.dylib
│   ├── libdocoptd.0.dylib
│   ├── libdocoptd.a
│   ├── libdocoptd.dylib
│   └── pkgconfig
│       └── docopt.pc
└── licenses
    └── docopt
        ├── LICENSE-Boost-1.0
        └── LICENSE-MIT

But when I use the package, I get docopt library target, but DOCOPT_INCLUDE_DIRS is empty. Moreover, there is no output for grep docopt_include * -nri

godbyk commented 4 years ago

Using DOCOPT_INCLUDE_DIRS and DOCOPT_LIBRARIES would be the old-school way of using CMake.

The modern way is to just pass docopt (or docopt_s) to target_link_libraries():

find_package(docopt REQUIRED)
target_link_libraries(myprogram PUBLIC docopt)

The include directories will be added automatically because they're set as properties on the docopt library target.

kunaltyagi commented 4 years ago

My CMakeLists (tried with both the commented version and the uncommented versions)

# find_package (docopt REQUIRED)
find_package (docopt COMPONENTS CXX REQUIRED)
message (STATUS ${DOCOPT_INCLUDE_DIRS})

add_executable (intro src/main.cpp)
#target_link_libraries (intro doctopt)
target_link_libraries (intro PUBLIC doctopt)

${DOCOPT_ROOT} is set and docopt target is available. But I get the error:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++    -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -mmacosx-version-min=10.14   -std=c++1z -MD -MT CMakeFiles/intro.dir/src/main.cpp.o -MF CMakeFiles/intro.dir/src/main.cpp.o.d -o CMakeFiles/intro.dir/src/main.cpp.o -c ../src/main.cpp
../src/main.cpp:1:10: fatal error: 'docopt.h' file not found
#include <docopt.h>

Same issue if I use docopt/ since the header path isn't in the command invocation.

alucardthefish commented 4 years ago

I got this error when compiling the example code given in the Readme page. Can I get some help please?

docoptest.cpp:9:10: fatal error: docopt.h: No such file or directory
    9 | #include <docopt.h>
      |          ^~~~~~~~~~

I installed docopt following the manual installation steps through CMake. I have to say that I don't know much about CMake I just installed it this way:

sudo apt install cmake
# then install docopt
git clone
cmake .
make install
mibli commented 2 years ago

So on arch find_package is borked, because arch doesn't ship static libs. I ended up using pkgconfig in the end, and for that modern PkgConfig::docopt, also didn't work for me. I'll paste that here, in case someone gets as confused as I do.

find_package(PkgConfig REQUIRED)
pkg_check_modules(DOCOPT REQUIRED docopt)

include_directories(${DOCOPT_INCLUDE_DIRS})
target_link_libraries(${CMAKE_PROJECT_NAME} ${DOCOPT_LIBRARIES})