在堆栈的包文件中,库和可执行文件依赖项之间有什么区别?
On a stack's package file, what is the difference between library and executables dependencies?
在Haskell中,在使用stack时,我们可以在三个地方定义dependencies 在 package.yaml
文件上;在 library
和 executables
下。在这些地方定义依赖有什么区别,我应该在什么时候使用它们?
假设您想要使用两个前端构建和应用程序:CLI 和 GUI,两者都使用相同的底层逻辑。显然,您的 CLI 不使用任何图形库,因此它不应该依赖于它们,反之亦然。您的 package.yaml
看起来像。
name: my-app
version: 0.1.0.0
# This are the dependencies all the components depends on.
dependencies:
- base >= 4.7 && < 5
# This is the description of your "common logic" i.e. the library
library:
source-dirs: src
# depends on whatever libraries of your choice
dependencies:
- bytestring
- megaparsec
- parser-combinators
- transformers
executables:
# The executable name for the cli
my-app-cli:
# The main function is in cli.hs
main: cli.hs
source-dirs: app
ghc-options:
- -Wall
- -Wextra
- -threaded
- -rtsopts
- -with-rtsopts=-qg
# It depends on you library, the base library (which remember is at the top of the file), and on whatever other libraries you use to build the cli, for example optparse-applicative
dependencies:
- my-app
- optparse-applicative
# The executable name for the GUI
my-app-gui:
# The main function is on gui.hs
main: gui.hs
source-dirs: app
ghc-options:
- -Wall
- -Wextra
- -threaded
- -rtsopts
- -with-rtsopts=-qg
# Again, It depends on your library, the base, and a GUI library of your choice. Example monomer.
dependencies:
- my-app
- monomer
现在,当您 运行 stack build
时,它将创建两个可执行文件,一个名为 my-app-cli
,另一个名为 my-app-gui
,每个都有自己的依赖项,但共享公共的.理想情况下,可以 运行 stack build my-app:my-app-cli
只构建一个可执行文件,但由于某种原因 stack
构建所有内容(这显然是由于某些 cabal
行为......不要'不知道,不在乎)
话虽如此,我认为这与其他编程语言没有什么不同。例如,我倾向于以相同的方式构建我的 Python
代码。一个有自己 requirements.txt
的公共库,然后每个应用程序都有自己的 requirement.txt
,具体取决于应用程序是 Web 服务器、机器学习模型还是什么……这简化了缓存层的创建例如在 docker 中。如果我需要向 Web 服务器添加一些依赖项,它们将被添加到 Web 服务器 requirements.txt
而不是库服务器。这当然是自以为是,但我的观点是这不是 haskell 具体的。
在Haskell中,在使用stack时,我们可以在三个地方定义dependencies 在 package.yaml
文件上;在 library
和 executables
下。在这些地方定义依赖有什么区别,我应该在什么时候使用它们?
假设您想要使用两个前端构建和应用程序:CLI 和 GUI,两者都使用相同的底层逻辑。显然,您的 CLI 不使用任何图形库,因此它不应该依赖于它们,反之亦然。您的 package.yaml
看起来像。
name: my-app
version: 0.1.0.0
# This are the dependencies all the components depends on.
dependencies:
- base >= 4.7 && < 5
# This is the description of your "common logic" i.e. the library
library:
source-dirs: src
# depends on whatever libraries of your choice
dependencies:
- bytestring
- megaparsec
- parser-combinators
- transformers
executables:
# The executable name for the cli
my-app-cli:
# The main function is in cli.hs
main: cli.hs
source-dirs: app
ghc-options:
- -Wall
- -Wextra
- -threaded
- -rtsopts
- -with-rtsopts=-qg
# It depends on you library, the base library (which remember is at the top of the file), and on whatever other libraries you use to build the cli, for example optparse-applicative
dependencies:
- my-app
- optparse-applicative
# The executable name for the GUI
my-app-gui:
# The main function is on gui.hs
main: gui.hs
source-dirs: app
ghc-options:
- -Wall
- -Wextra
- -threaded
- -rtsopts
- -with-rtsopts=-qg
# Again, It depends on your library, the base, and a GUI library of your choice. Example monomer.
dependencies:
- my-app
- monomer
现在,当您 运行 stack build
时,它将创建两个可执行文件,一个名为 my-app-cli
,另一个名为 my-app-gui
,每个都有自己的依赖项,但共享公共的.理想情况下,可以 运行 stack build my-app:my-app-cli
只构建一个可执行文件,但由于某种原因 stack
构建所有内容(这显然是由于某些 cabal
行为......不要'不知道,不在乎)
话虽如此,我认为这与其他编程语言没有什么不同。例如,我倾向于以相同的方式构建我的 Python
代码。一个有自己 requirements.txt
的公共库,然后每个应用程序都有自己的 requirement.txt
,具体取决于应用程序是 Web 服务器、机器学习模型还是什么……这简化了缓存层的创建例如在 docker 中。如果我需要向 Web 服务器添加一些依赖项,它们将被添加到 Web 服务器 requirements.txt
而不是库服务器。这当然是自以为是,但我的观点是这不是 haskell 具体的。